OSDN Git Service

* config/i386/i386.h (NON_STACK_REG_P, REGNO_OK_FOR_SIREG_P,
[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
125    ; x87 Rounding
126    (UNSPEC_FRNDINT_FLOOR        70)
127    (UNSPEC_FRNDINT_CEIL         71)
128    (UNSPEC_FRNDINT_TRUNC        72)
129    (UNSPEC_FRNDINT_MASK_PM      73)
130    (UNSPEC_FIST_FLOOR           74)
131    (UNSPEC_FIST_CEIL            75)
132
133    ; x87 Double output FP
134    (UNSPEC_SINCOS_COS           80)
135    (UNSPEC_SINCOS_SIN           81)
136    (UNSPEC_TAN_ONE              82)
137    (UNSPEC_TAN_TAN              83)
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
159 (define_constants
160   [(UNSPECV_BLOCKAGE            0)
161    (UNSPECV_STACK_PROBE         1)
162    (UNSPECV_EMMS                2)
163    (UNSPECV_LDMXCSR             3)
164    (UNSPECV_STMXCSR             4)
165    (UNSPECV_FEMMS               5)
166    (UNSPECV_CLFLUSH             6)
167    (UNSPECV_ALIGN               7)
168    (UNSPECV_MONITOR             8)
169    (UNSPECV_MWAIT               9)
170    (UNSPECV_CMPXCHG_1           10)
171    (UNSPECV_CMPXCHG_2           11)
172    (UNSPECV_XCHG                12)
173    (UNSPECV_LOCK                13)
174   ])
175
176 ;; Registers by name.
177 (define_constants
178   [(BP_REG                       6)
179    (SP_REG                       7)
180    (FLAGS_REG                   17)
181    (FPSR_REG                    18)
182    (FPCR_REG                    19)
183    (R10_REG                     39)
184    (R11_REG                     40)
185   ])
186
187 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
188 ;; from i386.c.
189
190 ;; In C guard expressions, put expressions which may be compile-time
191 ;; constants first.  This allows for better optimization.  For
192 ;; example, write "TARGET_64BIT && reload_completed", not
193 ;; "reload_completed && TARGET_64BIT".
194
195 \f
196 ;; Processor type.  This attribute must exactly match the processor_type
197 ;; enumeration in i386.h.
198 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
199   (const (symbol_ref "ix86_tune")))
200
201 ;; A basic instruction type.  Refinements due to arguments to be
202 ;; provided in other attributes.
203 (define_attr "type"
204   "other,multi,
205    alu,alu1,negnot,imov,imovx,lea,
206    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
207    icmp,test,ibr,setcc,icmov,
208    push,pop,call,callv,leave,
209    str,
210    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
211    sselog,sselog1,sseiadd,sseishft,sseimul,
212    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
213    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
214   (const_string "other"))
215
216 ;; Main data type used by the insn
217 (define_attr "mode"
218   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
219   (const_string "unknown"))
220
221 ;; The CPU unit operations uses.
222 (define_attr "unit" "integer,i387,sse,mmx,unknown"
223   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
224            (const_string "i387")
225          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
226                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
227            (const_string "sse")
228          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
229            (const_string "mmx")
230          (eq_attr "type" "other")
231            (const_string "unknown")]
232          (const_string "integer")))
233
234 ;; The (bounding maximum) length of an instruction immediate.
235 (define_attr "length_immediate" ""
236   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave")
237            (const_int 0)
238          (eq_attr "unit" "i387,sse,mmx")
239            (const_int 0)
240          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
241                           imul,icmp,push,pop")
242            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
243          (eq_attr "type" "imov,test")
244            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
245          (eq_attr "type" "call")
246            (if_then_else (match_operand 0 "constant_call_address_operand" "")
247              (const_int 4)
248              (const_int 0))
249          (eq_attr "type" "callv")
250            (if_then_else (match_operand 1 "constant_call_address_operand" "")
251              (const_int 4)
252              (const_int 0))
253          ;; We don't know the size before shorten_branches.  Expect
254          ;; the instruction to fit for better scheduling.
255          (eq_attr "type" "ibr")
256            (const_int 1)
257          ]
258          (symbol_ref "/* Update immediate_length and other attributes! */
259                       gcc_unreachable (),1")))
260
261 ;; The (bounding maximum) length of an instruction address.
262 (define_attr "length_address" ""
263   (cond [(eq_attr "type" "str,other,multi,fxch")
264            (const_int 0)
265          (and (eq_attr "type" "call")
266               (match_operand 0 "constant_call_address_operand" ""))
267              (const_int 0)
268          (and (eq_attr "type" "callv")
269               (match_operand 1 "constant_call_address_operand" ""))
270              (const_int 0)
271          ]
272          (symbol_ref "ix86_attr_length_address_default (insn)")))
273
274 ;; Set when length prefix is used.
275 (define_attr "prefix_data16" ""
276   (if_then_else (ior (eq_attr "mode" "HI")
277                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
278     (const_int 1)
279     (const_int 0)))
280
281 ;; Set when string REP prefix is used.
282 (define_attr "prefix_rep" ""
283   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
284     (const_int 1)
285     (const_int 0)))
286
287 ;; Set when 0f opcode prefix is used.
288 (define_attr "prefix_0f" ""
289   (if_then_else
290     (ior (eq_attr "type" "imovx,setcc,icmov")
291          (eq_attr "unit" "sse,mmx"))
292     (const_int 1)
293     (const_int 0)))
294
295 ;; Set when REX opcode prefix is used.
296 (define_attr "prefix_rex" ""
297   (cond [(and (eq_attr "mode" "DI")
298               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
299            (const_int 1)
300          (and (eq_attr "mode" "QI")
301               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
302                   (const_int 0)))
303            (const_int 1)
304          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
305              (const_int 0))
306            (const_int 1)
307         ]
308         (const_int 0)))
309
310 ;; Set when modrm byte is used.
311 (define_attr "modrm" ""
312   (cond [(eq_attr "type" "str,leave")
313            (const_int 0)
314          (eq_attr "unit" "i387")
315            (const_int 0)
316          (and (eq_attr "type" "incdec")
317               (ior (match_operand:SI 1 "register_operand" "")
318                    (match_operand:HI 1 "register_operand" "")))
319            (const_int 0)
320          (and (eq_attr "type" "push")
321               (not (match_operand 1 "memory_operand" "")))
322            (const_int 0)
323          (and (eq_attr "type" "pop")
324               (not (match_operand 0 "memory_operand" "")))
325            (const_int 0)
326          (and (eq_attr "type" "imov")
327               (ior (and (match_operand 0 "register_operand" "")
328                         (match_operand 1 "immediate_operand" ""))
329                    (ior (and (match_operand 0 "ax_reg_operand" "")
330                              (match_operand 1 "memory_displacement_only_operand" ""))
331                         (and (match_operand 0 "memory_displacement_only_operand" "")
332                              (match_operand 1 "ax_reg_operand" "")))))
333            (const_int 0)
334          (and (eq_attr "type" "call")
335               (match_operand 0 "constant_call_address_operand" ""))
336              (const_int 0)
337          (and (eq_attr "type" "callv")
338               (match_operand 1 "constant_call_address_operand" ""))
339              (const_int 0)
340          ]
341          (const_int 1)))
342
343 ;; The (bounding maximum) length of an instruction in bytes.
344 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
345 ;; Later we may want to split them and compute proper length as for
346 ;; other insns.
347 (define_attr "length" ""
348   (cond [(eq_attr "type" "other,multi,fistp,frndint")
349            (const_int 16)
350          (eq_attr "type" "fcmp")
351            (const_int 4)
352          (eq_attr "unit" "i387")
353            (plus (const_int 2)
354                  (plus (attr "prefix_data16")
355                        (attr "length_address")))]
356          (plus (plus (attr "modrm")
357                      (plus (attr "prefix_0f")
358                            (plus (attr "prefix_rex")
359                                  (const_int 1))))
360                (plus (attr "prefix_rep")
361                      (plus (attr "prefix_data16")
362                            (plus (attr "length_immediate")
363                                  (attr "length_address")))))))
364
365 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
366 ;; `store' if there is a simple memory reference therein, or `unknown'
367 ;; if the instruction is complex.
368
369 (define_attr "memory" "none,load,store,both,unknown"
370   (cond [(eq_attr "type" "other,multi,str")
371            (const_string "unknown")
372          (eq_attr "type" "lea,fcmov,fpspc")
373            (const_string "none")
374          (eq_attr "type" "fistp,leave")
375            (const_string "both")
376          (eq_attr "type" "frndint")
377            (const_string "load")
378          (eq_attr "type" "push")
379            (if_then_else (match_operand 1 "memory_operand" "")
380              (const_string "both")
381              (const_string "store"))
382          (eq_attr "type" "pop")
383            (if_then_else (match_operand 0 "memory_operand" "")
384              (const_string "both")
385              (const_string "load"))
386          (eq_attr "type" "setcc")
387            (if_then_else (match_operand 0 "memory_operand" "")
388              (const_string "store")
389              (const_string "none"))
390          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
391            (if_then_else (ior (match_operand 0 "memory_operand" "")
392                               (match_operand 1 "memory_operand" ""))
393              (const_string "load")
394              (const_string "none"))
395          (eq_attr "type" "ibr")
396            (if_then_else (match_operand 0 "memory_operand" "")
397              (const_string "load")
398              (const_string "none"))
399          (eq_attr "type" "call")
400            (if_then_else (match_operand 0 "constant_call_address_operand" "")
401              (const_string "none")
402              (const_string "load"))
403          (eq_attr "type" "callv")
404            (if_then_else (match_operand 1 "constant_call_address_operand" "")
405              (const_string "none")
406              (const_string "load"))
407          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
408               (match_operand 1 "memory_operand" ""))
409            (const_string "both")
410          (and (match_operand 0 "memory_operand" "")
411               (match_operand 1 "memory_operand" ""))
412            (const_string "both")
413          (match_operand 0 "memory_operand" "")
414            (const_string "store")
415          (match_operand 1 "memory_operand" "")
416            (const_string "load")
417          (and (eq_attr "type"
418                  "!alu1,negnot,ishift1,
419                    imov,imovx,icmp,test,
420                    fmov,fcmp,fsgn,
421                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
422                    mmx,mmxmov,mmxcmp,mmxcvt")
423               (match_operand 2 "memory_operand" ""))
424            (const_string "load")
425          (and (eq_attr "type" "icmov")
426               (match_operand 3 "memory_operand" ""))
427            (const_string "load")
428         ]
429         (const_string "none")))
430
431 ;; Indicates if an instruction has both an immediate and a displacement.
432
433 (define_attr "imm_disp" "false,true,unknown"
434   (cond [(eq_attr "type" "other,multi")
435            (const_string "unknown")
436          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
437               (and (match_operand 0 "memory_displacement_operand" "")
438                    (match_operand 1 "immediate_operand" "")))
439            (const_string "true")
440          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
441               (and (match_operand 0 "memory_displacement_operand" "")
442                    (match_operand 2 "immediate_operand" "")))
443            (const_string "true")
444         ]
445         (const_string "false")))
446
447 ;; Indicates if an FP operation has an integer source.
448
449 (define_attr "fp_int_src" "false,true"
450   (const_string "false"))
451
452 ;; Defines rounding mode of an FP operation.
453
454 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
455   (const_string "any"))
456
457 ;; Describe a user's asm statement.
458 (define_asm_attributes
459   [(set_attr "length" "128")
460    (set_attr "type" "multi")])
461
462 ;; All x87 floating point modes
463 (define_mode_macro X87MODEF [SF DF XF])
464
465 ;; x87 SFmode and DFMode floating point modes
466 (define_mode_macro X87MODEF12 [SF DF])
467
468 ;; All integer modes handled by x87 fisttp operator.
469 (define_mode_macro X87MODEI [HI SI DI])
470
471 ;; All integer modes handled by integer x87 operators.
472 (define_mode_macro X87MODEI12 [HI SI])
473
474 ;; All SSE floating point modes
475 (define_mode_macro SSEMODEF [SF DF])
476
477 ;; All integer modes handled by SSE cvtts?2si* operators.
478 (define_mode_macro SSEMODEI24 [SI DI])
479
480 ;; SSE asm suffix for floating point modes
481 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
482
483 \f
484 ;; Scheduling descriptions
485
486 (include "pentium.md")
487 (include "ppro.md")
488 (include "k6.md")
489 (include "athlon.md")
490 (include "geode.md")
491
492 \f
493 ;; Operand and operator predicates and constraints
494
495 (include "predicates.md")
496 (include "constraints.md")
497
498 \f
499 ;; Compare instructions.
500
501 ;; All compare insns have expanders that save the operands away without
502 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
503 ;; after the cmp) will actually emit the cmpM.
504
505 (define_expand "cmpti"
506   [(set (reg:CC FLAGS_REG)
507         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
508                     (match_operand:TI 1 "x86_64_general_operand" "")))]
509   "TARGET_64BIT"
510 {
511   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
512     operands[0] = force_reg (TImode, operands[0]);
513   ix86_compare_op0 = operands[0];
514   ix86_compare_op1 = operands[1];
515   DONE;
516 })
517
518 (define_expand "cmpdi"
519   [(set (reg:CC FLAGS_REG)
520         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
521                     (match_operand:DI 1 "x86_64_general_operand" "")))]
522   ""
523 {
524   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
525     operands[0] = force_reg (DImode, operands[0]);
526   ix86_compare_op0 = operands[0];
527   ix86_compare_op1 = operands[1];
528   DONE;
529 })
530
531 (define_expand "cmpsi"
532   [(set (reg:CC FLAGS_REG)
533         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
534                     (match_operand:SI 1 "general_operand" "")))]
535   ""
536 {
537   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
538     operands[0] = force_reg (SImode, operands[0]);
539   ix86_compare_op0 = operands[0];
540   ix86_compare_op1 = operands[1];
541   DONE;
542 })
543
544 (define_expand "cmphi"
545   [(set (reg:CC FLAGS_REG)
546         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
547                     (match_operand:HI 1 "general_operand" "")))]
548   ""
549 {
550   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
551     operands[0] = force_reg (HImode, operands[0]);
552   ix86_compare_op0 = operands[0];
553   ix86_compare_op1 = operands[1];
554   DONE;
555 })
556
557 (define_expand "cmpqi"
558   [(set (reg:CC FLAGS_REG)
559         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
560                     (match_operand:QI 1 "general_operand" "")))]
561   "TARGET_QIMODE_MATH"
562 {
563   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
564     operands[0] = force_reg (QImode, operands[0]);
565   ix86_compare_op0 = operands[0];
566   ix86_compare_op1 = operands[1];
567   DONE;
568 })
569
570 (define_insn "cmpdi_ccno_1_rex64"
571   [(set (reg FLAGS_REG)
572         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
573                  (match_operand:DI 1 "const0_operand" "n,n")))]
574   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
575   "@
576    test{q}\t{%0, %0|%0, %0}
577    cmp{q}\t{%1, %0|%0, %1}"
578   [(set_attr "type" "test,icmp")
579    (set_attr "length_immediate" "0,1")
580    (set_attr "mode" "DI")])
581
582 (define_insn "*cmpdi_minus_1_rex64"
583   [(set (reg FLAGS_REG)
584         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
585                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
586                  (const_int 0)))]
587   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
588   "cmp{q}\t{%1, %0|%0, %1}"
589   [(set_attr "type" "icmp")
590    (set_attr "mode" "DI")])
591
592 (define_expand "cmpdi_1_rex64"
593   [(set (reg:CC FLAGS_REG)
594         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
595                     (match_operand:DI 1 "general_operand" "")))]
596   "TARGET_64BIT"
597   "")
598
599 (define_insn "cmpdi_1_insn_rex64"
600   [(set (reg FLAGS_REG)
601         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
602                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
603   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
604   "cmp{q}\t{%1, %0|%0, %1}"
605   [(set_attr "type" "icmp")
606    (set_attr "mode" "DI")])
607
608
609 (define_insn "*cmpsi_ccno_1"
610   [(set (reg FLAGS_REG)
611         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
612                  (match_operand:SI 1 "const0_operand" "n,n")))]
613   "ix86_match_ccmode (insn, CCNOmode)"
614   "@
615    test{l}\t{%0, %0|%0, %0}
616    cmp{l}\t{%1, %0|%0, %1}"
617   [(set_attr "type" "test,icmp")
618    (set_attr "length_immediate" "0,1")
619    (set_attr "mode" "SI")])
620
621 (define_insn "*cmpsi_minus_1"
622   [(set (reg FLAGS_REG)
623         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
624                            (match_operand:SI 1 "general_operand" "ri,mr"))
625                  (const_int 0)))]
626   "ix86_match_ccmode (insn, CCGOCmode)"
627   "cmp{l}\t{%1, %0|%0, %1}"
628   [(set_attr "type" "icmp")
629    (set_attr "mode" "SI")])
630
631 (define_expand "cmpsi_1"
632   [(set (reg:CC FLAGS_REG)
633         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
634                     (match_operand:SI 1 "general_operand" "ri,mr")))]
635   ""
636   "")
637
638 (define_insn "*cmpsi_1_insn"
639   [(set (reg FLAGS_REG)
640         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
641                  (match_operand:SI 1 "general_operand" "ri,mr")))]
642   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
643     && ix86_match_ccmode (insn, CCmode)"
644   "cmp{l}\t{%1, %0|%0, %1}"
645   [(set_attr "type" "icmp")
646    (set_attr "mode" "SI")])
647
648 (define_insn "*cmphi_ccno_1"
649   [(set (reg FLAGS_REG)
650         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
651                  (match_operand:HI 1 "const0_operand" "n,n")))]
652   "ix86_match_ccmode (insn, CCNOmode)"
653   "@
654    test{w}\t{%0, %0|%0, %0}
655    cmp{w}\t{%1, %0|%0, %1}"
656   [(set_attr "type" "test,icmp")
657    (set_attr "length_immediate" "0,1")
658    (set_attr "mode" "HI")])
659
660 (define_insn "*cmphi_minus_1"
661   [(set (reg FLAGS_REG)
662         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
663                            (match_operand:HI 1 "general_operand" "ri,mr"))
664                  (const_int 0)))]
665   "ix86_match_ccmode (insn, CCGOCmode)"
666   "cmp{w}\t{%1, %0|%0, %1}"
667   [(set_attr "type" "icmp")
668    (set_attr "mode" "HI")])
669
670 (define_insn "*cmphi_1"
671   [(set (reg FLAGS_REG)
672         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
673                  (match_operand:HI 1 "general_operand" "ri,mr")))]
674   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
675    && ix86_match_ccmode (insn, CCmode)"
676   "cmp{w}\t{%1, %0|%0, %1}"
677   [(set_attr "type" "icmp")
678    (set_attr "mode" "HI")])
679
680 (define_insn "*cmpqi_ccno_1"
681   [(set (reg FLAGS_REG)
682         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
683                  (match_operand:QI 1 "const0_operand" "n,n")))]
684   "ix86_match_ccmode (insn, CCNOmode)"
685   "@
686    test{b}\t{%0, %0|%0, %0}
687    cmp{b}\t{$0, %0|%0, 0}"
688   [(set_attr "type" "test,icmp")
689    (set_attr "length_immediate" "0,1")
690    (set_attr "mode" "QI")])
691
692 (define_insn "*cmpqi_1"
693   [(set (reg FLAGS_REG)
694         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
695                  (match_operand:QI 1 "general_operand" "qi,mq")))]
696   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
697     && ix86_match_ccmode (insn, CCmode)"
698   "cmp{b}\t{%1, %0|%0, %1}"
699   [(set_attr "type" "icmp")
700    (set_attr "mode" "QI")])
701
702 (define_insn "*cmpqi_minus_1"
703   [(set (reg FLAGS_REG)
704         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
705                            (match_operand:QI 1 "general_operand" "qi,mq"))
706                  (const_int 0)))]
707   "ix86_match_ccmode (insn, CCGOCmode)"
708   "cmp{b}\t{%1, %0|%0, %1}"
709   [(set_attr "type" "icmp")
710    (set_attr "mode" "QI")])
711
712 (define_insn "*cmpqi_ext_1"
713   [(set (reg FLAGS_REG)
714         (compare
715           (match_operand:QI 0 "general_operand" "Qm")
716           (subreg:QI
717             (zero_extract:SI
718               (match_operand 1 "ext_register_operand" "Q")
719               (const_int 8)
720               (const_int 8)) 0)))]
721   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
722   "cmp{b}\t{%h1, %0|%0, %h1}"
723   [(set_attr "type" "icmp")
724    (set_attr "mode" "QI")])
725
726 (define_insn "*cmpqi_ext_1_rex64"
727   [(set (reg FLAGS_REG)
728         (compare
729           (match_operand:QI 0 "register_operand" "Q")
730           (subreg:QI
731             (zero_extract:SI
732               (match_operand 1 "ext_register_operand" "Q")
733               (const_int 8)
734               (const_int 8)) 0)))]
735   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
736   "cmp{b}\t{%h1, %0|%0, %h1}"
737   [(set_attr "type" "icmp")
738    (set_attr "mode" "QI")])
739
740 (define_insn "*cmpqi_ext_2"
741   [(set (reg FLAGS_REG)
742         (compare
743           (subreg:QI
744             (zero_extract:SI
745               (match_operand 0 "ext_register_operand" "Q")
746               (const_int 8)
747               (const_int 8)) 0)
748           (match_operand:QI 1 "const0_operand" "n")))]
749   "ix86_match_ccmode (insn, CCNOmode)"
750   "test{b}\t%h0, %h0"
751   [(set_attr "type" "test")
752    (set_attr "length_immediate" "0")
753    (set_attr "mode" "QI")])
754
755 (define_expand "cmpqi_ext_3"
756   [(set (reg:CC FLAGS_REG)
757         (compare:CC
758           (subreg:QI
759             (zero_extract:SI
760               (match_operand 0 "ext_register_operand" "")
761               (const_int 8)
762               (const_int 8)) 0)
763           (match_operand:QI 1 "general_operand" "")))]
764   ""
765   "")
766
767 (define_insn "cmpqi_ext_3_insn"
768   [(set (reg FLAGS_REG)
769         (compare
770           (subreg:QI
771             (zero_extract:SI
772               (match_operand 0 "ext_register_operand" "Q")
773               (const_int 8)
774               (const_int 8)) 0)
775           (match_operand:QI 1 "general_operand" "Qmn")))]
776   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
777   "cmp{b}\t{%1, %h0|%h0, %1}"
778   [(set_attr "type" "icmp")
779    (set_attr "mode" "QI")])
780
781 (define_insn "cmpqi_ext_3_insn_rex64"
782   [(set (reg FLAGS_REG)
783         (compare
784           (subreg:QI
785             (zero_extract:SI
786               (match_operand 0 "ext_register_operand" "Q")
787               (const_int 8)
788               (const_int 8)) 0)
789           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
790   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
791   "cmp{b}\t{%1, %h0|%h0, %1}"
792   [(set_attr "type" "icmp")
793    (set_attr "mode" "QI")])
794
795 (define_insn "*cmpqi_ext_4"
796   [(set (reg FLAGS_REG)
797         (compare
798           (subreg:QI
799             (zero_extract:SI
800               (match_operand 0 "ext_register_operand" "Q")
801               (const_int 8)
802               (const_int 8)) 0)
803           (subreg:QI
804             (zero_extract:SI
805               (match_operand 1 "ext_register_operand" "Q")
806               (const_int 8)
807               (const_int 8)) 0)))]
808   "ix86_match_ccmode (insn, CCmode)"
809   "cmp{b}\t{%h1, %h0|%h0, %h1}"
810   [(set_attr "type" "icmp")
811    (set_attr "mode" "QI")])
812
813 ;; These implement float point compares.
814 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
815 ;; which would allow mix and match FP modes on the compares.  Which is what
816 ;; the old patterns did, but with many more of them.
817
818 (define_expand "cmpxf"
819   [(set (reg:CC FLAGS_REG)
820         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
821                     (match_operand:XF 1 "nonmemory_operand" "")))]
822   "TARGET_80387"
823 {
824   ix86_compare_op0 = operands[0];
825   ix86_compare_op1 = operands[1];
826   DONE;
827 })
828
829 (define_expand "cmpdf"
830   [(set (reg:CC FLAGS_REG)
831         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
832                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
833   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
834 {
835   ix86_compare_op0 = operands[0];
836   ix86_compare_op1 = operands[1];
837   DONE;
838 })
839
840 (define_expand "cmpsf"
841   [(set (reg:CC FLAGS_REG)
842         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
843                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
844   "TARGET_80387 || TARGET_SSE_MATH"
845 {
846   ix86_compare_op0 = operands[0];
847   ix86_compare_op1 = operands[1];
848   DONE;
849 })
850
851 ;; FP compares, step 1:
852 ;; Set the FP condition codes.
853 ;;
854 ;; CCFPmode     compare with exceptions
855 ;; CCFPUmode    compare with no exceptions
856
857 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
858 ;; used to manage the reg stack popping would not be preserved.
859
860 (define_insn "*cmpfp_0"
861   [(set (match_operand:HI 0 "register_operand" "=a")
862         (unspec:HI
863           [(compare:CCFP
864              (match_operand 1 "register_operand" "f")
865              (match_operand 2 "const0_operand" "X"))]
866         UNSPEC_FNSTSW))]
867   "TARGET_80387
868    && FLOAT_MODE_P (GET_MODE (operands[1]))
869    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
870   "* return output_fp_compare (insn, operands, 0, 0);"
871   [(set_attr "type" "multi")
872    (set_attr "unit" "i387")
873    (set (attr "mode")
874      (cond [(match_operand:SF 1 "" "")
875               (const_string "SF")
876             (match_operand:DF 1 "" "")
877               (const_string "DF")
878            ]
879            (const_string "XF")))])
880
881 (define_insn "*cmpfp_sf"
882   [(set (match_operand:HI 0 "register_operand" "=a")
883         (unspec:HI
884           [(compare:CCFP
885              (match_operand:SF 1 "register_operand" "f")
886              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
887           UNSPEC_FNSTSW))]
888   "TARGET_80387"
889   "* return output_fp_compare (insn, operands, 0, 0);"
890   [(set_attr "type" "multi")
891    (set_attr "unit" "i387")
892    (set_attr "mode" "SF")])
893
894 (define_insn "*cmpfp_df"
895   [(set (match_operand:HI 0 "register_operand" "=a")
896         (unspec:HI
897           [(compare:CCFP
898              (match_operand:DF 1 "register_operand" "f")
899              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
900           UNSPEC_FNSTSW))]
901   "TARGET_80387"
902   "* return output_fp_compare (insn, operands, 0, 0);"
903   [(set_attr "type" "multi")
904    (set_attr "unit" "i387")
905    (set_attr "mode" "DF")])
906
907 (define_insn "*cmpfp_xf"
908   [(set (match_operand:HI 0 "register_operand" "=a")
909         (unspec:HI
910           [(compare:CCFP
911              (match_operand:XF 1 "register_operand" "f")
912              (match_operand:XF 2 "register_operand" "f"))]
913           UNSPEC_FNSTSW))]
914   "TARGET_80387"
915   "* return output_fp_compare (insn, operands, 0, 0);"
916   [(set_attr "type" "multi")
917    (set_attr "unit" "i387")
918    (set_attr "mode" "XF")])
919
920 (define_insn "*cmpfp_u"
921   [(set (match_operand:HI 0 "register_operand" "=a")
922         (unspec:HI
923           [(compare:CCFPU
924              (match_operand 1 "register_operand" "f")
925              (match_operand 2 "register_operand" "f"))]
926           UNSPEC_FNSTSW))]
927   "TARGET_80387
928    && FLOAT_MODE_P (GET_MODE (operands[1]))
929    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
930   "* return output_fp_compare (insn, operands, 0, 1);"
931   [(set_attr "type" "multi")
932    (set_attr "unit" "i387")
933    (set (attr "mode")
934      (cond [(match_operand:SF 1 "" "")
935               (const_string "SF")
936             (match_operand:DF 1 "" "")
937               (const_string "DF")
938            ]
939            (const_string "XF")))])
940
941 (define_insn "*cmpfp_<mode>"
942   [(set (match_operand:HI 0 "register_operand" "=a")
943         (unspec:HI
944           [(compare:CCFP
945              (match_operand 1 "register_operand" "f")
946              (match_operator 3 "float_operator"
947                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
948           UNSPEC_FNSTSW))]
949   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
950    && FLOAT_MODE_P (GET_MODE (operands[1]))
951    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
952   "* return output_fp_compare (insn, operands, 0, 0);"
953   [(set_attr "type" "multi")
954    (set_attr "unit" "i387")
955    (set_attr "fp_int_src" "true")
956    (set_attr "mode" "<MODE>")])
957
958 ;; FP compares, step 2
959 ;; Move the fpsw to ax.
960
961 (define_insn "x86_fnstsw_1"
962   [(set (match_operand:HI 0 "register_operand" "=a")
963         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
964   "TARGET_80387"
965   "fnstsw\t%0"
966   [(set_attr "length" "2")
967    (set_attr "mode" "SI")
968    (set_attr "unit" "i387")])
969
970 ;; FP compares, step 3
971 ;; Get ax into flags, general case.
972
973 (define_insn "x86_sahf_1"
974   [(set (reg:CC FLAGS_REG)
975         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
976   "!TARGET_64BIT"
977   "sahf"
978   [(set_attr "length" "1")
979    (set_attr "athlon_decode" "vector")
980    (set_attr "mode" "SI")])
981
982 ;; Pentium Pro can do steps 1 through 3 in one go.
983
984 (define_insn "*cmpfp_i_mixed"
985   [(set (reg:CCFP FLAGS_REG)
986         (compare:CCFP (match_operand 0 "register_operand" "f,x")
987                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
988   "TARGET_MIX_SSE_I387
989    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991   "* return output_fp_compare (insn, operands, 1, 0);"
992   [(set_attr "type" "fcmp,ssecomi")
993    (set (attr "mode")
994      (if_then_else (match_operand:SF 1 "" "")
995         (const_string "SF")
996         (const_string "DF")))
997    (set_attr "athlon_decode" "vector")])
998
999 (define_insn "*cmpfp_i_sse"
1000   [(set (reg:CCFP FLAGS_REG)
1001         (compare:CCFP (match_operand 0 "register_operand" "x")
1002                       (match_operand 1 "nonimmediate_operand" "xm")))]
1003   "TARGET_SSE_MATH
1004    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1005    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006   "* return output_fp_compare (insn, operands, 1, 0);"
1007   [(set_attr "type" "ssecomi")
1008    (set (attr "mode")
1009      (if_then_else (match_operand:SF 1 "" "")
1010         (const_string "SF")
1011         (const_string "DF")))
1012    (set_attr "athlon_decode" "vector")])
1013
1014 (define_insn "*cmpfp_i_i387"
1015   [(set (reg:CCFP FLAGS_REG)
1016         (compare:CCFP (match_operand 0 "register_operand" "f")
1017                       (match_operand 1 "register_operand" "f")))]
1018   "TARGET_80387 && TARGET_CMOVE
1019    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1020    && FLOAT_MODE_P (GET_MODE (operands[0]))
1021    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022   "* return output_fp_compare (insn, operands, 1, 0);"
1023   [(set_attr "type" "fcmp")
1024    (set (attr "mode")
1025      (cond [(match_operand:SF 1 "" "")
1026               (const_string "SF")
1027             (match_operand:DF 1 "" "")
1028               (const_string "DF")
1029            ]
1030            (const_string "XF")))
1031    (set_attr "athlon_decode" "vector")])
1032
1033 (define_insn "*cmpfp_iu_mixed"
1034   [(set (reg:CCFPU FLAGS_REG)
1035         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1036                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1037   "TARGET_MIX_SSE_I387
1038    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040   "* return output_fp_compare (insn, operands, 1, 1);"
1041   [(set_attr "type" "fcmp,ssecomi")
1042    (set (attr "mode")
1043      (if_then_else (match_operand:SF 1 "" "")
1044         (const_string "SF")
1045         (const_string "DF")))
1046    (set_attr "athlon_decode" "vector")])
1047
1048 (define_insn "*cmpfp_iu_sse"
1049   [(set (reg:CCFPU FLAGS_REG)
1050         (compare:CCFPU (match_operand 0 "register_operand" "x")
1051                        (match_operand 1 "nonimmediate_operand" "xm")))]
1052   "TARGET_SSE_MATH
1053    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1054    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055   "* return output_fp_compare (insn, operands, 1, 1);"
1056   [(set_attr "type" "ssecomi")
1057    (set (attr "mode")
1058      (if_then_else (match_operand:SF 1 "" "")
1059         (const_string "SF")
1060         (const_string "DF")))
1061    (set_attr "athlon_decode" "vector")])
1062
1063 (define_insn "*cmpfp_iu_387"
1064   [(set (reg:CCFPU FLAGS_REG)
1065         (compare:CCFPU (match_operand 0 "register_operand" "f")
1066                        (match_operand 1 "register_operand" "f")))]
1067   "TARGET_80387 && TARGET_CMOVE
1068    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1069    && FLOAT_MODE_P (GET_MODE (operands[0]))
1070    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1071   "* return output_fp_compare (insn, operands, 1, 1);"
1072   [(set_attr "type" "fcmp")
1073    (set (attr "mode")
1074      (cond [(match_operand:SF 1 "" "")
1075               (const_string "SF")
1076             (match_operand:DF 1 "" "")
1077               (const_string "DF")
1078            ]
1079            (const_string "XF")))
1080    (set_attr "athlon_decode" "vector")])
1081 \f
1082 ;; Move instructions.
1083
1084 ;; General case of fullword move.
1085
1086 (define_expand "movsi"
1087   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1088         (match_operand:SI 1 "general_operand" ""))]
1089   ""
1090   "ix86_expand_move (SImode, operands); DONE;")
1091
1092 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1093 ;; general_operand.
1094 ;;
1095 ;; %%% We don't use a post-inc memory reference because x86 is not a
1096 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1097 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1098 ;; targets without our curiosities, and it is just as easy to represent
1099 ;; this differently.
1100
1101 (define_insn "*pushsi2"
1102   [(set (match_operand:SI 0 "push_operand" "=<")
1103         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1104   "!TARGET_64BIT"
1105   "push{l}\t%1"
1106   [(set_attr "type" "push")
1107    (set_attr "mode" "SI")])
1108
1109 ;; For 64BIT abi we always round up to 8 bytes.
1110 (define_insn "*pushsi2_rex64"
1111   [(set (match_operand:SI 0 "push_operand" "=X")
1112         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1113   "TARGET_64BIT"
1114   "push{q}\t%q1"
1115   [(set_attr "type" "push")
1116    (set_attr "mode" "SI")])
1117
1118 (define_insn "*pushsi2_prologue"
1119   [(set (match_operand:SI 0 "push_operand" "=<")
1120         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1121    (clobber (mem:BLK (scratch)))]
1122   "!TARGET_64BIT"
1123   "push{l}\t%1"
1124   [(set_attr "type" "push")
1125    (set_attr "mode" "SI")])
1126
1127 (define_insn "*popsi1_epilogue"
1128   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1129         (mem:SI (reg:SI SP_REG)))
1130    (set (reg:SI SP_REG)
1131         (plus:SI (reg:SI SP_REG) (const_int 4)))
1132    (clobber (mem:BLK (scratch)))]
1133   "!TARGET_64BIT"
1134   "pop{l}\t%0"
1135   [(set_attr "type" "pop")
1136    (set_attr "mode" "SI")])
1137
1138 (define_insn "popsi1"
1139   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1140         (mem:SI (reg:SI SP_REG)))
1141    (set (reg:SI SP_REG)
1142         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1143   "!TARGET_64BIT"
1144   "pop{l}\t%0"
1145   [(set_attr "type" "pop")
1146    (set_attr "mode" "SI")])
1147
1148 (define_insn "*movsi_xor"
1149   [(set (match_operand:SI 0 "register_operand" "=r")
1150         (match_operand:SI 1 "const0_operand" "i"))
1151    (clobber (reg:CC FLAGS_REG))]
1152   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1153   "xor{l}\t{%0, %0|%0, %0}"
1154   [(set_attr "type" "alu1")
1155    (set_attr "mode" "SI")
1156    (set_attr "length_immediate" "0")])
1157
1158 (define_insn "*movsi_or"
1159   [(set (match_operand:SI 0 "register_operand" "=r")
1160         (match_operand:SI 1 "immediate_operand" "i"))
1161    (clobber (reg:CC FLAGS_REG))]
1162   "reload_completed
1163    && operands[1] == constm1_rtx
1164    && (TARGET_PENTIUM || optimize_size)"
1165 {
1166   operands[1] = constm1_rtx;
1167   return "or{l}\t{%1, %0|%0, %1}";
1168 }
1169   [(set_attr "type" "alu1")
1170    (set_attr "mode" "SI")
1171    (set_attr "length_immediate" "1")])
1172
1173 (define_insn "*movsi_1"
1174   [(set (match_operand:SI 0 "nonimmediate_operand"
1175                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1176         (match_operand:SI 1 "general_operand"
1177                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1178   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1179 {
1180   switch (get_attr_type (insn))
1181     {
1182     case TYPE_SSELOG1:
1183       if (get_attr_mode (insn) == MODE_TI)
1184         return "pxor\t%0, %0";
1185       return "xorps\t%0, %0";
1186
1187     case TYPE_SSEMOV:
1188       switch (get_attr_mode (insn))
1189         {
1190         case MODE_TI:
1191           return "movdqa\t{%1, %0|%0, %1}";
1192         case MODE_V4SF:
1193           return "movaps\t{%1, %0|%0, %1}";
1194         case MODE_SI:
1195           return "movd\t{%1, %0|%0, %1}";
1196         case MODE_SF:
1197           return "movss\t{%1, %0|%0, %1}";
1198         default:
1199           gcc_unreachable ();
1200         }
1201
1202     case TYPE_MMXADD:
1203       return "pxor\t%0, %0";
1204
1205     case TYPE_MMXMOV:
1206       if (get_attr_mode (insn) == MODE_DI)
1207         return "movq\t{%1, %0|%0, %1}";
1208       return "movd\t{%1, %0|%0, %1}";
1209
1210     case TYPE_LEA:
1211       return "lea{l}\t{%1, %0|%0, %1}";
1212
1213     default:
1214       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1215       return "mov{l}\t{%1, %0|%0, %1}";
1216     }
1217 }
1218   [(set (attr "type")
1219      (cond [(eq_attr "alternative" "2")
1220               (const_string "mmxadd")
1221             (eq_attr "alternative" "3,4,5")
1222               (const_string "mmxmov")
1223             (eq_attr "alternative" "6")
1224               (const_string "sselog1")
1225             (eq_attr "alternative" "7,8,9,10,11")
1226               (const_string "ssemov")
1227             (match_operand:DI 1 "pic_32bit_operand" "")
1228               (const_string "lea")
1229            ]
1230            (const_string "imov")))
1231    (set (attr "mode")
1232      (cond [(eq_attr "alternative" "2,3")
1233               (const_string "DI")
1234             (eq_attr "alternative" "6,7")
1235               (if_then_else
1236                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1237                 (const_string "V4SF")
1238                 (const_string "TI"))
1239             (and (eq_attr "alternative" "8,9,10,11")
1240                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1241               (const_string "SF")
1242            ]
1243            (const_string "SI")))])
1244
1245 ;; Stores and loads of ax to arbitrary constant address.
1246 ;; We fake an second form of instruction to force reload to load address
1247 ;; into register when rax is not available
1248 (define_insn "*movabssi_1_rex64"
1249   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1250         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1251   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1252   "@
1253    movabs{l}\t{%1, %P0|%P0, %1}
1254    mov{l}\t{%1, %a0|%a0, %1}"
1255   [(set_attr "type" "imov")
1256    (set_attr "modrm" "0,*")
1257    (set_attr "length_address" "8,0")
1258    (set_attr "length_immediate" "0,*")
1259    (set_attr "memory" "store")
1260    (set_attr "mode" "SI")])
1261
1262 (define_insn "*movabssi_2_rex64"
1263   [(set (match_operand:SI 0 "register_operand" "=a,r")
1264         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1265   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1266   "@
1267    movabs{l}\t{%P1, %0|%0, %P1}
1268    mov{l}\t{%a1, %0|%0, %a1}"
1269   [(set_attr "type" "imov")
1270    (set_attr "modrm" "0,*")
1271    (set_attr "length_address" "8,0")
1272    (set_attr "length_immediate" "0")
1273    (set_attr "memory" "load")
1274    (set_attr "mode" "SI")])
1275
1276 (define_insn "*swapsi"
1277   [(set (match_operand:SI 0 "register_operand" "+r")
1278         (match_operand:SI 1 "register_operand" "+r"))
1279    (set (match_dup 1)
1280         (match_dup 0))]
1281   ""
1282   "xchg{l}\t%1, %0"
1283   [(set_attr "type" "imov")
1284    (set_attr "mode" "SI")
1285    (set_attr "pent_pair" "np")
1286    (set_attr "athlon_decode" "vector")])
1287
1288 (define_expand "movhi"
1289   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1290         (match_operand:HI 1 "general_operand" ""))]
1291   ""
1292   "ix86_expand_move (HImode, operands); DONE;")
1293
1294 (define_insn "*pushhi2"
1295   [(set (match_operand:HI 0 "push_operand" "=X")
1296         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1297   "!TARGET_64BIT"
1298   "push{l}\t%k1"
1299   [(set_attr "type" "push")
1300    (set_attr "mode" "SI")])
1301
1302 ;; For 64BIT abi we always round up to 8 bytes.
1303 (define_insn "*pushhi2_rex64"
1304   [(set (match_operand:HI 0 "push_operand" "=X")
1305         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1306   "TARGET_64BIT"
1307   "push{q}\t%q1"
1308   [(set_attr "type" "push")
1309    (set_attr "mode" "DI")])
1310
1311 (define_insn "*movhi_1"
1312   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1313         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1314   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1315 {
1316   switch (get_attr_type (insn))
1317     {
1318     case TYPE_IMOVX:
1319       /* movzwl is faster than movw on p2 due to partial word stalls,
1320          though not as fast as an aligned movl.  */
1321       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1322     default:
1323       if (get_attr_mode (insn) == MODE_SI)
1324         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1325       else
1326         return "mov{w}\t{%1, %0|%0, %1}";
1327     }
1328 }
1329   [(set (attr "type")
1330      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1331               (const_string "imov")
1332             (and (eq_attr "alternative" "0")
1333                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1334                           (const_int 0))
1335                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1336                           (const_int 0))))
1337               (const_string "imov")
1338             (and (eq_attr "alternative" "1,2")
1339                  (match_operand:HI 1 "aligned_operand" ""))
1340               (const_string "imov")
1341             (and (ne (symbol_ref "TARGET_MOVX")
1342                      (const_int 0))
1343                  (eq_attr "alternative" "0,2"))
1344               (const_string "imovx")
1345            ]
1346            (const_string "imov")))
1347     (set (attr "mode")
1348       (cond [(eq_attr "type" "imovx")
1349                (const_string "SI")
1350              (and (eq_attr "alternative" "1,2")
1351                   (match_operand:HI 1 "aligned_operand" ""))
1352                (const_string "SI")
1353              (and (eq_attr "alternative" "0")
1354                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1355                            (const_int 0))
1356                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1357                            (const_int 0))))
1358                (const_string "SI")
1359             ]
1360             (const_string "HI")))])
1361
1362 ;; Stores and loads of ax to arbitrary constant address.
1363 ;; We fake an second form of instruction to force reload to load address
1364 ;; into register when rax is not available
1365 (define_insn "*movabshi_1_rex64"
1366   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1367         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1368   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1369   "@
1370    movabs{w}\t{%1, %P0|%P0, %1}
1371    mov{w}\t{%1, %a0|%a0, %1}"
1372   [(set_attr "type" "imov")
1373    (set_attr "modrm" "0,*")
1374    (set_attr "length_address" "8,0")
1375    (set_attr "length_immediate" "0,*")
1376    (set_attr "memory" "store")
1377    (set_attr "mode" "HI")])
1378
1379 (define_insn "*movabshi_2_rex64"
1380   [(set (match_operand:HI 0 "register_operand" "=a,r")
1381         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1382   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1383   "@
1384    movabs{w}\t{%P1, %0|%0, %P1}
1385    mov{w}\t{%a1, %0|%0, %a1}"
1386   [(set_attr "type" "imov")
1387    (set_attr "modrm" "0,*")
1388    (set_attr "length_address" "8,0")
1389    (set_attr "length_immediate" "0")
1390    (set_attr "memory" "load")
1391    (set_attr "mode" "HI")])
1392
1393 (define_insn "*swaphi_1"
1394   [(set (match_operand:HI 0 "register_operand" "+r")
1395         (match_operand:HI 1 "register_operand" "+r"))
1396    (set (match_dup 1)
1397         (match_dup 0))]
1398   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1399   "xchg{l}\t%k1, %k0"
1400   [(set_attr "type" "imov")
1401    (set_attr "mode" "SI")
1402    (set_attr "pent_pair" "np")
1403    (set_attr "athlon_decode" "vector")])
1404
1405 (define_insn "*swaphi_2"
1406   [(set (match_operand:HI 0 "register_operand" "+r")
1407         (match_operand:HI 1 "register_operand" "+r"))
1408    (set (match_dup 1)
1409         (match_dup 0))]
1410   "TARGET_PARTIAL_REG_STALL"
1411   "xchg{w}\t%1, %0"
1412   [(set_attr "type" "imov")
1413    (set_attr "mode" "HI")
1414    (set_attr "pent_pair" "np")
1415    (set_attr "athlon_decode" "vector")])
1416
1417 (define_expand "movstricthi"
1418   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1419         (match_operand:HI 1 "general_operand" ""))]
1420   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1421 {
1422   /* Don't generate memory->memory moves, go through a register */
1423   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1424     operands[1] = force_reg (HImode, operands[1]);
1425 })
1426
1427 (define_insn "*movstricthi_1"
1428   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1429         (match_operand:HI 1 "general_operand" "rn,m"))]
1430   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1431    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1432   "mov{w}\t{%1, %0|%0, %1}"
1433   [(set_attr "type" "imov")
1434    (set_attr "mode" "HI")])
1435
1436 (define_insn "*movstricthi_xor"
1437   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1438         (match_operand:HI 1 "const0_operand" "i"))
1439    (clobber (reg:CC FLAGS_REG))]
1440   "reload_completed
1441    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1442   "xor{w}\t{%0, %0|%0, %0}"
1443   [(set_attr "type" "alu1")
1444    (set_attr "mode" "HI")
1445    (set_attr "length_immediate" "0")])
1446
1447 (define_expand "movqi"
1448   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1449         (match_operand:QI 1 "general_operand" ""))]
1450   ""
1451   "ix86_expand_move (QImode, operands); DONE;")
1452
1453 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1454 ;; "push a byte".  But actually we use pushl, which has the effect
1455 ;; of rounding the amount pushed up to a word.
1456
1457 (define_insn "*pushqi2"
1458   [(set (match_operand:QI 0 "push_operand" "=X")
1459         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1460   "!TARGET_64BIT"
1461   "push{l}\t%k1"
1462   [(set_attr "type" "push")
1463    (set_attr "mode" "SI")])
1464
1465 ;; For 64BIT abi we always round up to 8 bytes.
1466 (define_insn "*pushqi2_rex64"
1467   [(set (match_operand:QI 0 "push_operand" "=X")
1468         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1469   "TARGET_64BIT"
1470   "push{q}\t%q1"
1471   [(set_attr "type" "push")
1472    (set_attr "mode" "DI")])
1473
1474 ;; Situation is quite tricky about when to choose full sized (SImode) move
1475 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1476 ;; partial register dependency machines (such as AMD Athlon), where QImode
1477 ;; moves issue extra dependency and for partial register stalls machines
1478 ;; that don't use QImode patterns (and QImode move cause stall on the next
1479 ;; instruction).
1480 ;;
1481 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1482 ;; register stall machines with, where we use QImode instructions, since
1483 ;; partial register stall can be caused there.  Then we use movzx.
1484 (define_insn "*movqi_1"
1485   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1486         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1487   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1488 {
1489   switch (get_attr_type (insn))
1490     {
1491     case TYPE_IMOVX:
1492       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1493       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1494     default:
1495       if (get_attr_mode (insn) == MODE_SI)
1496         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1497       else
1498         return "mov{b}\t{%1, %0|%0, %1}";
1499     }
1500 }
1501   [(set (attr "type")
1502      (cond [(and (eq_attr "alternative" "5")
1503                  (not (match_operand:QI 1 "aligned_operand" "")))
1504               (const_string "imovx")
1505             (ne (symbol_ref "optimize_size") (const_int 0))
1506               (const_string "imov")
1507             (and (eq_attr "alternative" "3")
1508                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1509                           (const_int 0))
1510                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1511                           (const_int 0))))
1512               (const_string "imov")
1513             (eq_attr "alternative" "3,5")
1514               (const_string "imovx")
1515             (and (ne (symbol_ref "TARGET_MOVX")
1516                      (const_int 0))
1517                  (eq_attr "alternative" "2"))
1518               (const_string "imovx")
1519            ]
1520            (const_string "imov")))
1521    (set (attr "mode")
1522       (cond [(eq_attr "alternative" "3,4,5")
1523                (const_string "SI")
1524              (eq_attr "alternative" "6")
1525                (const_string "QI")
1526              (eq_attr "type" "imovx")
1527                (const_string "SI")
1528              (and (eq_attr "type" "imov")
1529                   (and (eq_attr "alternative" "0,1")
1530                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1531                                 (const_int 0))
1532                             (and (eq (symbol_ref "optimize_size")
1533                                      (const_int 0))
1534                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1535                                      (const_int 0))))))
1536                (const_string "SI")
1537              ;; Avoid partial register stalls when not using QImode arithmetic
1538              (and (eq_attr "type" "imov")
1539                   (and (eq_attr "alternative" "0,1")
1540                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1541                                 (const_int 0))
1542                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1543                                 (const_int 0)))))
1544                (const_string "SI")
1545            ]
1546            (const_string "QI")))])
1547
1548 (define_expand "reload_outqi"
1549   [(parallel [(match_operand:QI 0 "" "=m")
1550               (match_operand:QI 1 "register_operand" "r")
1551               (match_operand:QI 2 "register_operand" "=&q")])]
1552   ""
1553 {
1554   rtx op0, op1, op2;
1555   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1556
1557   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1558   if (! q_regs_operand (op1, QImode))
1559     {
1560       emit_insn (gen_movqi (op2, op1));
1561       op1 = op2;
1562     }
1563   emit_insn (gen_movqi (op0, op1));
1564   DONE;
1565 })
1566
1567 (define_insn "*swapqi_1"
1568   [(set (match_operand:QI 0 "register_operand" "+r")
1569         (match_operand:QI 1 "register_operand" "+r"))
1570    (set (match_dup 1)
1571         (match_dup 0))]
1572   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1573   "xchg{l}\t%k1, %k0"
1574   [(set_attr "type" "imov")
1575    (set_attr "mode" "SI")
1576    (set_attr "pent_pair" "np")
1577    (set_attr "athlon_decode" "vector")])
1578
1579 (define_insn "*swapqi_2"
1580   [(set (match_operand:QI 0 "register_operand" "+q")
1581         (match_operand:QI 1 "register_operand" "+q"))
1582    (set (match_dup 1)
1583         (match_dup 0))]
1584   "TARGET_PARTIAL_REG_STALL"
1585   "xchg{b}\t%1, %0"
1586   [(set_attr "type" "imov")
1587    (set_attr "mode" "QI")
1588    (set_attr "pent_pair" "np")
1589    (set_attr "athlon_decode" "vector")])
1590
1591 (define_expand "movstrictqi"
1592   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1593         (match_operand:QI 1 "general_operand" ""))]
1594   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1595 {
1596   /* Don't generate memory->memory moves, go through a register.  */
1597   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1598     operands[1] = force_reg (QImode, operands[1]);
1599 })
1600
1601 (define_insn "*movstrictqi_1"
1602   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1603         (match_operand:QI 1 "general_operand" "*qn,m"))]
1604   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1605    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1606   "mov{b}\t{%1, %0|%0, %1}"
1607   [(set_attr "type" "imov")
1608    (set_attr "mode" "QI")])
1609
1610 (define_insn "*movstrictqi_xor"
1611   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1612         (match_operand:QI 1 "const0_operand" "i"))
1613    (clobber (reg:CC FLAGS_REG))]
1614   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1615   "xor{b}\t{%0, %0|%0, %0}"
1616   [(set_attr "type" "alu1")
1617    (set_attr "mode" "QI")
1618    (set_attr "length_immediate" "0")])
1619
1620 (define_insn "*movsi_extv_1"
1621   [(set (match_operand:SI 0 "register_operand" "=R")
1622         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1623                          (const_int 8)
1624                          (const_int 8)))]
1625   ""
1626   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1627   [(set_attr "type" "imovx")
1628    (set_attr "mode" "SI")])
1629
1630 (define_insn "*movhi_extv_1"
1631   [(set (match_operand:HI 0 "register_operand" "=R")
1632         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1633                          (const_int 8)
1634                          (const_int 8)))]
1635   ""
1636   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1637   [(set_attr "type" "imovx")
1638    (set_attr "mode" "SI")])
1639
1640 (define_insn "*movqi_extv_1"
1641   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1642         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1643                          (const_int 8)
1644                          (const_int 8)))]
1645   "!TARGET_64BIT"
1646 {
1647   switch (get_attr_type (insn))
1648     {
1649     case TYPE_IMOVX:
1650       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1651     default:
1652       return "mov{b}\t{%h1, %0|%0, %h1}";
1653     }
1654 }
1655   [(set (attr "type")
1656      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1657                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1658                              (ne (symbol_ref "TARGET_MOVX")
1659                                  (const_int 0))))
1660         (const_string "imovx")
1661         (const_string "imov")))
1662    (set (attr "mode")
1663      (if_then_else (eq_attr "type" "imovx")
1664         (const_string "SI")
1665         (const_string "QI")))])
1666
1667 (define_insn "*movqi_extv_1_rex64"
1668   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1669         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1670                          (const_int 8)
1671                          (const_int 8)))]
1672   "TARGET_64BIT"
1673 {
1674   switch (get_attr_type (insn))
1675     {
1676     case TYPE_IMOVX:
1677       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1678     default:
1679       return "mov{b}\t{%h1, %0|%0, %h1}";
1680     }
1681 }
1682   [(set (attr "type")
1683      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1684                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1685                              (ne (symbol_ref "TARGET_MOVX")
1686                                  (const_int 0))))
1687         (const_string "imovx")
1688         (const_string "imov")))
1689    (set (attr "mode")
1690      (if_then_else (eq_attr "type" "imovx")
1691         (const_string "SI")
1692         (const_string "QI")))])
1693
1694 ;; Stores and loads of ax to arbitrary constant address.
1695 ;; We fake an second form of instruction to force reload to load address
1696 ;; into register when rax is not available
1697 (define_insn "*movabsqi_1_rex64"
1698   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1699         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1700   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1701   "@
1702    movabs{b}\t{%1, %P0|%P0, %1}
1703    mov{b}\t{%1, %a0|%a0, %1}"
1704   [(set_attr "type" "imov")
1705    (set_attr "modrm" "0,*")
1706    (set_attr "length_address" "8,0")
1707    (set_attr "length_immediate" "0,*")
1708    (set_attr "memory" "store")
1709    (set_attr "mode" "QI")])
1710
1711 (define_insn "*movabsqi_2_rex64"
1712   [(set (match_operand:QI 0 "register_operand" "=a,r")
1713         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1714   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1715   "@
1716    movabs{b}\t{%P1, %0|%0, %P1}
1717    mov{b}\t{%a1, %0|%0, %a1}"
1718   [(set_attr "type" "imov")
1719    (set_attr "modrm" "0,*")
1720    (set_attr "length_address" "8,0")
1721    (set_attr "length_immediate" "0")
1722    (set_attr "memory" "load")
1723    (set_attr "mode" "QI")])
1724
1725 (define_insn "*movdi_extzv_1"
1726   [(set (match_operand:DI 0 "register_operand" "=R")
1727         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1728                          (const_int 8)
1729                          (const_int 8)))]
1730   "TARGET_64BIT"
1731   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1732   [(set_attr "type" "imovx")
1733    (set_attr "mode" "DI")])
1734
1735 (define_insn "*movsi_extzv_1"
1736   [(set (match_operand:SI 0 "register_operand" "=R")
1737         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1738                          (const_int 8)
1739                          (const_int 8)))]
1740   ""
1741   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1742   [(set_attr "type" "imovx")
1743    (set_attr "mode" "SI")])
1744
1745 (define_insn "*movqi_extzv_2"
1746   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1747         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1748                                     (const_int 8)
1749                                     (const_int 8)) 0))]
1750   "!TARGET_64BIT"
1751 {
1752   switch (get_attr_type (insn))
1753     {
1754     case TYPE_IMOVX:
1755       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1756     default:
1757       return "mov{b}\t{%h1, %0|%0, %h1}";
1758     }
1759 }
1760   [(set (attr "type")
1761      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1762                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1763                              (ne (symbol_ref "TARGET_MOVX")
1764                                  (const_int 0))))
1765         (const_string "imovx")
1766         (const_string "imov")))
1767    (set (attr "mode")
1768      (if_then_else (eq_attr "type" "imovx")
1769         (const_string "SI")
1770         (const_string "QI")))])
1771
1772 (define_insn "*movqi_extzv_2_rex64"
1773   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1774         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1775                                     (const_int 8)
1776                                     (const_int 8)) 0))]
1777   "TARGET_64BIT"
1778 {
1779   switch (get_attr_type (insn))
1780     {
1781     case TYPE_IMOVX:
1782       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1783     default:
1784       return "mov{b}\t{%h1, %0|%0, %h1}";
1785     }
1786 }
1787   [(set (attr "type")
1788      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1789                         (ne (symbol_ref "TARGET_MOVX")
1790                             (const_int 0)))
1791         (const_string "imovx")
1792         (const_string "imov")))
1793    (set (attr "mode")
1794      (if_then_else (eq_attr "type" "imovx")
1795         (const_string "SI")
1796         (const_string "QI")))])
1797
1798 (define_insn "movsi_insv_1"
1799   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1800                          (const_int 8)
1801                          (const_int 8))
1802         (match_operand:SI 1 "general_operand" "Qmn"))]
1803   "!TARGET_64BIT"
1804   "mov{b}\t{%b1, %h0|%h0, %b1}"
1805   [(set_attr "type" "imov")
1806    (set_attr "mode" "QI")])
1807
1808 (define_insn "*movsi_insv_1_rex64"
1809   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1810                          (const_int 8)
1811                          (const_int 8))
1812         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1813   "TARGET_64BIT"
1814   "mov{b}\t{%b1, %h0|%h0, %b1}"
1815   [(set_attr "type" "imov")
1816    (set_attr "mode" "QI")])
1817
1818 (define_insn "movdi_insv_1_rex64"
1819   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1820                          (const_int 8)
1821                          (const_int 8))
1822         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
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 "*movqi_insv_2"
1829   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1830                          (const_int 8)
1831                          (const_int 8))
1832         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1833                      (const_int 8)))]
1834   ""
1835   "mov{b}\t{%h1, %h0|%h0, %h1}"
1836   [(set_attr "type" "imov")
1837    (set_attr "mode" "QI")])
1838
1839 (define_expand "movdi"
1840   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1841         (match_operand:DI 1 "general_operand" ""))]
1842   ""
1843   "ix86_expand_move (DImode, operands); DONE;")
1844
1845 (define_insn "*pushdi"
1846   [(set (match_operand:DI 0 "push_operand" "=<")
1847         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1848   "!TARGET_64BIT"
1849   "#")
1850
1851 (define_insn "*pushdi2_rex64"
1852   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1853         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1854   "TARGET_64BIT"
1855   "@
1856    push{q}\t%1
1857    #"
1858   [(set_attr "type" "push,multi")
1859    (set_attr "mode" "DI")])
1860
1861 ;; Convert impossible pushes of immediate to existing instructions.
1862 ;; First try to get scratch register and go through it.  In case this
1863 ;; fails, push sign extended lower part first and then overwrite
1864 ;; upper part by 32bit move.
1865 (define_peephole2
1866   [(match_scratch:DI 2 "r")
1867    (set (match_operand:DI 0 "push_operand" "")
1868         (match_operand:DI 1 "immediate_operand" ""))]
1869   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1870    && !x86_64_immediate_operand (operands[1], DImode)"
1871   [(set (match_dup 2) (match_dup 1))
1872    (set (match_dup 0) (match_dup 2))]
1873   "")
1874
1875 ;; We need to define this as both peepholer and splitter for case
1876 ;; peephole2 pass is not run.
1877 ;; "&& 1" is needed to keep it from matching the previous pattern.
1878 (define_peephole2
1879   [(set (match_operand:DI 0 "push_operand" "")
1880         (match_operand:DI 1 "immediate_operand" ""))]
1881   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1882    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1883   [(set (match_dup 0) (match_dup 1))
1884    (set (match_dup 2) (match_dup 3))]
1885   "split_di (operands + 1, 1, operands + 2, operands + 3);
1886    operands[1] = gen_lowpart (DImode, operands[2]);
1887    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1888                                                     GEN_INT (4)));
1889   ")
1890
1891 (define_split
1892   [(set (match_operand:DI 0 "push_operand" "")
1893         (match_operand:DI 1 "immediate_operand" ""))]
1894   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1895                     ? flow2_completed : reload_completed)
1896    && !symbolic_operand (operands[1], DImode)
1897    && !x86_64_immediate_operand (operands[1], DImode)"
1898   [(set (match_dup 0) (match_dup 1))
1899    (set (match_dup 2) (match_dup 3))]
1900   "split_di (operands + 1, 1, operands + 2, operands + 3);
1901    operands[1] = gen_lowpart (DImode, operands[2]);
1902    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1903                                                     GEN_INT (4)));
1904   ")
1905
1906 (define_insn "*pushdi2_prologue_rex64"
1907   [(set (match_operand:DI 0 "push_operand" "=<")
1908         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1909    (clobber (mem:BLK (scratch)))]
1910   "TARGET_64BIT"
1911   "push{q}\t%1"
1912   [(set_attr "type" "push")
1913    (set_attr "mode" "DI")])
1914
1915 (define_insn "*popdi1_epilogue_rex64"
1916   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1917         (mem:DI (reg:DI SP_REG)))
1918    (set (reg:DI SP_REG)
1919         (plus:DI (reg:DI SP_REG) (const_int 8)))
1920    (clobber (mem:BLK (scratch)))]
1921   "TARGET_64BIT"
1922   "pop{q}\t%0"
1923   [(set_attr "type" "pop")
1924    (set_attr "mode" "DI")])
1925
1926 (define_insn "popdi1"
1927   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1928         (mem:DI (reg:DI SP_REG)))
1929    (set (reg:DI SP_REG)
1930         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1931   "TARGET_64BIT"
1932   "pop{q}\t%0"
1933   [(set_attr "type" "pop")
1934    (set_attr "mode" "DI")])
1935
1936 (define_insn "*movdi_xor_rex64"
1937   [(set (match_operand:DI 0 "register_operand" "=r")
1938         (match_operand:DI 1 "const0_operand" "i"))
1939    (clobber (reg:CC FLAGS_REG))]
1940   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1941    && reload_completed"
1942   "xor{l}\t{%k0, %k0|%k0, %k0}"
1943   [(set_attr "type" "alu1")
1944    (set_attr "mode" "SI")
1945    (set_attr "length_immediate" "0")])
1946
1947 (define_insn "*movdi_or_rex64"
1948   [(set (match_operand:DI 0 "register_operand" "=r")
1949         (match_operand:DI 1 "const_int_operand" "i"))
1950    (clobber (reg:CC FLAGS_REG))]
1951   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1952    && reload_completed
1953    && operands[1] == constm1_rtx"
1954 {
1955   operands[1] = constm1_rtx;
1956   return "or{q}\t{%1, %0|%0, %1}";
1957 }
1958   [(set_attr "type" "alu1")
1959    (set_attr "mode" "DI")
1960    (set_attr "length_immediate" "1")])
1961
1962 (define_insn "*movdi_2"
1963   [(set (match_operand:DI 0 "nonimmediate_operand"
1964                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1965         (match_operand:DI 1 "general_operand"
1966                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1967   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1968   "@
1969    #
1970    #
1971    pxor\t%0, %0
1972    movq\t{%1, %0|%0, %1}
1973    movq\t{%1, %0|%0, %1}
1974    pxor\t%0, %0
1975    movq\t{%1, %0|%0, %1}
1976    movdqa\t{%1, %0|%0, %1}
1977    movq\t{%1, %0|%0, %1}
1978    xorps\t%0, %0
1979    movlps\t{%1, %0|%0, %1}
1980    movaps\t{%1, %0|%0, %1}
1981    movlps\t{%1, %0|%0, %1}"
1982   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1983    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1984
1985 (define_split
1986   [(set (match_operand:DI 0 "push_operand" "")
1987         (match_operand:DI 1 "general_operand" ""))]
1988   "!TARGET_64BIT && reload_completed
1989    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1990   [(const_int 0)]
1991   "ix86_split_long_move (operands); DONE;")
1992
1993 ;; %%% This multiword shite has got to go.
1994 (define_split
1995   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1996         (match_operand:DI 1 "general_operand" ""))]
1997   "!TARGET_64BIT && reload_completed
1998    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1999    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2000   [(const_int 0)]
2001   "ix86_split_long_move (operands); DONE;")
2002
2003 (define_insn "*movdi_1_rex64"
2004   [(set (match_operand:DI 0 "nonimmediate_operand"
2005                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2006         (match_operand:DI 1 "general_operand"
2007                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2008   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2009 {
2010   switch (get_attr_type (insn))
2011     {
2012     case TYPE_SSECVT:
2013       if (which_alternative == 13)
2014         return "movq2dq\t{%1, %0|%0, %1}";
2015       else
2016         return "movdq2q\t{%1, %0|%0, %1}";
2017     case TYPE_SSEMOV:
2018       if (get_attr_mode (insn) == MODE_TI)
2019           return "movdqa\t{%1, %0|%0, %1}";
2020       /* FALLTHRU */
2021     case TYPE_MMXMOV:
2022       /* Moves from and into integer register is done using movd opcode with
2023          REX prefix.  */
2024       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2025           return "movd\t{%1, %0|%0, %1}";
2026       return "movq\t{%1, %0|%0, %1}";
2027     case TYPE_SSELOG1:
2028     case TYPE_MMXADD:
2029       return "pxor\t%0, %0";
2030     case TYPE_MULTI:
2031       return "#";
2032     case TYPE_LEA:
2033       return "lea{q}\t{%a1, %0|%0, %a1}";
2034     default:
2035       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2036       if (get_attr_mode (insn) == MODE_SI)
2037         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2038       else if (which_alternative == 2)
2039         return "movabs{q}\t{%1, %0|%0, %1}";
2040       else
2041         return "mov{q}\t{%1, %0|%0, %1}";
2042     }
2043 }
2044   [(set (attr "type")
2045      (cond [(eq_attr "alternative" "5")
2046               (const_string "mmxadd")
2047             (eq_attr "alternative" "6,7,8")
2048               (const_string "mmxmov")
2049             (eq_attr "alternative" "9")
2050               (const_string "sselog1")
2051             (eq_attr "alternative" "10,11,12")
2052               (const_string "ssemov")
2053             (eq_attr "alternative" "13,14")
2054               (const_string "ssecvt")
2055             (eq_attr "alternative" "4")
2056               (const_string "multi")
2057             (match_operand:DI 1 "pic_32bit_operand" "")
2058               (const_string "lea")
2059            ]
2060            (const_string "imov")))
2061    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2062    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2063    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2064
2065 ;; Stores and loads of ax to arbitrary constant address.
2066 ;; We fake an second form of instruction to force reload to load address
2067 ;; into register when rax is not available
2068 (define_insn "*movabsdi_1_rex64"
2069   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2070         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2071   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2072   "@
2073    movabs{q}\t{%1, %P0|%P0, %1}
2074    mov{q}\t{%1, %a0|%a0, %1}"
2075   [(set_attr "type" "imov")
2076    (set_attr "modrm" "0,*")
2077    (set_attr "length_address" "8,0")
2078    (set_attr "length_immediate" "0,*")
2079    (set_attr "memory" "store")
2080    (set_attr "mode" "DI")])
2081
2082 (define_insn "*movabsdi_2_rex64"
2083   [(set (match_operand:DI 0 "register_operand" "=a,r")
2084         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2085   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2086   "@
2087    movabs{q}\t{%P1, %0|%0, %P1}
2088    mov{q}\t{%a1, %0|%0, %a1}"
2089   [(set_attr "type" "imov")
2090    (set_attr "modrm" "0,*")
2091    (set_attr "length_address" "8,0")
2092    (set_attr "length_immediate" "0")
2093    (set_attr "memory" "load")
2094    (set_attr "mode" "DI")])
2095
2096 ;; Convert impossible stores of immediate to existing instructions.
2097 ;; First try to get scratch register and go through it.  In case this
2098 ;; fails, move by 32bit parts.
2099 (define_peephole2
2100   [(match_scratch:DI 2 "r")
2101    (set (match_operand:DI 0 "memory_operand" "")
2102         (match_operand:DI 1 "immediate_operand" ""))]
2103   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2104    && !x86_64_immediate_operand (operands[1], DImode)"
2105   [(set (match_dup 2) (match_dup 1))
2106    (set (match_dup 0) (match_dup 2))]
2107   "")
2108
2109 ;; We need to define this as both peepholer and splitter for case
2110 ;; peephole2 pass is not run.
2111 ;; "&& 1" is needed to keep it from matching the previous pattern.
2112 (define_peephole2
2113   [(set (match_operand:DI 0 "memory_operand" "")
2114         (match_operand:DI 1 "immediate_operand" ""))]
2115   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2116    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2117   [(set (match_dup 2) (match_dup 3))
2118    (set (match_dup 4) (match_dup 5))]
2119   "split_di (operands, 2, operands + 2, operands + 4);")
2120
2121 (define_split
2122   [(set (match_operand:DI 0 "memory_operand" "")
2123         (match_operand:DI 1 "immediate_operand" ""))]
2124   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2125                     ? flow2_completed : reload_completed)
2126    && !symbolic_operand (operands[1], DImode)
2127    && !x86_64_immediate_operand (operands[1], DImode)"
2128   [(set (match_dup 2) (match_dup 3))
2129    (set (match_dup 4) (match_dup 5))]
2130   "split_di (operands, 2, operands + 2, operands + 4);")
2131
2132 (define_insn "*swapdi_rex64"
2133   [(set (match_operand:DI 0 "register_operand" "+r")
2134         (match_operand:DI 1 "register_operand" "+r"))
2135    (set (match_dup 1)
2136         (match_dup 0))]
2137   "TARGET_64BIT"
2138   "xchg{q}\t%1, %0"
2139   [(set_attr "type" "imov")
2140    (set_attr "mode" "DI")
2141    (set_attr "pent_pair" "np")
2142    (set_attr "athlon_decode" "vector")])
2143
2144 (define_expand "movti"
2145   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2146         (match_operand:TI 1 "nonimmediate_operand" ""))]
2147   "TARGET_SSE || TARGET_64BIT"
2148 {
2149   if (TARGET_64BIT)
2150     ix86_expand_move (TImode, operands);
2151   else
2152     ix86_expand_vector_move (TImode, operands);
2153   DONE;
2154 })
2155
2156 (define_insn "*movti_internal"
2157   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2158         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2159   "TARGET_SSE && !TARGET_64BIT
2160    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2161 {
2162   switch (which_alternative)
2163     {
2164     case 0:
2165       if (get_attr_mode (insn) == MODE_V4SF)
2166         return "xorps\t%0, %0";
2167       else
2168         return "pxor\t%0, %0";
2169     case 1:
2170     case 2:
2171       if (get_attr_mode (insn) == MODE_V4SF)
2172         return "movaps\t{%1, %0|%0, %1}";
2173       else
2174         return "movdqa\t{%1, %0|%0, %1}";
2175     default:
2176       gcc_unreachable ();
2177     }
2178 }
2179   [(set_attr "type" "sselog1,ssemov,ssemov")
2180    (set (attr "mode")
2181         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2182                     (ne (symbol_ref "optimize_size") (const_int 0)))
2183                  (const_string "V4SF")
2184                (and (eq_attr "alternative" "2")
2185                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2186                         (const_int 0)))
2187                  (const_string "V4SF")]
2188               (const_string "TI")))])
2189
2190 (define_insn "*movti_rex64"
2191   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2192         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2193   "TARGET_64BIT
2194    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2195 {
2196   switch (which_alternative)
2197     {
2198     case 0:
2199     case 1:
2200       return "#";
2201     case 2:
2202       if (get_attr_mode (insn) == MODE_V4SF)
2203         return "xorps\t%0, %0";
2204       else
2205         return "pxor\t%0, %0";
2206     case 3:
2207     case 4:
2208       if (get_attr_mode (insn) == MODE_V4SF)
2209         return "movaps\t{%1, %0|%0, %1}";
2210       else
2211         return "movdqa\t{%1, %0|%0, %1}";
2212     default:
2213       gcc_unreachable ();
2214     }
2215 }
2216   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2217    (set (attr "mode")
2218         (cond [(eq_attr "alternative" "2,3")
2219                  (if_then_else
2220                    (ne (symbol_ref "optimize_size")
2221                        (const_int 0))
2222                    (const_string "V4SF")
2223                    (const_string "TI"))
2224                (eq_attr "alternative" "4")
2225                  (if_then_else
2226                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2227                             (const_int 0))
2228                         (ne (symbol_ref "optimize_size")
2229                             (const_int 0)))
2230                    (const_string "V4SF")
2231                    (const_string "TI"))]
2232                (const_string "DI")))])
2233
2234 (define_split
2235   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2236         (match_operand:TI 1 "general_operand" ""))]
2237   "reload_completed && !SSE_REG_P (operands[0])
2238    && !SSE_REG_P (operands[1])"
2239   [(const_int 0)]
2240   "ix86_split_long_move (operands); DONE;")
2241
2242 (define_expand "movsf"
2243   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2244         (match_operand:SF 1 "general_operand" ""))]
2245   ""
2246   "ix86_expand_move (SFmode, operands); DONE;")
2247
2248 (define_insn "*pushsf"
2249   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2250         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2251   "!TARGET_64BIT"
2252 {
2253   /* Anything else should be already split before reg-stack.  */
2254   gcc_assert (which_alternative == 1);
2255   return "push{l}\t%1";
2256 }
2257   [(set_attr "type" "multi,push,multi")
2258    (set_attr "unit" "i387,*,*")
2259    (set_attr "mode" "SF,SI,SF")])
2260
2261 (define_insn "*pushsf_rex64"
2262   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2263         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2264   "TARGET_64BIT"
2265 {
2266   /* Anything else should be already split before reg-stack.  */
2267   gcc_assert (which_alternative == 1);
2268   return "push{q}\t%q1";
2269 }
2270   [(set_attr "type" "multi,push,multi")
2271    (set_attr "unit" "i387,*,*")
2272    (set_attr "mode" "SF,DI,SF")])
2273
2274 (define_split
2275   [(set (match_operand:SF 0 "push_operand" "")
2276         (match_operand:SF 1 "memory_operand" ""))]
2277   "reload_completed
2278    && GET_CODE (operands[1]) == MEM
2279    && constant_pool_reference_p (operands[1])"
2280   [(set (match_dup 0)
2281         (match_dup 1))]
2282   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2283
2284
2285 ;; %%% Kill this when call knows how to work this out.
2286 (define_split
2287   [(set (match_operand:SF 0 "push_operand" "")
2288         (match_operand:SF 1 "any_fp_register_operand" ""))]
2289   "!TARGET_64BIT"
2290   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2291    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2292
2293 (define_split
2294   [(set (match_operand:SF 0 "push_operand" "")
2295         (match_operand:SF 1 "any_fp_register_operand" ""))]
2296   "TARGET_64BIT"
2297   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2298    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2299
2300 (define_insn "*movsf_1"
2301   [(set (match_operand:SF 0 "nonimmediate_operand"
2302           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2303         (match_operand:SF 1 "general_operand"
2304           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2305   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2306    && (reload_in_progress || reload_completed
2307        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2308        || (!TARGET_SSE_MATH && optimize_size
2309            && standard_80387_constant_p (operands[1]))
2310        || GET_CODE (operands[1]) != CONST_DOUBLE
2311        || memory_operand (operands[0], SFmode))"
2312 {
2313   switch (which_alternative)
2314     {
2315     case 0:
2316       return output_387_reg_move (insn, operands);
2317
2318     case 1:
2319       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2320         return "fstp%z0\t%y0";
2321       else
2322         return "fst%z0\t%y0";
2323
2324     case 2:
2325       return standard_80387_constant_opcode (operands[1]);
2326
2327     case 3:
2328     case 4:
2329       return "mov{l}\t{%1, %0|%0, %1}";
2330     case 5:
2331       if (get_attr_mode (insn) == MODE_TI)
2332         return "pxor\t%0, %0";
2333       else
2334         return "xorps\t%0, %0";
2335     case 6:
2336       if (get_attr_mode (insn) == MODE_V4SF)
2337         return "movaps\t{%1, %0|%0, %1}";
2338       else
2339         return "movss\t{%1, %0|%0, %1}";
2340     case 7:
2341     case 8:
2342       return "movss\t{%1, %0|%0, %1}";
2343
2344     case 9:
2345     case 10:
2346       return "movd\t{%1, %0|%0, %1}";
2347
2348     case 11:
2349       return "movq\t{%1, %0|%0, %1}";
2350
2351     default:
2352       gcc_unreachable ();
2353     }
2354 }
2355   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2356    (set (attr "mode")
2357         (cond [(eq_attr "alternative" "3,4,9,10")
2358                  (const_string "SI")
2359                (eq_attr "alternative" "5")
2360                  (if_then_else
2361                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2362                                  (const_int 0))
2363                              (ne (symbol_ref "TARGET_SSE2")
2364                                  (const_int 0)))
2365                         (eq (symbol_ref "optimize_size")
2366                             (const_int 0)))
2367                    (const_string "TI")
2368                    (const_string "V4SF"))
2369                /* For architectures resolving dependencies on
2370                   whole SSE registers use APS move to break dependency
2371                   chains, otherwise use short move to avoid extra work.
2372
2373                   Do the same for architectures resolving dependencies on
2374                   the parts.  While in DF mode it is better to always handle
2375                   just register parts, the SF mode is different due to lack
2376                   of instructions to load just part of the register.  It is
2377                   better to maintain the whole registers in single format
2378                   to avoid problems on using packed logical operations.  */
2379                (eq_attr "alternative" "6")
2380                  (if_then_else
2381                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2382                             (const_int 0))
2383                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2384                             (const_int 0)))
2385                    (const_string "V4SF")
2386                    (const_string "SF"))
2387                (eq_attr "alternative" "11")
2388                  (const_string "DI")]
2389                (const_string "SF")))])
2390
2391 (define_insn "*swapsf"
2392   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2393         (match_operand:SF 1 "fp_register_operand" "+f"))
2394    (set (match_dup 1)
2395         (match_dup 0))]
2396   "reload_completed || TARGET_80387"
2397 {
2398   if (STACK_TOP_P (operands[0]))
2399     return "fxch\t%1";
2400   else
2401     return "fxch\t%0";
2402 }
2403   [(set_attr "type" "fxch")
2404    (set_attr "mode" "SF")])
2405
2406 (define_expand "movdf"
2407   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2408         (match_operand:DF 1 "general_operand" ""))]
2409   ""
2410   "ix86_expand_move (DFmode, operands); DONE;")
2411
2412 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2413 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2414 ;; On the average, pushdf using integers can be still shorter.  Allow this
2415 ;; pattern for optimize_size too.
2416
2417 (define_insn "*pushdf_nointeger"
2418   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2419         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2420   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2421 {
2422   /* This insn should be already split before reg-stack.  */
2423   gcc_unreachable ();
2424 }
2425   [(set_attr "type" "multi")
2426    (set_attr "unit" "i387,*,*,*")
2427    (set_attr "mode" "DF,SI,SI,DF")])
2428
2429 (define_insn "*pushdf_integer"
2430   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2431         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2432   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2433 {
2434   /* This insn should be already split before reg-stack.  */
2435   gcc_unreachable ();
2436 }
2437   [(set_attr "type" "multi")
2438    (set_attr "unit" "i387,*,*")
2439    (set_attr "mode" "DF,SI,DF")])
2440
2441 ;; %%% Kill this when call knows how to work this out.
2442 (define_split
2443   [(set (match_operand:DF 0 "push_operand" "")
2444         (match_operand:DF 1 "any_fp_register_operand" ""))]
2445   "!TARGET_64BIT && reload_completed"
2446   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2447    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2448   "")
2449
2450 (define_split
2451   [(set (match_operand:DF 0 "push_operand" "")
2452         (match_operand:DF 1 "any_fp_register_operand" ""))]
2453   "TARGET_64BIT && reload_completed"
2454   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2455    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2456   "")
2457
2458 (define_split
2459   [(set (match_operand:DF 0 "push_operand" "")
2460         (match_operand:DF 1 "general_operand" ""))]
2461   "reload_completed"
2462   [(const_int 0)]
2463   "ix86_split_long_move (operands); DONE;")
2464
2465 ;; Moving is usually shorter when only FP registers are used. This separate
2466 ;; movdf pattern avoids the use of integer registers for FP operations
2467 ;; when optimizing for size.
2468
2469 (define_insn "*movdf_nointeger"
2470   [(set (match_operand:DF 0 "nonimmediate_operand"
2471                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2472         (match_operand:DF 1 "general_operand"
2473                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2474   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2475    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2476    && (reload_in_progress || reload_completed
2477        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2478        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2479            && standard_80387_constant_p (operands[1]))
2480        || GET_CODE (operands[1]) != CONST_DOUBLE
2481        || memory_operand (operands[0], DFmode))"
2482 {
2483   switch (which_alternative)
2484     {
2485     case 0:
2486       return output_387_reg_move (insn, operands);
2487
2488     case 1:
2489       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2490         return "fstp%z0\t%y0";
2491       else
2492         return "fst%z0\t%y0";
2493
2494     case 2:
2495       return standard_80387_constant_opcode (operands[1]);
2496
2497     case 3:
2498     case 4:
2499       return "#";
2500     case 5:
2501       switch (get_attr_mode (insn))
2502         {
2503         case MODE_V4SF:
2504           return "xorps\t%0, %0";
2505         case MODE_V2DF:
2506           return "xorpd\t%0, %0";
2507         case MODE_TI:
2508           return "pxor\t%0, %0";
2509         default:
2510           gcc_unreachable ();
2511         }
2512     case 6:
2513     case 7:
2514     case 8:
2515       switch (get_attr_mode (insn))
2516         {
2517         case MODE_V4SF:
2518           return "movaps\t{%1, %0|%0, %1}";
2519         case MODE_V2DF:
2520           return "movapd\t{%1, %0|%0, %1}";
2521         case MODE_TI:
2522           return "movdqa\t{%1, %0|%0, %1}";
2523         case MODE_DI:
2524           return "movq\t{%1, %0|%0, %1}";
2525         case MODE_DF:
2526           return "movsd\t{%1, %0|%0, %1}";
2527         case MODE_V1DF:
2528           return "movlpd\t{%1, %0|%0, %1}";
2529         case MODE_V2SF:
2530           return "movlps\t{%1, %0|%0, %1}";
2531         default:
2532           gcc_unreachable ();
2533         }
2534
2535     default:
2536       gcc_unreachable ();
2537     }
2538 }
2539   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2540    (set (attr "mode")
2541         (cond [(eq_attr "alternative" "0,1,2")
2542                  (const_string "DF")
2543                (eq_attr "alternative" "3,4")
2544                  (const_string "SI")
2545
2546                /* For SSE1, we have many fewer alternatives.  */
2547                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2548                  (cond [(eq_attr "alternative" "5,6")
2549                           (const_string "V4SF")
2550                        ]
2551                    (const_string "V2SF"))
2552
2553                /* xorps is one byte shorter.  */
2554                (eq_attr "alternative" "5")
2555                  (cond [(ne (symbol_ref "optimize_size")
2556                             (const_int 0))
2557                           (const_string "V4SF")
2558                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2559                             (const_int 0))
2560                           (const_string "TI")
2561                        ]
2562                        (const_string "V2DF"))
2563
2564                /* For architectures resolving dependencies on
2565                   whole SSE registers use APD move to break dependency
2566                   chains, otherwise use short move to avoid extra work.
2567
2568                   movaps encodes one byte shorter.  */
2569                (eq_attr "alternative" "6")
2570                  (cond
2571                    [(ne (symbol_ref "optimize_size")
2572                         (const_int 0))
2573                       (const_string "V4SF")
2574                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2575                         (const_int 0))
2576                       (const_string "V2DF")
2577                    ]
2578                    (const_string "DF"))
2579                /* For architectures resolving dependencies on register
2580                   parts we may avoid extra work to zero out upper part
2581                   of register.  */
2582                (eq_attr "alternative" "7")
2583                  (if_then_else
2584                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2585                        (const_int 0))
2586                    (const_string "V1DF")
2587                    (const_string "DF"))
2588               ]
2589               (const_string "DF")))])
2590
2591 (define_insn "*movdf_integer"
2592   [(set (match_operand:DF 0 "nonimmediate_operand"
2593                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2594         (match_operand:DF 1 "general_operand"
2595                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2596   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2597    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2598    && (reload_in_progress || reload_completed
2599        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2600        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2601            && standard_80387_constant_p (operands[1]))
2602        || GET_CODE (operands[1]) != CONST_DOUBLE
2603        || memory_operand (operands[0], DFmode))"
2604 {
2605   switch (which_alternative)
2606     {
2607     case 0:
2608       return output_387_reg_move (insn, operands);
2609
2610     case 1:
2611       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2612         return "fstp%z0\t%y0";
2613       else
2614         return "fst%z0\t%y0";
2615
2616     case 2:
2617       return standard_80387_constant_opcode (operands[1]);
2618
2619     case 3:
2620     case 4:
2621       return "#";
2622
2623     case 5:
2624       switch (get_attr_mode (insn))
2625         {
2626         case MODE_V4SF:
2627           return "xorps\t%0, %0";
2628         case MODE_V2DF:
2629           return "xorpd\t%0, %0";
2630         case MODE_TI:
2631           return "pxor\t%0, %0";
2632         default:
2633           gcc_unreachable ();
2634         }
2635     case 6:
2636     case 7:
2637     case 8:
2638       switch (get_attr_mode (insn))
2639         {
2640         case MODE_V4SF:
2641           return "movaps\t{%1, %0|%0, %1}";
2642         case MODE_V2DF:
2643           return "movapd\t{%1, %0|%0, %1}";
2644         case MODE_TI:
2645           return "movdqa\t{%1, %0|%0, %1}";
2646         case MODE_DI:
2647           return "movq\t{%1, %0|%0, %1}";
2648         case MODE_DF:
2649           return "movsd\t{%1, %0|%0, %1}";
2650         case MODE_V1DF:
2651           return "movlpd\t{%1, %0|%0, %1}";
2652         case MODE_V2SF:
2653           return "movlps\t{%1, %0|%0, %1}";
2654         default:
2655           gcc_unreachable ();
2656         }
2657
2658     default:
2659       gcc_unreachable();
2660     }
2661 }
2662   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2663    (set (attr "mode")
2664         (cond [(eq_attr "alternative" "0,1,2")
2665                  (const_string "DF")
2666                (eq_attr "alternative" "3,4")
2667                  (const_string "SI")
2668
2669                /* For SSE1, we have many fewer alternatives.  */
2670                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2671                  (cond [(eq_attr "alternative" "5,6")
2672                           (const_string "V4SF")
2673                        ]
2674                    (const_string "V2SF"))
2675
2676                /* xorps is one byte shorter.  */
2677                (eq_attr "alternative" "5")
2678                  (cond [(ne (symbol_ref "optimize_size")
2679                             (const_int 0))
2680                           (const_string "V4SF")
2681                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2682                             (const_int 0))
2683                           (const_string "TI")
2684                        ]
2685                        (const_string "V2DF"))
2686
2687                /* For architectures resolving dependencies on
2688                   whole SSE registers use APD move to break dependency
2689                   chains, otherwise use short move to avoid extra work.
2690
2691                   movaps encodes one byte shorter.  */
2692                (eq_attr "alternative" "6")
2693                  (cond
2694                    [(ne (symbol_ref "optimize_size")
2695                         (const_int 0))
2696                       (const_string "V4SF")
2697                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2698                         (const_int 0))
2699                       (const_string "V2DF")
2700                    ]
2701                    (const_string "DF"))
2702                /* For architectures resolving dependencies on register
2703                   parts we may avoid extra work to zero out upper part
2704                   of register.  */
2705                (eq_attr "alternative" "7")
2706                  (if_then_else
2707                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2708                        (const_int 0))
2709                    (const_string "V1DF")
2710                    (const_string "DF"))
2711               ]
2712               (const_string "DF")))])
2713
2714 (define_split
2715   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2716         (match_operand:DF 1 "general_operand" ""))]
2717   "reload_completed
2718    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2719    && ! (ANY_FP_REG_P (operands[0]) ||
2720          (GET_CODE (operands[0]) == SUBREG
2721           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2722    && ! (ANY_FP_REG_P (operands[1]) ||
2723          (GET_CODE (operands[1]) == SUBREG
2724           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2725   [(const_int 0)]
2726   "ix86_split_long_move (operands); DONE;")
2727
2728 (define_insn "*swapdf"
2729   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2730         (match_operand:DF 1 "fp_register_operand" "+f"))
2731    (set (match_dup 1)
2732         (match_dup 0))]
2733   "reload_completed || TARGET_80387"
2734 {
2735   if (STACK_TOP_P (operands[0]))
2736     return "fxch\t%1";
2737   else
2738     return "fxch\t%0";
2739 }
2740   [(set_attr "type" "fxch")
2741    (set_attr "mode" "DF")])
2742
2743 (define_expand "movxf"
2744   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2745         (match_operand:XF 1 "general_operand" ""))]
2746   ""
2747   "ix86_expand_move (XFmode, operands); DONE;")
2748
2749 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2750 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2751 ;; Pushing using integer instructions is longer except for constants
2752 ;; and direct memory references.
2753 ;; (assuming that any given constant is pushed only once, but this ought to be
2754 ;;  handled elsewhere).
2755
2756 (define_insn "*pushxf_nointeger"
2757   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2758         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2759   "optimize_size"
2760 {
2761   /* This insn should be already split before reg-stack.  */
2762   gcc_unreachable ();
2763 }
2764   [(set_attr "type" "multi")
2765    (set_attr "unit" "i387,*,*")
2766    (set_attr "mode" "XF,SI,SI")])
2767
2768 (define_insn "*pushxf_integer"
2769   [(set (match_operand:XF 0 "push_operand" "=<,<")
2770         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2771   "!optimize_size"
2772 {
2773   /* This insn should be already split before reg-stack.  */
2774   gcc_unreachable ();
2775 }
2776   [(set_attr "type" "multi")
2777    (set_attr "unit" "i387,*")
2778    (set_attr "mode" "XF,SI")])
2779
2780 (define_split
2781   [(set (match_operand 0 "push_operand" "")
2782         (match_operand 1 "general_operand" ""))]
2783   "reload_completed
2784    && (GET_MODE (operands[0]) == XFmode
2785        || GET_MODE (operands[0]) == DFmode)
2786    && !ANY_FP_REG_P (operands[1])"
2787   [(const_int 0)]
2788   "ix86_split_long_move (operands); DONE;")
2789
2790 (define_split
2791   [(set (match_operand:XF 0 "push_operand" "")
2792         (match_operand:XF 1 "any_fp_register_operand" ""))]
2793   "!TARGET_64BIT"
2794   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2795    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2796   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2797
2798 (define_split
2799   [(set (match_operand:XF 0 "push_operand" "")
2800         (match_operand:XF 1 "any_fp_register_operand" ""))]
2801   "TARGET_64BIT"
2802   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2803    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2804   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2805
2806 ;; Do not use integer registers when optimizing for size
2807 (define_insn "*movxf_nointeger"
2808   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2809         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2810   "optimize_size
2811    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2812    && (reload_in_progress || reload_completed
2813        || (optimize_size && standard_80387_constant_p (operands[1]))
2814        || GET_CODE (operands[1]) != CONST_DOUBLE
2815        || memory_operand (operands[0], XFmode))"
2816 {
2817   switch (which_alternative)
2818     {
2819     case 0:
2820       return output_387_reg_move (insn, operands);
2821
2822     case 1:
2823       /* There is no non-popping store to memory for XFmode.  So if
2824          we need one, follow the store with a load.  */
2825       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2826         return "fstp%z0\t%y0\;fld%z0\t%y0";
2827       else
2828         return "fstp%z0\t%y0";
2829
2830     case 2:
2831       return standard_80387_constant_opcode (operands[1]);
2832
2833     case 3: case 4:
2834       return "#";
2835     default:
2836       gcc_unreachable ();
2837     }
2838 }
2839   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2840    (set_attr "mode" "XF,XF,XF,SI,SI")])
2841
2842 (define_insn "*movxf_integer"
2843   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2844         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2845   "!optimize_size
2846    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2847    && (reload_in_progress || reload_completed
2848        || (optimize_size && standard_80387_constant_p (operands[1]))
2849        || GET_CODE (operands[1]) != CONST_DOUBLE
2850        || memory_operand (operands[0], XFmode))"
2851 {
2852   switch (which_alternative)
2853     {
2854     case 0:
2855       return output_387_reg_move (insn, operands);
2856
2857     case 1:
2858       /* There is no non-popping store to memory for XFmode.  So if
2859          we need one, follow the store with a load.  */
2860       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2861         return "fstp%z0\t%y0\;fld%z0\t%y0";
2862       else
2863         return "fstp%z0\t%y0";
2864
2865     case 2:
2866       return standard_80387_constant_opcode (operands[1]);
2867
2868     case 3: case 4:
2869       return "#";
2870
2871     default:
2872       gcc_unreachable ();
2873     }
2874 }
2875   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2876    (set_attr "mode" "XF,XF,XF,SI,SI")])
2877
2878 (define_split
2879   [(set (match_operand 0 "nonimmediate_operand" "")
2880         (match_operand 1 "general_operand" ""))]
2881   "reload_completed
2882    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2883    && GET_MODE (operands[0]) == XFmode
2884    && ! (ANY_FP_REG_P (operands[0]) ||
2885          (GET_CODE (operands[0]) == SUBREG
2886           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2887    && ! (ANY_FP_REG_P (operands[1]) ||
2888          (GET_CODE (operands[1]) == SUBREG
2889           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2890   [(const_int 0)]
2891   "ix86_split_long_move (operands); DONE;")
2892
2893 (define_split
2894   [(set (match_operand 0 "register_operand" "")
2895         (match_operand 1 "memory_operand" ""))]
2896   "reload_completed
2897    && GET_CODE (operands[1]) == MEM
2898    && (GET_MODE (operands[0]) == XFmode
2899        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2900    && constant_pool_reference_p (operands[1])"
2901   [(set (match_dup 0) (match_dup 1))]
2902 {
2903   rtx c = avoid_constant_pool_reference (operands[1]);
2904   rtx r = operands[0];
2905
2906   if (GET_CODE (r) == SUBREG)
2907     r = SUBREG_REG (r);
2908
2909   if (SSE_REG_P (r))
2910     {
2911       if (!standard_sse_constant_p (c))
2912         FAIL;
2913     }
2914   else if (FP_REG_P (r))
2915     {
2916       if (!standard_80387_constant_p (c))
2917         FAIL;
2918     }
2919   else if (MMX_REG_P (r))
2920     FAIL;
2921
2922   operands[1] = c;
2923 })
2924
2925 (define_split
2926   [(set (match_operand 0 "register_operand" "")
2927         (float_extend (match_operand 1 "memory_operand" "")))]
2928   "reload_completed
2929    && GET_CODE (operands[1]) == MEM
2930    && (GET_MODE (operands[0]) == XFmode
2931        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2932    && constant_pool_reference_p (operands[1])"
2933   [(set (match_dup 0) (match_dup 1))]
2934 {
2935   rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
2936   rtx r = operands[0];
2937
2938   if (GET_CODE (r) == SUBREG)
2939     r = SUBREG_REG (r);
2940
2941   if (SSE_REG_P (r))
2942     {
2943       if (!standard_sse_constant_p (c))
2944         FAIL;
2945     }
2946   else if (FP_REG_P (r))
2947     {
2948       if (!standard_80387_constant_p (c))
2949         FAIL;
2950     }
2951   else if (MMX_REG_P (r))
2952     FAIL;
2953
2954   operands[1] = c;
2955 })
2956
2957 (define_insn "swapxf"
2958   [(set (match_operand:XF 0 "register_operand" "+f")
2959         (match_operand:XF 1 "register_operand" "+f"))
2960    (set (match_dup 1)
2961         (match_dup 0))]
2962   "TARGET_80387"
2963 {
2964   if (STACK_TOP_P (operands[0]))
2965     return "fxch\t%1";
2966   else
2967     return "fxch\t%0";
2968 }
2969   [(set_attr "type" "fxch")
2970    (set_attr "mode" "XF")])
2971
2972 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2973 (define_split
2974   [(set (match_operand:X87MODEF 0 "register_operand" "")
2975         (match_operand:X87MODEF 1 "immediate_operand" ""))]
2976   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2977    && (standard_80387_constant_p (operands[1]) == 8
2978        || standard_80387_constant_p (operands[1]) == 9)"
2979   [(set (match_dup 0)(match_dup 1))
2980    (set (match_dup 0)
2981         (neg:X87MODEF (match_dup 0)))]
2982 {
2983   REAL_VALUE_TYPE r;
2984
2985   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2986   if (real_isnegzero (&r))
2987     operands[1] = CONST0_RTX (<MODE>mode);
2988   else
2989     operands[1] = CONST1_RTX (<MODE>mode);
2990 })
2991
2992 (define_expand "movtf"
2993   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2994         (match_operand:TF 1 "nonimmediate_operand" ""))]
2995   "TARGET_64BIT"
2996 {
2997   ix86_expand_move (TFmode, operands);
2998   DONE;
2999 })
3000
3001 (define_insn "*movtf_internal"
3002   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3003         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3004   "TARGET_64BIT
3005    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3006 {
3007   switch (which_alternative)
3008     {
3009     case 0:
3010     case 1:
3011       return "#";
3012     case 2:
3013       if (get_attr_mode (insn) == MODE_V4SF)
3014         return "xorps\t%0, %0";
3015       else
3016         return "pxor\t%0, %0";
3017     case 3:
3018     case 4:
3019       if (get_attr_mode (insn) == MODE_V4SF)
3020         return "movaps\t{%1, %0|%0, %1}";
3021       else
3022         return "movdqa\t{%1, %0|%0, %1}";
3023     default:
3024       gcc_unreachable ();
3025     }
3026 }
3027   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3028    (set (attr "mode")
3029         (cond [(eq_attr "alternative" "2,3")
3030                  (if_then_else
3031                    (ne (symbol_ref "optimize_size")
3032                        (const_int 0))
3033                    (const_string "V4SF")
3034                    (const_string "TI"))
3035                (eq_attr "alternative" "4")
3036                  (if_then_else
3037                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3038                             (const_int 0))
3039                         (ne (symbol_ref "optimize_size")
3040                             (const_int 0)))
3041                    (const_string "V4SF")
3042                    (const_string "TI"))]
3043                (const_string "DI")))])
3044
3045 (define_split
3046   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3047         (match_operand:TF 1 "general_operand" ""))]
3048   "reload_completed && !SSE_REG_P (operands[0])
3049    && !SSE_REG_P (operands[1])"
3050   [(const_int 0)]
3051   "ix86_split_long_move (operands); DONE;")
3052 \f
3053 ;; Zero extension instructions
3054
3055 (define_expand "zero_extendhisi2"
3056   [(set (match_operand:SI 0 "register_operand" "")
3057      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3058   ""
3059 {
3060   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3061     {
3062       operands[1] = force_reg (HImode, operands[1]);
3063       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3064       DONE;
3065     }
3066 })
3067
3068 (define_insn "zero_extendhisi2_and"
3069   [(set (match_operand:SI 0 "register_operand" "=r")
3070      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3071    (clobber (reg:CC FLAGS_REG))]
3072   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3073   "#"
3074   [(set_attr "type" "alu1")
3075    (set_attr "mode" "SI")])
3076
3077 (define_split
3078   [(set (match_operand:SI 0 "register_operand" "")
3079         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3080    (clobber (reg:CC FLAGS_REG))]
3081   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3082   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3083               (clobber (reg:CC FLAGS_REG))])]
3084   "")
3085
3086 (define_insn "*zero_extendhisi2_movzwl"
3087   [(set (match_operand:SI 0 "register_operand" "=r")
3088      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3089   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3090   "movz{wl|x}\t{%1, %0|%0, %1}"
3091   [(set_attr "type" "imovx")
3092    (set_attr "mode" "SI")])
3093
3094 (define_expand "zero_extendqihi2"
3095   [(parallel
3096     [(set (match_operand:HI 0 "register_operand" "")
3097        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3098      (clobber (reg:CC FLAGS_REG))])]
3099   ""
3100   "")
3101
3102 (define_insn "*zero_extendqihi2_and"
3103   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3104      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3105    (clobber (reg:CC FLAGS_REG))]
3106   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3107   "#"
3108   [(set_attr "type" "alu1")
3109    (set_attr "mode" "HI")])
3110
3111 (define_insn "*zero_extendqihi2_movzbw_and"
3112   [(set (match_operand:HI 0 "register_operand" "=r,r")
3113      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3114    (clobber (reg:CC FLAGS_REG))]
3115   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3116   "#"
3117   [(set_attr "type" "imovx,alu1")
3118    (set_attr "mode" "HI")])
3119
3120 ; zero extend to SImode here to avoid partial register stalls
3121 (define_insn "*zero_extendqihi2_movzbl"
3122   [(set (match_operand:HI 0 "register_operand" "=r")
3123      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3124   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3125   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3126   [(set_attr "type" "imovx")
3127    (set_attr "mode" "SI")])
3128
3129 ;; For the movzbw case strip only the clobber
3130 (define_split
3131   [(set (match_operand:HI 0 "register_operand" "")
3132         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3133    (clobber (reg:CC FLAGS_REG))]
3134   "reload_completed
3135    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3136    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3137   [(set (match_operand:HI 0 "register_operand" "")
3138         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3139
3140 ;; When source and destination does not overlap, clear destination
3141 ;; first and then do the movb
3142 (define_split
3143   [(set (match_operand:HI 0 "register_operand" "")
3144         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3145    (clobber (reg:CC FLAGS_REG))]
3146   "reload_completed
3147    && ANY_QI_REG_P (operands[0])
3148    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3149    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3150   [(set (match_dup 0) (const_int 0))
3151    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3152   "operands[2] = gen_lowpart (QImode, operands[0]);")
3153
3154 ;; Rest is handled by single and.
3155 (define_split
3156   [(set (match_operand:HI 0 "register_operand" "")
3157         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3158    (clobber (reg:CC FLAGS_REG))]
3159   "reload_completed
3160    && true_regnum (operands[0]) == true_regnum (operands[1])"
3161   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3162               (clobber (reg:CC FLAGS_REG))])]
3163   "")
3164
3165 (define_expand "zero_extendqisi2"
3166   [(parallel
3167     [(set (match_operand:SI 0 "register_operand" "")
3168        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3169      (clobber (reg:CC FLAGS_REG))])]
3170   ""
3171   "")
3172
3173 (define_insn "*zero_extendqisi2_and"
3174   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3175      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3176    (clobber (reg:CC FLAGS_REG))]
3177   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3178   "#"
3179   [(set_attr "type" "alu1")
3180    (set_attr "mode" "SI")])
3181
3182 (define_insn "*zero_extendqisi2_movzbw_and"
3183   [(set (match_operand:SI 0 "register_operand" "=r,r")
3184      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3185    (clobber (reg:CC FLAGS_REG))]
3186   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3187   "#"
3188   [(set_attr "type" "imovx,alu1")
3189    (set_attr "mode" "SI")])
3190
3191 (define_insn "*zero_extendqisi2_movzbw"
3192   [(set (match_operand:SI 0 "register_operand" "=r")
3193      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3194   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3195   "movz{bl|x}\t{%1, %0|%0, %1}"
3196   [(set_attr "type" "imovx")
3197    (set_attr "mode" "SI")])
3198
3199 ;; For the movzbl case strip only the clobber
3200 (define_split
3201   [(set (match_operand:SI 0 "register_operand" "")
3202         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3203    (clobber (reg:CC FLAGS_REG))]
3204   "reload_completed
3205    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3206    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3207   [(set (match_dup 0)
3208         (zero_extend:SI (match_dup 1)))])
3209
3210 ;; When source and destination does not overlap, clear destination
3211 ;; first and then do the movb
3212 (define_split
3213   [(set (match_operand:SI 0 "register_operand" "")
3214         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3215    (clobber (reg:CC FLAGS_REG))]
3216   "reload_completed
3217    && ANY_QI_REG_P (operands[0])
3218    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3219    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3220    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3221   [(set (match_dup 0) (const_int 0))
3222    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3223   "operands[2] = gen_lowpart (QImode, operands[0]);")
3224
3225 ;; Rest is handled by single and.
3226 (define_split
3227   [(set (match_operand:SI 0 "register_operand" "")
3228         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3229    (clobber (reg:CC FLAGS_REG))]
3230   "reload_completed
3231    && true_regnum (operands[0]) == true_regnum (operands[1])"
3232   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3233               (clobber (reg:CC FLAGS_REG))])]
3234   "")
3235
3236 ;; %%% Kill me once multi-word ops are sane.
3237 (define_expand "zero_extendsidi2"
3238   [(set (match_operand:DI 0 "register_operand" "=r")
3239      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3240   ""
3241   "if (!TARGET_64BIT)
3242      {
3243        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3244        DONE;
3245      }
3246   ")
3247
3248 (define_insn "zero_extendsidi2_32"
3249   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3250         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3251    (clobber (reg:CC FLAGS_REG))]
3252   "!TARGET_64BIT"
3253   "@
3254    #
3255    #
3256    #
3257    movd\t{%1, %0|%0, %1}
3258    movd\t{%1, %0|%0, %1}"
3259   [(set_attr "mode" "SI,SI,SI,DI,TI")
3260    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3261
3262 (define_insn "zero_extendsidi2_rex64"
3263   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3264      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3265   "TARGET_64BIT"
3266   "@
3267    mov\t{%k1, %k0|%k0, %k1}
3268    #
3269    movd\t{%1, %0|%0, %1}
3270    movd\t{%1, %0|%0, %1}"
3271   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3272    (set_attr "mode" "SI,DI,SI,SI")])
3273
3274 (define_split
3275   [(set (match_operand:DI 0 "memory_operand" "")
3276      (zero_extend:DI (match_dup 0)))]
3277   "TARGET_64BIT"
3278   [(set (match_dup 4) (const_int 0))]
3279   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3280
3281 (define_split
3282   [(set (match_operand:DI 0 "register_operand" "")
3283         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3284    (clobber (reg:CC FLAGS_REG))]
3285   "!TARGET_64BIT && reload_completed
3286    && true_regnum (operands[0]) == true_regnum (operands[1])"
3287   [(set (match_dup 4) (const_int 0))]
3288   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3289
3290 (define_split
3291   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3292         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3293    (clobber (reg:CC FLAGS_REG))]
3294   "!TARGET_64BIT && reload_completed
3295    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3296   [(set (match_dup 3) (match_dup 1))
3297    (set (match_dup 4) (const_int 0))]
3298   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3299
3300 (define_insn "zero_extendhidi2"
3301   [(set (match_operand:DI 0 "register_operand" "=r")
3302      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3303   "TARGET_64BIT"
3304   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3305   [(set_attr "type" "imovx")
3306    (set_attr "mode" "DI")])
3307
3308 (define_insn "zero_extendqidi2"
3309   [(set (match_operand:DI 0 "register_operand" "=r")
3310      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3311   "TARGET_64BIT"
3312   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3313   [(set_attr "type" "imovx")
3314    (set_attr "mode" "DI")])
3315 \f
3316 ;; Sign extension instructions
3317
3318 (define_expand "extendsidi2"
3319   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3320                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3321               (clobber (reg:CC FLAGS_REG))
3322               (clobber (match_scratch:SI 2 ""))])]
3323   ""
3324 {
3325   if (TARGET_64BIT)
3326     {
3327       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3328       DONE;
3329     }
3330 })
3331
3332 (define_insn "*extendsidi2_1"
3333   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3334         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3335    (clobber (reg:CC FLAGS_REG))
3336    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3337   "!TARGET_64BIT"
3338   "#")
3339
3340 (define_insn "extendsidi2_rex64"
3341   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3342         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3343   "TARGET_64BIT"
3344   "@
3345    {cltq|cdqe}
3346    movs{lq|x}\t{%1,%0|%0, %1}"
3347   [(set_attr "type" "imovx")
3348    (set_attr "mode" "DI")
3349    (set_attr "prefix_0f" "0")
3350    (set_attr "modrm" "0,1")])
3351
3352 (define_insn "extendhidi2"
3353   [(set (match_operand:DI 0 "register_operand" "=r")
3354         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3355   "TARGET_64BIT"
3356   "movs{wq|x}\t{%1,%0|%0, %1}"
3357   [(set_attr "type" "imovx")
3358    (set_attr "mode" "DI")])
3359
3360 (define_insn "extendqidi2"
3361   [(set (match_operand:DI 0 "register_operand" "=r")
3362         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3363   "TARGET_64BIT"
3364   "movs{bq|x}\t{%1,%0|%0, %1}"
3365    [(set_attr "type" "imovx")
3366     (set_attr "mode" "DI")])
3367
3368 ;; Extend to memory case when source register does die.
3369 (define_split
3370   [(set (match_operand:DI 0 "memory_operand" "")
3371         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3372    (clobber (reg:CC FLAGS_REG))
3373    (clobber (match_operand:SI 2 "register_operand" ""))]
3374   "(reload_completed
3375     && dead_or_set_p (insn, operands[1])
3376     && !reg_mentioned_p (operands[1], operands[0]))"
3377   [(set (match_dup 3) (match_dup 1))
3378    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3379               (clobber (reg:CC FLAGS_REG))])
3380    (set (match_dup 4) (match_dup 1))]
3381   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3382
3383 ;; Extend to memory case when source register does not die.
3384 (define_split
3385   [(set (match_operand:DI 0 "memory_operand" "")
3386         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3387    (clobber (reg:CC FLAGS_REG))
3388    (clobber (match_operand:SI 2 "register_operand" ""))]
3389   "reload_completed"
3390   [(const_int 0)]
3391 {
3392   split_di (&operands[0], 1, &operands[3], &operands[4]);
3393
3394   emit_move_insn (operands[3], operands[1]);
3395
3396   /* Generate a cltd if possible and doing so it profitable.  */
3397   if (true_regnum (operands[1]) == 0
3398       && true_regnum (operands[2]) == 1
3399       && (optimize_size || TARGET_USE_CLTD))
3400     {
3401       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3402     }
3403   else
3404     {
3405       emit_move_insn (operands[2], operands[1]);
3406       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3407     }
3408   emit_move_insn (operands[4], operands[2]);
3409   DONE;
3410 })
3411
3412 ;; Extend to register case.  Optimize case where source and destination
3413 ;; registers match and cases where we can use cltd.
3414 (define_split
3415   [(set (match_operand:DI 0 "register_operand" "")
3416         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3417    (clobber (reg:CC FLAGS_REG))
3418    (clobber (match_scratch:SI 2 ""))]
3419   "reload_completed"
3420   [(const_int 0)]
3421 {
3422   split_di (&operands[0], 1, &operands[3], &operands[4]);
3423
3424   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3425     emit_move_insn (operands[3], operands[1]);
3426
3427   /* Generate a cltd if possible and doing so it profitable.  */
3428   if (true_regnum (operands[3]) == 0
3429       && (optimize_size || TARGET_USE_CLTD))
3430     {
3431       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3432       DONE;
3433     }
3434
3435   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3436     emit_move_insn (operands[4], operands[1]);
3437
3438   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3439   DONE;
3440 })
3441
3442 (define_insn "extendhisi2"
3443   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3444         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3445   ""
3446 {
3447   switch (get_attr_prefix_0f (insn))
3448     {
3449     case 0:
3450       return "{cwtl|cwde}";
3451     default:
3452       return "movs{wl|x}\t{%1,%0|%0, %1}";
3453     }
3454 }
3455   [(set_attr "type" "imovx")
3456    (set_attr "mode" "SI")
3457    (set (attr "prefix_0f")
3458      ;; movsx is short decodable while cwtl is vector decoded.
3459      (if_then_else (and (eq_attr "cpu" "!k6")
3460                         (eq_attr "alternative" "0"))
3461         (const_string "0")
3462         (const_string "1")))
3463    (set (attr "modrm")
3464      (if_then_else (eq_attr "prefix_0f" "0")
3465         (const_string "0")
3466         (const_string "1")))])
3467
3468 (define_insn "*extendhisi2_zext"
3469   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3470         (zero_extend:DI
3471           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3472   "TARGET_64BIT"
3473 {
3474   switch (get_attr_prefix_0f (insn))
3475     {
3476     case 0:
3477       return "{cwtl|cwde}";
3478     default:
3479       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3480     }
3481 }
3482   [(set_attr "type" "imovx")
3483    (set_attr "mode" "SI")
3484    (set (attr "prefix_0f")
3485      ;; movsx is short decodable while cwtl is vector decoded.
3486      (if_then_else (and (eq_attr "cpu" "!k6")
3487                         (eq_attr "alternative" "0"))
3488         (const_string "0")
3489         (const_string "1")))
3490    (set (attr "modrm")
3491      (if_then_else (eq_attr "prefix_0f" "0")
3492         (const_string "0")
3493         (const_string "1")))])
3494
3495 (define_insn "extendqihi2"
3496   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3497         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3498   ""
3499 {
3500   switch (get_attr_prefix_0f (insn))
3501     {
3502     case 0:
3503       return "{cbtw|cbw}";
3504     default:
3505       return "movs{bw|x}\t{%1,%0|%0, %1}";
3506     }
3507 }
3508   [(set_attr "type" "imovx")
3509    (set_attr "mode" "HI")
3510    (set (attr "prefix_0f")
3511      ;; movsx is short decodable while cwtl is vector decoded.
3512      (if_then_else (and (eq_attr "cpu" "!k6")
3513                         (eq_attr "alternative" "0"))
3514         (const_string "0")
3515         (const_string "1")))
3516    (set (attr "modrm")
3517      (if_then_else (eq_attr "prefix_0f" "0")
3518         (const_string "0")
3519         (const_string "1")))])
3520
3521 (define_insn "extendqisi2"
3522   [(set (match_operand:SI 0 "register_operand" "=r")
3523         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3524   ""
3525   "movs{bl|x}\t{%1,%0|%0, %1}"
3526    [(set_attr "type" "imovx")
3527     (set_attr "mode" "SI")])
3528
3529 (define_insn "*extendqisi2_zext"
3530   [(set (match_operand:DI 0 "register_operand" "=r")
3531         (zero_extend:DI
3532           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3533   "TARGET_64BIT"
3534   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3535    [(set_attr "type" "imovx")
3536     (set_attr "mode" "SI")])
3537 \f
3538 ;; Conversions between float and double.
3539
3540 ;; These are all no-ops in the model used for the 80387.  So just
3541 ;; emit moves.
3542
3543 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3544 (define_insn "*dummy_extendsfdf2"
3545   [(set (match_operand:DF 0 "push_operand" "=<")
3546         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3547   "0"
3548   "#")
3549
3550 (define_split
3551   [(set (match_operand:DF 0 "push_operand" "")
3552         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3553   "!TARGET_64BIT"
3554   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3555    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3556
3557 (define_split
3558   [(set (match_operand:DF 0 "push_operand" "")
3559         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3560   "TARGET_64BIT"
3561   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3562    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3563
3564 (define_insn "*dummy_extendsfxf2"
3565   [(set (match_operand:XF 0 "push_operand" "=<")
3566         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3567   "0"
3568   "#")
3569
3570 (define_split
3571   [(set (match_operand:XF 0 "push_operand" "")
3572         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3573   ""
3574   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3575    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3576   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3577
3578 (define_split
3579   [(set (match_operand:XF 0 "push_operand" "")
3580         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3581   "TARGET_64BIT"
3582   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3583    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3584   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3585
3586 (define_split
3587   [(set (match_operand:XF 0 "push_operand" "")
3588         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3589   ""
3590   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3591    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3592   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3593
3594 (define_split
3595   [(set (match_operand:XF 0 "push_operand" "")
3596         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3597   "TARGET_64BIT"
3598   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3599    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3600   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3601
3602 (define_expand "extendsfdf2"
3603   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3604         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3605   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3606 {
3607   /* ??? Needed for compress_float_constant since all fp constants
3608      are LEGITIMATE_CONSTANT_P.  */
3609   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3610     {
3611       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3612           && standard_80387_constant_p (operands[1]) > 0)
3613         {
3614           operands[1] = simplify_const_unary_operation
3615             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3616           emit_move_insn_1 (operands[0], operands[1]);
3617           DONE;
3618         }
3619       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3620     }
3621 })
3622
3623 (define_insn "*extendsfdf2_mixed"
3624   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3625         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3626   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3627 {
3628   switch (which_alternative)
3629     {
3630     case 0:
3631       return output_387_reg_move (insn, operands);
3632
3633     case 1:
3634       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3635         return "fstp%z0\t%y0";
3636       else
3637         return "fst%z0\t%y0";
3638
3639     case 2:
3640       return "cvtss2sd\t{%1, %0|%0, %1}";
3641
3642     default:
3643       gcc_unreachable ();
3644     }
3645 }
3646   [(set_attr "type" "fmov,fmov,ssecvt")
3647    (set_attr "mode" "SF,XF,DF")])
3648
3649 (define_insn "*extendsfdf2_sse"
3650   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3651         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3652   "TARGET_SSE2 && TARGET_SSE_MATH"
3653   "cvtss2sd\t{%1, %0|%0, %1}"
3654   [(set_attr "type" "ssecvt")
3655    (set_attr "mode" "DF")])
3656
3657 (define_insn "*extendsfdf2_i387"
3658   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3659         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3660   "TARGET_80387"
3661 {
3662   switch (which_alternative)
3663     {
3664     case 0:
3665       return output_387_reg_move (insn, operands);
3666
3667     case 1:
3668       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3669         return "fstp%z0\t%y0";
3670       else
3671         return "fst%z0\t%y0";
3672
3673     default:
3674       gcc_unreachable ();
3675     }
3676 }
3677   [(set_attr "type" "fmov")
3678    (set_attr "mode" "SF,XF")])
3679
3680 (define_expand "extendsfxf2"
3681   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3682         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3683   "TARGET_80387"
3684 {
3685   /* ??? Needed for compress_float_constant since all fp constants
3686      are LEGITIMATE_CONSTANT_P.  */
3687   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3688     {
3689       if (standard_80387_constant_p (operands[1]) > 0)
3690         {
3691           operands[1] = simplify_const_unary_operation
3692             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3693           emit_move_insn_1 (operands[0], operands[1]);
3694           DONE;
3695         }
3696       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3697     }
3698 })
3699
3700 (define_insn "*extendsfxf2_i387"
3701   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3702         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3703   "TARGET_80387"
3704 {
3705   switch (which_alternative)
3706     {
3707     case 0:
3708       return output_387_reg_move (insn, operands);
3709
3710     case 1:
3711       /* There is no non-popping store to memory for XFmode.  So if
3712          we need one, follow the store with a load.  */
3713       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3714         return "fstp%z0\t%y0";
3715       else
3716         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3717
3718     default:
3719       gcc_unreachable ();
3720     }
3721 }
3722   [(set_attr "type" "fmov")
3723    (set_attr "mode" "SF,XF")])
3724
3725 (define_expand "extenddfxf2"
3726   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3727         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3728   "TARGET_80387"
3729 {
3730   /* ??? Needed for compress_float_constant since all fp constants
3731      are LEGITIMATE_CONSTANT_P.  */
3732   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3733     {
3734       if (standard_80387_constant_p (operands[1]) > 0)
3735         {
3736           operands[1] = simplify_const_unary_operation
3737             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3738           emit_move_insn_1 (operands[0], operands[1]);
3739           DONE;
3740         }
3741       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3742     }
3743 })
3744
3745 (define_insn "*extenddfxf2_i387"
3746   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3747         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3748   "TARGET_80387"
3749 {
3750   switch (which_alternative)
3751     {
3752     case 0:
3753       return output_387_reg_move (insn, operands);
3754
3755     case 1:
3756       /* There is no non-popping store to memory for XFmode.  So if
3757          we need one, follow the store with a load.  */
3758       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3759         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3760       else
3761         return "fstp%z0\t%y0";
3762
3763     default:
3764       gcc_unreachable ();
3765     }
3766 }
3767   [(set_attr "type" "fmov")
3768    (set_attr "mode" "DF,XF")])
3769
3770 ;; %%% This seems bad bad news.
3771 ;; This cannot output into an f-reg because there is no way to be sure
3772 ;; of truncating in that case.  Otherwise this is just like a simple move
3773 ;; insn.  So we pretend we can output to a reg in order to get better
3774 ;; register preferencing, but we really use a stack slot.
3775
3776 ;; Conversion from DFmode to SFmode.
3777
3778 (define_expand "truncdfsf2"
3779   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3780         (float_truncate:SF
3781           (match_operand:DF 1 "nonimmediate_operand" "")))]
3782   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3783 {
3784   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3785     ;
3786   else if (flag_unsafe_math_optimizations)
3787     ;
3788   else
3789     {
3790       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3791       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3792       DONE;
3793     }
3794 })
3795
3796 (define_expand "truncdfsf2_with_temp"
3797   [(parallel [(set (match_operand:SF 0 "" "")
3798                    (float_truncate:SF (match_operand:DF 1 "" "")))
3799               (clobber (match_operand:SF 2 "" ""))])]
3800   "")
3801
3802 (define_insn "*truncdfsf_fast_mixed"
3803   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3804         (float_truncate:SF
3805           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3806   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3807 {
3808   switch (which_alternative)
3809     {
3810     case 0:
3811       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3812         return "fstp%z0\t%y0";
3813       else
3814         return "fst%z0\t%y0";
3815     case 1:
3816       return output_387_reg_move (insn, operands);
3817     case 2:
3818       return "cvtsd2ss\t{%1, %0|%0, %1}";
3819     default:
3820       gcc_unreachable ();
3821     }
3822 }
3823   [(set_attr "type" "fmov,fmov,ssecvt")
3824    (set_attr "mode" "SF")])
3825
3826 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3827 ;; because nothing we do here is unsafe.
3828 (define_insn "*truncdfsf_fast_sse"
3829   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3830         (float_truncate:SF
3831           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3832   "TARGET_SSE2 && TARGET_SSE_MATH"
3833   "cvtsd2ss\t{%1, %0|%0, %1}"
3834   [(set_attr "type" "ssecvt")
3835    (set_attr "mode" "SF")])
3836
3837 (define_insn "*truncdfsf_fast_i387"
3838   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3839         (float_truncate:SF
3840           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3841   "TARGET_80387 && flag_unsafe_math_optimizations"
3842   "* return output_387_reg_move (insn, operands);"
3843   [(set_attr "type" "fmov")
3844    (set_attr "mode" "SF")])
3845
3846 (define_insn "*truncdfsf_mixed"
3847   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3848         (float_truncate:SF
3849           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3850    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3851   "TARGET_MIX_SSE_I387"
3852 {
3853   switch (which_alternative)
3854     {
3855     case 0:
3856       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3857         return "fstp%z0\t%y0";
3858       else
3859         return "fst%z0\t%y0";
3860     case 1:
3861       return "#";
3862     case 2:
3863       return "cvtsd2ss\t{%1, %0|%0, %1}";
3864     default:
3865       gcc_unreachable ();
3866     }
3867 }
3868   [(set_attr "type" "fmov,multi,ssecvt")
3869    (set_attr "unit" "*,i387,*")
3870    (set_attr "mode" "SF")])
3871
3872 (define_insn "*truncdfsf_i387"
3873   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3874         (float_truncate:SF
3875           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3876    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3877   "TARGET_80387"
3878 {
3879   switch (which_alternative)
3880     {
3881     case 0:
3882       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3883         return "fstp%z0\t%y0";
3884       else
3885         return "fst%z0\t%y0";
3886     case 1:
3887       return "#";
3888     default:
3889       gcc_unreachable ();
3890     }
3891 }
3892   [(set_attr "type" "fmov,multi")
3893    (set_attr "unit" "*,i387")
3894    (set_attr "mode" "SF")])
3895
3896 (define_insn "*truncdfsf2_i387_1"
3897   [(set (match_operand:SF 0 "memory_operand" "=m")
3898         (float_truncate:SF
3899           (match_operand:DF 1 "register_operand" "f")))]
3900   "TARGET_80387
3901    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3902    && !TARGET_MIX_SSE_I387"
3903 {
3904   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3905     return "fstp%z0\t%y0";
3906   else
3907     return "fst%z0\t%y0";
3908 }
3909   [(set_attr "type" "fmov")
3910    (set_attr "mode" "SF")])
3911
3912 (define_split
3913   [(set (match_operand:SF 0 "register_operand" "")
3914         (float_truncate:SF
3915          (match_operand:DF 1 "fp_register_operand" "")))
3916    (clobber (match_operand 2 "" ""))]
3917   "reload_completed"
3918   [(set (match_dup 2) (match_dup 1))
3919    (set (match_dup 0) (match_dup 2))]
3920 {
3921   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3922 })
3923
3924 ;; Conversion from XFmode to SFmode.
3925
3926 (define_expand "truncxfsf2"
3927   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3928                    (float_truncate:SF
3929                     (match_operand:XF 1 "register_operand" "")))
3930               (clobber (match_dup 2))])]
3931   "TARGET_80387"
3932 {
3933   if (flag_unsafe_math_optimizations)
3934     {
3935       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3936       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3937       if (reg != operands[0])
3938         emit_move_insn (operands[0], reg);
3939       DONE;
3940     }
3941   else
3942     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3943 })
3944
3945 (define_insn "*truncxfsf2_mixed"
3946   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3947         (float_truncate:SF
3948          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3949    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3950   "TARGET_80387"
3951 {
3952   gcc_assert (!which_alternative);
3953   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3954     return "fstp%z0\t%y0";
3955   else
3956     return "fst%z0\t%y0";
3957 }
3958   [(set_attr "type" "fmov,multi,multi,multi")
3959    (set_attr "unit" "*,i387,i387,i387")
3960    (set_attr "mode" "SF")])
3961
3962 (define_insn "truncxfsf2_i387_noop"
3963   [(set (match_operand:SF 0 "register_operand" "=f")
3964         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3965   "TARGET_80387 && flag_unsafe_math_optimizations"
3966   "* return output_387_reg_move (insn, operands);"
3967   [(set_attr "type" "fmov")
3968    (set_attr "mode" "SF")])
3969
3970 (define_insn "*truncxfsf2_i387"
3971   [(set (match_operand:SF 0 "memory_operand" "=m")
3972         (float_truncate:SF
3973          (match_operand:XF 1 "register_operand" "f")))]
3974   "TARGET_80387"
3975 {
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")
3982    (set_attr "mode" "SF")])
3983
3984 (define_split
3985   [(set (match_operand:SF 0 "register_operand" "")
3986         (float_truncate:SF
3987          (match_operand:XF 1 "register_operand" "")))
3988    (clobber (match_operand:SF 2 "memory_operand" ""))]
3989   "TARGET_80387 && reload_completed"
3990   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3991    (set (match_dup 0) (match_dup 2))]
3992   "")
3993
3994 (define_split
3995   [(set (match_operand:SF 0 "memory_operand" "")
3996         (float_truncate:SF
3997          (match_operand:XF 1 "register_operand" "")))
3998    (clobber (match_operand:SF 2 "memory_operand" ""))]
3999   "TARGET_80387"
4000   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4001   "")
4002
4003 ;; Conversion from XFmode to DFmode.
4004
4005 (define_expand "truncxfdf2"
4006   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4007                    (float_truncate:DF
4008                     (match_operand:XF 1 "register_operand" "")))
4009               (clobber (match_dup 2))])]
4010   "TARGET_80387"
4011 {
4012   if (flag_unsafe_math_optimizations)
4013     {
4014       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4015       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4016       if (reg != operands[0])
4017         emit_move_insn (operands[0], reg);
4018       DONE;
4019     }
4020   else
4021     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4022 })
4023
4024 (define_insn "*truncxfdf2_mixed"
4025   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4026         (float_truncate:DF
4027          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4028    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4029   "TARGET_80387"
4030 {
4031   gcc_assert (!which_alternative);
4032   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4033     return "fstp%z0\t%y0";
4034   else
4035     return "fst%z0\t%y0";
4036 }
4037   [(set_attr "type" "fmov,multi,multi,multi")
4038    (set_attr "unit" "*,i387,i387,i387")
4039    (set_attr "mode" "DF")])
4040
4041 (define_insn "truncxfdf2_i387_noop"
4042   [(set (match_operand:DF 0 "register_operand" "=f")
4043         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4044   "TARGET_80387 && flag_unsafe_math_optimizations"
4045   "* return output_387_reg_move (insn, operands);"
4046   [(set_attr "type" "fmov")
4047    (set_attr "mode" "DF")])
4048
4049 (define_insn "*truncxfdf2_i387"
4050   [(set (match_operand:DF 0 "memory_operand" "=m")
4051         (float_truncate:DF
4052           (match_operand:XF 1 "register_operand" "f")))]
4053   "TARGET_80387"
4054 {
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")
4061    (set_attr "mode" "DF")])
4062
4063 (define_split
4064   [(set (match_operand:DF 0 "register_operand" "")
4065         (float_truncate:DF
4066          (match_operand:XF 1 "register_operand" "")))
4067    (clobber (match_operand:DF 2 "memory_operand" ""))]
4068   "TARGET_80387 && reload_completed"
4069   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4070    (set (match_dup 0) (match_dup 2))]
4071   "")
4072
4073 (define_split
4074   [(set (match_operand:DF 0 "memory_operand" "")
4075         (float_truncate:DF
4076          (match_operand:XF 1 "register_operand" "")))
4077    (clobber (match_operand:DF 2 "memory_operand" ""))]
4078   "TARGET_80387"
4079   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4080   "")
4081 \f
4082 ;; Signed conversion to DImode.
4083
4084 (define_expand "fix_truncxfdi2"
4085   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4086                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4087               (clobber (reg:CC FLAGS_REG))])]
4088   "TARGET_80387"
4089 {
4090   if (TARGET_FISTTP)
4091    {
4092      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4093      DONE;
4094    }
4095 })
4096
4097 (define_expand "fix_trunc<mode>di2"
4098   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4099                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4100               (clobber (reg:CC FLAGS_REG))])]
4101   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4102 {
4103   if (TARGET_FISTTP
4104       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4105    {
4106      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4107      DONE;
4108    }
4109   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4110    {
4111      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4112      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4113      if (out != operands[0])
4114         emit_move_insn (operands[0], out);
4115      DONE;
4116    }
4117 })
4118
4119 ;; Signed conversion to SImode.
4120
4121 (define_expand "fix_truncxfsi2"
4122   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4123                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4124               (clobber (reg:CC FLAGS_REG))])]
4125   "TARGET_80387"
4126 {
4127   if (TARGET_FISTTP)
4128    {
4129      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4130      DONE;
4131    }
4132 })
4133
4134 (define_expand "fix_trunc<mode>si2"
4135   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4136                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4137               (clobber (reg:CC FLAGS_REG))])]
4138   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4139 {
4140   if (TARGET_FISTTP
4141       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4142    {
4143      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4144      DONE;
4145    }
4146   if (SSE_FLOAT_MODE_P (<MODE>mode))
4147    {
4148      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4149      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4150      if (out != operands[0])
4151         emit_move_insn (operands[0], out);
4152      DONE;
4153    }
4154 })
4155
4156 ;; Signed conversion to HImode.
4157
4158 (define_expand "fix_trunc<mode>hi2"
4159   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4160                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4161               (clobber (reg:CC FLAGS_REG))])]
4162   "TARGET_80387
4163    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4164 {
4165   if (TARGET_FISTTP)
4166    {
4167      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4168      DONE;
4169    }
4170 })
4171
4172 ;; When SSE is available, it is always faster to use it!
4173 (define_insn "fix_truncsfdi_sse"
4174   [(set (match_operand:DI 0 "register_operand" "=r,r")
4175         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4176   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4177   "cvttss2si{q}\t{%1, %0|%0, %1}"
4178   [(set_attr "type" "sseicvt")
4179    (set_attr "mode" "SF")
4180    (set_attr "athlon_decode" "double,vector")])
4181
4182 (define_insn "fix_truncdfdi_sse"
4183   [(set (match_operand:DI 0 "register_operand" "=r,r")
4184         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4185   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4186   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4187   [(set_attr "type" "sseicvt")
4188    (set_attr "mode" "DF")
4189    (set_attr "athlon_decode" "double,vector")])
4190
4191 (define_insn "fix_truncsfsi_sse"
4192   [(set (match_operand:SI 0 "register_operand" "=r,r")
4193         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4194   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4195   "cvttss2si\t{%1, %0|%0, %1}"
4196   [(set_attr "type" "sseicvt")
4197    (set_attr "mode" "DF")
4198    (set_attr "athlon_decode" "double,vector")])
4199
4200 (define_insn "fix_truncdfsi_sse"
4201   [(set (match_operand:SI 0 "register_operand" "=r,r")
4202         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4203   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4204   "cvttsd2si\t{%1, %0|%0, %1}"
4205   [(set_attr "type" "sseicvt")
4206    (set_attr "mode" "DF")
4207    (set_attr "athlon_decode" "double,vector")])
4208
4209 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4210 (define_peephole2
4211   [(set (match_operand:DF 0 "register_operand" "")
4212         (match_operand:DF 1 "memory_operand" ""))
4213    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4214         (fix:SSEMODEI24 (match_dup 0)))]
4215   "!TARGET_K8
4216    && peep2_reg_dead_p (2, operands[0])"
4217   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4218   "")
4219
4220 (define_peephole2
4221   [(set (match_operand:SF 0 "register_operand" "")
4222         (match_operand:SF 1 "memory_operand" ""))
4223    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4224         (fix:SSEMODEI24 (match_dup 0)))]
4225   "!TARGET_K8
4226    && peep2_reg_dead_p (2, operands[0])"
4227   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4228   "")
4229
4230 ;; Avoid vector decoded forms of the instruction.
4231 (define_peephole2
4232   [(match_scratch:DF 2 "Y")
4233    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4234         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4235   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4236   [(set (match_dup 2) (match_dup 1))
4237    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4238   "")
4239
4240 (define_peephole2
4241   [(match_scratch:SF 2 "x")
4242    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4243         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4244   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4245   [(set (match_dup 2) (match_dup 1))
4246    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4247   "")
4248
4249 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4250   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4251         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4252   "TARGET_FISTTP
4253    && FLOAT_MODE_P (GET_MODE (operands[1]))
4254    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4255          && (TARGET_64BIT || <MODE>mode != DImode))
4256         && TARGET_SSE_MATH)
4257    && !(reload_completed || reload_in_progress)"
4258   "#"
4259   "&& 1"
4260   [(const_int 0)]
4261 {
4262   if (memory_operand (operands[0], VOIDmode))
4263     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4264   else
4265     {
4266       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4267       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4268                                                             operands[1],
4269                                                             operands[2]));
4270     }
4271   DONE;
4272 }
4273   [(set_attr "type" "fisttp")
4274    (set_attr "mode" "<MODE>")])
4275
4276 (define_insn "fix_trunc<mode>_i387_fisttp"
4277   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4278         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4279    (clobber (match_scratch:XF 2 "=&1f"))]
4280   "TARGET_FISTTP
4281    && FLOAT_MODE_P (GET_MODE (operands[1]))
4282    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4283          && (TARGET_64BIT || <MODE>mode != DImode))
4284         && TARGET_SSE_MATH)"
4285   "* return output_fix_trunc (insn, operands, 1);"
4286   [(set_attr "type" "fisttp")
4287    (set_attr "mode" "<MODE>")])
4288
4289 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4290   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4291         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4292    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4293    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4294   "TARGET_FISTTP
4295    && FLOAT_MODE_P (GET_MODE (operands[1]))
4296    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4297         && (TARGET_64BIT || <MODE>mode != DImode))
4298         && TARGET_SSE_MATH)"
4299   "#"
4300   [(set_attr "type" "fisttp")
4301    (set_attr "mode" "<MODE>")])
4302
4303 (define_split
4304   [(set (match_operand:X87MODEI 0 "register_operand" "")
4305         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4306    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4307    (clobber (match_scratch 3 ""))]
4308   "reload_completed"
4309   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4310               (clobber (match_dup 3))])
4311    (set (match_dup 0) (match_dup 2))]
4312   "")
4313
4314 (define_split
4315   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4316         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4317    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4318    (clobber (match_scratch 3 ""))]
4319   "reload_completed"
4320   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4321               (clobber (match_dup 3))])]
4322   "")
4323
4324 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4325 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4326 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4327 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4328 ;; function in i386.c.
4329 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4330   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4331         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4332    (clobber (reg:CC FLAGS_REG))]
4333   "TARGET_80387 && !TARGET_FISTTP
4334    && FLOAT_MODE_P (GET_MODE (operands[1]))
4335    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4336          && (TARGET_64BIT || <MODE>mode != DImode))
4337    && !(reload_completed || reload_in_progress)"
4338   "#"
4339   "&& 1"
4340   [(const_int 0)]
4341 {
4342   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4343
4344   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4345   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4346   if (memory_operand (operands[0], VOIDmode))
4347     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4348                                          operands[2], operands[3]));
4349   else
4350     {
4351       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4352       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4353                                                      operands[2], operands[3],
4354                                                      operands[4]));
4355     }
4356   DONE;
4357 }
4358   [(set_attr "type" "fistp")
4359    (set_attr "i387_cw" "trunc")
4360    (set_attr "mode" "<MODE>")])
4361
4362 (define_insn "fix_truncdi_i387"
4363   [(set (match_operand:DI 0 "memory_operand" "=m")
4364         (fix:DI (match_operand 1 "register_operand" "f")))
4365    (use (match_operand:HI 2 "memory_operand" "m"))
4366    (use (match_operand:HI 3 "memory_operand" "m"))
4367    (clobber (match_scratch:XF 4 "=&1f"))]
4368   "TARGET_80387 && !TARGET_FISTTP
4369    && FLOAT_MODE_P (GET_MODE (operands[1]))
4370    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4371   "* return output_fix_trunc (insn, operands, 0);"
4372   [(set_attr "type" "fistp")
4373    (set_attr "i387_cw" "trunc")
4374    (set_attr "mode" "DI")])
4375
4376 (define_insn "fix_truncdi_i387_with_temp"
4377   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4378         (fix:DI (match_operand 1 "register_operand" "f,f")))
4379    (use (match_operand:HI 2 "memory_operand" "m,m"))
4380    (use (match_operand:HI 3 "memory_operand" "m,m"))
4381    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4382    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4383   "TARGET_80387 && !TARGET_FISTTP
4384    && FLOAT_MODE_P (GET_MODE (operands[1]))
4385    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4386   "#"
4387   [(set_attr "type" "fistp")
4388    (set_attr "i387_cw" "trunc")
4389    (set_attr "mode" "DI")])
4390
4391 (define_split
4392   [(set (match_operand:DI 0 "register_operand" "")
4393         (fix:DI (match_operand 1 "register_operand" "")))
4394    (use (match_operand:HI 2 "memory_operand" ""))
4395    (use (match_operand:HI 3 "memory_operand" ""))
4396    (clobber (match_operand:DI 4 "memory_operand" ""))
4397    (clobber (match_scratch 5 ""))]
4398   "reload_completed"
4399   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4400               (use (match_dup 2))
4401               (use (match_dup 3))
4402               (clobber (match_dup 5))])
4403    (set (match_dup 0) (match_dup 4))]
4404   "")
4405
4406 (define_split
4407   [(set (match_operand:DI 0 "memory_operand" "")
4408         (fix:DI (match_operand 1 "register_operand" "")))
4409    (use (match_operand:HI 2 "memory_operand" ""))
4410    (use (match_operand:HI 3 "memory_operand" ""))
4411    (clobber (match_operand:DI 4 "memory_operand" ""))
4412    (clobber (match_scratch 5 ""))]
4413   "reload_completed"
4414   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4415               (use (match_dup 2))
4416               (use (match_dup 3))
4417               (clobber (match_dup 5))])]
4418   "")
4419
4420 (define_insn "fix_trunc<mode>_i387"
4421   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4422         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4423    (use (match_operand:HI 2 "memory_operand" "m"))
4424    (use (match_operand:HI 3 "memory_operand" "m"))]
4425   "TARGET_80387 && !TARGET_FISTTP
4426    && FLOAT_MODE_P (GET_MODE (operands[1]))
4427    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4428   "* return output_fix_trunc (insn, operands, 0);"
4429   [(set_attr "type" "fistp")
4430    (set_attr "i387_cw" "trunc")
4431    (set_attr "mode" "<MODE>")])
4432
4433 (define_insn "fix_trunc<mode>_i387_with_temp"
4434   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4435         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4436    (use (match_operand:HI 2 "memory_operand" "m,m"))
4437    (use (match_operand:HI 3 "memory_operand" "m,m"))
4438    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4439   "TARGET_80387 && !TARGET_FISTTP
4440    && FLOAT_MODE_P (GET_MODE (operands[1]))
4441    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4442   "#"
4443   [(set_attr "type" "fistp")
4444    (set_attr "i387_cw" "trunc")
4445    (set_attr "mode" "<MODE>")])
4446
4447 (define_split
4448   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4449         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4450    (use (match_operand:HI 2 "memory_operand" ""))
4451    (use (match_operand:HI 3 "memory_operand" ""))
4452    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4453   "reload_completed"
4454   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4455               (use (match_dup 2))
4456               (use (match_dup 3))])
4457    (set (match_dup 0) (match_dup 4))]
4458   "")
4459
4460 (define_split
4461   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4462         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4463    (use (match_operand:HI 2 "memory_operand" ""))
4464    (use (match_operand:HI 3 "memory_operand" ""))
4465    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4466   "reload_completed"
4467   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4468               (use (match_dup 2))
4469               (use (match_dup 3))])]
4470   "")
4471
4472 (define_insn "x86_fnstcw_1"
4473   [(set (match_operand:HI 0 "memory_operand" "=m")
4474         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4475   "TARGET_80387"
4476   "fnstcw\t%0"
4477   [(set_attr "length" "2")
4478    (set_attr "mode" "HI")
4479    (set_attr "unit" "i387")])
4480
4481 (define_insn "x86_fldcw_1"
4482   [(set (reg:HI FPCR_REG)
4483         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4484   "TARGET_80387"
4485   "fldcw\t%0"
4486   [(set_attr "length" "2")
4487    (set_attr "mode" "HI")
4488    (set_attr "unit" "i387")
4489    (set_attr "athlon_decode" "vector")])
4490 \f
4491 ;; Conversion between fixed point and floating point.
4492
4493 ;; Even though we only accept memory inputs, the backend _really_
4494 ;; wants to be able to do this between registers.
4495
4496 (define_expand "floathisf2"
4497   [(set (match_operand:SF 0 "register_operand" "")
4498         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4499   "TARGET_80387 || TARGET_SSE_MATH"
4500 {
4501   if (TARGET_SSE_MATH)
4502     {
4503       emit_insn (gen_floatsisf2 (operands[0],
4504                                  convert_to_mode (SImode, operands[1], 0)));
4505       DONE;
4506     }
4507 })
4508
4509 (define_insn "*floathisf2_i387"
4510   [(set (match_operand:SF 0 "register_operand" "=f,f")
4511         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4512   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4513   "@
4514    fild%z1\t%1
4515    #"
4516   [(set_attr "type" "fmov,multi")
4517    (set_attr "mode" "SF")
4518    (set_attr "unit" "*,i387")
4519    (set_attr "fp_int_src" "true")])
4520
4521 (define_expand "floatsisf2"
4522   [(set (match_operand:SF 0 "register_operand" "")
4523         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4524   "TARGET_80387 || TARGET_SSE_MATH"
4525   "")
4526
4527 (define_insn "*floatsisf2_mixed"
4528   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4529         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4530   "TARGET_MIX_SSE_I387"
4531   "@
4532    fild%z1\t%1
4533    #
4534    cvtsi2ss\t{%1, %0|%0, %1}
4535    cvtsi2ss\t{%1, %0|%0, %1}"
4536   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4537    (set_attr "mode" "SF")
4538    (set_attr "unit" "*,i387,*,*")
4539    (set_attr "athlon_decode" "*,*,vector,double")
4540    (set_attr "fp_int_src" "true")])
4541
4542 (define_insn "*floatsisf2_sse"
4543   [(set (match_operand:SF 0 "register_operand" "=x,x")
4544         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4545   "TARGET_SSE_MATH"
4546   "cvtsi2ss\t{%1, %0|%0, %1}"
4547   [(set_attr "type" "sseicvt")
4548    (set_attr "mode" "SF")
4549    (set_attr "athlon_decode" "vector,double")
4550    (set_attr "fp_int_src" "true")])
4551
4552 (define_insn "*floatsisf2_i387"
4553   [(set (match_operand:SF 0 "register_operand" "=f,f")
4554         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4555   "TARGET_80387"
4556   "@
4557    fild%z1\t%1
4558    #"
4559   [(set_attr "type" "fmov,multi")
4560    (set_attr "mode" "SF")
4561    (set_attr "unit" "*,i387")
4562    (set_attr "fp_int_src" "true")])
4563
4564 (define_expand "floatdisf2"
4565   [(set (match_operand:SF 0 "register_operand" "")
4566         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4567   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4568   "")
4569
4570 (define_insn "*floatdisf2_mixed"
4571   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4572         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4573   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4574   "@
4575    fild%z1\t%1
4576    #
4577    cvtsi2ss{q}\t{%1, %0|%0, %1}
4578    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4579   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4580    (set_attr "mode" "SF")
4581    (set_attr "unit" "*,i387,*,*")
4582    (set_attr "athlon_decode" "*,*,vector,double")
4583    (set_attr "fp_int_src" "true")])
4584
4585 (define_insn "*floatdisf2_sse"
4586   [(set (match_operand:SF 0 "register_operand" "=x,x")
4587         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4588   "TARGET_64BIT && TARGET_SSE_MATH"
4589   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4590   [(set_attr "type" "sseicvt")
4591    (set_attr "mode" "SF")
4592    (set_attr "athlon_decode" "vector,double")
4593    (set_attr "fp_int_src" "true")])
4594
4595 (define_insn "*floatdisf2_i387"
4596   [(set (match_operand:SF 0 "register_operand" "=f,f")
4597         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4598   "TARGET_80387"
4599   "@
4600    fild%z1\t%1
4601    #"
4602   [(set_attr "type" "fmov,multi")
4603    (set_attr "mode" "SF")
4604    (set_attr "unit" "*,i387")
4605    (set_attr "fp_int_src" "true")])
4606
4607 (define_expand "floathidf2"
4608   [(set (match_operand:DF 0 "register_operand" "")
4609         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4610   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4611 {
4612   if (TARGET_SSE2 && TARGET_SSE_MATH)
4613     {
4614       emit_insn (gen_floatsidf2 (operands[0],
4615                                  convert_to_mode (SImode, operands[1], 0)));
4616       DONE;
4617     }
4618 })
4619
4620 (define_insn "*floathidf2_i387"
4621   [(set (match_operand:DF 0 "register_operand" "=f,f")
4622         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4623   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4624   "@
4625    fild%z1\t%1
4626    #"
4627   [(set_attr "type" "fmov,multi")
4628    (set_attr "mode" "DF")
4629    (set_attr "unit" "*,i387")
4630    (set_attr "fp_int_src" "true")])
4631
4632 (define_expand "floatsidf2"
4633   [(set (match_operand:DF 0 "register_operand" "")
4634         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4635   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4636   "")
4637
4638 (define_insn "*floatsidf2_mixed"
4639   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4640         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4641   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4642   "@
4643    fild%z1\t%1
4644    #
4645    cvtsi2sd\t{%1, %0|%0, %1}
4646    cvtsi2sd\t{%1, %0|%0, %1}"
4647   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4648    (set_attr "mode" "DF")
4649    (set_attr "unit" "*,i387,*,*")
4650    (set_attr "athlon_decode" "*,*,double,direct")
4651    (set_attr "fp_int_src" "true")])
4652
4653 (define_insn "*floatsidf2_sse"
4654   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4655         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4656   "TARGET_SSE2 && TARGET_SSE_MATH"
4657   "cvtsi2sd\t{%1, %0|%0, %1}"
4658   [(set_attr "type" "sseicvt")
4659    (set_attr "mode" "DF")
4660    (set_attr "athlon_decode" "double,direct")
4661    (set_attr "fp_int_src" "true")])
4662
4663 (define_insn "*floatsidf2_i387"
4664   [(set (match_operand:DF 0 "register_operand" "=f,f")
4665         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4666   "TARGET_80387"
4667   "@
4668    fild%z1\t%1
4669    #"
4670   [(set_attr "type" "fmov,multi")
4671    (set_attr "mode" "DF")
4672    (set_attr "unit" "*,i387")
4673    (set_attr "fp_int_src" "true")])
4674
4675 (define_expand "floatdidf2"
4676   [(set (match_operand:DF 0 "register_operand" "")
4677         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4678   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4679   "")
4680
4681 (define_insn "*floatdidf2_mixed"
4682   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4683         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4684   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4685   "@
4686    fild%z1\t%1
4687    #
4688    cvtsi2sd{q}\t{%1, %0|%0, %1}
4689    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4690   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4691    (set_attr "mode" "DF")
4692    (set_attr "unit" "*,i387,*,*")
4693    (set_attr "athlon_decode" "*,*,double,direct")
4694    (set_attr "fp_int_src" "true")])
4695
4696 (define_insn "*floatdidf2_sse"
4697   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4698         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4699   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4700   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4701   [(set_attr "type" "sseicvt")
4702    (set_attr "mode" "DF")
4703    (set_attr "athlon_decode" "double,direct")
4704    (set_attr "fp_int_src" "true")])
4705
4706 (define_insn "*floatdidf2_i387"
4707   [(set (match_operand:DF 0 "register_operand" "=f,f")
4708         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4709   "TARGET_80387"
4710   "@
4711    fild%z1\t%1
4712    #"
4713   [(set_attr "type" "fmov,multi")
4714    (set_attr "mode" "DF")
4715    (set_attr "unit" "*,i387")
4716    (set_attr "fp_int_src" "true")])
4717
4718 (define_insn "floathixf2"
4719   [(set (match_operand:XF 0 "register_operand" "=f,f")
4720         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4721   "TARGET_80387"
4722   "@
4723    fild%z1\t%1
4724    #"
4725   [(set_attr "type" "fmov,multi")
4726    (set_attr "mode" "XF")
4727    (set_attr "unit" "*,i387")
4728    (set_attr "fp_int_src" "true")])
4729
4730 (define_insn "floatsixf2"
4731   [(set (match_operand:XF 0 "register_operand" "=f,f")
4732         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4733   "TARGET_80387"
4734   "@
4735    fild%z1\t%1
4736    #"
4737   [(set_attr "type" "fmov,multi")
4738    (set_attr "mode" "XF")
4739    (set_attr "unit" "*,i387")
4740    (set_attr "fp_int_src" "true")])
4741
4742 (define_insn "floatdixf2"
4743   [(set (match_operand:XF 0 "register_operand" "=f,f")
4744         (float:XF (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" "XF")
4751    (set_attr "unit" "*,i387")
4752    (set_attr "fp_int_src" "true")])
4753
4754 ;; %%% Kill these when reload knows how to do it.
4755 (define_split
4756   [(set (match_operand 0 "fp_register_operand" "")
4757         (float (match_operand 1 "register_operand" "")))]
4758   "reload_completed
4759    && TARGET_80387
4760    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4761   [(const_int 0)]
4762 {
4763   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4764   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4765   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4766   ix86_free_from_memory (GET_MODE (operands[1]));
4767   DONE;
4768 })
4769
4770 (define_expand "floatunssisf2"
4771   [(use (match_operand:SF 0 "register_operand" ""))
4772    (use (match_operand:SI 1 "register_operand" ""))]
4773   "!TARGET_64BIT && TARGET_SSE_MATH"
4774   "x86_emit_floatuns (operands); DONE;")
4775
4776 (define_expand "floatunsdisf2"
4777   [(use (match_operand:SF 0 "register_operand" ""))
4778    (use (match_operand:DI 1 "register_operand" ""))]
4779   "TARGET_64BIT && TARGET_SSE_MATH"
4780   "x86_emit_floatuns (operands); DONE;")
4781
4782 (define_expand "floatunsdidf2"
4783   [(use (match_operand:DF 0 "register_operand" ""))
4784    (use (match_operand:DI 1 "register_operand" ""))]
4785   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4786   "x86_emit_floatuns (operands); DONE;")
4787 \f
4788 ;; SSE extract/set expanders
4789
4790 \f
4791 ;; Add instructions
4792
4793 ;; %%% splits for addditi3
4794
4795 (define_expand "addti3"
4796   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4797         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4798                  (match_operand:TI 2 "x86_64_general_operand" "")))
4799    (clobber (reg:CC FLAGS_REG))]
4800   "TARGET_64BIT"
4801   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4802
4803 (define_insn "*addti3_1"
4804   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4805         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4806                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4807    (clobber (reg:CC FLAGS_REG))]
4808   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4809   "#")
4810
4811 (define_split
4812   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4813         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4814                  (match_operand:TI 2 "general_operand" "")))
4815    (clobber (reg:CC FLAGS_REG))]
4816   "TARGET_64BIT && reload_completed"
4817   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4818                                           UNSPEC_ADD_CARRY))
4819               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4820    (parallel [(set (match_dup 3)
4821                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4822                                      (match_dup 4))
4823                             (match_dup 5)))
4824               (clobber (reg:CC FLAGS_REG))])]
4825   "split_ti (operands+0, 1, operands+0, operands+3);
4826    split_ti (operands+1, 1, operands+1, operands+4);
4827    split_ti (operands+2, 1, operands+2, operands+5);")
4828
4829 ;; %%% splits for addsidi3
4830 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4831 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4832 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4833
4834 (define_expand "adddi3"
4835   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4836         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4837                  (match_operand:DI 2 "x86_64_general_operand" "")))
4838    (clobber (reg:CC FLAGS_REG))]
4839   ""
4840   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4841
4842 (define_insn "*adddi3_1"
4843   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4844         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4845                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4846    (clobber (reg:CC FLAGS_REG))]
4847   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4848   "#")
4849
4850 (define_split
4851   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4852         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4853                  (match_operand:DI 2 "general_operand" "")))
4854    (clobber (reg:CC FLAGS_REG))]
4855   "!TARGET_64BIT && reload_completed"
4856   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4857                                           UNSPEC_ADD_CARRY))
4858               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4859    (parallel [(set (match_dup 3)
4860                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4861                                      (match_dup 4))
4862                             (match_dup 5)))
4863               (clobber (reg:CC FLAGS_REG))])]
4864   "split_di (operands+0, 1, operands+0, operands+3);
4865    split_di (operands+1, 1, operands+1, operands+4);
4866    split_di (operands+2, 1, operands+2, operands+5);")
4867
4868 (define_insn "adddi3_carry_rex64"
4869   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4870           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4871                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4872                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4873    (clobber (reg:CC FLAGS_REG))]
4874   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4875   "adc{q}\t{%2, %0|%0, %2}"
4876   [(set_attr "type" "alu")
4877    (set_attr "pent_pair" "pu")
4878    (set_attr "mode" "DI")])
4879
4880 (define_insn "*adddi3_cc_rex64"
4881   [(set (reg:CC FLAGS_REG)
4882         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4883                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4884                    UNSPEC_ADD_CARRY))
4885    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4886         (plus:DI (match_dup 1) (match_dup 2)))]
4887   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4888   "add{q}\t{%2, %0|%0, %2}"
4889   [(set_attr "type" "alu")
4890    (set_attr "mode" "DI")])
4891
4892 (define_insn "addqi3_carry"
4893   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4894           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4895                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4896                    (match_operand:QI 2 "general_operand" "qi,qm")))
4897    (clobber (reg:CC FLAGS_REG))]
4898   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4899   "adc{b}\t{%2, %0|%0, %2}"
4900   [(set_attr "type" "alu")
4901    (set_attr "pent_pair" "pu")
4902    (set_attr "mode" "QI")])
4903
4904 (define_insn "addhi3_carry"
4905   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4906           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4907                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4908                    (match_operand:HI 2 "general_operand" "ri,rm")))
4909    (clobber (reg:CC FLAGS_REG))]
4910   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4911   "adc{w}\t{%2, %0|%0, %2}"
4912   [(set_attr "type" "alu")
4913    (set_attr "pent_pair" "pu")
4914    (set_attr "mode" "HI")])
4915
4916 (define_insn "addsi3_carry"
4917   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4918           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4919                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4920                    (match_operand:SI 2 "general_operand" "ri,rm")))
4921    (clobber (reg:CC FLAGS_REG))]
4922   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4923   "adc{l}\t{%2, %0|%0, %2}"
4924   [(set_attr "type" "alu")
4925    (set_attr "pent_pair" "pu")
4926    (set_attr "mode" "SI")])
4927
4928 (define_insn "*addsi3_carry_zext"
4929   [(set (match_operand:DI 0 "register_operand" "=r")
4930           (zero_extend:DI
4931             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4932                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4933                      (match_operand:SI 2 "general_operand" "rim"))))
4934    (clobber (reg:CC FLAGS_REG))]
4935   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4936   "adc{l}\t{%2, %k0|%k0, %2}"
4937   [(set_attr "type" "alu")
4938    (set_attr "pent_pair" "pu")
4939    (set_attr "mode" "SI")])
4940
4941 (define_insn "*addsi3_cc"
4942   [(set (reg:CC FLAGS_REG)
4943         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4944                     (match_operand:SI 2 "general_operand" "ri,rm")]
4945                    UNSPEC_ADD_CARRY))
4946    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4947         (plus:SI (match_dup 1) (match_dup 2)))]
4948   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4949   "add{l}\t{%2, %0|%0, %2}"
4950   [(set_attr "type" "alu")
4951    (set_attr "mode" "SI")])
4952
4953 (define_insn "addqi3_cc"
4954   [(set (reg:CC FLAGS_REG)
4955         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4956                     (match_operand:QI 2 "general_operand" "qi,qm")]
4957                    UNSPEC_ADD_CARRY))
4958    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4959         (plus:QI (match_dup 1) (match_dup 2)))]
4960   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4961   "add{b}\t{%2, %0|%0, %2}"
4962   [(set_attr "type" "alu")
4963    (set_attr "mode" "QI")])
4964
4965 (define_expand "addsi3"
4966   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4967                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4968                             (match_operand:SI 2 "general_operand" "")))
4969               (clobber (reg:CC FLAGS_REG))])]
4970   ""
4971   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4972
4973 (define_insn "*lea_1"
4974   [(set (match_operand:SI 0 "register_operand" "=r")
4975         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4976   "!TARGET_64BIT"
4977   "lea{l}\t{%a1, %0|%0, %a1}"
4978   [(set_attr "type" "lea")
4979    (set_attr "mode" "SI")])
4980
4981 (define_insn "*lea_1_rex64"
4982   [(set (match_operand:SI 0 "register_operand" "=r")
4983         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4984   "TARGET_64BIT"
4985   "lea{l}\t{%a1, %0|%0, %a1}"
4986   [(set_attr "type" "lea")
4987    (set_attr "mode" "SI")])
4988
4989 (define_insn "*lea_1_zext"
4990   [(set (match_operand:DI 0 "register_operand" "=r")
4991         (zero_extend:DI
4992          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4993   "TARGET_64BIT"
4994   "lea{l}\t{%a1, %k0|%k0, %a1}"
4995   [(set_attr "type" "lea")
4996    (set_attr "mode" "SI")])
4997
4998 (define_insn "*lea_2_rex64"
4999   [(set (match_operand:DI 0 "register_operand" "=r")
5000         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5001   "TARGET_64BIT"
5002   "lea{q}\t{%a1, %0|%0, %a1}"
5003   [(set_attr "type" "lea")
5004    (set_attr "mode" "DI")])
5005
5006 ;; The lea patterns for non-Pmodes needs to be matched by several
5007 ;; insns converted to real lea by splitters.
5008
5009 (define_insn_and_split "*lea_general_1"
5010   [(set (match_operand 0 "register_operand" "=r")
5011         (plus (plus (match_operand 1 "index_register_operand" "l")
5012                     (match_operand 2 "register_operand" "r"))
5013               (match_operand 3 "immediate_operand" "i")))]
5014   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5015     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5016    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5017    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5018    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5019    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5020        || GET_MODE (operands[3]) == VOIDmode)"
5021   "#"
5022   "&& reload_completed"
5023   [(const_int 0)]
5024 {
5025   rtx pat;
5026   operands[0] = gen_lowpart (SImode, operands[0]);
5027   operands[1] = gen_lowpart (Pmode, operands[1]);
5028   operands[2] = gen_lowpart (Pmode, operands[2]);
5029   operands[3] = gen_lowpart (Pmode, operands[3]);
5030   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5031                       operands[3]);
5032   if (Pmode != SImode)
5033     pat = gen_rtx_SUBREG (SImode, pat, 0);
5034   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5035   DONE;
5036 }
5037   [(set_attr "type" "lea")
5038    (set_attr "mode" "SI")])
5039
5040 (define_insn_and_split "*lea_general_1_zext"
5041   [(set (match_operand:DI 0 "register_operand" "=r")
5042         (zero_extend:DI
5043           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5044                             (match_operand:SI 2 "register_operand" "r"))
5045                    (match_operand:SI 3 "immediate_operand" "i"))))]
5046   "TARGET_64BIT"
5047   "#"
5048   "&& reload_completed"
5049   [(set (match_dup 0)
5050         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5051                                                      (match_dup 2))
5052                                             (match_dup 3)) 0)))]
5053 {
5054   operands[1] = gen_lowpart (Pmode, operands[1]);
5055   operands[2] = gen_lowpart (Pmode, operands[2]);
5056   operands[3] = gen_lowpart (Pmode, operands[3]);
5057 }
5058   [(set_attr "type" "lea")
5059    (set_attr "mode" "SI")])
5060
5061 (define_insn_and_split "*lea_general_2"
5062   [(set (match_operand 0 "register_operand" "=r")
5063         (plus (mult (match_operand 1 "index_register_operand" "l")
5064                     (match_operand 2 "const248_operand" "i"))
5065               (match_operand 3 "nonmemory_operand" "ri")))]
5066   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5067     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5068    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5069    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5070    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5071        || GET_MODE (operands[3]) == VOIDmode)"
5072   "#"
5073   "&& reload_completed"
5074   [(const_int 0)]
5075 {
5076   rtx pat;
5077   operands[0] = gen_lowpart (SImode, operands[0]);
5078   operands[1] = gen_lowpart (Pmode, operands[1]);
5079   operands[3] = gen_lowpart (Pmode, operands[3]);
5080   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5081                       operands[3]);
5082   if (Pmode != SImode)
5083     pat = gen_rtx_SUBREG (SImode, pat, 0);
5084   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5085   DONE;
5086 }
5087   [(set_attr "type" "lea")
5088    (set_attr "mode" "SI")])
5089
5090 (define_insn_and_split "*lea_general_2_zext"
5091   [(set (match_operand:DI 0 "register_operand" "=r")
5092         (zero_extend:DI
5093           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5094                             (match_operand:SI 2 "const248_operand" "n"))
5095                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5096   "TARGET_64BIT"
5097   "#"
5098   "&& reload_completed"
5099   [(set (match_dup 0)
5100         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5101                                                      (match_dup 2))
5102                                             (match_dup 3)) 0)))]
5103 {
5104   operands[1] = gen_lowpart (Pmode, operands[1]);
5105   operands[3] = gen_lowpart (Pmode, operands[3]);
5106 }
5107   [(set_attr "type" "lea")
5108    (set_attr "mode" "SI")])
5109
5110 (define_insn_and_split "*lea_general_3"
5111   [(set (match_operand 0 "register_operand" "=r")
5112         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5113                           (match_operand 2 "const248_operand" "i"))
5114                     (match_operand 3 "register_operand" "r"))
5115               (match_operand 4 "immediate_operand" "i")))]
5116   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5117     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5118    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5119    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5120    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5121   "#"
5122   "&& reload_completed"
5123   [(const_int 0)]
5124 {
5125   rtx pat;
5126   operands[0] = gen_lowpart (SImode, operands[0]);
5127   operands[1] = gen_lowpart (Pmode, operands[1]);
5128   operands[3] = gen_lowpart (Pmode, operands[3]);
5129   operands[4] = gen_lowpart (Pmode, operands[4]);
5130   pat = gen_rtx_PLUS (Pmode,
5131                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5132                                                          operands[2]),
5133                                     operands[3]),
5134                       operands[4]);
5135   if (Pmode != SImode)
5136     pat = gen_rtx_SUBREG (SImode, pat, 0);
5137   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5138   DONE;
5139 }
5140   [(set_attr "type" "lea")
5141    (set_attr "mode" "SI")])
5142
5143 (define_insn_and_split "*lea_general_3_zext"
5144   [(set (match_operand:DI 0 "register_operand" "=r")
5145         (zero_extend:DI
5146           (plus:SI (plus:SI (mult:SI
5147                               (match_operand:SI 1 "index_register_operand" "l")
5148                               (match_operand:SI 2 "const248_operand" "n"))
5149                             (match_operand:SI 3 "register_operand" "r"))
5150                    (match_operand:SI 4 "immediate_operand" "i"))))]
5151   "TARGET_64BIT"
5152   "#"
5153   "&& reload_completed"
5154   [(set (match_dup 0)
5155         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5156                                                               (match_dup 2))
5157                                                      (match_dup 3))
5158                                             (match_dup 4)) 0)))]
5159 {
5160   operands[1] = gen_lowpart (Pmode, operands[1]);
5161   operands[3] = gen_lowpart (Pmode, operands[3]);
5162   operands[4] = gen_lowpart (Pmode, operands[4]);
5163 }
5164   [(set_attr "type" "lea")
5165    (set_attr "mode" "SI")])
5166
5167 (define_insn "*adddi_1_rex64"
5168   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5169         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5170                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5171    (clobber (reg:CC FLAGS_REG))]
5172   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5173 {
5174   switch (get_attr_type (insn))
5175     {
5176     case TYPE_LEA:
5177       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5178       return "lea{q}\t{%a2, %0|%0, %a2}";
5179
5180     case TYPE_INCDEC:
5181       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5182       if (operands[2] == const1_rtx)
5183         return "inc{q}\t%0";
5184       else
5185         {
5186           gcc_assert (operands[2] == constm1_rtx);
5187           return "dec{q}\t%0";
5188         }
5189
5190     default:
5191       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5192
5193       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5194          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5195       if (GET_CODE (operands[2]) == CONST_INT
5196           /* Avoid overflows.  */
5197           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5198           && (INTVAL (operands[2]) == 128
5199               || (INTVAL (operands[2]) < 0
5200                   && INTVAL (operands[2]) != -128)))
5201         {
5202           operands[2] = GEN_INT (-INTVAL (operands[2]));
5203           return "sub{q}\t{%2, %0|%0, %2}";
5204         }
5205       return "add{q}\t{%2, %0|%0, %2}";
5206     }
5207 }
5208   [(set (attr "type")
5209      (cond [(eq_attr "alternative" "2")
5210               (const_string "lea")
5211             ; Current assemblers are broken and do not allow @GOTOFF in
5212             ; ought but a memory context.
5213             (match_operand:DI 2 "pic_symbolic_operand" "")
5214               (const_string "lea")
5215             (match_operand:DI 2 "incdec_operand" "")
5216               (const_string "incdec")
5217            ]
5218            (const_string "alu")))
5219    (set_attr "mode" "DI")])
5220
5221 ;; Convert lea to the lea pattern to avoid flags dependency.
5222 (define_split
5223   [(set (match_operand:DI 0 "register_operand" "")
5224         (plus:DI (match_operand:DI 1 "register_operand" "")
5225                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5226    (clobber (reg:CC FLAGS_REG))]
5227   "TARGET_64BIT && reload_completed
5228    && true_regnum (operands[0]) != true_regnum (operands[1])"
5229   [(set (match_dup 0)
5230         (plus:DI (match_dup 1)
5231                  (match_dup 2)))]
5232   "")
5233
5234 (define_insn "*adddi_2_rex64"
5235   [(set (reg FLAGS_REG)
5236         (compare
5237           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5238                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5239           (const_int 0)))
5240    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5241         (plus:DI (match_dup 1) (match_dup 2)))]
5242   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5243    && ix86_binary_operator_ok (PLUS, DImode, operands)
5244    /* Current assemblers are broken and do not allow @GOTOFF in
5245       ought but a memory context.  */
5246    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5247 {
5248   switch (get_attr_type (insn))
5249     {
5250     case TYPE_INCDEC:
5251       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5252       if (operands[2] == const1_rtx)
5253         return "inc{q}\t%0";
5254       else
5255         {
5256           gcc_assert (operands[2] == constm1_rtx);
5257           return "dec{q}\t%0";
5258         }
5259
5260     default:
5261       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5262       /* ???? We ought to handle there the 32bit case too
5263          - do we need new constraint?  */
5264       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5265          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5266       if (GET_CODE (operands[2]) == CONST_INT
5267           /* Avoid overflows.  */
5268           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5269           && (INTVAL (operands[2]) == 128
5270               || (INTVAL (operands[2]) < 0
5271                   && INTVAL (operands[2]) != -128)))
5272         {
5273           operands[2] = GEN_INT (-INTVAL (operands[2]));
5274           return "sub{q}\t{%2, %0|%0, %2}";
5275         }
5276       return "add{q}\t{%2, %0|%0, %2}";
5277     }
5278 }
5279   [(set (attr "type")
5280      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5281         (const_string "incdec")
5282         (const_string "alu")))
5283    (set_attr "mode" "DI")])
5284
5285 (define_insn "*adddi_3_rex64"
5286   [(set (reg FLAGS_REG)
5287         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5288                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5289    (clobber (match_scratch:DI 0 "=r"))]
5290   "TARGET_64BIT
5291    && ix86_match_ccmode (insn, CCZmode)
5292    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5293    /* Current assemblers are broken and do not allow @GOTOFF in
5294       ought but a memory context.  */
5295    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5296 {
5297   switch (get_attr_type (insn))
5298     {
5299     case TYPE_INCDEC:
5300       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5301       if (operands[2] == const1_rtx)
5302         return "inc{q}\t%0";
5303       else
5304         {
5305           gcc_assert (operands[2] == constm1_rtx);
5306           return "dec{q}\t%0";
5307         }
5308
5309     default:
5310       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5311       /* ???? We ought to handle there the 32bit case too
5312          - do we need new constraint?  */
5313       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5314          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5315       if (GET_CODE (operands[2]) == CONST_INT
5316           /* Avoid overflows.  */
5317           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5318           && (INTVAL (operands[2]) == 128
5319               || (INTVAL (operands[2]) < 0
5320                   && INTVAL (operands[2]) != -128)))
5321         {
5322           operands[2] = GEN_INT (-INTVAL (operands[2]));
5323           return "sub{q}\t{%2, %0|%0, %2}";
5324         }
5325       return "add{q}\t{%2, %0|%0, %2}";
5326     }
5327 }
5328   [(set (attr "type")
5329      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5330         (const_string "incdec")
5331         (const_string "alu")))
5332    (set_attr "mode" "DI")])
5333
5334 ; For comparisons against 1, -1 and 128, we may generate better code
5335 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5336 ; is matched then.  We can't accept general immediate, because for
5337 ; case of overflows,  the result is messed up.
5338 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5339 ; when negated.
5340 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5341 ; only for comparisons not depending on it.
5342 (define_insn "*adddi_4_rex64"
5343   [(set (reg FLAGS_REG)
5344         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5345                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5346    (clobber (match_scratch:DI 0 "=rm"))]
5347   "TARGET_64BIT
5348    &&  ix86_match_ccmode (insn, CCGCmode)"
5349 {
5350   switch (get_attr_type (insn))
5351     {
5352     case TYPE_INCDEC:
5353       if (operands[2] == constm1_rtx)
5354         return "inc{q}\t%0";
5355       else
5356         {
5357           gcc_assert (operands[2] == const1_rtx);
5358           return "dec{q}\t%0";
5359         }
5360
5361     default:
5362       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5363       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5364          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5365       if ((INTVAL (operands[2]) == -128
5366            || (INTVAL (operands[2]) > 0
5367                && INTVAL (operands[2]) != 128))
5368           /* Avoid overflows.  */
5369           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5370         return "sub{q}\t{%2, %0|%0, %2}";
5371       operands[2] = GEN_INT (-INTVAL (operands[2]));
5372       return "add{q}\t{%2, %0|%0, %2}";
5373     }
5374 }
5375   [(set (attr "type")
5376      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5377         (const_string "incdec")
5378         (const_string "alu")))
5379    (set_attr "mode" "DI")])
5380
5381 (define_insn "*adddi_5_rex64"
5382   [(set (reg FLAGS_REG)
5383         (compare
5384           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5385                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5386           (const_int 0)))
5387    (clobber (match_scratch:DI 0 "=r"))]
5388   "TARGET_64BIT
5389    && ix86_match_ccmode (insn, CCGOCmode)
5390    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5391    /* Current assemblers are broken and do not allow @GOTOFF in
5392       ought but a memory context.  */
5393    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5394 {
5395   switch (get_attr_type (insn))
5396     {
5397     case TYPE_INCDEC:
5398       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5399       if (operands[2] == const1_rtx)
5400         return "inc{q}\t%0";
5401       else
5402         {
5403           gcc_assert (operands[2] == constm1_rtx);
5404           return "dec{q}\t%0";
5405         }
5406
5407     default:
5408       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5409       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5410          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5411       if (GET_CODE (operands[2]) == CONST_INT
5412           /* Avoid overflows.  */
5413           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5414           && (INTVAL (operands[2]) == 128
5415               || (INTVAL (operands[2]) < 0
5416                   && INTVAL (operands[2]) != -128)))
5417         {
5418           operands[2] = GEN_INT (-INTVAL (operands[2]));
5419           return "sub{q}\t{%2, %0|%0, %2}";
5420         }
5421       return "add{q}\t{%2, %0|%0, %2}";
5422     }
5423 }
5424   [(set (attr "type")
5425      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5426         (const_string "incdec")
5427         (const_string "alu")))
5428    (set_attr "mode" "DI")])
5429
5430
5431 (define_insn "*addsi_1"
5432   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5433         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5434                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5435    (clobber (reg:CC FLAGS_REG))]
5436   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5437 {
5438   switch (get_attr_type (insn))
5439     {
5440     case TYPE_LEA:
5441       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5442       return "lea{l}\t{%a2, %0|%0, %a2}";
5443
5444     case TYPE_INCDEC:
5445       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5446       if (operands[2] == const1_rtx)
5447         return "inc{l}\t%0";
5448       else
5449         {
5450           gcc_assert (operands[2] == constm1_rtx);
5451           return "dec{l}\t%0";
5452         }
5453
5454     default:
5455       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5456
5457       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5458          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5459       if (GET_CODE (operands[2]) == CONST_INT
5460           && (INTVAL (operands[2]) == 128
5461               || (INTVAL (operands[2]) < 0
5462                   && INTVAL (operands[2]) != -128)))
5463         {
5464           operands[2] = GEN_INT (-INTVAL (operands[2]));
5465           return "sub{l}\t{%2, %0|%0, %2}";
5466         }
5467       return "add{l}\t{%2, %0|%0, %2}";
5468     }
5469 }
5470   [(set (attr "type")
5471      (cond [(eq_attr "alternative" "2")
5472               (const_string "lea")
5473             ; Current assemblers are broken and do not allow @GOTOFF in
5474             ; ought but a memory context.
5475             (match_operand:SI 2 "pic_symbolic_operand" "")
5476               (const_string "lea")
5477             (match_operand:SI 2 "incdec_operand" "")
5478               (const_string "incdec")
5479            ]
5480            (const_string "alu")))
5481    (set_attr "mode" "SI")])
5482
5483 ;; Convert lea to the lea pattern to avoid flags dependency.
5484 (define_split
5485   [(set (match_operand 0 "register_operand" "")
5486         (plus (match_operand 1 "register_operand" "")
5487               (match_operand 2 "nonmemory_operand" "")))
5488    (clobber (reg:CC FLAGS_REG))]
5489   "reload_completed
5490    && true_regnum (operands[0]) != true_regnum (operands[1])"
5491   [(const_int 0)]
5492 {
5493   rtx pat;
5494   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5495      may confuse gen_lowpart.  */
5496   if (GET_MODE (operands[0]) != Pmode)
5497     {
5498       operands[1] = gen_lowpart (Pmode, operands[1]);
5499       operands[2] = gen_lowpart (Pmode, operands[2]);
5500     }
5501   operands[0] = gen_lowpart (SImode, operands[0]);
5502   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5503   if (Pmode != SImode)
5504     pat = gen_rtx_SUBREG (SImode, pat, 0);
5505   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5506   DONE;
5507 })
5508
5509 ;; It may seem that nonimmediate operand is proper one for operand 1.
5510 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5511 ;; we take care in ix86_binary_operator_ok to not allow two memory
5512 ;; operands so proper swapping will be done in reload.  This allow
5513 ;; patterns constructed from addsi_1 to match.
5514 (define_insn "addsi_1_zext"
5515   [(set (match_operand:DI 0 "register_operand" "=r,r")
5516         (zero_extend:DI
5517           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5518                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5519    (clobber (reg:CC FLAGS_REG))]
5520   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5521 {
5522   switch (get_attr_type (insn))
5523     {
5524     case TYPE_LEA:
5525       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5526       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5527
5528     case TYPE_INCDEC:
5529       if (operands[2] == const1_rtx)
5530         return "inc{l}\t%k0";
5531       else
5532         {
5533           gcc_assert (operands[2] == constm1_rtx);
5534           return "dec{l}\t%k0";
5535         }
5536
5537     default:
5538       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5539          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5540       if (GET_CODE (operands[2]) == CONST_INT
5541           && (INTVAL (operands[2]) == 128
5542               || (INTVAL (operands[2]) < 0
5543                   && INTVAL (operands[2]) != -128)))
5544         {
5545           operands[2] = GEN_INT (-INTVAL (operands[2]));
5546           return "sub{l}\t{%2, %k0|%k0, %2}";
5547         }
5548       return "add{l}\t{%2, %k0|%k0, %2}";
5549     }
5550 }
5551   [(set (attr "type")
5552      (cond [(eq_attr "alternative" "1")
5553               (const_string "lea")
5554             ; Current assemblers are broken and do not allow @GOTOFF in
5555             ; ought but a memory context.
5556             (match_operand:SI 2 "pic_symbolic_operand" "")
5557               (const_string "lea")
5558             (match_operand:SI 2 "incdec_operand" "")
5559               (const_string "incdec")
5560            ]
5561            (const_string "alu")))
5562    (set_attr "mode" "SI")])
5563
5564 ;; Convert lea to the lea pattern to avoid flags dependency.
5565 (define_split
5566   [(set (match_operand:DI 0 "register_operand" "")
5567         (zero_extend:DI
5568           (plus:SI (match_operand:SI 1 "register_operand" "")
5569                    (match_operand:SI 2 "nonmemory_operand" ""))))
5570    (clobber (reg:CC FLAGS_REG))]
5571   "TARGET_64BIT && reload_completed
5572    && true_regnum (operands[0]) != true_regnum (operands[1])"
5573   [(set (match_dup 0)
5574         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5575 {
5576   operands[1] = gen_lowpart (Pmode, operands[1]);
5577   operands[2] = gen_lowpart (Pmode, operands[2]);
5578 })
5579
5580 (define_insn "*addsi_2"
5581   [(set (reg FLAGS_REG)
5582         (compare
5583           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5584                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5585           (const_int 0)))
5586    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5587         (plus:SI (match_dup 1) (match_dup 2)))]
5588   "ix86_match_ccmode (insn, CCGOCmode)
5589    && ix86_binary_operator_ok (PLUS, SImode, operands)
5590    /* Current assemblers are broken and do not allow @GOTOFF in
5591       ought but a memory context.  */
5592    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5593 {
5594   switch (get_attr_type (insn))
5595     {
5596     case TYPE_INCDEC:
5597       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5598       if (operands[2] == const1_rtx)
5599         return "inc{l}\t%0";
5600       else
5601         {
5602           gcc_assert (operands[2] == constm1_rtx);
5603           return "dec{l}\t%0";
5604         }
5605
5606     default:
5607       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5608       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5609          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5610       if (GET_CODE (operands[2]) == CONST_INT
5611           && (INTVAL (operands[2]) == 128
5612               || (INTVAL (operands[2]) < 0
5613                   && INTVAL (operands[2]) != -128)))
5614         {
5615           operands[2] = GEN_INT (-INTVAL (operands[2]));
5616           return "sub{l}\t{%2, %0|%0, %2}";
5617         }
5618       return "add{l}\t{%2, %0|%0, %2}";
5619     }
5620 }
5621   [(set (attr "type")
5622      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5623         (const_string "incdec")
5624         (const_string "alu")))
5625    (set_attr "mode" "SI")])
5626
5627 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5628 (define_insn "*addsi_2_zext"
5629   [(set (reg FLAGS_REG)
5630         (compare
5631           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5632                    (match_operand:SI 2 "general_operand" "rmni"))
5633           (const_int 0)))
5634    (set (match_operand:DI 0 "register_operand" "=r")
5635         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5636   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5637    && ix86_binary_operator_ok (PLUS, SImode, operands)
5638    /* Current assemblers are broken and do not allow @GOTOFF in
5639       ought but a memory context.  */
5640    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5641 {
5642   switch (get_attr_type (insn))
5643     {
5644     case TYPE_INCDEC:
5645       if (operands[2] == const1_rtx)
5646         return "inc{l}\t%k0";
5647       else
5648         {
5649           gcc_assert (operands[2] == constm1_rtx);
5650           return "dec{l}\t%k0";
5651         }
5652
5653     default:
5654       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5655          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5656       if (GET_CODE (operands[2]) == CONST_INT
5657           && (INTVAL (operands[2]) == 128
5658               || (INTVAL (operands[2]) < 0
5659                   && INTVAL (operands[2]) != -128)))
5660         {
5661           operands[2] = GEN_INT (-INTVAL (operands[2]));
5662           return "sub{l}\t{%2, %k0|%k0, %2}";
5663         }
5664       return "add{l}\t{%2, %k0|%k0, %2}";
5665     }
5666 }
5667   [(set (attr "type")
5668      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5669         (const_string "incdec")
5670         (const_string "alu")))
5671    (set_attr "mode" "SI")])
5672
5673 (define_insn "*addsi_3"
5674   [(set (reg FLAGS_REG)
5675         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5676                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5677    (clobber (match_scratch:SI 0 "=r"))]
5678   "ix86_match_ccmode (insn, CCZmode)
5679    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5680    /* Current assemblers are broken and do not allow @GOTOFF in
5681       ought but a memory context.  */
5682    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5683 {
5684   switch (get_attr_type (insn))
5685     {
5686     case TYPE_INCDEC:
5687       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5688       if (operands[2] == const1_rtx)
5689         return "inc{l}\t%0";
5690       else
5691         {
5692           gcc_assert (operands[2] == constm1_rtx);
5693           return "dec{l}\t%0";
5694         }
5695
5696     default:
5697       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5698       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5699          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5700       if (GET_CODE (operands[2]) == CONST_INT
5701           && (INTVAL (operands[2]) == 128
5702               || (INTVAL (operands[2]) < 0
5703                   && INTVAL (operands[2]) != -128)))
5704         {
5705           operands[2] = GEN_INT (-INTVAL (operands[2]));
5706           return "sub{l}\t{%2, %0|%0, %2}";
5707         }
5708       return "add{l}\t{%2, %0|%0, %2}";
5709     }
5710 }
5711   [(set (attr "type")
5712      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5713         (const_string "incdec")
5714         (const_string "alu")))
5715    (set_attr "mode" "SI")])
5716
5717 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5718 (define_insn "*addsi_3_zext"
5719   [(set (reg FLAGS_REG)
5720         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5721                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5722    (set (match_operand:DI 0 "register_operand" "=r")
5723         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5724   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5725    && ix86_binary_operator_ok (PLUS, SImode, operands)
5726    /* Current assemblers are broken and do not allow @GOTOFF in
5727       ought but a memory context.  */
5728    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5729 {
5730   switch (get_attr_type (insn))
5731     {
5732     case TYPE_INCDEC:
5733       if (operands[2] == const1_rtx)
5734         return "inc{l}\t%k0";
5735       else
5736         {
5737           gcc_assert (operands[2] == constm1_rtx);
5738           return "dec{l}\t%k0";
5739         }
5740
5741     default:
5742       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5743          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5744       if (GET_CODE (operands[2]) == CONST_INT
5745           && (INTVAL (operands[2]) == 128
5746               || (INTVAL (operands[2]) < 0
5747                   && INTVAL (operands[2]) != -128)))
5748         {
5749           operands[2] = GEN_INT (-INTVAL (operands[2]));
5750           return "sub{l}\t{%2, %k0|%k0, %2}";
5751         }
5752       return "add{l}\t{%2, %k0|%k0, %2}";
5753     }
5754 }
5755   [(set (attr "type")
5756      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5757         (const_string "incdec")
5758         (const_string "alu")))
5759    (set_attr "mode" "SI")])
5760
5761 ; For comparisons against 1, -1 and 128, we may generate better code
5762 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5763 ; is matched then.  We can't accept general immediate, because for
5764 ; case of overflows,  the result is messed up.
5765 ; This pattern also don't hold of 0x80000000, since the value overflows
5766 ; when negated.
5767 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5768 ; only for comparisons not depending on it.
5769 (define_insn "*addsi_4"
5770   [(set (reg FLAGS_REG)
5771         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5772                  (match_operand:SI 2 "const_int_operand" "n")))
5773    (clobber (match_scratch:SI 0 "=rm"))]
5774   "ix86_match_ccmode (insn, CCGCmode)
5775    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5776 {
5777   switch (get_attr_type (insn))
5778     {
5779     case TYPE_INCDEC:
5780       if (operands[2] == constm1_rtx)
5781         return "inc{l}\t%0";
5782       else
5783         {
5784           gcc_assert (operands[2] == const1_rtx);
5785           return "dec{l}\t%0";
5786         }
5787
5788     default:
5789       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5790       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5791          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5792       if ((INTVAL (operands[2]) == -128
5793            || (INTVAL (operands[2]) > 0
5794                && INTVAL (operands[2]) != 128)))
5795         return "sub{l}\t{%2, %0|%0, %2}";
5796       operands[2] = GEN_INT (-INTVAL (operands[2]));
5797       return "add{l}\t{%2, %0|%0, %2}";
5798     }
5799 }
5800   [(set (attr "type")
5801      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5802         (const_string "incdec")
5803         (const_string "alu")))
5804    (set_attr "mode" "SI")])
5805
5806 (define_insn "*addsi_5"
5807   [(set (reg FLAGS_REG)
5808         (compare
5809           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5810                    (match_operand:SI 2 "general_operand" "rmni"))
5811           (const_int 0)))
5812    (clobber (match_scratch:SI 0 "=r"))]
5813   "ix86_match_ccmode (insn, CCGOCmode)
5814    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5815    /* Current assemblers are broken and do not allow @GOTOFF in
5816       ought but a memory context.  */
5817    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5818 {
5819   switch (get_attr_type (insn))
5820     {
5821     case TYPE_INCDEC:
5822       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5823       if (operands[2] == const1_rtx)
5824         return "inc{l}\t%0";
5825       else
5826         {
5827           gcc_assert (operands[2] == constm1_rtx);
5828           return "dec{l}\t%0";
5829         }
5830
5831     default:
5832       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5833       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5834          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5835       if (GET_CODE (operands[2]) == CONST_INT
5836           && (INTVAL (operands[2]) == 128
5837               || (INTVAL (operands[2]) < 0
5838                   && INTVAL (operands[2]) != -128)))
5839         {
5840           operands[2] = GEN_INT (-INTVAL (operands[2]));
5841           return "sub{l}\t{%2, %0|%0, %2}";
5842         }
5843       return "add{l}\t{%2, %0|%0, %2}";
5844     }
5845 }
5846   [(set (attr "type")
5847      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5848         (const_string "incdec")
5849         (const_string "alu")))
5850    (set_attr "mode" "SI")])
5851
5852 (define_expand "addhi3"
5853   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5854                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5855                             (match_operand:HI 2 "general_operand" "")))
5856               (clobber (reg:CC FLAGS_REG))])]
5857   "TARGET_HIMODE_MATH"
5858   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5859
5860 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5861 ;; type optimizations enabled by define-splits.  This is not important
5862 ;; for PII, and in fact harmful because of partial register stalls.
5863
5864 (define_insn "*addhi_1_lea"
5865   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5866         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5867                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5868    (clobber (reg:CC FLAGS_REG))]
5869   "!TARGET_PARTIAL_REG_STALL
5870    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5871 {
5872   switch (get_attr_type (insn))
5873     {
5874     case TYPE_LEA:
5875       return "#";
5876     case TYPE_INCDEC:
5877       if (operands[2] == const1_rtx)
5878         return "inc{w}\t%0";
5879       else
5880         {
5881           gcc_assert (operands[2] == constm1_rtx);
5882           return "dec{w}\t%0";
5883         }
5884
5885     default:
5886       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5887          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5888       if (GET_CODE (operands[2]) == CONST_INT
5889           && (INTVAL (operands[2]) == 128
5890               || (INTVAL (operands[2]) < 0
5891                   && INTVAL (operands[2]) != -128)))
5892         {
5893           operands[2] = GEN_INT (-INTVAL (operands[2]));
5894           return "sub{w}\t{%2, %0|%0, %2}";
5895         }
5896       return "add{w}\t{%2, %0|%0, %2}";
5897     }
5898 }
5899   [(set (attr "type")
5900      (if_then_else (eq_attr "alternative" "2")
5901         (const_string "lea")
5902         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5903            (const_string "incdec")
5904            (const_string "alu"))))
5905    (set_attr "mode" "HI,HI,SI")])
5906
5907 (define_insn "*addhi_1"
5908   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5909         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5910                  (match_operand:HI 2 "general_operand" "ri,rm")))
5911    (clobber (reg:CC FLAGS_REG))]
5912   "TARGET_PARTIAL_REG_STALL
5913    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5914 {
5915   switch (get_attr_type (insn))
5916     {
5917     case TYPE_INCDEC:
5918       if (operands[2] == const1_rtx)
5919         return "inc{w}\t%0";
5920       else
5921         {
5922           gcc_assert (operands[2] == constm1_rtx);
5923           return "dec{w}\t%0";
5924         }
5925
5926     default:
5927       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5928          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5929       if (GET_CODE (operands[2]) == CONST_INT
5930           && (INTVAL (operands[2]) == 128
5931               || (INTVAL (operands[2]) < 0
5932                   && INTVAL (operands[2]) != -128)))
5933         {
5934           operands[2] = GEN_INT (-INTVAL (operands[2]));
5935           return "sub{w}\t{%2, %0|%0, %2}";
5936         }
5937       return "add{w}\t{%2, %0|%0, %2}";
5938     }
5939 }
5940   [(set (attr "type")
5941      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5942         (const_string "incdec")
5943         (const_string "alu")))
5944    (set_attr "mode" "HI")])
5945
5946 (define_insn "*addhi_2"
5947   [(set (reg FLAGS_REG)
5948         (compare
5949           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5950                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5951           (const_int 0)))
5952    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5953         (plus:HI (match_dup 1) (match_dup 2)))]
5954   "ix86_match_ccmode (insn, CCGOCmode)
5955    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5956 {
5957   switch (get_attr_type (insn))
5958     {
5959     case TYPE_INCDEC:
5960       if (operands[2] == const1_rtx)
5961         return "inc{w}\t%0";
5962       else
5963         {
5964           gcc_assert (operands[2] == constm1_rtx);
5965           return "dec{w}\t%0";
5966         }
5967
5968     default:
5969       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5970          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5971       if (GET_CODE (operands[2]) == CONST_INT
5972           && (INTVAL (operands[2]) == 128
5973               || (INTVAL (operands[2]) < 0
5974                   && INTVAL (operands[2]) != -128)))
5975         {
5976           operands[2] = GEN_INT (-INTVAL (operands[2]));
5977           return "sub{w}\t{%2, %0|%0, %2}";
5978         }
5979       return "add{w}\t{%2, %0|%0, %2}";
5980     }
5981 }
5982   [(set (attr "type")
5983      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5984         (const_string "incdec")
5985         (const_string "alu")))
5986    (set_attr "mode" "HI")])
5987
5988 (define_insn "*addhi_3"
5989   [(set (reg FLAGS_REG)
5990         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5991                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5992    (clobber (match_scratch:HI 0 "=r"))]
5993   "ix86_match_ccmode (insn, CCZmode)
5994    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5995 {
5996   switch (get_attr_type (insn))
5997     {
5998     case TYPE_INCDEC:
5999       if (operands[2] == const1_rtx)
6000         return "inc{w}\t%0";
6001       else
6002         {
6003           gcc_assert (operands[2] == constm1_rtx);
6004           return "dec{w}\t%0";
6005         }
6006
6007     default:
6008       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6009          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6010       if (GET_CODE (operands[2]) == CONST_INT
6011           && (INTVAL (operands[2]) == 128
6012               || (INTVAL (operands[2]) < 0
6013                   && INTVAL (operands[2]) != -128)))
6014         {
6015           operands[2] = GEN_INT (-INTVAL (operands[2]));
6016           return "sub{w}\t{%2, %0|%0, %2}";
6017         }
6018       return "add{w}\t{%2, %0|%0, %2}";
6019     }
6020 }
6021   [(set (attr "type")
6022      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6023         (const_string "incdec")
6024         (const_string "alu")))
6025    (set_attr "mode" "HI")])
6026
6027 ; See comments above addsi_4 for details.
6028 (define_insn "*addhi_4"
6029   [(set (reg FLAGS_REG)
6030         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6031                  (match_operand:HI 2 "const_int_operand" "n")))
6032    (clobber (match_scratch:HI 0 "=rm"))]
6033   "ix86_match_ccmode (insn, CCGCmode)
6034    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6035 {
6036   switch (get_attr_type (insn))
6037     {
6038     case TYPE_INCDEC:
6039       if (operands[2] == constm1_rtx)
6040         return "inc{w}\t%0";
6041       else
6042         {
6043           gcc_assert (operands[2] == const1_rtx);
6044           return "dec{w}\t%0";
6045         }
6046
6047     default:
6048       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6049       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6050          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6051       if ((INTVAL (operands[2]) == -128
6052            || (INTVAL (operands[2]) > 0
6053                && INTVAL (operands[2]) != 128)))
6054         return "sub{w}\t{%2, %0|%0, %2}";
6055       operands[2] = GEN_INT (-INTVAL (operands[2]));
6056       return "add{w}\t{%2, %0|%0, %2}";
6057     }
6058 }
6059   [(set (attr "type")
6060      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6061         (const_string "incdec")
6062         (const_string "alu")))
6063    (set_attr "mode" "SI")])
6064
6065
6066 (define_insn "*addhi_5"
6067   [(set (reg FLAGS_REG)
6068         (compare
6069           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6070                    (match_operand:HI 2 "general_operand" "rmni"))
6071           (const_int 0)))
6072    (clobber (match_scratch:HI 0 "=r"))]
6073   "ix86_match_ccmode (insn, CCGOCmode)
6074    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6075 {
6076   switch (get_attr_type (insn))
6077     {
6078     case TYPE_INCDEC:
6079       if (operands[2] == const1_rtx)
6080         return "inc{w}\t%0";
6081       else
6082         {
6083           gcc_assert (operands[2] == constm1_rtx);
6084           return "dec{w}\t%0";
6085         }
6086
6087     default:
6088       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6089          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6090       if (GET_CODE (operands[2]) == CONST_INT
6091           && (INTVAL (operands[2]) == 128
6092               || (INTVAL (operands[2]) < 0
6093                   && INTVAL (operands[2]) != -128)))
6094         {
6095           operands[2] = GEN_INT (-INTVAL (operands[2]));
6096           return "sub{w}\t{%2, %0|%0, %2}";
6097         }
6098       return "add{w}\t{%2, %0|%0, %2}";
6099     }
6100 }
6101   [(set (attr "type")
6102      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6103         (const_string "incdec")
6104         (const_string "alu")))
6105    (set_attr "mode" "HI")])
6106
6107 (define_expand "addqi3"
6108   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6109                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6110                             (match_operand:QI 2 "general_operand" "")))
6111               (clobber (reg:CC FLAGS_REG))])]
6112   "TARGET_QIMODE_MATH"
6113   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6114
6115 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6116 (define_insn "*addqi_1_lea"
6117   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6118         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6119                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6120    (clobber (reg:CC FLAGS_REG))]
6121   "!TARGET_PARTIAL_REG_STALL
6122    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6123 {
6124   int widen = (which_alternative == 2);
6125   switch (get_attr_type (insn))
6126     {
6127     case TYPE_LEA:
6128       return "#";
6129     case TYPE_INCDEC:
6130       if (operands[2] == const1_rtx)
6131         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6132       else
6133         {
6134           gcc_assert (operands[2] == constm1_rtx);
6135           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6136         }
6137
6138     default:
6139       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6140          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6141       if (GET_CODE (operands[2]) == CONST_INT
6142           && (INTVAL (operands[2]) == 128
6143               || (INTVAL (operands[2]) < 0
6144                   && INTVAL (operands[2]) != -128)))
6145         {
6146           operands[2] = GEN_INT (-INTVAL (operands[2]));
6147           if (widen)
6148             return "sub{l}\t{%2, %k0|%k0, %2}";
6149           else
6150             return "sub{b}\t{%2, %0|%0, %2}";
6151         }
6152       if (widen)
6153         return "add{l}\t{%k2, %k0|%k0, %k2}";
6154       else
6155         return "add{b}\t{%2, %0|%0, %2}";
6156     }
6157 }
6158   [(set (attr "type")
6159      (if_then_else (eq_attr "alternative" "3")
6160         (const_string "lea")
6161         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6162            (const_string "incdec")
6163            (const_string "alu"))))
6164    (set_attr "mode" "QI,QI,SI,SI")])
6165
6166 (define_insn "*addqi_1"
6167   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6168         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6169                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6170    (clobber (reg:CC FLAGS_REG))]
6171   "TARGET_PARTIAL_REG_STALL
6172    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6173 {
6174   int widen = (which_alternative == 2);
6175   switch (get_attr_type (insn))
6176     {
6177     case TYPE_INCDEC:
6178       if (operands[2] == const1_rtx)
6179         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6180       else
6181         {
6182           gcc_assert (operands[2] == constm1_rtx);
6183           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6184         }
6185
6186     default:
6187       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6188          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6189       if (GET_CODE (operands[2]) == CONST_INT
6190           && (INTVAL (operands[2]) == 128
6191               || (INTVAL (operands[2]) < 0
6192                   && INTVAL (operands[2]) != -128)))
6193         {
6194           operands[2] = GEN_INT (-INTVAL (operands[2]));
6195           if (widen)
6196             return "sub{l}\t{%2, %k0|%k0, %2}";
6197           else
6198             return "sub{b}\t{%2, %0|%0, %2}";
6199         }
6200       if (widen)
6201         return "add{l}\t{%k2, %k0|%k0, %k2}";
6202       else
6203         return "add{b}\t{%2, %0|%0, %2}";
6204     }
6205 }
6206   [(set (attr "type")
6207      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6208         (const_string "incdec")
6209         (const_string "alu")))
6210    (set_attr "mode" "QI,QI,SI")])
6211
6212 (define_insn "*addqi_1_slp"
6213   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6214         (plus:QI (match_dup 0)
6215                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6216    (clobber (reg:CC FLAGS_REG))]
6217   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6218    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6219 {
6220   switch (get_attr_type (insn))
6221     {
6222     case TYPE_INCDEC:
6223       if (operands[1] == const1_rtx)
6224         return "inc{b}\t%0";
6225       else
6226         {
6227           gcc_assert (operands[1] == constm1_rtx);
6228           return "dec{b}\t%0";
6229         }
6230
6231     default:
6232       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6233       if (GET_CODE (operands[1]) == CONST_INT
6234           && INTVAL (operands[1]) < 0)
6235         {
6236           operands[1] = GEN_INT (-INTVAL (operands[1]));
6237           return "sub{b}\t{%1, %0|%0, %1}";
6238         }
6239       return "add{b}\t{%1, %0|%0, %1}";
6240     }
6241 }
6242   [(set (attr "type")
6243      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6244         (const_string "incdec")
6245         (const_string "alu1")))
6246    (set (attr "memory")
6247      (if_then_else (match_operand 1 "memory_operand" "")
6248         (const_string "load")
6249         (const_string "none")))
6250    (set_attr "mode" "QI")])
6251
6252 (define_insn "*addqi_2"
6253   [(set (reg FLAGS_REG)
6254         (compare
6255           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6256                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6257           (const_int 0)))
6258    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6259         (plus:QI (match_dup 1) (match_dup 2)))]
6260   "ix86_match_ccmode (insn, CCGOCmode)
6261    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6262 {
6263   switch (get_attr_type (insn))
6264     {
6265     case TYPE_INCDEC:
6266       if (operands[2] == const1_rtx)
6267         return "inc{b}\t%0";
6268       else
6269         {
6270           gcc_assert (operands[2] == constm1_rtx
6271                       || (GET_CODE (operands[2]) == CONST_INT
6272                           && INTVAL (operands[2]) == 255));
6273           return "dec{b}\t%0";
6274         }
6275
6276     default:
6277       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6278       if (GET_CODE (operands[2]) == CONST_INT
6279           && INTVAL (operands[2]) < 0)
6280         {
6281           operands[2] = GEN_INT (-INTVAL (operands[2]));
6282           return "sub{b}\t{%2, %0|%0, %2}";
6283         }
6284       return "add{b}\t{%2, %0|%0, %2}";
6285     }
6286 }
6287   [(set (attr "type")
6288      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6289         (const_string "incdec")
6290         (const_string "alu")))
6291    (set_attr "mode" "QI")])
6292
6293 (define_insn "*addqi_3"
6294   [(set (reg FLAGS_REG)
6295         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6296                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6297    (clobber (match_scratch:QI 0 "=q"))]
6298   "ix86_match_ccmode (insn, CCZmode)
6299    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6300 {
6301   switch (get_attr_type (insn))
6302     {
6303     case TYPE_INCDEC:
6304       if (operands[2] == const1_rtx)
6305         return "inc{b}\t%0";
6306       else
6307         {
6308           gcc_assert (operands[2] == constm1_rtx
6309                       || (GET_CODE (operands[2]) == CONST_INT
6310                           && INTVAL (operands[2]) == 255));
6311           return "dec{b}\t%0";
6312         }
6313
6314     default:
6315       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6316       if (GET_CODE (operands[2]) == CONST_INT
6317           && INTVAL (operands[2]) < 0)
6318         {
6319           operands[2] = GEN_INT (-INTVAL (operands[2]));
6320           return "sub{b}\t{%2, %0|%0, %2}";
6321         }
6322       return "add{b}\t{%2, %0|%0, %2}";
6323     }
6324 }
6325   [(set (attr "type")
6326      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6327         (const_string "incdec")
6328         (const_string "alu")))
6329    (set_attr "mode" "QI")])
6330
6331 ; See comments above addsi_4 for details.
6332 (define_insn "*addqi_4"
6333   [(set (reg FLAGS_REG)
6334         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6335                  (match_operand:QI 2 "const_int_operand" "n")))
6336    (clobber (match_scratch:QI 0 "=qm"))]
6337   "ix86_match_ccmode (insn, CCGCmode)
6338    && (INTVAL (operands[2]) & 0xff) != 0x80"
6339 {
6340   switch (get_attr_type (insn))
6341     {
6342     case TYPE_INCDEC:
6343       if (operands[2] == constm1_rtx
6344           || (GET_CODE (operands[2]) == CONST_INT
6345               && INTVAL (operands[2]) == 255))
6346         return "inc{b}\t%0";
6347       else
6348         {
6349           gcc_assert (operands[2] == const1_rtx);
6350           return "dec{b}\t%0";
6351         }
6352
6353     default:
6354       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6355       if (INTVAL (operands[2]) < 0)
6356         {
6357           operands[2] = GEN_INT (-INTVAL (operands[2]));
6358           return "add{b}\t{%2, %0|%0, %2}";
6359         }
6360       return "sub{b}\t{%2, %0|%0, %2}";
6361     }
6362 }
6363   [(set (attr "type")
6364      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6365         (const_string "incdec")
6366         (const_string "alu")))
6367    (set_attr "mode" "QI")])
6368
6369
6370 (define_insn "*addqi_5"
6371   [(set (reg FLAGS_REG)
6372         (compare
6373           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6374                    (match_operand:QI 2 "general_operand" "qmni"))
6375           (const_int 0)))
6376    (clobber (match_scratch:QI 0 "=q"))]
6377   "ix86_match_ccmode (insn, CCGOCmode)
6378    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6379 {
6380   switch (get_attr_type (insn))
6381     {
6382     case TYPE_INCDEC:
6383       if (operands[2] == const1_rtx)
6384         return "inc{b}\t%0";
6385       else
6386         {
6387           gcc_assert (operands[2] == constm1_rtx
6388                       || (GET_CODE (operands[2]) == CONST_INT
6389                           && INTVAL (operands[2]) == 255));
6390           return "dec{b}\t%0";
6391         }
6392
6393     default:
6394       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6395       if (GET_CODE (operands[2]) == CONST_INT
6396           && INTVAL (operands[2]) < 0)
6397         {
6398           operands[2] = GEN_INT (-INTVAL (operands[2]));
6399           return "sub{b}\t{%2, %0|%0, %2}";
6400         }
6401       return "add{b}\t{%2, %0|%0, %2}";
6402     }
6403 }
6404   [(set (attr "type")
6405      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6406         (const_string "incdec")
6407         (const_string "alu")))
6408    (set_attr "mode" "QI")])
6409
6410
6411 (define_insn "addqi_ext_1"
6412   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6413                          (const_int 8)
6414                          (const_int 8))
6415         (plus:SI
6416           (zero_extract:SI
6417             (match_operand 1 "ext_register_operand" "0")
6418             (const_int 8)
6419             (const_int 8))
6420           (match_operand:QI 2 "general_operand" "Qmn")))
6421    (clobber (reg:CC FLAGS_REG))]
6422   "!TARGET_64BIT"
6423 {
6424   switch (get_attr_type (insn))
6425     {
6426     case TYPE_INCDEC:
6427       if (operands[2] == const1_rtx)
6428         return "inc{b}\t%h0";
6429       else
6430         {
6431           gcc_assert (operands[2] == constm1_rtx
6432                       || (GET_CODE (operands[2]) == CONST_INT
6433                           && INTVAL (operands[2]) == 255));
6434           return "dec{b}\t%h0";
6435         }
6436
6437     default:
6438       return "add{b}\t{%2, %h0|%h0, %2}";
6439     }
6440 }
6441   [(set (attr "type")
6442      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6443         (const_string "incdec")
6444         (const_string "alu")))
6445    (set_attr "mode" "QI")])
6446
6447 (define_insn "*addqi_ext_1_rex64"
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 "nonmemory_operand" "Qn")))
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                       || (GET_CODE (operands[2]) == CONST_INT
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_2"
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           (zero_extract:SI
6493             (match_operand 2 "ext_register_operand" "Q")
6494             (const_int 8)
6495             (const_int 8))))
6496    (clobber (reg:CC FLAGS_REG))]
6497   ""
6498   "add{b}\t{%h2, %h0|%h0, %h2}"
6499   [(set_attr "type" "alu")
6500    (set_attr "mode" "QI")])
6501
6502 ;; The patterns that match these are at the end of this file.
6503
6504 (define_expand "addxf3"
6505   [(set (match_operand:XF 0 "register_operand" "")
6506         (plus:XF (match_operand:XF 1 "register_operand" "")
6507                  (match_operand:XF 2 "register_operand" "")))]
6508   "TARGET_80387"
6509   "")
6510
6511 (define_expand "adddf3"
6512   [(set (match_operand:DF 0 "register_operand" "")
6513         (plus:DF (match_operand:DF 1 "register_operand" "")
6514                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6515   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6516   "")
6517
6518 (define_expand "addsf3"
6519   [(set (match_operand:SF 0 "register_operand" "")
6520         (plus:SF (match_operand:SF 1 "register_operand" "")
6521                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6522   "TARGET_80387 || TARGET_SSE_MATH"
6523   "")
6524 \f
6525 ;; Subtract instructions
6526
6527 ;; %%% splits for subditi3
6528
6529 (define_expand "subti3"
6530   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6531                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6532                              (match_operand:TI 2 "x86_64_general_operand" "")))
6533               (clobber (reg:CC FLAGS_REG))])]
6534   "TARGET_64BIT"
6535   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6536
6537 (define_insn "*subti3_1"
6538   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6539         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6540                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6541    (clobber (reg:CC FLAGS_REG))]
6542   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6543   "#")
6544
6545 (define_split
6546   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6547         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6548                   (match_operand:TI 2 "general_operand" "")))
6549    (clobber (reg:CC FLAGS_REG))]
6550   "TARGET_64BIT && reload_completed"
6551   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6552               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6553    (parallel [(set (match_dup 3)
6554                    (minus:DI (match_dup 4)
6555                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6556                                       (match_dup 5))))
6557               (clobber (reg:CC FLAGS_REG))])]
6558   "split_ti (operands+0, 1, operands+0, operands+3);
6559    split_ti (operands+1, 1, operands+1, operands+4);
6560    split_ti (operands+2, 1, operands+2, operands+5);")
6561
6562 ;; %%% splits for subsidi3
6563
6564 (define_expand "subdi3"
6565   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6566                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6567                              (match_operand:DI 2 "x86_64_general_operand" "")))
6568               (clobber (reg:CC FLAGS_REG))])]
6569   ""
6570   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6571
6572 (define_insn "*subdi3_1"
6573   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6574         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6575                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6576    (clobber (reg:CC FLAGS_REG))]
6577   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6578   "#")
6579
6580 (define_split
6581   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6582         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6583                   (match_operand:DI 2 "general_operand" "")))
6584    (clobber (reg:CC FLAGS_REG))]
6585   "!TARGET_64BIT && reload_completed"
6586   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6587               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6588    (parallel [(set (match_dup 3)
6589                    (minus:SI (match_dup 4)
6590                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6591                                       (match_dup 5))))
6592               (clobber (reg:CC FLAGS_REG))])]
6593   "split_di (operands+0, 1, operands+0, operands+3);
6594    split_di (operands+1, 1, operands+1, operands+4);
6595    split_di (operands+2, 1, operands+2, operands+5);")
6596
6597 (define_insn "subdi3_carry_rex64"
6598   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6599           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6600             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6601                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6602    (clobber (reg:CC FLAGS_REG))]
6603   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6604   "sbb{q}\t{%2, %0|%0, %2}"
6605   [(set_attr "type" "alu")
6606    (set_attr "pent_pair" "pu")
6607    (set_attr "mode" "DI")])
6608
6609 (define_insn "*subdi_1_rex64"
6610   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6611         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6612                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6613    (clobber (reg:CC FLAGS_REG))]
6614   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6615   "sub{q}\t{%2, %0|%0, %2}"
6616   [(set_attr "type" "alu")
6617    (set_attr "mode" "DI")])
6618
6619 (define_insn "*subdi_2_rex64"
6620   [(set (reg FLAGS_REG)
6621         (compare
6622           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6623                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6624           (const_int 0)))
6625    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6626         (minus:DI (match_dup 1) (match_dup 2)))]
6627   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6628    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6629   "sub{q}\t{%2, %0|%0, %2}"
6630   [(set_attr "type" "alu")
6631    (set_attr "mode" "DI")])
6632
6633 (define_insn "*subdi_3_rex63"
6634   [(set (reg FLAGS_REG)
6635         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6636                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6637    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6638         (minus:DI (match_dup 1) (match_dup 2)))]
6639   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6640    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6641   "sub{q}\t{%2, %0|%0, %2}"
6642   [(set_attr "type" "alu")
6643    (set_attr "mode" "DI")])
6644
6645 (define_insn "subqi3_carry"
6646   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6647           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6648             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6649                (match_operand:QI 2 "general_operand" "qi,qm"))))
6650    (clobber (reg:CC FLAGS_REG))]
6651   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6652   "sbb{b}\t{%2, %0|%0, %2}"
6653   [(set_attr "type" "alu")
6654    (set_attr "pent_pair" "pu")
6655    (set_attr "mode" "QI")])
6656
6657 (define_insn "subhi3_carry"
6658   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6659           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6660             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6661                (match_operand:HI 2 "general_operand" "ri,rm"))))
6662    (clobber (reg:CC FLAGS_REG))]
6663   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6664   "sbb{w}\t{%2, %0|%0, %2}"
6665   [(set_attr "type" "alu")
6666    (set_attr "pent_pair" "pu")
6667    (set_attr "mode" "HI")])
6668
6669 (define_insn "subsi3_carry"
6670   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6671           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6672             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6673                (match_operand:SI 2 "general_operand" "ri,rm"))))
6674    (clobber (reg:CC FLAGS_REG))]
6675   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6676   "sbb{l}\t{%2, %0|%0, %2}"
6677   [(set_attr "type" "alu")
6678    (set_attr "pent_pair" "pu")
6679    (set_attr "mode" "SI")])
6680
6681 (define_insn "subsi3_carry_zext"
6682   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6683           (zero_extend:DI
6684             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6685               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6686                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6687    (clobber (reg:CC FLAGS_REG))]
6688   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6689   "sbb{l}\t{%2, %k0|%k0, %2}"
6690   [(set_attr "type" "alu")
6691    (set_attr "pent_pair" "pu")
6692    (set_attr "mode" "SI")])
6693
6694 (define_expand "subsi3"
6695   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6696                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6697                              (match_operand:SI 2 "general_operand" "")))
6698               (clobber (reg:CC FLAGS_REG))])]
6699   ""
6700   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6701
6702 (define_insn "*subsi_1"
6703   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6704         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6705                   (match_operand:SI 2 "general_operand" "ri,rm")))
6706    (clobber (reg:CC FLAGS_REG))]
6707   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6708   "sub{l}\t{%2, %0|%0, %2}"
6709   [(set_attr "type" "alu")
6710    (set_attr "mode" "SI")])
6711
6712 (define_insn "*subsi_1_zext"
6713   [(set (match_operand:DI 0 "register_operand" "=r")
6714         (zero_extend:DI
6715           (minus:SI (match_operand:SI 1 "register_operand" "0")
6716                     (match_operand:SI 2 "general_operand" "rim"))))
6717    (clobber (reg:CC FLAGS_REG))]
6718   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6719   "sub{l}\t{%2, %k0|%k0, %2}"
6720   [(set_attr "type" "alu")
6721    (set_attr "mode" "SI")])
6722
6723 (define_insn "*subsi_2"
6724   [(set (reg FLAGS_REG)
6725         (compare
6726           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6727                     (match_operand:SI 2 "general_operand" "ri,rm"))
6728           (const_int 0)))
6729    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6730         (minus:SI (match_dup 1) (match_dup 2)))]
6731   "ix86_match_ccmode (insn, CCGOCmode)
6732    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6733   "sub{l}\t{%2, %0|%0, %2}"
6734   [(set_attr "type" "alu")
6735    (set_attr "mode" "SI")])
6736
6737 (define_insn "*subsi_2_zext"
6738   [(set (reg FLAGS_REG)
6739         (compare
6740           (minus:SI (match_operand:SI 1 "register_operand" "0")
6741                     (match_operand:SI 2 "general_operand" "rim"))
6742           (const_int 0)))
6743    (set (match_operand:DI 0 "register_operand" "=r")
6744         (zero_extend:DI
6745           (minus:SI (match_dup 1)
6746                     (match_dup 2))))]
6747   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6748    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6749   "sub{l}\t{%2, %k0|%k0, %2}"
6750   [(set_attr "type" "alu")
6751    (set_attr "mode" "SI")])
6752
6753 (define_insn "*subsi_3"
6754   [(set (reg FLAGS_REG)
6755         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6756                  (match_operand:SI 2 "general_operand" "ri,rm")))
6757    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6758         (minus:SI (match_dup 1) (match_dup 2)))]
6759   "ix86_match_ccmode (insn, CCmode)
6760    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6761   "sub{l}\t{%2, %0|%0, %2}"
6762   [(set_attr "type" "alu")
6763    (set_attr "mode" "SI")])
6764
6765 (define_insn "*subsi_3_zext"
6766   [(set (reg FLAGS_REG)
6767         (compare (match_operand:SI 1 "register_operand" "0")
6768                  (match_operand:SI 2 "general_operand" "rim")))
6769    (set (match_operand:DI 0 "register_operand" "=r")
6770         (zero_extend:DI
6771           (minus:SI (match_dup 1)
6772                     (match_dup 2))))]
6773   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6774    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6775   "sub{l}\t{%2, %1|%1, %2}"
6776   [(set_attr "type" "alu")
6777    (set_attr "mode" "DI")])
6778
6779 (define_expand "subhi3"
6780   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6781                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6782                              (match_operand:HI 2 "general_operand" "")))
6783               (clobber (reg:CC FLAGS_REG))])]
6784   "TARGET_HIMODE_MATH"
6785   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6786
6787 (define_insn "*subhi_1"
6788   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6789         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6790                   (match_operand:HI 2 "general_operand" "ri,rm")))
6791    (clobber (reg:CC FLAGS_REG))]
6792   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6793   "sub{w}\t{%2, %0|%0, %2}"
6794   [(set_attr "type" "alu")
6795    (set_attr "mode" "HI")])
6796
6797 (define_insn "*subhi_2"
6798   [(set (reg FLAGS_REG)
6799         (compare
6800           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6801                     (match_operand:HI 2 "general_operand" "ri,rm"))
6802           (const_int 0)))
6803    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6804         (minus:HI (match_dup 1) (match_dup 2)))]
6805   "ix86_match_ccmode (insn, CCGOCmode)
6806    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6807   "sub{w}\t{%2, %0|%0, %2}"
6808   [(set_attr "type" "alu")
6809    (set_attr "mode" "HI")])
6810
6811 (define_insn "*subhi_3"
6812   [(set (reg FLAGS_REG)
6813         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6814                  (match_operand:HI 2 "general_operand" "ri,rm")))
6815    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6816         (minus:HI (match_dup 1) (match_dup 2)))]
6817   "ix86_match_ccmode (insn, CCmode)
6818    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6819   "sub{w}\t{%2, %0|%0, %2}"
6820   [(set_attr "type" "alu")
6821    (set_attr "mode" "HI")])
6822
6823 (define_expand "subqi3"
6824   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6825                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6826                              (match_operand:QI 2 "general_operand" "")))
6827               (clobber (reg:CC FLAGS_REG))])]
6828   "TARGET_QIMODE_MATH"
6829   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6830
6831 (define_insn "*subqi_1"
6832   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6833         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6834                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6835    (clobber (reg:CC FLAGS_REG))]
6836   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6837   "sub{b}\t{%2, %0|%0, %2}"
6838   [(set_attr "type" "alu")
6839    (set_attr "mode" "QI")])
6840
6841 (define_insn "*subqi_1_slp"
6842   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6843         (minus:QI (match_dup 0)
6844                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6845    (clobber (reg:CC FLAGS_REG))]
6846   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6847    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6848   "sub{b}\t{%1, %0|%0, %1}"
6849   [(set_attr "type" "alu1")
6850    (set_attr "mode" "QI")])
6851
6852 (define_insn "*subqi_2"
6853   [(set (reg FLAGS_REG)
6854         (compare
6855           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6856                     (match_operand:QI 2 "general_operand" "qi,qm"))
6857           (const_int 0)))
6858    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6859         (minus:HI (match_dup 1) (match_dup 2)))]
6860   "ix86_match_ccmode (insn, CCGOCmode)
6861    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6862   "sub{b}\t{%2, %0|%0, %2}"
6863   [(set_attr "type" "alu")
6864    (set_attr "mode" "QI")])
6865
6866 (define_insn "*subqi_3"
6867   [(set (reg FLAGS_REG)
6868         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6869                  (match_operand:QI 2 "general_operand" "qi,qm")))
6870    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6871         (minus:HI (match_dup 1) (match_dup 2)))]
6872   "ix86_match_ccmode (insn, CCmode)
6873    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6874   "sub{b}\t{%2, %0|%0, %2}"
6875   [(set_attr "type" "alu")
6876    (set_attr "mode" "QI")])
6877
6878 ;; The patterns that match these are at the end of this file.
6879
6880 (define_expand "subxf3"
6881   [(set (match_operand:XF 0 "register_operand" "")
6882         (minus:XF (match_operand:XF 1 "register_operand" "")
6883                   (match_operand:XF 2 "register_operand" "")))]
6884   "TARGET_80387"
6885   "")
6886
6887 (define_expand "subdf3"
6888   [(set (match_operand:DF 0 "register_operand" "")
6889         (minus:DF (match_operand:DF 1 "register_operand" "")
6890                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6891   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6892   "")
6893
6894 (define_expand "subsf3"
6895   [(set (match_operand:SF 0 "register_operand" "")
6896         (minus:SF (match_operand:SF 1 "register_operand" "")
6897                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6898   "TARGET_80387 || TARGET_SSE_MATH"
6899   "")
6900 \f
6901 ;; Multiply instructions
6902
6903 (define_expand "muldi3"
6904   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6905                    (mult:DI (match_operand:DI 1 "register_operand" "")
6906                             (match_operand:DI 2 "x86_64_general_operand" "")))
6907               (clobber (reg:CC FLAGS_REG))])]
6908   "TARGET_64BIT"
6909   "")
6910
6911 (define_insn "*muldi3_1_rex64"
6912   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6913         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6914                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6915    (clobber (reg:CC FLAGS_REG))]
6916   "TARGET_64BIT
6917    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6918   "@
6919    imul{q}\t{%2, %1, %0|%0, %1, %2}
6920    imul{q}\t{%2, %1, %0|%0, %1, %2}
6921    imul{q}\t{%2, %0|%0, %2}"
6922   [(set_attr "type" "imul")
6923    (set_attr "prefix_0f" "0,0,1")
6924    (set (attr "athlon_decode")
6925         (cond [(eq_attr "cpu" "athlon")
6926                   (const_string "vector")
6927                (eq_attr "alternative" "1")
6928                   (const_string "vector")
6929                (and (eq_attr "alternative" "2")
6930                     (match_operand 1 "memory_operand" ""))
6931                   (const_string "vector")]
6932               (const_string "direct")))
6933    (set_attr "mode" "DI")])
6934
6935 (define_expand "mulsi3"
6936   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6937                    (mult:SI (match_operand:SI 1 "register_operand" "")
6938                             (match_operand:SI 2 "general_operand" "")))
6939               (clobber (reg:CC FLAGS_REG))])]
6940   ""
6941   "")
6942
6943 (define_insn "*mulsi3_1"
6944   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6945         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6946                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6947    (clobber (reg:CC FLAGS_REG))]
6948   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6949   "@
6950    imul{l}\t{%2, %1, %0|%0, %1, %2}
6951    imul{l}\t{%2, %1, %0|%0, %1, %2}
6952    imul{l}\t{%2, %0|%0, %2}"
6953   [(set_attr "type" "imul")
6954    (set_attr "prefix_0f" "0,0,1")
6955    (set (attr "athlon_decode")
6956         (cond [(eq_attr "cpu" "athlon")
6957                   (const_string "vector")
6958                (eq_attr "alternative" "1")
6959                   (const_string "vector")
6960                (and (eq_attr "alternative" "2")
6961                     (match_operand 1 "memory_operand" ""))
6962                   (const_string "vector")]
6963               (const_string "direct")))
6964    (set_attr "mode" "SI")])
6965
6966 (define_insn "*mulsi3_1_zext"
6967   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6968         (zero_extend:DI
6969           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6970                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6971    (clobber (reg:CC FLAGS_REG))]
6972   "TARGET_64BIT
6973    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6974   "@
6975    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6976    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6977    imul{l}\t{%2, %k0|%k0, %2}"
6978   [(set_attr "type" "imul")
6979    (set_attr "prefix_0f" "0,0,1")
6980    (set (attr "athlon_decode")
6981         (cond [(eq_attr "cpu" "athlon")
6982                   (const_string "vector")
6983                (eq_attr "alternative" "1")
6984                   (const_string "vector")
6985                (and (eq_attr "alternative" "2")
6986                     (match_operand 1 "memory_operand" ""))
6987                   (const_string "vector")]
6988               (const_string "direct")))
6989    (set_attr "mode" "SI")])
6990
6991 (define_expand "mulhi3"
6992   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6993                    (mult:HI (match_operand:HI 1 "register_operand" "")
6994                             (match_operand:HI 2 "general_operand" "")))
6995               (clobber (reg:CC FLAGS_REG))])]
6996   "TARGET_HIMODE_MATH"
6997   "")
6998
6999 (define_insn "*mulhi3_1"
7000   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7001         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7002                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7003    (clobber (reg:CC FLAGS_REG))]
7004   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7005   "@
7006    imul{w}\t{%2, %1, %0|%0, %1, %2}
7007    imul{w}\t{%2, %1, %0|%0, %1, %2}
7008    imul{w}\t{%2, %0|%0, %2}"
7009   [(set_attr "type" "imul")
7010    (set_attr "prefix_0f" "0,0,1")
7011    (set (attr "athlon_decode")
7012         (cond [(eq_attr "cpu" "athlon")
7013                   (const_string "vector")
7014                (eq_attr "alternative" "1,2")
7015                   (const_string "vector")]
7016               (const_string "direct")))
7017    (set_attr "mode" "HI")])
7018
7019 (define_expand "mulqi3"
7020   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7021                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7022                             (match_operand:QI 2 "register_operand" "")))
7023               (clobber (reg:CC FLAGS_REG))])]
7024   "TARGET_QIMODE_MATH"
7025   "")
7026
7027 (define_insn "*mulqi3_1"
7028   [(set (match_operand:QI 0 "register_operand" "=a")
7029         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7030                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7031    (clobber (reg:CC FLAGS_REG))]
7032   "TARGET_QIMODE_MATH
7033    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7034   "mul{b}\t%2"
7035   [(set_attr "type" "imul")
7036    (set_attr "length_immediate" "0")
7037    (set (attr "athlon_decode")
7038      (if_then_else (eq_attr "cpu" "athlon")
7039         (const_string "vector")
7040         (const_string "direct")))
7041    (set_attr "mode" "QI")])
7042
7043 (define_expand "umulqihi3"
7044   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7045                    (mult:HI (zero_extend:HI
7046                               (match_operand:QI 1 "nonimmediate_operand" ""))
7047                             (zero_extend:HI
7048                               (match_operand:QI 2 "register_operand" ""))))
7049               (clobber (reg:CC FLAGS_REG))])]
7050   "TARGET_QIMODE_MATH"
7051   "")
7052
7053 (define_insn "*umulqihi3_1"
7054   [(set (match_operand:HI 0 "register_operand" "=a")
7055         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7056                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7057    (clobber (reg:CC FLAGS_REG))]
7058   "TARGET_QIMODE_MATH
7059    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7060   "mul{b}\t%2"
7061   [(set_attr "type" "imul")
7062    (set_attr "length_immediate" "0")
7063    (set (attr "athlon_decode")
7064      (if_then_else (eq_attr "cpu" "athlon")
7065         (const_string "vector")
7066         (const_string "direct")))
7067    (set_attr "mode" "QI")])
7068
7069 (define_expand "mulqihi3"
7070   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7071                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7072                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7073               (clobber (reg:CC FLAGS_REG))])]
7074   "TARGET_QIMODE_MATH"
7075   "")
7076
7077 (define_insn "*mulqihi3_insn"
7078   [(set (match_operand:HI 0 "register_operand" "=a")
7079         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7080                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7081    (clobber (reg:CC FLAGS_REG))]
7082   "TARGET_QIMODE_MATH
7083    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7084   "imul{b}\t%2"
7085   [(set_attr "type" "imul")
7086    (set_attr "length_immediate" "0")
7087    (set (attr "athlon_decode")
7088      (if_then_else (eq_attr "cpu" "athlon")
7089         (const_string "vector")
7090         (const_string "direct")))
7091    (set_attr "mode" "QI")])
7092
7093 (define_expand "umulditi3"
7094   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7095                    (mult:TI (zero_extend:TI
7096                               (match_operand:DI 1 "nonimmediate_operand" ""))
7097                             (zero_extend:TI
7098                               (match_operand:DI 2 "register_operand" ""))))
7099               (clobber (reg:CC FLAGS_REG))])]
7100   "TARGET_64BIT"
7101   "")
7102
7103 (define_insn "*umulditi3_insn"
7104   [(set (match_operand:TI 0 "register_operand" "=A")
7105         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7106                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7107    (clobber (reg:CC FLAGS_REG))]
7108   "TARGET_64BIT
7109    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7110   "mul{q}\t%2"
7111   [(set_attr "type" "imul")
7112    (set_attr "length_immediate" "0")
7113    (set (attr "athlon_decode")
7114      (if_then_else (eq_attr "cpu" "athlon")
7115         (const_string "vector")
7116         (const_string "double")))
7117    (set_attr "mode" "DI")])
7118
7119 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7120 (define_expand "umulsidi3"
7121   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7122                    (mult:DI (zero_extend:DI
7123                               (match_operand:SI 1 "nonimmediate_operand" ""))
7124                             (zero_extend:DI
7125                               (match_operand:SI 2 "register_operand" ""))))
7126               (clobber (reg:CC FLAGS_REG))])]
7127   "!TARGET_64BIT"
7128   "")
7129
7130 (define_insn "*umulsidi3_insn"
7131   [(set (match_operand:DI 0 "register_operand" "=A")
7132         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7133                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7134    (clobber (reg:CC FLAGS_REG))]
7135   "!TARGET_64BIT
7136    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7137   "mul{l}\t%2"
7138   [(set_attr "type" "imul")
7139    (set_attr "length_immediate" "0")
7140    (set (attr "athlon_decode")
7141      (if_then_else (eq_attr "cpu" "athlon")
7142         (const_string "vector")
7143         (const_string "double")))
7144    (set_attr "mode" "SI")])
7145
7146 (define_expand "mulditi3"
7147   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7148                    (mult:TI (sign_extend:TI
7149                               (match_operand:DI 1 "nonimmediate_operand" ""))
7150                             (sign_extend:TI
7151                               (match_operand:DI 2 "register_operand" ""))))
7152               (clobber (reg:CC FLAGS_REG))])]
7153   "TARGET_64BIT"
7154   "")
7155
7156 (define_insn "*mulditi3_insn"
7157   [(set (match_operand:TI 0 "register_operand" "=A")
7158         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7159                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7160    (clobber (reg:CC FLAGS_REG))]
7161   "TARGET_64BIT
7162    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7163   "imul{q}\t%2"
7164   [(set_attr "type" "imul")
7165    (set_attr "length_immediate" "0")
7166    (set (attr "athlon_decode")
7167      (if_then_else (eq_attr "cpu" "athlon")
7168         (const_string "vector")
7169         (const_string "double")))
7170    (set_attr "mode" "DI")])
7171
7172 (define_expand "mulsidi3"
7173   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7174                    (mult:DI (sign_extend:DI
7175                               (match_operand:SI 1 "nonimmediate_operand" ""))
7176                             (sign_extend:DI
7177                               (match_operand:SI 2 "register_operand" ""))))
7178               (clobber (reg:CC FLAGS_REG))])]
7179   "!TARGET_64BIT"
7180   "")
7181
7182 (define_insn "*mulsidi3_insn"
7183   [(set (match_operand:DI 0 "register_operand" "=A")
7184         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7185                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7186    (clobber (reg:CC FLAGS_REG))]
7187   "!TARGET_64BIT
7188    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7189   "imul{l}\t%2"
7190   [(set_attr "type" "imul")
7191    (set_attr "length_immediate" "0")
7192    (set (attr "athlon_decode")
7193      (if_then_else (eq_attr "cpu" "athlon")
7194         (const_string "vector")
7195         (const_string "double")))
7196    (set_attr "mode" "SI")])
7197
7198 (define_expand "umuldi3_highpart"
7199   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7200                    (truncate:DI
7201                      (lshiftrt:TI
7202                        (mult:TI (zero_extend:TI
7203                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7204                                 (zero_extend:TI
7205                                   (match_operand:DI 2 "register_operand" "")))
7206                        (const_int 64))))
7207               (clobber (match_scratch:DI 3 ""))
7208               (clobber (reg:CC FLAGS_REG))])]
7209   "TARGET_64BIT"
7210   "")
7211
7212 (define_insn "*umuldi3_highpart_rex64"
7213   [(set (match_operand:DI 0 "register_operand" "=d")
7214         (truncate:DI
7215           (lshiftrt:TI
7216             (mult:TI (zero_extend:TI
7217                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7218                      (zero_extend:TI
7219                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7220             (const_int 64))))
7221    (clobber (match_scratch:DI 3 "=1"))
7222    (clobber (reg:CC FLAGS_REG))]
7223   "TARGET_64BIT
7224    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7225   "mul{q}\t%2"
7226   [(set_attr "type" "imul")
7227    (set_attr "length_immediate" "0")
7228    (set (attr "athlon_decode")
7229      (if_then_else (eq_attr "cpu" "athlon")
7230         (const_string "vector")
7231         (const_string "double")))
7232    (set_attr "mode" "DI")])
7233
7234 (define_expand "umulsi3_highpart"
7235   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7236                    (truncate:SI
7237                      (lshiftrt:DI
7238                        (mult:DI (zero_extend:DI
7239                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7240                                 (zero_extend:DI
7241                                   (match_operand:SI 2 "register_operand" "")))
7242                        (const_int 32))))
7243               (clobber (match_scratch:SI 3 ""))
7244               (clobber (reg:CC FLAGS_REG))])]
7245   ""
7246   "")
7247
7248 (define_insn "*umulsi3_highpart_insn"
7249   [(set (match_operand:SI 0 "register_operand" "=d")
7250         (truncate:SI
7251           (lshiftrt:DI
7252             (mult:DI (zero_extend:DI
7253                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7254                      (zero_extend:DI
7255                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7256             (const_int 32))))
7257    (clobber (match_scratch:SI 3 "=1"))
7258    (clobber (reg:CC FLAGS_REG))]
7259   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7260   "mul{l}\t%2"
7261   [(set_attr "type" "imul")
7262    (set_attr "length_immediate" "0")
7263    (set (attr "athlon_decode")
7264      (if_then_else (eq_attr "cpu" "athlon")
7265         (const_string "vector")
7266         (const_string "double")))
7267    (set_attr "mode" "SI")])
7268
7269 (define_insn "*umulsi3_highpart_zext"
7270   [(set (match_operand:DI 0 "register_operand" "=d")
7271         (zero_extend:DI (truncate:SI
7272           (lshiftrt:DI
7273             (mult:DI (zero_extend:DI
7274                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7275                      (zero_extend:DI
7276                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7277             (const_int 32)))))
7278    (clobber (match_scratch:SI 3 "=1"))
7279    (clobber (reg:CC FLAGS_REG))]
7280   "TARGET_64BIT
7281    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7282   "mul{l}\t%2"
7283   [(set_attr "type" "imul")
7284    (set_attr "length_immediate" "0")
7285    (set (attr "athlon_decode")
7286      (if_then_else (eq_attr "cpu" "athlon")
7287         (const_string "vector")
7288         (const_string "double")))
7289    (set_attr "mode" "SI")])
7290
7291 (define_expand "smuldi3_highpart"
7292   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7293                    (truncate:DI
7294                      (lshiftrt:TI
7295                        (mult:TI (sign_extend:TI
7296                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7297                                 (sign_extend:TI
7298                                   (match_operand:DI 2 "register_operand" "")))
7299                        (const_int 64))))
7300               (clobber (match_scratch:DI 3 ""))
7301               (clobber (reg:CC FLAGS_REG))])]
7302   "TARGET_64BIT"
7303   "")
7304
7305 (define_insn "*smuldi3_highpart_rex64"
7306   [(set (match_operand:DI 0 "register_operand" "=d")
7307         (truncate:DI
7308           (lshiftrt:TI
7309             (mult:TI (sign_extend:TI
7310                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7311                      (sign_extend:TI
7312                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7313             (const_int 64))))
7314    (clobber (match_scratch:DI 3 "=1"))
7315    (clobber (reg:CC FLAGS_REG))]
7316   "TARGET_64BIT
7317    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7318   "imul{q}\t%2"
7319   [(set_attr "type" "imul")
7320    (set (attr "athlon_decode")
7321      (if_then_else (eq_attr "cpu" "athlon")
7322         (const_string "vector")
7323         (const_string "double")))
7324    (set_attr "mode" "DI")])
7325
7326 (define_expand "smulsi3_highpart"
7327   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7328                    (truncate:SI
7329                      (lshiftrt:DI
7330                        (mult:DI (sign_extend:DI
7331                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7332                                 (sign_extend:DI
7333                                   (match_operand:SI 2 "register_operand" "")))
7334                        (const_int 32))))
7335               (clobber (match_scratch:SI 3 ""))
7336               (clobber (reg:CC FLAGS_REG))])]
7337   ""
7338   "")
7339
7340 (define_insn "*smulsi3_highpart_insn"
7341   [(set (match_operand:SI 0 "register_operand" "=d")
7342         (truncate:SI
7343           (lshiftrt:DI
7344             (mult:DI (sign_extend:DI
7345                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7346                      (sign_extend:DI
7347                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7348             (const_int 32))))
7349    (clobber (match_scratch:SI 3 "=1"))
7350    (clobber (reg:CC FLAGS_REG))]
7351   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7352   "imul{l}\t%2"
7353   [(set_attr "type" "imul")
7354    (set (attr "athlon_decode")
7355      (if_then_else (eq_attr "cpu" "athlon")
7356         (const_string "vector")
7357         (const_string "double")))
7358    (set_attr "mode" "SI")])
7359
7360 (define_insn "*smulsi3_highpart_zext"
7361   [(set (match_operand:DI 0 "register_operand" "=d")
7362         (zero_extend:DI (truncate:SI
7363           (lshiftrt:DI
7364             (mult:DI (sign_extend:DI
7365                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7366                      (sign_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    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7373   "imul{l}\t%2"
7374   [(set_attr "type" "imul")
7375    (set (attr "athlon_decode")
7376      (if_then_else (eq_attr "cpu" "athlon")
7377         (const_string "vector")
7378         (const_string "double")))
7379    (set_attr "mode" "SI")])
7380
7381 ;; The patterns that match these are at the end of this file.
7382
7383 (define_expand "mulxf3"
7384   [(set (match_operand:XF 0 "register_operand" "")
7385         (mult:XF (match_operand:XF 1 "register_operand" "")
7386                  (match_operand:XF 2 "register_operand" "")))]
7387   "TARGET_80387"
7388   "")
7389
7390 (define_expand "muldf3"
7391   [(set (match_operand:DF 0 "register_operand" "")
7392         (mult:DF (match_operand:DF 1 "register_operand" "")
7393                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7394   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7395   "")
7396
7397 (define_expand "mulsf3"
7398   [(set (match_operand:SF 0 "register_operand" "")
7399         (mult:SF (match_operand:SF 1 "register_operand" "")
7400                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7401   "TARGET_80387 || TARGET_SSE_MATH"
7402   "")
7403 \f
7404 ;; Divide instructions
7405
7406 (define_insn "divqi3"
7407   [(set (match_operand:QI 0 "register_operand" "=a")
7408         (div:QI (match_operand:HI 1 "register_operand" "0")
7409                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7410    (clobber (reg:CC FLAGS_REG))]
7411   "TARGET_QIMODE_MATH"
7412   "idiv{b}\t%2"
7413   [(set_attr "type" "idiv")
7414    (set_attr "mode" "QI")])
7415
7416 (define_insn "udivqi3"
7417   [(set (match_operand:QI 0 "register_operand" "=a")
7418         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7419                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7420    (clobber (reg:CC FLAGS_REG))]
7421   "TARGET_QIMODE_MATH"
7422   "div{b}\t%2"
7423   [(set_attr "type" "idiv")
7424    (set_attr "mode" "QI")])
7425
7426 ;; The patterns that match these are at the end of this file.
7427
7428 (define_expand "divxf3"
7429   [(set (match_operand:XF 0 "register_operand" "")
7430         (div:XF (match_operand:XF 1 "register_operand" "")
7431                 (match_operand:XF 2 "register_operand" "")))]
7432   "TARGET_80387"
7433   "")
7434
7435 (define_expand "divdf3"
7436   [(set (match_operand:DF 0 "register_operand" "")
7437         (div:DF (match_operand:DF 1 "register_operand" "")
7438                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7439    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7440    "")
7441
7442 (define_expand "divsf3"
7443   [(set (match_operand:SF 0 "register_operand" "")
7444         (div:SF (match_operand:SF 1 "register_operand" "")
7445                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7446   "TARGET_80387 || TARGET_SSE_MATH"
7447   "")
7448 \f
7449 ;; Remainder instructions.
7450
7451 (define_expand "divmoddi4"
7452   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7453                    (div:DI (match_operand:DI 1 "register_operand" "")
7454                            (match_operand:DI 2 "nonimmediate_operand" "")))
7455               (set (match_operand:DI 3 "register_operand" "")
7456                    (mod:DI (match_dup 1) (match_dup 2)))
7457               (clobber (reg:CC FLAGS_REG))])]
7458   "TARGET_64BIT"
7459   "")
7460
7461 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7462 ;; Penalize eax case slightly because it results in worse scheduling
7463 ;; of code.
7464 (define_insn "*divmoddi4_nocltd_rex64"
7465   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7466         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7467                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7468    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7469         (mod:DI (match_dup 2) (match_dup 3)))
7470    (clobber (reg:CC FLAGS_REG))]
7471   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7472   "#"
7473   [(set_attr "type" "multi")])
7474
7475 (define_insn "*divmoddi4_cltd_rex64"
7476   [(set (match_operand:DI 0 "register_operand" "=a")
7477         (div:DI (match_operand:DI 2 "register_operand" "a")
7478                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7479    (set (match_operand:DI 1 "register_operand" "=&d")
7480         (mod:DI (match_dup 2) (match_dup 3)))
7481    (clobber (reg:CC FLAGS_REG))]
7482   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7483   "#"
7484   [(set_attr "type" "multi")])
7485
7486 (define_insn "*divmoddi_noext_rex64"
7487   [(set (match_operand:DI 0 "register_operand" "=a")
7488         (div:DI (match_operand:DI 1 "register_operand" "0")
7489                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7490    (set (match_operand:DI 3 "register_operand" "=d")
7491         (mod:DI (match_dup 1) (match_dup 2)))
7492    (use (match_operand:DI 4 "register_operand" "3"))
7493    (clobber (reg:CC FLAGS_REG))]
7494   "TARGET_64BIT"
7495   "idiv{q}\t%2"
7496   [(set_attr "type" "idiv")
7497    (set_attr "mode" "DI")])
7498
7499 (define_split
7500   [(set (match_operand:DI 0 "register_operand" "")
7501         (div:DI (match_operand:DI 1 "register_operand" "")
7502                 (match_operand:DI 2 "nonimmediate_operand" "")))
7503    (set (match_operand:DI 3 "register_operand" "")
7504         (mod:DI (match_dup 1) (match_dup 2)))
7505    (clobber (reg:CC FLAGS_REG))]
7506   "TARGET_64BIT && reload_completed"
7507   [(parallel [(set (match_dup 3)
7508                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7509               (clobber (reg:CC FLAGS_REG))])
7510    (parallel [(set (match_dup 0)
7511                    (div:DI (reg:DI 0) (match_dup 2)))
7512               (set (match_dup 3)
7513                    (mod:DI (reg:DI 0) (match_dup 2)))
7514               (use (match_dup 3))
7515               (clobber (reg:CC FLAGS_REG))])]
7516 {
7517   /* Avoid use of cltd in favor of a mov+shift.  */
7518   if (!TARGET_USE_CLTD && !optimize_size)
7519     {
7520       if (true_regnum (operands[1]))
7521         emit_move_insn (operands[0], operands[1]);
7522       else
7523         emit_move_insn (operands[3], operands[1]);
7524       operands[4] = operands[3];
7525     }
7526   else
7527     {
7528       gcc_assert (!true_regnum (operands[1]));
7529       operands[4] = operands[1];
7530     }
7531 })
7532
7533
7534 (define_expand "divmodsi4"
7535   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7536                    (div:SI (match_operand:SI 1 "register_operand" "")
7537                            (match_operand:SI 2 "nonimmediate_operand" "")))
7538               (set (match_operand:SI 3 "register_operand" "")
7539                    (mod:SI (match_dup 1) (match_dup 2)))
7540               (clobber (reg:CC FLAGS_REG))])]
7541   ""
7542   "")
7543
7544 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7545 ;; Penalize eax case slightly because it results in worse scheduling
7546 ;; of code.
7547 (define_insn "*divmodsi4_nocltd"
7548   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7549         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7550                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7551    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7552         (mod:SI (match_dup 2) (match_dup 3)))
7553    (clobber (reg:CC FLAGS_REG))]
7554   "!optimize_size && !TARGET_USE_CLTD"
7555   "#"
7556   [(set_attr "type" "multi")])
7557
7558 (define_insn "*divmodsi4_cltd"
7559   [(set (match_operand:SI 0 "register_operand" "=a")
7560         (div:SI (match_operand:SI 2 "register_operand" "a")
7561                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7562    (set (match_operand:SI 1 "register_operand" "=&d")
7563         (mod:SI (match_dup 2) (match_dup 3)))
7564    (clobber (reg:CC FLAGS_REG))]
7565   "optimize_size || TARGET_USE_CLTD"
7566   "#"
7567   [(set_attr "type" "multi")])
7568
7569 (define_insn "*divmodsi_noext"
7570   [(set (match_operand:SI 0 "register_operand" "=a")
7571         (div:SI (match_operand:SI 1 "register_operand" "0")
7572                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7573    (set (match_operand:SI 3 "register_operand" "=d")
7574         (mod:SI (match_dup 1) (match_dup 2)))
7575    (use (match_operand:SI 4 "register_operand" "3"))
7576    (clobber (reg:CC FLAGS_REG))]
7577   ""
7578   "idiv{l}\t%2"
7579   [(set_attr "type" "idiv")
7580    (set_attr "mode" "SI")])
7581
7582 (define_split
7583   [(set (match_operand:SI 0 "register_operand" "")
7584         (div:SI (match_operand:SI 1 "register_operand" "")
7585                 (match_operand:SI 2 "nonimmediate_operand" "")))
7586    (set (match_operand:SI 3 "register_operand" "")
7587         (mod:SI (match_dup 1) (match_dup 2)))
7588    (clobber (reg:CC FLAGS_REG))]
7589   "reload_completed"
7590   [(parallel [(set (match_dup 3)
7591                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7592               (clobber (reg:CC FLAGS_REG))])
7593    (parallel [(set (match_dup 0)
7594                    (div:SI (reg:SI 0) (match_dup 2)))
7595               (set (match_dup 3)
7596                    (mod:SI (reg:SI 0) (match_dup 2)))
7597               (use (match_dup 3))
7598               (clobber (reg:CC FLAGS_REG))])]
7599 {
7600   /* Avoid use of cltd in favor of a mov+shift.  */
7601   if (!TARGET_USE_CLTD && !optimize_size)
7602     {
7603       if (true_regnum (operands[1]))
7604         emit_move_insn (operands[0], operands[1]);
7605       else
7606         emit_move_insn (operands[3], operands[1]);
7607       operands[4] = operands[3];
7608     }
7609   else
7610     {
7611       gcc_assert (!true_regnum (operands[1]));
7612       operands[4] = operands[1];
7613     }
7614 })
7615 ;; %%% Split me.
7616 (define_insn "divmodhi4"
7617   [(set (match_operand:HI 0 "register_operand" "=a")
7618         (div:HI (match_operand:HI 1 "register_operand" "0")
7619                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7620    (set (match_operand:HI 3 "register_operand" "=&d")
7621         (mod:HI (match_dup 1) (match_dup 2)))
7622    (clobber (reg:CC FLAGS_REG))]
7623   "TARGET_HIMODE_MATH"
7624   "cwtd\;idiv{w}\t%2"
7625   [(set_attr "type" "multi")
7626    (set_attr "length_immediate" "0")
7627    (set_attr "mode" "SI")])
7628
7629 (define_insn "udivmoddi4"
7630   [(set (match_operand:DI 0 "register_operand" "=a")
7631         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7632                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7633    (set (match_operand:DI 3 "register_operand" "=&d")
7634         (umod:DI (match_dup 1) (match_dup 2)))
7635    (clobber (reg:CC FLAGS_REG))]
7636   "TARGET_64BIT"
7637   "xor{q}\t%3, %3\;div{q}\t%2"
7638   [(set_attr "type" "multi")
7639    (set_attr "length_immediate" "0")
7640    (set_attr "mode" "DI")])
7641
7642 (define_insn "*udivmoddi4_noext"
7643   [(set (match_operand:DI 0 "register_operand" "=a")
7644         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7645                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7646    (set (match_operand:DI 3 "register_operand" "=d")
7647         (umod:DI (match_dup 1) (match_dup 2)))
7648    (use (match_dup 3))
7649    (clobber (reg:CC FLAGS_REG))]
7650   "TARGET_64BIT"
7651   "div{q}\t%2"
7652   [(set_attr "type" "idiv")
7653    (set_attr "mode" "DI")])
7654
7655 (define_split
7656   [(set (match_operand:DI 0 "register_operand" "")
7657         (udiv:DI (match_operand:DI 1 "register_operand" "")
7658                  (match_operand:DI 2 "nonimmediate_operand" "")))
7659    (set (match_operand:DI 3 "register_operand" "")
7660         (umod:DI (match_dup 1) (match_dup 2)))
7661    (clobber (reg:CC FLAGS_REG))]
7662   "TARGET_64BIT && reload_completed"
7663   [(set (match_dup 3) (const_int 0))
7664    (parallel [(set (match_dup 0)
7665                    (udiv:DI (match_dup 1) (match_dup 2)))
7666               (set (match_dup 3)
7667                    (umod:DI (match_dup 1) (match_dup 2)))
7668               (use (match_dup 3))
7669               (clobber (reg:CC FLAGS_REG))])]
7670   "")
7671
7672 (define_insn "udivmodsi4"
7673   [(set (match_operand:SI 0 "register_operand" "=a")
7674         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7675                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7676    (set (match_operand:SI 3 "register_operand" "=&d")
7677         (umod:SI (match_dup 1) (match_dup 2)))
7678    (clobber (reg:CC FLAGS_REG))]
7679   ""
7680   "xor{l}\t%3, %3\;div{l}\t%2"
7681   [(set_attr "type" "multi")
7682    (set_attr "length_immediate" "0")
7683    (set_attr "mode" "SI")])
7684
7685 (define_insn "*udivmodsi4_noext"
7686   [(set (match_operand:SI 0 "register_operand" "=a")
7687         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7688                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7689    (set (match_operand:SI 3 "register_operand" "=d")
7690         (umod:SI (match_dup 1) (match_dup 2)))
7691    (use (match_dup 3))
7692    (clobber (reg:CC FLAGS_REG))]
7693   ""
7694   "div{l}\t%2"
7695   [(set_attr "type" "idiv")
7696    (set_attr "mode" "SI")])
7697
7698 (define_split
7699   [(set (match_operand:SI 0 "register_operand" "")
7700         (udiv:SI (match_operand:SI 1 "register_operand" "")
7701                  (match_operand:SI 2 "nonimmediate_operand" "")))
7702    (set (match_operand:SI 3 "register_operand" "")
7703         (umod:SI (match_dup 1) (match_dup 2)))
7704    (clobber (reg:CC FLAGS_REG))]
7705   "reload_completed"
7706   [(set (match_dup 3) (const_int 0))
7707    (parallel [(set (match_dup 0)
7708                    (udiv:SI (match_dup 1) (match_dup 2)))
7709               (set (match_dup 3)
7710                    (umod:SI (match_dup 1) (match_dup 2)))
7711               (use (match_dup 3))
7712               (clobber (reg:CC FLAGS_REG))])]
7713   "")
7714
7715 (define_expand "udivmodhi4"
7716   [(set (match_dup 4) (const_int 0))
7717    (parallel [(set (match_operand:HI 0 "register_operand" "")
7718                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7719                             (match_operand:HI 2 "nonimmediate_operand" "")))
7720               (set (match_operand:HI 3 "register_operand" "")
7721                    (umod:HI (match_dup 1) (match_dup 2)))
7722               (use (match_dup 4))
7723               (clobber (reg:CC FLAGS_REG))])]
7724   "TARGET_HIMODE_MATH"
7725   "operands[4] = gen_reg_rtx (HImode);")
7726
7727 (define_insn "*udivmodhi_noext"
7728   [(set (match_operand:HI 0 "register_operand" "=a")
7729         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7730                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7731    (set (match_operand:HI 3 "register_operand" "=d")
7732         (umod:HI (match_dup 1) (match_dup 2)))
7733    (use (match_operand:HI 4 "register_operand" "3"))
7734    (clobber (reg:CC FLAGS_REG))]
7735   ""
7736   "div{w}\t%2"
7737   [(set_attr "type" "idiv")
7738    (set_attr "mode" "HI")])
7739
7740 ;; We cannot use div/idiv for double division, because it causes
7741 ;; "division by zero" on the overflow and that's not what we expect
7742 ;; from truncate.  Because true (non truncating) double division is
7743 ;; never generated, we can't create this insn anyway.
7744 ;
7745 ;(define_insn ""
7746 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7747 ;       (truncate:SI
7748 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7749 ;                  (zero_extend:DI
7750 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7751 ;   (set (match_operand:SI 3 "register_operand" "=d")
7752 ;       (truncate:SI
7753 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7754 ;   (clobber (reg:CC FLAGS_REG))]
7755 ;  ""
7756 ;  "div{l}\t{%2, %0|%0, %2}"
7757 ;  [(set_attr "type" "idiv")])
7758 \f
7759 ;;- Logical AND instructions
7760
7761 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7762 ;; Note that this excludes ah.
7763
7764 (define_insn "*testdi_1_rex64"
7765   [(set (reg FLAGS_REG)
7766         (compare
7767           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7768                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7769           (const_int 0)))]
7770   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7771    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7772   "@
7773    test{l}\t{%k1, %k0|%k0, %k1}
7774    test{l}\t{%k1, %k0|%k0, %k1}
7775    test{q}\t{%1, %0|%0, %1}
7776    test{q}\t{%1, %0|%0, %1}
7777    test{q}\t{%1, %0|%0, %1}"
7778   [(set_attr "type" "test")
7779    (set_attr "modrm" "0,1,0,1,1")
7780    (set_attr "mode" "SI,SI,DI,DI,DI")
7781    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7782
7783 (define_insn "testsi_1"
7784   [(set (reg FLAGS_REG)
7785         (compare
7786           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7787                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7788           (const_int 0)))]
7789   "ix86_match_ccmode (insn, CCNOmode)
7790    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7791   "test{l}\t{%1, %0|%0, %1}"
7792   [(set_attr "type" "test")
7793    (set_attr "modrm" "0,1,1")
7794    (set_attr "mode" "SI")
7795    (set_attr "pent_pair" "uv,np,uv")])
7796
7797 (define_expand "testsi_ccno_1"
7798   [(set (reg:CCNO FLAGS_REG)
7799         (compare:CCNO
7800           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7801                   (match_operand:SI 1 "nonmemory_operand" ""))
7802           (const_int 0)))]
7803   ""
7804   "")
7805
7806 (define_insn "*testhi_1"
7807   [(set (reg FLAGS_REG)
7808         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7809                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7810                  (const_int 0)))]
7811   "ix86_match_ccmode (insn, CCNOmode)
7812    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7813   "test{w}\t{%1, %0|%0, %1}"
7814   [(set_attr "type" "test")
7815    (set_attr "modrm" "0,1,1")
7816    (set_attr "mode" "HI")
7817    (set_attr "pent_pair" "uv,np,uv")])
7818
7819 (define_expand "testqi_ccz_1"
7820   [(set (reg:CCZ FLAGS_REG)
7821         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7822                              (match_operand:QI 1 "nonmemory_operand" ""))
7823                  (const_int 0)))]
7824   ""
7825   "")
7826
7827 (define_insn "*testqi_1_maybe_si"
7828   [(set (reg FLAGS_REG)
7829         (compare
7830           (and:QI
7831             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7832             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7833           (const_int 0)))]
7834    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7835     && ix86_match_ccmode (insn,
7836                          GET_CODE (operands[1]) == CONST_INT
7837                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7838 {
7839   if (which_alternative == 3)
7840     {
7841       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7842         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7843       return "test{l}\t{%1, %k0|%k0, %1}";
7844     }
7845   return "test{b}\t{%1, %0|%0, %1}";
7846 }
7847   [(set_attr "type" "test")
7848    (set_attr "modrm" "0,1,1,1")
7849    (set_attr "mode" "QI,QI,QI,SI")
7850    (set_attr "pent_pair" "uv,np,uv,np")])
7851
7852 (define_insn "*testqi_1"
7853   [(set (reg FLAGS_REG)
7854         (compare
7855           (and:QI
7856             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7857             (match_operand:QI 1 "general_operand" "n,n,qn"))
7858           (const_int 0)))]
7859   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7860    && ix86_match_ccmode (insn, CCNOmode)"
7861   "test{b}\t{%1, %0|%0, %1}"
7862   [(set_attr "type" "test")
7863    (set_attr "modrm" "0,1,1")
7864    (set_attr "mode" "QI")
7865    (set_attr "pent_pair" "uv,np,uv")])
7866
7867 (define_expand "testqi_ext_ccno_0"
7868   [(set (reg:CCNO FLAGS_REG)
7869         (compare:CCNO
7870           (and:SI
7871             (zero_extract:SI
7872               (match_operand 0 "ext_register_operand" "")
7873               (const_int 8)
7874               (const_int 8))
7875             (match_operand 1 "const_int_operand" ""))
7876           (const_int 0)))]
7877   ""
7878   "")
7879
7880 (define_insn "*testqi_ext_0"
7881   [(set (reg FLAGS_REG)
7882         (compare
7883           (and:SI
7884             (zero_extract:SI
7885               (match_operand 0 "ext_register_operand" "Q")
7886               (const_int 8)
7887               (const_int 8))
7888             (match_operand 1 "const_int_operand" "n"))
7889           (const_int 0)))]
7890   "ix86_match_ccmode (insn, CCNOmode)"
7891   "test{b}\t{%1, %h0|%h0, %1}"
7892   [(set_attr "type" "test")
7893    (set_attr "mode" "QI")
7894    (set_attr "length_immediate" "1")
7895    (set_attr "pent_pair" "np")])
7896
7897 (define_insn "*testqi_ext_1"
7898   [(set (reg FLAGS_REG)
7899         (compare
7900           (and:SI
7901             (zero_extract:SI
7902               (match_operand 0 "ext_register_operand" "Q")
7903               (const_int 8)
7904               (const_int 8))
7905             (zero_extend:SI
7906               (match_operand:QI 1 "general_operand" "Qm")))
7907           (const_int 0)))]
7908   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7909    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7910   "test{b}\t{%1, %h0|%h0, %1}"
7911   [(set_attr "type" "test")
7912    (set_attr "mode" "QI")])
7913
7914 (define_insn "*testqi_ext_1_rex64"
7915   [(set (reg FLAGS_REG)
7916         (compare
7917           (and:SI
7918             (zero_extract:SI
7919               (match_operand 0 "ext_register_operand" "Q")
7920               (const_int 8)
7921               (const_int 8))
7922             (zero_extend:SI
7923               (match_operand:QI 1 "register_operand" "Q")))
7924           (const_int 0)))]
7925   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7926   "test{b}\t{%1, %h0|%h0, %1}"
7927   [(set_attr "type" "test")
7928    (set_attr "mode" "QI")])
7929
7930 (define_insn "*testqi_ext_2"
7931   [(set (reg FLAGS_REG)
7932         (compare
7933           (and:SI
7934             (zero_extract:SI
7935               (match_operand 0 "ext_register_operand" "Q")
7936               (const_int 8)
7937               (const_int 8))
7938             (zero_extract:SI
7939               (match_operand 1 "ext_register_operand" "Q")
7940               (const_int 8)
7941               (const_int 8)))
7942           (const_int 0)))]
7943   "ix86_match_ccmode (insn, CCNOmode)"
7944   "test{b}\t{%h1, %h0|%h0, %h1}"
7945   [(set_attr "type" "test")
7946    (set_attr "mode" "QI")])
7947
7948 ;; Combine likes to form bit extractions for some tests.  Humor it.
7949 (define_insn "*testqi_ext_3"
7950   [(set (reg FLAGS_REG)
7951         (compare (zero_extract:SI
7952                    (match_operand 0 "nonimmediate_operand" "rm")
7953                    (match_operand:SI 1 "const_int_operand" "")
7954                    (match_operand:SI 2 "const_int_operand" ""))
7955                  (const_int 0)))]
7956   "ix86_match_ccmode (insn, CCNOmode)
7957    && INTVAL (operands[1]) > 0
7958    && INTVAL (operands[2]) >= 0
7959    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7960    && (GET_MODE (operands[0]) == SImode
7961        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7962        || GET_MODE (operands[0]) == HImode
7963        || GET_MODE (operands[0]) == QImode)"
7964   "#")
7965
7966 (define_insn "*testqi_ext_3_rex64"
7967   [(set (reg FLAGS_REG)
7968         (compare (zero_extract:DI
7969                    (match_operand 0 "nonimmediate_operand" "rm")
7970                    (match_operand:DI 1 "const_int_operand" "")
7971                    (match_operand:DI 2 "const_int_operand" ""))
7972                  (const_int 0)))]
7973   "TARGET_64BIT
7974    && ix86_match_ccmode (insn, CCNOmode)
7975    && INTVAL (operands[1]) > 0
7976    && INTVAL (operands[2]) >= 0
7977    /* Ensure that resulting mask is zero or sign extended operand.  */
7978    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7979        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7980            && INTVAL (operands[1]) > 32))
7981    && (GET_MODE (operands[0]) == SImode
7982        || GET_MODE (operands[0]) == DImode
7983        || GET_MODE (operands[0]) == HImode
7984        || GET_MODE (operands[0]) == QImode)"
7985   "#")
7986
7987 (define_split
7988   [(set (match_operand 0 "flags_reg_operand" "")
7989         (match_operator 1 "compare_operator"
7990           [(zero_extract
7991              (match_operand 2 "nonimmediate_operand" "")
7992              (match_operand 3 "const_int_operand" "")
7993              (match_operand 4 "const_int_operand" ""))
7994            (const_int 0)]))]
7995   "ix86_match_ccmode (insn, CCNOmode)"
7996   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7997 {
7998   rtx val = operands[2];
7999   HOST_WIDE_INT len = INTVAL (operands[3]);
8000   HOST_WIDE_INT pos = INTVAL (operands[4]);
8001   HOST_WIDE_INT mask;
8002   enum machine_mode mode, submode;
8003
8004   mode = GET_MODE (val);
8005   if (GET_CODE (val) == MEM)
8006     {
8007       /* ??? Combine likes to put non-volatile mem extractions in QImode
8008          no matter the size of the test.  So find a mode that works.  */
8009       if (! MEM_VOLATILE_P (val))
8010         {
8011           mode = smallest_mode_for_size (pos + len, MODE_INT);
8012           val = adjust_address (val, mode, 0);
8013         }
8014     }
8015   else if (GET_CODE (val) == SUBREG
8016            && (submode = GET_MODE (SUBREG_REG (val)),
8017                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8018            && pos + len <= GET_MODE_BITSIZE (submode))
8019     {
8020       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8021       mode = submode;
8022       val = SUBREG_REG (val);
8023     }
8024   else if (mode == HImode && pos + len <= 8)
8025     {
8026       /* Small HImode tests can be converted to QImode.  */
8027       mode = QImode;
8028       val = gen_lowpart (QImode, val);
8029     }
8030
8031   if (len == HOST_BITS_PER_WIDE_INT)
8032     mask = -1;
8033   else
8034     mask = ((HOST_WIDE_INT)1 << len) - 1;
8035   mask <<= pos;
8036
8037   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8038 })
8039
8040 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8041 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8042 ;; this is relatively important trick.
8043 ;; Do the conversion only post-reload to avoid limiting of the register class
8044 ;; to QI regs.
8045 (define_split
8046   [(set (match_operand 0 "flags_reg_operand" "")
8047         (match_operator 1 "compare_operator"
8048           [(and (match_operand 2 "register_operand" "")
8049                 (match_operand 3 "const_int_operand" ""))
8050            (const_int 0)]))]
8051    "reload_completed
8052     && QI_REG_P (operands[2])
8053     && GET_MODE (operands[2]) != QImode
8054     && ((ix86_match_ccmode (insn, CCZmode)
8055          && !(INTVAL (operands[3]) & ~(255 << 8)))
8056         || (ix86_match_ccmode (insn, CCNOmode)
8057             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8058   [(set (match_dup 0)
8059         (match_op_dup 1
8060           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8061                    (match_dup 3))
8062            (const_int 0)]))]
8063   "operands[2] = gen_lowpart (SImode, operands[2]);
8064    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8065
8066 (define_split
8067   [(set (match_operand 0 "flags_reg_operand" "")
8068         (match_operator 1 "compare_operator"
8069           [(and (match_operand 2 "nonimmediate_operand" "")
8070                 (match_operand 3 "const_int_operand" ""))
8071            (const_int 0)]))]
8072    "reload_completed
8073     && GET_MODE (operands[2]) != QImode
8074     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8075     && ((ix86_match_ccmode (insn, CCZmode)
8076          && !(INTVAL (operands[3]) & ~255))
8077         || (ix86_match_ccmode (insn, CCNOmode)
8078             && !(INTVAL (operands[3]) & ~127)))"
8079   [(set (match_dup 0)
8080         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8081                          (const_int 0)]))]
8082   "operands[2] = gen_lowpart (QImode, operands[2]);
8083    operands[3] = gen_lowpart (QImode, operands[3]);")
8084
8085
8086 ;; %%% This used to optimize known byte-wide and operations to memory,
8087 ;; and sometimes to QImode registers.  If this is considered useful,
8088 ;; it should be done with splitters.
8089
8090 (define_expand "anddi3"
8091   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8092         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8093                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8094    (clobber (reg:CC FLAGS_REG))]
8095   "TARGET_64BIT"
8096   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8097
8098 (define_insn "*anddi_1_rex64"
8099   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8100         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8101                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8102    (clobber (reg:CC FLAGS_REG))]
8103   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8104 {
8105   switch (get_attr_type (insn))
8106     {
8107     case TYPE_IMOVX:
8108       {
8109         enum machine_mode mode;
8110
8111         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8112         if (INTVAL (operands[2]) == 0xff)
8113           mode = QImode;
8114         else
8115           {
8116             gcc_assert (INTVAL (operands[2]) == 0xffff);
8117             mode = HImode;
8118           }
8119
8120         operands[1] = gen_lowpart (mode, operands[1]);
8121         if (mode == QImode)
8122           return "movz{bq|x}\t{%1,%0|%0, %1}";
8123         else
8124           return "movz{wq|x}\t{%1,%0|%0, %1}";
8125       }
8126
8127     default:
8128       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8129       if (get_attr_mode (insn) == MODE_SI)
8130         return "and{l}\t{%k2, %k0|%k0, %k2}";
8131       else
8132         return "and{q}\t{%2, %0|%0, %2}";
8133     }
8134 }
8135   [(set_attr "type" "alu,alu,alu,imovx")
8136    (set_attr "length_immediate" "*,*,*,0")
8137    (set_attr "mode" "SI,DI,DI,DI")])
8138
8139 (define_insn "*anddi_2"
8140   [(set (reg FLAGS_REG)
8141         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8142                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8143                  (const_int 0)))
8144    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8145         (and:DI (match_dup 1) (match_dup 2)))]
8146   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8147    && ix86_binary_operator_ok (AND, DImode, operands)"
8148   "@
8149    and{l}\t{%k2, %k0|%k0, %k2}
8150    and{q}\t{%2, %0|%0, %2}
8151    and{q}\t{%2, %0|%0, %2}"
8152   [(set_attr "type" "alu")
8153    (set_attr "mode" "SI,DI,DI")])
8154
8155 (define_expand "andsi3"
8156   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8157         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8158                 (match_operand:SI 2 "general_operand" "")))
8159    (clobber (reg:CC FLAGS_REG))]
8160   ""
8161   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8162
8163 (define_insn "*andsi_1"
8164   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8165         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8166                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8167    (clobber (reg:CC FLAGS_REG))]
8168   "ix86_binary_operator_ok (AND, SImode, operands)"
8169 {
8170   switch (get_attr_type (insn))
8171     {
8172     case TYPE_IMOVX:
8173       {
8174         enum machine_mode mode;
8175
8176         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8177         if (INTVAL (operands[2]) == 0xff)
8178           mode = QImode;
8179         else
8180           {
8181             gcc_assert (INTVAL (operands[2]) == 0xffff);
8182             mode = HImode;
8183           }
8184
8185         operands[1] = gen_lowpart (mode, operands[1]);
8186         if (mode == QImode)
8187           return "movz{bl|x}\t{%1,%0|%0, %1}";
8188         else
8189           return "movz{wl|x}\t{%1,%0|%0, %1}";
8190       }
8191
8192     default:
8193       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8194       return "and{l}\t{%2, %0|%0, %2}";
8195     }
8196 }
8197   [(set_attr "type" "alu,alu,imovx")
8198    (set_attr "length_immediate" "*,*,0")
8199    (set_attr "mode" "SI")])
8200
8201 (define_split
8202   [(set (match_operand 0 "register_operand" "")
8203         (and (match_dup 0)
8204              (const_int -65536)))
8205    (clobber (reg:CC FLAGS_REG))]
8206   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8207   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8208   "operands[1] = gen_lowpart (HImode, operands[0]);")
8209
8210 (define_split
8211   [(set (match_operand 0 "ext_register_operand" "")
8212         (and (match_dup 0)
8213              (const_int -256)))
8214    (clobber (reg:CC FLAGS_REG))]
8215   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8216   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8217   "operands[1] = gen_lowpart (QImode, operands[0]);")
8218
8219 (define_split
8220   [(set (match_operand 0 "ext_register_operand" "")
8221         (and (match_dup 0)
8222              (const_int -65281)))
8223    (clobber (reg:CC FLAGS_REG))]
8224   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8225   [(parallel [(set (zero_extract:SI (match_dup 0)
8226                                     (const_int 8)
8227                                     (const_int 8))
8228                    (xor:SI
8229                      (zero_extract:SI (match_dup 0)
8230                                       (const_int 8)
8231                                       (const_int 8))
8232                      (zero_extract:SI (match_dup 0)
8233                                       (const_int 8)
8234                                       (const_int 8))))
8235               (clobber (reg:CC FLAGS_REG))])]
8236   "operands[0] = gen_lowpart (SImode, operands[0]);")
8237
8238 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8239 (define_insn "*andsi_1_zext"
8240   [(set (match_operand:DI 0 "register_operand" "=r")
8241         (zero_extend:DI
8242           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8243                   (match_operand:SI 2 "general_operand" "rim"))))
8244    (clobber (reg:CC FLAGS_REG))]
8245   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8246   "and{l}\t{%2, %k0|%k0, %2}"
8247   [(set_attr "type" "alu")
8248    (set_attr "mode" "SI")])
8249
8250 (define_insn "*andsi_2"
8251   [(set (reg FLAGS_REG)
8252         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8253                          (match_operand:SI 2 "general_operand" "rim,ri"))
8254                  (const_int 0)))
8255    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8256         (and:SI (match_dup 1) (match_dup 2)))]
8257   "ix86_match_ccmode (insn, CCNOmode)
8258    && ix86_binary_operator_ok (AND, SImode, operands)"
8259   "and{l}\t{%2, %0|%0, %2}"
8260   [(set_attr "type" "alu")
8261    (set_attr "mode" "SI")])
8262
8263 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8264 (define_insn "*andsi_2_zext"
8265   [(set (reg FLAGS_REG)
8266         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8267                          (match_operand:SI 2 "general_operand" "rim"))
8268                  (const_int 0)))
8269    (set (match_operand:DI 0 "register_operand" "=r")
8270         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8271   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8272    && ix86_binary_operator_ok (AND, SImode, operands)"
8273   "and{l}\t{%2, %k0|%k0, %2}"
8274   [(set_attr "type" "alu")
8275    (set_attr "mode" "SI")])
8276
8277 (define_expand "andhi3"
8278   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8279         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8280                 (match_operand:HI 2 "general_operand" "")))
8281    (clobber (reg:CC FLAGS_REG))]
8282   "TARGET_HIMODE_MATH"
8283   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8284
8285 (define_insn "*andhi_1"
8286   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8287         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8288                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8289    (clobber (reg:CC FLAGS_REG))]
8290   "ix86_binary_operator_ok (AND, HImode, operands)"
8291 {
8292   switch (get_attr_type (insn))
8293     {
8294     case TYPE_IMOVX:
8295       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8296       gcc_assert (INTVAL (operands[2]) == 0xff);
8297       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8298
8299     default:
8300       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8301
8302       return "and{w}\t{%2, %0|%0, %2}";
8303     }
8304 }
8305   [(set_attr "type" "alu,alu,imovx")
8306    (set_attr "length_immediate" "*,*,0")
8307    (set_attr "mode" "HI,HI,SI")])
8308
8309 (define_insn "*andhi_2"
8310   [(set (reg FLAGS_REG)
8311         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8312                          (match_operand:HI 2 "general_operand" "rim,ri"))
8313                  (const_int 0)))
8314    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8315         (and:HI (match_dup 1) (match_dup 2)))]
8316   "ix86_match_ccmode (insn, CCNOmode)
8317    && ix86_binary_operator_ok (AND, HImode, operands)"
8318   "and{w}\t{%2, %0|%0, %2}"
8319   [(set_attr "type" "alu")
8320    (set_attr "mode" "HI")])
8321
8322 (define_expand "andqi3"
8323   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8324         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8325                 (match_operand:QI 2 "general_operand" "")))
8326    (clobber (reg:CC FLAGS_REG))]
8327   "TARGET_QIMODE_MATH"
8328   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8329
8330 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8331 (define_insn "*andqi_1"
8332   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8333         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8334                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8335    (clobber (reg:CC FLAGS_REG))]
8336   "ix86_binary_operator_ok (AND, QImode, operands)"
8337   "@
8338    and{b}\t{%2, %0|%0, %2}
8339    and{b}\t{%2, %0|%0, %2}
8340    and{l}\t{%k2, %k0|%k0, %k2}"
8341   [(set_attr "type" "alu")
8342    (set_attr "mode" "QI,QI,SI")])
8343
8344 (define_insn "*andqi_1_slp"
8345   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8346         (and:QI (match_dup 0)
8347                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8348    (clobber (reg:CC FLAGS_REG))]
8349   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8350    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8351   "and{b}\t{%1, %0|%0, %1}"
8352   [(set_attr "type" "alu1")
8353    (set_attr "mode" "QI")])
8354
8355 (define_insn "*andqi_2_maybe_si"
8356   [(set (reg FLAGS_REG)
8357         (compare (and:QI
8358                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8359                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8360                  (const_int 0)))
8361    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8362         (and:QI (match_dup 1) (match_dup 2)))]
8363   "ix86_binary_operator_ok (AND, QImode, operands)
8364    && ix86_match_ccmode (insn,
8365                          GET_CODE (operands[2]) == CONST_INT
8366                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8367 {
8368   if (which_alternative == 2)
8369     {
8370       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8371         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8372       return "and{l}\t{%2, %k0|%k0, %2}";
8373     }
8374   return "and{b}\t{%2, %0|%0, %2}";
8375 }
8376   [(set_attr "type" "alu")
8377    (set_attr "mode" "QI,QI,SI")])
8378
8379 (define_insn "*andqi_2"
8380   [(set (reg FLAGS_REG)
8381         (compare (and:QI
8382                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8383                    (match_operand:QI 2 "general_operand" "qim,qi"))
8384                  (const_int 0)))
8385    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8386         (and:QI (match_dup 1) (match_dup 2)))]
8387   "ix86_match_ccmode (insn, CCNOmode)
8388    && ix86_binary_operator_ok (AND, QImode, operands)"
8389   "and{b}\t{%2, %0|%0, %2}"
8390   [(set_attr "type" "alu")
8391    (set_attr "mode" "QI")])
8392
8393 (define_insn "*andqi_2_slp"
8394   [(set (reg FLAGS_REG)
8395         (compare (and:QI
8396                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8397                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8398                  (const_int 0)))
8399    (set (strict_low_part (match_dup 0))
8400         (and:QI (match_dup 0) (match_dup 1)))]
8401   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8402    && ix86_match_ccmode (insn, CCNOmode)
8403    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8404   "and{b}\t{%1, %0|%0, %1}"
8405   [(set_attr "type" "alu1")
8406    (set_attr "mode" "QI")])
8407
8408 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8409 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8410 ;; for a QImode operand, which of course failed.
8411
8412 (define_insn "andqi_ext_0"
8413   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8414                          (const_int 8)
8415                          (const_int 8))
8416         (and:SI
8417           (zero_extract:SI
8418             (match_operand 1 "ext_register_operand" "0")
8419             (const_int 8)
8420             (const_int 8))
8421           (match_operand 2 "const_int_operand" "n")))
8422    (clobber (reg:CC FLAGS_REG))]
8423   ""
8424   "and{b}\t{%2, %h0|%h0, %2}"
8425   [(set_attr "type" "alu")
8426    (set_attr "length_immediate" "1")
8427    (set_attr "mode" "QI")])
8428
8429 ;; Generated by peephole translating test to and.  This shows up
8430 ;; often in fp comparisons.
8431
8432 (define_insn "*andqi_ext_0_cc"
8433   [(set (reg FLAGS_REG)
8434         (compare
8435           (and:SI
8436             (zero_extract:SI
8437               (match_operand 1 "ext_register_operand" "0")
8438               (const_int 8)
8439               (const_int 8))
8440             (match_operand 2 "const_int_operand" "n"))
8441           (const_int 0)))
8442    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8443                          (const_int 8)
8444                          (const_int 8))
8445         (and:SI
8446           (zero_extract:SI
8447             (match_dup 1)
8448             (const_int 8)
8449             (const_int 8))
8450           (match_dup 2)))]
8451   "ix86_match_ccmode (insn, CCNOmode)"
8452   "and{b}\t{%2, %h0|%h0, %2}"
8453   [(set_attr "type" "alu")
8454    (set_attr "length_immediate" "1")
8455    (set_attr "mode" "QI")])
8456
8457 (define_insn "*andqi_ext_1"
8458   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8459                          (const_int 8)
8460                          (const_int 8))
8461         (and:SI
8462           (zero_extract:SI
8463             (match_operand 1 "ext_register_operand" "0")
8464             (const_int 8)
8465             (const_int 8))
8466           (zero_extend:SI
8467             (match_operand:QI 2 "general_operand" "Qm"))))
8468    (clobber (reg:CC FLAGS_REG))]
8469   "!TARGET_64BIT"
8470   "and{b}\t{%2, %h0|%h0, %2}"
8471   [(set_attr "type" "alu")
8472    (set_attr "length_immediate" "0")
8473    (set_attr "mode" "QI")])
8474
8475 (define_insn "*andqi_ext_1_rex64"
8476   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8477                          (const_int 8)
8478                          (const_int 8))
8479         (and:SI
8480           (zero_extract:SI
8481             (match_operand 1 "ext_register_operand" "0")
8482             (const_int 8)
8483             (const_int 8))
8484           (zero_extend:SI
8485             (match_operand 2 "ext_register_operand" "Q"))))
8486    (clobber (reg:CC FLAGS_REG))]
8487   "TARGET_64BIT"
8488   "and{b}\t{%2, %h0|%h0, %2}"
8489   [(set_attr "type" "alu")
8490    (set_attr "length_immediate" "0")
8491    (set_attr "mode" "QI")])
8492
8493 (define_insn "*andqi_ext_2"
8494   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8495                          (const_int 8)
8496                          (const_int 8))
8497         (and:SI
8498           (zero_extract:SI
8499             (match_operand 1 "ext_register_operand" "%0")
8500             (const_int 8)
8501             (const_int 8))
8502           (zero_extract:SI
8503             (match_operand 2 "ext_register_operand" "Q")
8504             (const_int 8)
8505             (const_int 8))))
8506    (clobber (reg:CC FLAGS_REG))]
8507   ""
8508   "and{b}\t{%h2, %h0|%h0, %h2}"
8509   [(set_attr "type" "alu")
8510    (set_attr "length_immediate" "0")
8511    (set_attr "mode" "QI")])
8512
8513 ;; Convert wide AND instructions with immediate operand to shorter QImode
8514 ;; equivalents when possible.
8515 ;; Don't do the splitting with memory operands, since it introduces risk
8516 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8517 ;; for size, but that can (should?) be handled by generic code instead.
8518 (define_split
8519   [(set (match_operand 0 "register_operand" "")
8520         (and (match_operand 1 "register_operand" "")
8521              (match_operand 2 "const_int_operand" "")))
8522    (clobber (reg:CC FLAGS_REG))]
8523    "reload_completed
8524     && QI_REG_P (operands[0])
8525     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8526     && !(~INTVAL (operands[2]) & ~(255 << 8))
8527     && GET_MODE (operands[0]) != QImode"
8528   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8529                    (and:SI (zero_extract:SI (match_dup 1)
8530                                             (const_int 8) (const_int 8))
8531                            (match_dup 2)))
8532               (clobber (reg:CC FLAGS_REG))])]
8533   "operands[0] = gen_lowpart (SImode, operands[0]);
8534    operands[1] = gen_lowpart (SImode, operands[1]);
8535    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8536
8537 ;; Since AND can be encoded with sign extended immediate, this is only
8538 ;; profitable when 7th bit is not set.
8539 (define_split
8540   [(set (match_operand 0 "register_operand" "")
8541         (and (match_operand 1 "general_operand" "")
8542              (match_operand 2 "const_int_operand" "")))
8543    (clobber (reg:CC FLAGS_REG))]
8544    "reload_completed
8545     && ANY_QI_REG_P (operands[0])
8546     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8547     && !(~INTVAL (operands[2]) & ~255)
8548     && !(INTVAL (operands[2]) & 128)
8549     && GET_MODE (operands[0]) != QImode"
8550   [(parallel [(set (strict_low_part (match_dup 0))
8551                    (and:QI (match_dup 1)
8552                            (match_dup 2)))
8553               (clobber (reg:CC FLAGS_REG))])]
8554   "operands[0] = gen_lowpart (QImode, operands[0]);
8555    operands[1] = gen_lowpart (QImode, operands[1]);
8556    operands[2] = gen_lowpart (QImode, operands[2]);")
8557 \f
8558 ;; Logical inclusive OR instructions
8559
8560 ;; %%% This used to optimize known byte-wide and operations to memory.
8561 ;; If this is considered useful, it should be done with splitters.
8562
8563 (define_expand "iordi3"
8564   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8565         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8566                 (match_operand:DI 2 "x86_64_general_operand" "")))
8567    (clobber (reg:CC FLAGS_REG))]
8568   "TARGET_64BIT"
8569   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8570
8571 (define_insn "*iordi_1_rex64"
8572   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8573         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8574                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8575    (clobber (reg:CC FLAGS_REG))]
8576   "TARGET_64BIT
8577    && ix86_binary_operator_ok (IOR, DImode, operands)"
8578   "or{q}\t{%2, %0|%0, %2}"
8579   [(set_attr "type" "alu")
8580    (set_attr "mode" "DI")])
8581
8582 (define_insn "*iordi_2_rex64"
8583   [(set (reg FLAGS_REG)
8584         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8585                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8586                  (const_int 0)))
8587    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8588         (ior:DI (match_dup 1) (match_dup 2)))]
8589   "TARGET_64BIT
8590    && ix86_match_ccmode (insn, CCNOmode)
8591    && ix86_binary_operator_ok (IOR, DImode, operands)"
8592   "or{q}\t{%2, %0|%0, %2}"
8593   [(set_attr "type" "alu")
8594    (set_attr "mode" "DI")])
8595
8596 (define_insn "*iordi_3_rex64"
8597   [(set (reg FLAGS_REG)
8598         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8599                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8600                  (const_int 0)))
8601    (clobber (match_scratch:DI 0 "=r"))]
8602   "TARGET_64BIT
8603    && ix86_match_ccmode (insn, CCNOmode)
8604    && ix86_binary_operator_ok (IOR, DImode, operands)"
8605   "or{q}\t{%2, %0|%0, %2}"
8606   [(set_attr "type" "alu")
8607    (set_attr "mode" "DI")])
8608
8609
8610 (define_expand "iorsi3"
8611   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8612         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8613                 (match_operand:SI 2 "general_operand" "")))
8614    (clobber (reg:CC FLAGS_REG))]
8615   ""
8616   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8617
8618 (define_insn "*iorsi_1"
8619   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8620         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8621                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8622    (clobber (reg:CC FLAGS_REG))]
8623   "ix86_binary_operator_ok (IOR, SImode, operands)"
8624   "or{l}\t{%2, %0|%0, %2}"
8625   [(set_attr "type" "alu")
8626    (set_attr "mode" "SI")])
8627
8628 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8629 (define_insn "*iorsi_1_zext"
8630   [(set (match_operand:DI 0 "register_operand" "=rm")
8631         (zero_extend:DI
8632           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8633                   (match_operand:SI 2 "general_operand" "rim"))))
8634    (clobber (reg:CC FLAGS_REG))]
8635   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8636   "or{l}\t{%2, %k0|%k0, %2}"
8637   [(set_attr "type" "alu")
8638    (set_attr "mode" "SI")])
8639
8640 (define_insn "*iorsi_1_zext_imm"
8641   [(set (match_operand:DI 0 "register_operand" "=rm")
8642         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8643                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8644    (clobber (reg:CC FLAGS_REG))]
8645   "TARGET_64BIT"
8646   "or{l}\t{%2, %k0|%k0, %2}"
8647   [(set_attr "type" "alu")
8648    (set_attr "mode" "SI")])
8649
8650 (define_insn "*iorsi_2"
8651   [(set (reg FLAGS_REG)
8652         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8653                          (match_operand:SI 2 "general_operand" "rim,ri"))
8654                  (const_int 0)))
8655    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8656         (ior:SI (match_dup 1) (match_dup 2)))]
8657   "ix86_match_ccmode (insn, CCNOmode)
8658    && ix86_binary_operator_ok (IOR, SImode, operands)"
8659   "or{l}\t{%2, %0|%0, %2}"
8660   [(set_attr "type" "alu")
8661    (set_attr "mode" "SI")])
8662
8663 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8664 ;; ??? Special case for immediate operand is missing - it is tricky.
8665 (define_insn "*iorsi_2_zext"
8666   [(set (reg FLAGS_REG)
8667         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8668                          (match_operand:SI 2 "general_operand" "rim"))
8669                  (const_int 0)))
8670    (set (match_operand:DI 0 "register_operand" "=r")
8671         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8672   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8673    && ix86_binary_operator_ok (IOR, SImode, operands)"
8674   "or{l}\t{%2, %k0|%k0, %2}"
8675   [(set_attr "type" "alu")
8676    (set_attr "mode" "SI")])
8677
8678 (define_insn "*iorsi_2_zext_imm"
8679   [(set (reg FLAGS_REG)
8680         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8681                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8682                  (const_int 0)))
8683    (set (match_operand:DI 0 "register_operand" "=r")
8684         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8685   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8686    && ix86_binary_operator_ok (IOR, SImode, operands)"
8687   "or{l}\t{%2, %k0|%k0, %2}"
8688   [(set_attr "type" "alu")
8689    (set_attr "mode" "SI")])
8690
8691 (define_insn "*iorsi_3"
8692   [(set (reg FLAGS_REG)
8693         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8694                          (match_operand:SI 2 "general_operand" "rim"))
8695                  (const_int 0)))
8696    (clobber (match_scratch:SI 0 "=r"))]
8697   "ix86_match_ccmode (insn, CCNOmode)
8698    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8699   "or{l}\t{%2, %0|%0, %2}"
8700   [(set_attr "type" "alu")
8701    (set_attr "mode" "SI")])
8702
8703 (define_expand "iorhi3"
8704   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8705         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8706                 (match_operand:HI 2 "general_operand" "")))
8707    (clobber (reg:CC FLAGS_REG))]
8708   "TARGET_HIMODE_MATH"
8709   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8710
8711 (define_insn "*iorhi_1"
8712   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8713         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8714                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8715    (clobber (reg:CC FLAGS_REG))]
8716   "ix86_binary_operator_ok (IOR, HImode, operands)"
8717   "or{w}\t{%2, %0|%0, %2}"
8718   [(set_attr "type" "alu")
8719    (set_attr "mode" "HI")])
8720
8721 (define_insn "*iorhi_2"
8722   [(set (reg FLAGS_REG)
8723         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8724                          (match_operand:HI 2 "general_operand" "rim,ri"))
8725                  (const_int 0)))
8726    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8727         (ior:HI (match_dup 1) (match_dup 2)))]
8728   "ix86_match_ccmode (insn, CCNOmode)
8729    && ix86_binary_operator_ok (IOR, HImode, operands)"
8730   "or{w}\t{%2, %0|%0, %2}"
8731   [(set_attr "type" "alu")
8732    (set_attr "mode" "HI")])
8733
8734 (define_insn "*iorhi_3"
8735   [(set (reg FLAGS_REG)
8736         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8737                          (match_operand:HI 2 "general_operand" "rim"))
8738                  (const_int 0)))
8739    (clobber (match_scratch:HI 0 "=r"))]
8740   "ix86_match_ccmode (insn, CCNOmode)
8741    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8742   "or{w}\t{%2, %0|%0, %2}"
8743   [(set_attr "type" "alu")
8744    (set_attr "mode" "HI")])
8745
8746 (define_expand "iorqi3"
8747   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8748         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8749                 (match_operand:QI 2 "general_operand" "")))
8750    (clobber (reg:CC FLAGS_REG))]
8751   "TARGET_QIMODE_MATH"
8752   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8753
8754 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8755 (define_insn "*iorqi_1"
8756   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8757         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8758                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8759    (clobber (reg:CC FLAGS_REG))]
8760   "ix86_binary_operator_ok (IOR, QImode, operands)"
8761   "@
8762    or{b}\t{%2, %0|%0, %2}
8763    or{b}\t{%2, %0|%0, %2}
8764    or{l}\t{%k2, %k0|%k0, %k2}"
8765   [(set_attr "type" "alu")
8766    (set_attr "mode" "QI,QI,SI")])
8767
8768 (define_insn "*iorqi_1_slp"
8769   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8770         (ior:QI (match_dup 0)
8771                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8772    (clobber (reg:CC FLAGS_REG))]
8773   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8774    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8775   "or{b}\t{%1, %0|%0, %1}"
8776   [(set_attr "type" "alu1")
8777    (set_attr "mode" "QI")])
8778
8779 (define_insn "*iorqi_2"
8780   [(set (reg FLAGS_REG)
8781         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8782                          (match_operand:QI 2 "general_operand" "qim,qi"))
8783                  (const_int 0)))
8784    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8785         (ior:QI (match_dup 1) (match_dup 2)))]
8786   "ix86_match_ccmode (insn, CCNOmode)
8787    && ix86_binary_operator_ok (IOR, QImode, operands)"
8788   "or{b}\t{%2, %0|%0, %2}"
8789   [(set_attr "type" "alu")
8790    (set_attr "mode" "QI")])
8791
8792 (define_insn "*iorqi_2_slp"
8793   [(set (reg FLAGS_REG)
8794         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8795                          (match_operand:QI 1 "general_operand" "qim,qi"))
8796                  (const_int 0)))
8797    (set (strict_low_part (match_dup 0))
8798         (ior:QI (match_dup 0) (match_dup 1)))]
8799   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8800    && ix86_match_ccmode (insn, CCNOmode)
8801    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8802   "or{b}\t{%1, %0|%0, %1}"
8803   [(set_attr "type" "alu1")
8804    (set_attr "mode" "QI")])
8805
8806 (define_insn "*iorqi_3"
8807   [(set (reg FLAGS_REG)
8808         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8809                          (match_operand:QI 2 "general_operand" "qim"))
8810                  (const_int 0)))
8811    (clobber (match_scratch:QI 0 "=q"))]
8812   "ix86_match_ccmode (insn, CCNOmode)
8813    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8814   "or{b}\t{%2, %0|%0, %2}"
8815   [(set_attr "type" "alu")
8816    (set_attr "mode" "QI")])
8817
8818 (define_insn "iorqi_ext_0"
8819   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8820                          (const_int 8)
8821                          (const_int 8))
8822         (ior:SI
8823           (zero_extract:SI
8824             (match_operand 1 "ext_register_operand" "0")
8825             (const_int 8)
8826             (const_int 8))
8827           (match_operand 2 "const_int_operand" "n")))
8828    (clobber (reg:CC FLAGS_REG))]
8829   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8830   "or{b}\t{%2, %h0|%h0, %2}"
8831   [(set_attr "type" "alu")
8832    (set_attr "length_immediate" "1")
8833    (set_attr "mode" "QI")])
8834
8835 (define_insn "*iorqi_ext_1"
8836   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8837                          (const_int 8)
8838                          (const_int 8))
8839         (ior:SI
8840           (zero_extract:SI
8841             (match_operand 1 "ext_register_operand" "0")
8842             (const_int 8)
8843             (const_int 8))
8844           (zero_extend:SI
8845             (match_operand:QI 2 "general_operand" "Qm"))))
8846    (clobber (reg:CC FLAGS_REG))]
8847   "!TARGET_64BIT
8848    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8849   "or{b}\t{%2, %h0|%h0, %2}"
8850   [(set_attr "type" "alu")
8851    (set_attr "length_immediate" "0")
8852    (set_attr "mode" "QI")])
8853
8854 (define_insn "*iorqi_ext_1_rex64"
8855   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8856                          (const_int 8)
8857                          (const_int 8))
8858         (ior:SI
8859           (zero_extract:SI
8860             (match_operand 1 "ext_register_operand" "0")
8861             (const_int 8)
8862             (const_int 8))
8863           (zero_extend:SI
8864             (match_operand 2 "ext_register_operand" "Q"))))
8865    (clobber (reg:CC FLAGS_REG))]
8866   "TARGET_64BIT
8867    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8868   "or{b}\t{%2, %h0|%h0, %2}"
8869   [(set_attr "type" "alu")
8870    (set_attr "length_immediate" "0")
8871    (set_attr "mode" "QI")])
8872
8873 (define_insn "*iorqi_ext_2"
8874   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8875                          (const_int 8)
8876                          (const_int 8))
8877         (ior:SI
8878           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8879                            (const_int 8)
8880                            (const_int 8))
8881           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8882                            (const_int 8)
8883                            (const_int 8))))
8884    (clobber (reg:CC FLAGS_REG))]
8885   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8886   "ior{b}\t{%h2, %h0|%h0, %h2}"
8887   [(set_attr "type" "alu")
8888    (set_attr "length_immediate" "0")
8889    (set_attr "mode" "QI")])
8890
8891 (define_split
8892   [(set (match_operand 0 "register_operand" "")
8893         (ior (match_operand 1 "register_operand" "")
8894              (match_operand 2 "const_int_operand" "")))
8895    (clobber (reg:CC FLAGS_REG))]
8896    "reload_completed
8897     && QI_REG_P (operands[0])
8898     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8899     && !(INTVAL (operands[2]) & ~(255 << 8))
8900     && GET_MODE (operands[0]) != QImode"
8901   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8902                    (ior:SI (zero_extract:SI (match_dup 1)
8903                                             (const_int 8) (const_int 8))
8904                            (match_dup 2)))
8905               (clobber (reg:CC FLAGS_REG))])]
8906   "operands[0] = gen_lowpart (SImode, operands[0]);
8907    operands[1] = gen_lowpart (SImode, operands[1]);
8908    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8909
8910 ;; Since OR can be encoded with sign extended immediate, this is only
8911 ;; profitable when 7th bit is set.
8912 (define_split
8913   [(set (match_operand 0 "register_operand" "")
8914         (ior (match_operand 1 "general_operand" "")
8915              (match_operand 2 "const_int_operand" "")))
8916    (clobber (reg:CC FLAGS_REG))]
8917    "reload_completed
8918     && ANY_QI_REG_P (operands[0])
8919     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8920     && !(INTVAL (operands[2]) & ~255)
8921     && (INTVAL (operands[2]) & 128)
8922     && GET_MODE (operands[0]) != QImode"
8923   [(parallel [(set (strict_low_part (match_dup 0))
8924                    (ior:QI (match_dup 1)
8925                            (match_dup 2)))
8926               (clobber (reg:CC FLAGS_REG))])]
8927   "operands[0] = gen_lowpart (QImode, operands[0]);
8928    operands[1] = gen_lowpart (QImode, operands[1]);
8929    operands[2] = gen_lowpart (QImode, operands[2]);")
8930 \f
8931 ;; Logical XOR instructions
8932
8933 ;; %%% This used to optimize known byte-wide and operations to memory.
8934 ;; If this is considered useful, it should be done with splitters.
8935
8936 (define_expand "xordi3"
8937   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8938         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8939                 (match_operand:DI 2 "x86_64_general_operand" "")))
8940    (clobber (reg:CC FLAGS_REG))]
8941   "TARGET_64BIT"
8942   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8943
8944 (define_insn "*xordi_1_rex64"
8945   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8946         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8947                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8948    (clobber (reg:CC FLAGS_REG))]
8949   "TARGET_64BIT
8950    && ix86_binary_operator_ok (XOR, DImode, operands)"
8951   "@
8952    xor{q}\t{%2, %0|%0, %2}
8953    xor{q}\t{%2, %0|%0, %2}"
8954   [(set_attr "type" "alu")
8955    (set_attr "mode" "DI,DI")])
8956
8957 (define_insn "*xordi_2_rex64"
8958   [(set (reg FLAGS_REG)
8959         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8960                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8961                  (const_int 0)))
8962    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8963         (xor:DI (match_dup 1) (match_dup 2)))]
8964   "TARGET_64BIT
8965    && ix86_match_ccmode (insn, CCNOmode)
8966    && ix86_binary_operator_ok (XOR, DImode, operands)"
8967   "@
8968    xor{q}\t{%2, %0|%0, %2}
8969    xor{q}\t{%2, %0|%0, %2}"
8970   [(set_attr "type" "alu")
8971    (set_attr "mode" "DI,DI")])
8972
8973 (define_insn "*xordi_3_rex64"
8974   [(set (reg FLAGS_REG)
8975         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8976                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8977                  (const_int 0)))
8978    (clobber (match_scratch:DI 0 "=r"))]
8979   "TARGET_64BIT
8980    && ix86_match_ccmode (insn, CCNOmode)
8981    && ix86_binary_operator_ok (XOR, DImode, operands)"
8982   "xor{q}\t{%2, %0|%0, %2}"
8983   [(set_attr "type" "alu")
8984    (set_attr "mode" "DI")])
8985
8986 (define_expand "xorsi3"
8987   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8988         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8989                 (match_operand:SI 2 "general_operand" "")))
8990    (clobber (reg:CC FLAGS_REG))]
8991   ""
8992   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8993
8994 (define_insn "*xorsi_1"
8995   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8996         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8997                 (match_operand:SI 2 "general_operand" "ri,rm")))
8998    (clobber (reg:CC FLAGS_REG))]
8999   "ix86_binary_operator_ok (XOR, SImode, operands)"
9000   "xor{l}\t{%2, %0|%0, %2}"
9001   [(set_attr "type" "alu")
9002    (set_attr "mode" "SI")])
9003
9004 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9005 ;; Add speccase for immediates
9006 (define_insn "*xorsi_1_zext"
9007   [(set (match_operand:DI 0 "register_operand" "=r")
9008         (zero_extend:DI
9009           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9010                   (match_operand:SI 2 "general_operand" "rim"))))
9011    (clobber (reg:CC FLAGS_REG))]
9012   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9013   "xor{l}\t{%2, %k0|%k0, %2}"
9014   [(set_attr "type" "alu")
9015    (set_attr "mode" "SI")])
9016
9017 (define_insn "*xorsi_1_zext_imm"
9018   [(set (match_operand:DI 0 "register_operand" "=r")
9019         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9020                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9021    (clobber (reg:CC FLAGS_REG))]
9022   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9023   "xor{l}\t{%2, %k0|%k0, %2}"
9024   [(set_attr "type" "alu")
9025    (set_attr "mode" "SI")])
9026
9027 (define_insn "*xorsi_2"
9028   [(set (reg FLAGS_REG)
9029         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9030                          (match_operand:SI 2 "general_operand" "rim,ri"))
9031                  (const_int 0)))
9032    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9033         (xor:SI (match_dup 1) (match_dup 2)))]
9034   "ix86_match_ccmode (insn, CCNOmode)
9035    && ix86_binary_operator_ok (XOR, SImode, operands)"
9036   "xor{l}\t{%2, %0|%0, %2}"
9037   [(set_attr "type" "alu")
9038    (set_attr "mode" "SI")])
9039
9040 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9041 ;; ??? Special case for immediate operand is missing - it is tricky.
9042 (define_insn "*xorsi_2_zext"
9043   [(set (reg FLAGS_REG)
9044         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9045                          (match_operand:SI 2 "general_operand" "rim"))
9046                  (const_int 0)))
9047    (set (match_operand:DI 0 "register_operand" "=r")
9048         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9049   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9050    && ix86_binary_operator_ok (XOR, SImode, operands)"
9051   "xor{l}\t{%2, %k0|%k0, %2}"
9052   [(set_attr "type" "alu")
9053    (set_attr "mode" "SI")])
9054
9055 (define_insn "*xorsi_2_zext_imm"
9056   [(set (reg FLAGS_REG)
9057         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9058                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9059                  (const_int 0)))
9060    (set (match_operand:DI 0 "register_operand" "=r")
9061         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9062   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9063    && ix86_binary_operator_ok (XOR, SImode, operands)"
9064   "xor{l}\t{%2, %k0|%k0, %2}"
9065   [(set_attr "type" "alu")
9066    (set_attr "mode" "SI")])
9067
9068 (define_insn "*xorsi_3"
9069   [(set (reg FLAGS_REG)
9070         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9071                          (match_operand:SI 2 "general_operand" "rim"))
9072                  (const_int 0)))
9073    (clobber (match_scratch:SI 0 "=r"))]
9074   "ix86_match_ccmode (insn, CCNOmode)
9075    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9076   "xor{l}\t{%2, %0|%0, %2}"
9077   [(set_attr "type" "alu")
9078    (set_attr "mode" "SI")])
9079
9080 (define_expand "xorhi3"
9081   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9082         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9083                 (match_operand:HI 2 "general_operand" "")))
9084    (clobber (reg:CC FLAGS_REG))]
9085   "TARGET_HIMODE_MATH"
9086   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9087
9088 (define_insn "*xorhi_1"
9089   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9090         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9091                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9092    (clobber (reg:CC FLAGS_REG))]
9093   "ix86_binary_operator_ok (XOR, HImode, operands)"
9094   "xor{w}\t{%2, %0|%0, %2}"
9095   [(set_attr "type" "alu")
9096    (set_attr "mode" "HI")])
9097
9098 (define_insn "*xorhi_2"
9099   [(set (reg FLAGS_REG)
9100         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9101                          (match_operand:HI 2 "general_operand" "rim,ri"))
9102                  (const_int 0)))
9103    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9104         (xor:HI (match_dup 1) (match_dup 2)))]
9105   "ix86_match_ccmode (insn, CCNOmode)
9106    && ix86_binary_operator_ok (XOR, HImode, operands)"
9107   "xor{w}\t{%2, %0|%0, %2}"
9108   [(set_attr "type" "alu")
9109    (set_attr "mode" "HI")])
9110
9111 (define_insn "*xorhi_3"
9112   [(set (reg FLAGS_REG)
9113         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9114                          (match_operand:HI 2 "general_operand" "rim"))
9115                  (const_int 0)))
9116    (clobber (match_scratch:HI 0 "=r"))]
9117   "ix86_match_ccmode (insn, CCNOmode)
9118    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9119   "xor{w}\t{%2, %0|%0, %2}"
9120   [(set_attr "type" "alu")
9121    (set_attr "mode" "HI")])
9122
9123 (define_expand "xorqi3"
9124   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9125         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9126                 (match_operand:QI 2 "general_operand" "")))
9127    (clobber (reg:CC FLAGS_REG))]
9128   "TARGET_QIMODE_MATH"
9129   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9130
9131 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9132 (define_insn "*xorqi_1"
9133   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9134         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9135                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9136    (clobber (reg:CC FLAGS_REG))]
9137   "ix86_binary_operator_ok (XOR, QImode, operands)"
9138   "@
9139    xor{b}\t{%2, %0|%0, %2}
9140    xor{b}\t{%2, %0|%0, %2}
9141    xor{l}\t{%k2, %k0|%k0, %k2}"
9142   [(set_attr "type" "alu")
9143    (set_attr "mode" "QI,QI,SI")])
9144
9145 (define_insn "*xorqi_1_slp"
9146   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9147         (xor:QI (match_dup 0)
9148                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9149    (clobber (reg:CC FLAGS_REG))]
9150   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9151    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9152   "xor{b}\t{%1, %0|%0, %1}"
9153   [(set_attr "type" "alu1")
9154    (set_attr "mode" "QI")])
9155
9156 (define_insn "xorqi_ext_0"
9157   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9158                          (const_int 8)
9159                          (const_int 8))
9160         (xor:SI
9161           (zero_extract:SI
9162             (match_operand 1 "ext_register_operand" "0")
9163             (const_int 8)
9164             (const_int 8))
9165           (match_operand 2 "const_int_operand" "n")))
9166    (clobber (reg:CC FLAGS_REG))]
9167   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9168   "xor{b}\t{%2, %h0|%h0, %2}"
9169   [(set_attr "type" "alu")
9170    (set_attr "length_immediate" "1")
9171    (set_attr "mode" "QI")])
9172
9173 (define_insn "*xorqi_ext_1"
9174   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9175                          (const_int 8)
9176                          (const_int 8))
9177         (xor:SI
9178           (zero_extract:SI
9179             (match_operand 1 "ext_register_operand" "0")
9180             (const_int 8)
9181             (const_int 8))
9182           (zero_extend:SI
9183             (match_operand:QI 2 "general_operand" "Qm"))))
9184    (clobber (reg:CC FLAGS_REG))]
9185   "!TARGET_64BIT
9186    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9187   "xor{b}\t{%2, %h0|%h0, %2}"
9188   [(set_attr "type" "alu")
9189    (set_attr "length_immediate" "0")
9190    (set_attr "mode" "QI")])
9191
9192 (define_insn "*xorqi_ext_1_rex64"
9193   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9194                          (const_int 8)
9195                          (const_int 8))
9196         (xor:SI
9197           (zero_extract:SI
9198             (match_operand 1 "ext_register_operand" "0")
9199             (const_int 8)
9200             (const_int 8))
9201           (zero_extend:SI
9202             (match_operand 2 "ext_register_operand" "Q"))))
9203    (clobber (reg:CC FLAGS_REG))]
9204   "TARGET_64BIT
9205    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9206   "xor{b}\t{%2, %h0|%h0, %2}"
9207   [(set_attr "type" "alu")
9208    (set_attr "length_immediate" "0")
9209    (set_attr "mode" "QI")])
9210
9211 (define_insn "*xorqi_ext_2"
9212   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9213                          (const_int 8)
9214                          (const_int 8))
9215         (xor:SI
9216           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9217                            (const_int 8)
9218                            (const_int 8))
9219           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9220                            (const_int 8)
9221                            (const_int 8))))
9222    (clobber (reg:CC FLAGS_REG))]
9223   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9224   "xor{b}\t{%h2, %h0|%h0, %h2}"
9225   [(set_attr "type" "alu")
9226    (set_attr "length_immediate" "0")
9227    (set_attr "mode" "QI")])
9228
9229 (define_insn "*xorqi_cc_1"
9230   [(set (reg FLAGS_REG)
9231         (compare
9232           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9233                   (match_operand:QI 2 "general_operand" "qim,qi"))
9234           (const_int 0)))
9235    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9236         (xor:QI (match_dup 1) (match_dup 2)))]
9237   "ix86_match_ccmode (insn, CCNOmode)
9238    && ix86_binary_operator_ok (XOR, QImode, operands)"
9239   "xor{b}\t{%2, %0|%0, %2}"
9240   [(set_attr "type" "alu")
9241    (set_attr "mode" "QI")])
9242
9243 (define_insn "*xorqi_2_slp"
9244   [(set (reg FLAGS_REG)
9245         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9246                          (match_operand:QI 1 "general_operand" "qim,qi"))
9247                  (const_int 0)))
9248    (set (strict_low_part (match_dup 0))
9249         (xor:QI (match_dup 0) (match_dup 1)))]
9250   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9251    && ix86_match_ccmode (insn, CCNOmode)
9252    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9253   "xor{b}\t{%1, %0|%0, %1}"
9254   [(set_attr "type" "alu1")
9255    (set_attr "mode" "QI")])
9256
9257 (define_insn "*xorqi_cc_2"
9258   [(set (reg FLAGS_REG)
9259         (compare
9260           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9261                   (match_operand:QI 2 "general_operand" "qim"))
9262           (const_int 0)))
9263    (clobber (match_scratch:QI 0 "=q"))]
9264   "ix86_match_ccmode (insn, CCNOmode)
9265    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9266   "xor{b}\t{%2, %0|%0, %2}"
9267   [(set_attr "type" "alu")
9268    (set_attr "mode" "QI")])
9269
9270 (define_insn "*xorqi_cc_ext_1"
9271   [(set (reg FLAGS_REG)
9272         (compare
9273           (xor:SI
9274             (zero_extract:SI
9275               (match_operand 1 "ext_register_operand" "0")
9276               (const_int 8)
9277               (const_int 8))
9278             (match_operand:QI 2 "general_operand" "qmn"))
9279           (const_int 0)))
9280    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9281                          (const_int 8)
9282                          (const_int 8))
9283         (xor:SI
9284           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9285           (match_dup 2)))]
9286   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9287   "xor{b}\t{%2, %h0|%h0, %2}"
9288   [(set_attr "type" "alu")
9289    (set_attr "mode" "QI")])
9290
9291 (define_insn "*xorqi_cc_ext_1_rex64"
9292   [(set (reg FLAGS_REG)
9293         (compare
9294           (xor:SI
9295             (zero_extract:SI
9296               (match_operand 1 "ext_register_operand" "0")
9297               (const_int 8)
9298               (const_int 8))
9299             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9300           (const_int 0)))
9301    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9302                          (const_int 8)
9303                          (const_int 8))
9304         (xor:SI
9305           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9306           (match_dup 2)))]
9307   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9308   "xor{b}\t{%2, %h0|%h0, %2}"
9309   [(set_attr "type" "alu")
9310    (set_attr "mode" "QI")])
9311
9312 (define_expand "xorqi_cc_ext_1"
9313   [(parallel [
9314      (set (reg:CCNO FLAGS_REG)
9315           (compare:CCNO
9316             (xor:SI
9317               (zero_extract:SI
9318                 (match_operand 1 "ext_register_operand" "")
9319                 (const_int 8)
9320                 (const_int 8))
9321               (match_operand:QI 2 "general_operand" ""))
9322             (const_int 0)))
9323      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9324                            (const_int 8)
9325                            (const_int 8))
9326           (xor:SI
9327             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9328             (match_dup 2)))])]
9329   ""
9330   "")
9331
9332 (define_split
9333   [(set (match_operand 0 "register_operand" "")
9334         (xor (match_operand 1 "register_operand" "")
9335              (match_operand 2 "const_int_operand" "")))
9336    (clobber (reg:CC FLAGS_REG))]
9337    "reload_completed
9338     && QI_REG_P (operands[0])
9339     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9340     && !(INTVAL (operands[2]) & ~(255 << 8))
9341     && GET_MODE (operands[0]) != QImode"
9342   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9343                    (xor:SI (zero_extract:SI (match_dup 1)
9344                                             (const_int 8) (const_int 8))
9345                            (match_dup 2)))
9346               (clobber (reg:CC FLAGS_REG))])]
9347   "operands[0] = gen_lowpart (SImode, operands[0]);
9348    operands[1] = gen_lowpart (SImode, operands[1]);
9349    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9350
9351 ;; Since XOR can be encoded with sign extended immediate, this is only
9352 ;; profitable when 7th bit is set.
9353 (define_split
9354   [(set (match_operand 0 "register_operand" "")
9355         (xor (match_operand 1 "general_operand" "")
9356              (match_operand 2 "const_int_operand" "")))
9357    (clobber (reg:CC FLAGS_REG))]
9358    "reload_completed
9359     && ANY_QI_REG_P (operands[0])
9360     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9361     && !(INTVAL (operands[2]) & ~255)
9362     && (INTVAL (operands[2]) & 128)
9363     && GET_MODE (operands[0]) != QImode"
9364   [(parallel [(set (strict_low_part (match_dup 0))
9365                    (xor:QI (match_dup 1)
9366                            (match_dup 2)))
9367               (clobber (reg:CC FLAGS_REG))])]
9368   "operands[0] = gen_lowpart (QImode, operands[0]);
9369    operands[1] = gen_lowpart (QImode, operands[1]);
9370    operands[2] = gen_lowpart (QImode, operands[2]);")
9371 \f
9372 ;; Negation instructions
9373
9374 (define_expand "negti2"
9375   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9376                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9377               (clobber (reg:CC FLAGS_REG))])]
9378   "TARGET_64BIT"
9379   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9380
9381 (define_insn "*negti2_1"
9382   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9383         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9384    (clobber (reg:CC FLAGS_REG))]
9385   "TARGET_64BIT
9386    && ix86_unary_operator_ok (NEG, TImode, operands)"
9387   "#")
9388
9389 (define_split
9390   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9391         (neg:TI (match_operand:TI 1 "general_operand" "")))
9392    (clobber (reg:CC FLAGS_REG))]
9393   "TARGET_64BIT && reload_completed"
9394   [(parallel
9395     [(set (reg:CCZ FLAGS_REG)
9396           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9397      (set (match_dup 0) (neg:DI (match_dup 2)))])
9398    (parallel
9399     [(set (match_dup 1)
9400           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9401                             (match_dup 3))
9402                    (const_int 0)))
9403      (clobber (reg:CC FLAGS_REG))])
9404    (parallel
9405     [(set (match_dup 1)
9406           (neg:DI (match_dup 1)))
9407      (clobber (reg:CC FLAGS_REG))])]
9408   "split_ti (operands+1, 1, operands+2, operands+3);
9409    split_ti (operands+0, 1, operands+0, operands+1);")
9410
9411 (define_expand "negdi2"
9412   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9413                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9414               (clobber (reg:CC FLAGS_REG))])]
9415   ""
9416   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9417
9418 (define_insn "*negdi2_1"
9419   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9420         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9421    (clobber (reg:CC FLAGS_REG))]
9422   "!TARGET_64BIT
9423    && ix86_unary_operator_ok (NEG, DImode, operands)"
9424   "#")
9425
9426 (define_split
9427   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9428         (neg:DI (match_operand:DI 1 "general_operand" "")))
9429    (clobber (reg:CC FLAGS_REG))]
9430   "!TARGET_64BIT && reload_completed"
9431   [(parallel
9432     [(set (reg:CCZ FLAGS_REG)
9433           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9434      (set (match_dup 0) (neg:SI (match_dup 2)))])
9435    (parallel
9436     [(set (match_dup 1)
9437           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9438                             (match_dup 3))
9439                    (const_int 0)))
9440      (clobber (reg:CC FLAGS_REG))])
9441    (parallel
9442     [(set (match_dup 1)
9443           (neg:SI (match_dup 1)))
9444      (clobber (reg:CC FLAGS_REG))])]
9445   "split_di (operands+1, 1, operands+2, operands+3);
9446    split_di (operands+0, 1, operands+0, operands+1);")
9447
9448 (define_insn "*negdi2_1_rex64"
9449   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9450         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9451    (clobber (reg:CC FLAGS_REG))]
9452   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9453   "neg{q}\t%0"
9454   [(set_attr "type" "negnot")
9455    (set_attr "mode" "DI")])
9456
9457 ;; The problem with neg is that it does not perform (compare x 0),
9458 ;; it really performs (compare 0 x), which leaves us with the zero
9459 ;; flag being the only useful item.
9460
9461 (define_insn "*negdi2_cmpz_rex64"
9462   [(set (reg:CCZ FLAGS_REG)
9463         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9464                      (const_int 0)))
9465    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9466         (neg:DI (match_dup 1)))]
9467   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9468   "neg{q}\t%0"
9469   [(set_attr "type" "negnot")
9470    (set_attr "mode" "DI")])
9471
9472
9473 (define_expand "negsi2"
9474   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9475                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9476               (clobber (reg:CC FLAGS_REG))])]
9477   ""
9478   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9479
9480 (define_insn "*negsi2_1"
9481   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9482         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9483    (clobber (reg:CC FLAGS_REG))]
9484   "ix86_unary_operator_ok (NEG, SImode, operands)"
9485   "neg{l}\t%0"
9486   [(set_attr "type" "negnot")
9487    (set_attr "mode" "SI")])
9488
9489 ;; Combine is quite creative about this pattern.
9490 (define_insn "*negsi2_1_zext"
9491   [(set (match_operand:DI 0 "register_operand" "=r")
9492         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9493                                         (const_int 32)))
9494                      (const_int 32)))
9495    (clobber (reg:CC FLAGS_REG))]
9496   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9497   "neg{l}\t%k0"
9498   [(set_attr "type" "negnot")
9499    (set_attr "mode" "SI")])
9500
9501 ;; The problem with neg is that it does not perform (compare x 0),
9502 ;; it really performs (compare 0 x), which leaves us with the zero
9503 ;; flag being the only useful item.
9504
9505 (define_insn "*negsi2_cmpz"
9506   [(set (reg:CCZ FLAGS_REG)
9507         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9508                      (const_int 0)))
9509    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9510         (neg:SI (match_dup 1)))]
9511   "ix86_unary_operator_ok (NEG, SImode, operands)"
9512   "neg{l}\t%0"
9513   [(set_attr "type" "negnot")
9514    (set_attr "mode" "SI")])
9515
9516 (define_insn "*negsi2_cmpz_zext"
9517   [(set (reg:CCZ FLAGS_REG)
9518         (compare:CCZ (lshiftrt:DI
9519                        (neg:DI (ashift:DI
9520                                  (match_operand:DI 1 "register_operand" "0")
9521                                  (const_int 32)))
9522                        (const_int 32))
9523                      (const_int 0)))
9524    (set (match_operand:DI 0 "register_operand" "=r")
9525         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9526                                         (const_int 32)))
9527                      (const_int 32)))]
9528   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9529   "neg{l}\t%k0"
9530   [(set_attr "type" "negnot")
9531    (set_attr "mode" "SI")])
9532
9533 (define_expand "neghi2"
9534   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9535                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9536               (clobber (reg:CC FLAGS_REG))])]
9537   "TARGET_HIMODE_MATH"
9538   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9539
9540 (define_insn "*neghi2_1"
9541   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9542         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9543    (clobber (reg:CC FLAGS_REG))]
9544   "ix86_unary_operator_ok (NEG, HImode, operands)"
9545   "neg{w}\t%0"
9546   [(set_attr "type" "negnot")
9547    (set_attr "mode" "HI")])
9548
9549 (define_insn "*neghi2_cmpz"
9550   [(set (reg:CCZ FLAGS_REG)
9551         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9552                      (const_int 0)))
9553    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9554         (neg:HI (match_dup 1)))]
9555   "ix86_unary_operator_ok (NEG, HImode, operands)"
9556   "neg{w}\t%0"
9557   [(set_attr "type" "negnot")
9558    (set_attr "mode" "HI")])
9559
9560 (define_expand "negqi2"
9561   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9562                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9563               (clobber (reg:CC FLAGS_REG))])]
9564   "TARGET_QIMODE_MATH"
9565   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9566
9567 (define_insn "*negqi2_1"
9568   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9569         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9570    (clobber (reg:CC FLAGS_REG))]
9571   "ix86_unary_operator_ok (NEG, QImode, operands)"
9572   "neg{b}\t%0"
9573   [(set_attr "type" "negnot")
9574    (set_attr "mode" "QI")])
9575
9576 (define_insn "*negqi2_cmpz"
9577   [(set (reg:CCZ FLAGS_REG)
9578         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9579                      (const_int 0)))
9580    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9581         (neg:QI (match_dup 1)))]
9582   "ix86_unary_operator_ok (NEG, QImode, operands)"
9583   "neg{b}\t%0"
9584   [(set_attr "type" "negnot")
9585    (set_attr "mode" "QI")])
9586
9587 ;; Changing of sign for FP values is doable using integer unit too.
9588
9589 (define_expand "negsf2"
9590   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9591         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9592   "TARGET_80387 || TARGET_SSE_MATH"
9593   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9594
9595 (define_expand "abssf2"
9596   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9597         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9598   "TARGET_80387 || TARGET_SSE_MATH"
9599   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9600
9601 (define_insn "*absnegsf2_mixed"
9602   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9603         (match_operator:SF 3 "absneg_operator"
9604           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9605    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9606    (clobber (reg:CC FLAGS_REG))]
9607   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9608    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9609   "#")
9610
9611 (define_insn "*absnegsf2_sse"
9612   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9613         (match_operator:SF 3 "absneg_operator"
9614           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9615    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9616    (clobber (reg:CC FLAGS_REG))]
9617   "TARGET_SSE_MATH
9618    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9619   "#")
9620
9621 (define_insn "*absnegsf2_i387"
9622   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9623         (match_operator:SF 3 "absneg_operator"
9624           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9625    (use (match_operand 2 "" ""))
9626    (clobber (reg:CC FLAGS_REG))]
9627   "TARGET_80387 && !TARGET_SSE_MATH
9628    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9629   "#")
9630
9631 (define_expand "copysignsf3"
9632   [(match_operand:SF 0 "register_operand" "")
9633    (match_operand:SF 1 "nonmemory_operand" "")
9634    (match_operand:SF 2 "register_operand" "")]
9635   "TARGET_SSE_MATH"
9636 {
9637   ix86_expand_copysign (operands);
9638   DONE;
9639 })
9640
9641 (define_insn_and_split "copysignsf3_const"
9642   [(set (match_operand:SF 0 "register_operand"          "=x")
9643         (unspec:SF
9644           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9645            (match_operand:SF 2 "register_operand"       "0")
9646            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9647           UNSPEC_COPYSIGN))]
9648   "TARGET_SSE_MATH"
9649   "#"
9650   "&& reload_completed"
9651   [(const_int 0)]
9652 {
9653   ix86_split_copysign_const (operands);
9654   DONE;
9655 })
9656
9657 (define_insn "copysignsf3_var"
9658   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9659         (unspec:SF
9660           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9661            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9662            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9663            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9664           UNSPEC_COPYSIGN))
9665    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9666   "TARGET_SSE_MATH"
9667   "#")
9668
9669 (define_split
9670   [(set (match_operand:SF 0 "register_operand" "")
9671         (unspec:SF
9672           [(match_operand:SF 2 "register_operand" "")
9673            (match_operand:SF 3 "register_operand" "")
9674            (match_operand:V4SF 4 "" "")
9675            (match_operand:V4SF 5 "" "")]
9676           UNSPEC_COPYSIGN))
9677    (clobber (match_scratch:V4SF 1 ""))]
9678   "TARGET_SSE_MATH && reload_completed"
9679   [(const_int 0)]
9680 {
9681   ix86_split_copysign_var (operands);
9682   DONE;
9683 })
9684
9685 (define_expand "negdf2"
9686   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9687         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9688   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9689   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9690
9691 (define_expand "absdf2"
9692   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9693         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9694   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9695   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9696
9697 (define_insn "*absnegdf2_mixed"
9698   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9699         (match_operator:DF 3 "absneg_operator"
9700           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9701    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9702    (clobber (reg:CC FLAGS_REG))]
9703   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9704    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9705   "#")
9706
9707 (define_insn "*absnegdf2_sse"
9708   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9709         (match_operator:DF 3 "absneg_operator"
9710           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9711    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9712    (clobber (reg:CC FLAGS_REG))]
9713   "TARGET_SSE2 && TARGET_SSE_MATH
9714    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9715   "#")
9716
9717 (define_insn "*absnegdf2_i387"
9718   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9719         (match_operator:DF 3 "absneg_operator"
9720           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9721    (use (match_operand 2 "" ""))
9722    (clobber (reg:CC FLAGS_REG))]
9723   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9724    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9725   "#")
9726
9727 (define_expand "copysigndf3"
9728   [(match_operand:DF 0 "register_operand" "")
9729    (match_operand:DF 1 "nonmemory_operand" "")
9730    (match_operand:DF 2 "register_operand" "")]
9731   "TARGET_SSE2 && TARGET_SSE_MATH"
9732 {
9733   ix86_expand_copysign (operands);
9734   DONE;
9735 })
9736
9737 (define_insn_and_split "copysigndf3_const"
9738   [(set (match_operand:DF 0 "register_operand"          "=x")
9739         (unspec:DF
9740           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9741            (match_operand:DF 2 "register_operand"       "0")
9742            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9743           UNSPEC_COPYSIGN))]
9744   "TARGET_SSE2 && TARGET_SSE_MATH"
9745   "#"
9746   "&& reload_completed"
9747   [(const_int 0)]
9748 {
9749   ix86_split_copysign_const (operands);
9750   DONE;
9751 })
9752
9753 (define_insn "copysigndf3_var"
9754   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9755         (unspec:DF
9756           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9757            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9758            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9759            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9760           UNSPEC_COPYSIGN))
9761    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9762   "TARGET_SSE2 && TARGET_SSE_MATH"
9763   "#")
9764
9765 (define_split
9766   [(set (match_operand:DF 0 "register_operand" "")
9767         (unspec:DF
9768           [(match_operand:DF 2 "register_operand" "")
9769            (match_operand:DF 3 "register_operand" "")
9770            (match_operand:V2DF 4 "" "")
9771            (match_operand:V2DF 5 "" "")]
9772           UNSPEC_COPYSIGN))
9773    (clobber (match_scratch:V2DF 1 ""))]
9774   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9775   [(const_int 0)]
9776 {
9777   ix86_split_copysign_var (operands);
9778   DONE;
9779 })
9780
9781 (define_expand "negxf2"
9782   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9783         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9784   "TARGET_80387"
9785   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9786
9787 (define_expand "absxf2"
9788   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9789         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9790   "TARGET_80387"
9791   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9792
9793 (define_insn "*absnegxf2_i387"
9794   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9795         (match_operator:XF 3 "absneg_operator"
9796           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9797    (use (match_operand 2 "" ""))
9798    (clobber (reg:CC FLAGS_REG))]
9799   "TARGET_80387
9800    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9801   "#")
9802
9803 ;; Splitters for fp abs and neg.
9804
9805 (define_split
9806   [(set (match_operand 0 "fp_register_operand" "")
9807         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9808    (use (match_operand 2 "" ""))
9809    (clobber (reg:CC FLAGS_REG))]
9810   "reload_completed"
9811   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9812
9813 (define_split
9814   [(set (match_operand 0 "register_operand" "")
9815         (match_operator 3 "absneg_operator"
9816           [(match_operand 1 "register_operand" "")]))
9817    (use (match_operand 2 "nonimmediate_operand" ""))
9818    (clobber (reg:CC FLAGS_REG))]
9819   "reload_completed && SSE_REG_P (operands[0])"
9820   [(set (match_dup 0) (match_dup 3))]
9821 {
9822   enum machine_mode mode = GET_MODE (operands[0]);
9823   enum machine_mode vmode = GET_MODE (operands[2]);
9824   rtx tmp;
9825
9826   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9827   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9828   if (operands_match_p (operands[0], operands[2]))
9829     {
9830       tmp = operands[1];
9831       operands[1] = operands[2];
9832       operands[2] = tmp;
9833     }
9834   if (GET_CODE (operands[3]) == ABS)
9835     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9836   else
9837     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9838   operands[3] = tmp;
9839 })
9840
9841 (define_split
9842   [(set (match_operand:SF 0 "register_operand" "")
9843         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9844    (use (match_operand:V4SF 2 "" ""))
9845    (clobber (reg:CC FLAGS_REG))]
9846   "reload_completed"
9847   [(parallel [(set (match_dup 0) (match_dup 1))
9848               (clobber (reg:CC FLAGS_REG))])]
9849 {
9850   rtx tmp;
9851   operands[0] = gen_lowpart (SImode, operands[0]);
9852   if (GET_CODE (operands[1]) == ABS)
9853     {
9854       tmp = gen_int_mode (0x7fffffff, SImode);
9855       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9856     }
9857   else
9858     {
9859       tmp = gen_int_mode (0x80000000, SImode);
9860       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9861     }
9862   operands[1] = tmp;
9863 })
9864
9865 (define_split
9866   [(set (match_operand:DF 0 "register_operand" "")
9867         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9868    (use (match_operand 2 "" ""))
9869    (clobber (reg:CC FLAGS_REG))]
9870   "reload_completed"
9871   [(parallel [(set (match_dup 0) (match_dup 1))
9872               (clobber (reg:CC FLAGS_REG))])]
9873 {
9874   rtx tmp;
9875   if (TARGET_64BIT)
9876     {
9877       tmp = gen_lowpart (DImode, operands[0]);
9878       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9879       operands[0] = tmp;
9880
9881       if (GET_CODE (operands[1]) == ABS)
9882         tmp = const0_rtx;
9883       else
9884         tmp = gen_rtx_NOT (DImode, tmp);
9885     }
9886   else
9887     {
9888       operands[0] = gen_highpart (SImode, operands[0]);
9889       if (GET_CODE (operands[1]) == ABS)
9890         {
9891           tmp = gen_int_mode (0x7fffffff, SImode);
9892           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9893         }
9894       else
9895         {
9896           tmp = gen_int_mode (0x80000000, SImode);
9897           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9898         }
9899     }
9900   operands[1] = tmp;
9901 })
9902
9903 (define_split
9904   [(set (match_operand:XF 0 "register_operand" "")
9905         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9906    (use (match_operand 2 "" ""))
9907    (clobber (reg:CC FLAGS_REG))]
9908   "reload_completed"
9909   [(parallel [(set (match_dup 0) (match_dup 1))
9910               (clobber (reg:CC FLAGS_REG))])]
9911 {
9912   rtx tmp;
9913   operands[0] = gen_rtx_REG (SImode,
9914                              true_regnum (operands[0])
9915                              + (TARGET_64BIT ? 1 : 2));
9916   if (GET_CODE (operands[1]) == ABS)
9917     {
9918       tmp = GEN_INT (0x7fff);
9919       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9920     }
9921   else
9922     {
9923       tmp = GEN_INT (0x8000);
9924       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9925     }
9926   operands[1] = tmp;
9927 })
9928
9929 (define_split
9930   [(set (match_operand 0 "memory_operand" "")
9931         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9932    (use (match_operand 2 "" ""))
9933    (clobber (reg:CC FLAGS_REG))]
9934   "reload_completed"
9935   [(parallel [(set (match_dup 0) (match_dup 1))
9936               (clobber (reg:CC FLAGS_REG))])]
9937 {
9938   enum machine_mode mode = GET_MODE (operands[0]);
9939   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9940   rtx tmp;
9941
9942   operands[0] = adjust_address (operands[0], QImode, size - 1);
9943   if (GET_CODE (operands[1]) == ABS)
9944     {
9945       tmp = gen_int_mode (0x7f, QImode);
9946       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9947     }
9948   else
9949     {
9950       tmp = gen_int_mode (0x80, QImode);
9951       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9952     }
9953   operands[1] = tmp;
9954 })
9955
9956 ;; Conditionalize these after reload. If they match before reload, we
9957 ;; lose the clobber and ability to use integer instructions.
9958
9959 (define_insn "*negsf2_1"
9960   [(set (match_operand:SF 0 "register_operand" "=f")
9961         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9962   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9963   "fchs"
9964   [(set_attr "type" "fsgn")
9965    (set_attr "mode" "SF")])
9966
9967 (define_insn "*negdf2_1"
9968   [(set (match_operand:DF 0 "register_operand" "=f")
9969         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9970   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9971   "fchs"
9972   [(set_attr "type" "fsgn")
9973    (set_attr "mode" "DF")])
9974
9975 (define_insn "*negxf2_1"
9976   [(set (match_operand:XF 0 "register_operand" "=f")
9977         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9978   "TARGET_80387"
9979   "fchs"
9980   [(set_attr "type" "fsgn")
9981    (set_attr "mode" "XF")])
9982
9983 (define_insn "*abssf2_1"
9984   [(set (match_operand:SF 0 "register_operand" "=f")
9985         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9986   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9987   "fabs"
9988   [(set_attr "type" "fsgn")
9989    (set_attr "mode" "SF")])
9990
9991 (define_insn "*absdf2_1"
9992   [(set (match_operand:DF 0 "register_operand" "=f")
9993         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9994   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9995   "fabs"
9996   [(set_attr "type" "fsgn")
9997    (set_attr "mode" "DF")])
9998
9999 (define_insn "*absxf2_1"
10000   [(set (match_operand:XF 0 "register_operand" "=f")
10001         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10002   "TARGET_80387"
10003   "fabs"
10004   [(set_attr "type" "fsgn")
10005    (set_attr "mode" "DF")])
10006
10007 (define_insn "*negextendsfdf2"
10008   [(set (match_operand:DF 0 "register_operand" "=f")
10009         (neg:DF (float_extend:DF
10010                   (match_operand:SF 1 "register_operand" "0"))))]
10011   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10012   "fchs"
10013   [(set_attr "type" "fsgn")
10014    (set_attr "mode" "DF")])
10015
10016 (define_insn "*negextenddfxf2"
10017   [(set (match_operand:XF 0 "register_operand" "=f")
10018         (neg:XF (float_extend:XF
10019                   (match_operand:DF 1 "register_operand" "0"))))]
10020   "TARGET_80387"
10021   "fchs"
10022   [(set_attr "type" "fsgn")
10023    (set_attr "mode" "XF")])
10024
10025 (define_insn "*negextendsfxf2"
10026   [(set (match_operand:XF 0 "register_operand" "=f")
10027         (neg:XF (float_extend:XF
10028                   (match_operand:SF 1 "register_operand" "0"))))]
10029   "TARGET_80387"
10030   "fchs"
10031   [(set_attr "type" "fsgn")
10032    (set_attr "mode" "XF")])
10033
10034 (define_insn "*absextendsfdf2"
10035   [(set (match_operand:DF 0 "register_operand" "=f")
10036         (abs:DF (float_extend:DF
10037                   (match_operand:SF 1 "register_operand" "0"))))]
10038   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10039   "fabs"
10040   [(set_attr "type" "fsgn")
10041    (set_attr "mode" "DF")])
10042
10043 (define_insn "*absextenddfxf2"
10044   [(set (match_operand:XF 0 "register_operand" "=f")
10045         (abs:XF (float_extend:XF
10046           (match_operand:DF 1 "register_operand" "0"))))]
10047   "TARGET_80387"
10048   "fabs"
10049   [(set_attr "type" "fsgn")
10050    (set_attr "mode" "XF")])
10051
10052 (define_insn "*absextendsfxf2"
10053   [(set (match_operand:XF 0 "register_operand" "=f")
10054         (abs:XF (float_extend:XF
10055           (match_operand:SF 1 "register_operand" "0"))))]
10056   "TARGET_80387"
10057   "fabs"
10058   [(set_attr "type" "fsgn")
10059    (set_attr "mode" "XF")])
10060 \f
10061 ;; One complement instructions
10062
10063 (define_expand "one_cmpldi2"
10064   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10065         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10066   "TARGET_64BIT"
10067   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10068
10069 (define_insn "*one_cmpldi2_1_rex64"
10070   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10071         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10072   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10073   "not{q}\t%0"
10074   [(set_attr "type" "negnot")
10075    (set_attr "mode" "DI")])
10076
10077 (define_insn "*one_cmpldi2_2_rex64"
10078   [(set (reg FLAGS_REG)
10079         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10080                  (const_int 0)))
10081    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10082         (not:DI (match_dup 1)))]
10083   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10084    && ix86_unary_operator_ok (NOT, DImode, operands)"
10085   "#"
10086   [(set_attr "type" "alu1")
10087    (set_attr "mode" "DI")])
10088
10089 (define_split
10090   [(set (match_operand 0 "flags_reg_operand" "")
10091         (match_operator 2 "compare_operator"
10092           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10093            (const_int 0)]))
10094    (set (match_operand:DI 1 "nonimmediate_operand" "")
10095         (not:DI (match_dup 3)))]
10096   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10097   [(parallel [(set (match_dup 0)
10098                    (match_op_dup 2
10099                      [(xor:DI (match_dup 3) (const_int -1))
10100                       (const_int 0)]))
10101               (set (match_dup 1)
10102                    (xor:DI (match_dup 3) (const_int -1)))])]
10103   "")
10104
10105 (define_expand "one_cmplsi2"
10106   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10107         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10108   ""
10109   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10110
10111 (define_insn "*one_cmplsi2_1"
10112   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10113         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10114   "ix86_unary_operator_ok (NOT, SImode, operands)"
10115   "not{l}\t%0"
10116   [(set_attr "type" "negnot")
10117    (set_attr "mode" "SI")])
10118
10119 ;; ??? Currently never generated - xor is used instead.
10120 (define_insn "*one_cmplsi2_1_zext"
10121   [(set (match_operand:DI 0 "register_operand" "=r")
10122         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10123   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10124   "not{l}\t%k0"
10125   [(set_attr "type" "negnot")
10126    (set_attr "mode" "SI")])
10127
10128 (define_insn "*one_cmplsi2_2"
10129   [(set (reg FLAGS_REG)
10130         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10131                  (const_int 0)))
10132    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10133         (not:SI (match_dup 1)))]
10134   "ix86_match_ccmode (insn, CCNOmode)
10135    && ix86_unary_operator_ok (NOT, SImode, operands)"
10136   "#"
10137   [(set_attr "type" "alu1")
10138    (set_attr "mode" "SI")])
10139
10140 (define_split
10141   [(set (match_operand 0 "flags_reg_operand" "")
10142         (match_operator 2 "compare_operator"
10143           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10144            (const_int 0)]))
10145    (set (match_operand:SI 1 "nonimmediate_operand" "")
10146         (not:SI (match_dup 3)))]
10147   "ix86_match_ccmode (insn, CCNOmode)"
10148   [(parallel [(set (match_dup 0)
10149                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10150                                     (const_int 0)]))
10151               (set (match_dup 1)
10152                    (xor:SI (match_dup 3) (const_int -1)))])]
10153   "")
10154
10155 ;; ??? Currently never generated - xor is used instead.
10156 (define_insn "*one_cmplsi2_2_zext"
10157   [(set (reg FLAGS_REG)
10158         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10159                  (const_int 0)))
10160    (set (match_operand:DI 0 "register_operand" "=r")
10161         (zero_extend:DI (not:SI (match_dup 1))))]
10162   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10163    && ix86_unary_operator_ok (NOT, SImode, operands)"
10164   "#"
10165   [(set_attr "type" "alu1")
10166    (set_attr "mode" "SI")])
10167
10168 (define_split
10169   [(set (match_operand 0 "flags_reg_operand" "")
10170         (match_operator 2 "compare_operator"
10171           [(not:SI (match_operand:SI 3 "register_operand" ""))
10172            (const_int 0)]))
10173    (set (match_operand:DI 1 "register_operand" "")
10174         (zero_extend:DI (not:SI (match_dup 3))))]
10175   "ix86_match_ccmode (insn, CCNOmode)"
10176   [(parallel [(set (match_dup 0)
10177                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10178                                     (const_int 0)]))
10179               (set (match_dup 1)
10180                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10181   "")
10182
10183 (define_expand "one_cmplhi2"
10184   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10185         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10186   "TARGET_HIMODE_MATH"
10187   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10188
10189 (define_insn "*one_cmplhi2_1"
10190   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10191         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10192   "ix86_unary_operator_ok (NOT, HImode, operands)"
10193   "not{w}\t%0"
10194   [(set_attr "type" "negnot")
10195    (set_attr "mode" "HI")])
10196
10197 (define_insn "*one_cmplhi2_2"
10198   [(set (reg FLAGS_REG)
10199         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10200                  (const_int 0)))
10201    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10202         (not:HI (match_dup 1)))]
10203   "ix86_match_ccmode (insn, CCNOmode)
10204    && ix86_unary_operator_ok (NEG, HImode, operands)"
10205   "#"
10206   [(set_attr "type" "alu1")
10207    (set_attr "mode" "HI")])
10208
10209 (define_split
10210   [(set (match_operand 0 "flags_reg_operand" "")
10211         (match_operator 2 "compare_operator"
10212           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10213            (const_int 0)]))
10214    (set (match_operand:HI 1 "nonimmediate_operand" "")
10215         (not:HI (match_dup 3)))]
10216   "ix86_match_ccmode (insn, CCNOmode)"
10217   [(parallel [(set (match_dup 0)
10218                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10219                                     (const_int 0)]))
10220               (set (match_dup 1)
10221                    (xor:HI (match_dup 3) (const_int -1)))])]
10222   "")
10223
10224 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10225 (define_expand "one_cmplqi2"
10226   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10227         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10228   "TARGET_QIMODE_MATH"
10229   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10230
10231 (define_insn "*one_cmplqi2_1"
10232   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10233         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10234   "ix86_unary_operator_ok (NOT, QImode, operands)"
10235   "@
10236    not{b}\t%0
10237    not{l}\t%k0"
10238   [(set_attr "type" "negnot")
10239    (set_attr "mode" "QI,SI")])
10240
10241 (define_insn "*one_cmplqi2_2"
10242   [(set (reg FLAGS_REG)
10243         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10244                  (const_int 0)))
10245    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10246         (not:QI (match_dup 1)))]
10247   "ix86_match_ccmode (insn, CCNOmode)
10248    && ix86_unary_operator_ok (NOT, QImode, operands)"
10249   "#"
10250   [(set_attr "type" "alu1")
10251    (set_attr "mode" "QI")])
10252
10253 (define_split
10254   [(set (match_operand 0 "flags_reg_operand" "")
10255         (match_operator 2 "compare_operator"
10256           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10257            (const_int 0)]))
10258    (set (match_operand:QI 1 "nonimmediate_operand" "")
10259         (not:QI (match_dup 3)))]
10260   "ix86_match_ccmode (insn, CCNOmode)"
10261   [(parallel [(set (match_dup 0)
10262                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10263                                     (const_int 0)]))
10264               (set (match_dup 1)
10265                    (xor:QI (match_dup 3) (const_int -1)))])]
10266   "")
10267 \f
10268 ;; Arithmetic shift instructions
10269
10270 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10271 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10272 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10273 ;; from the assembler input.
10274 ;;
10275 ;; This instruction shifts the target reg/mem as usual, but instead of
10276 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10277 ;; is a left shift double, bits are taken from the high order bits of
10278 ;; reg, else if the insn is a shift right double, bits are taken from the
10279 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10280 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10281 ;;
10282 ;; Since sh[lr]d does not change the `reg' operand, that is done
10283 ;; separately, making all shifts emit pairs of shift double and normal
10284 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10285 ;; support a 63 bit shift, each shift where the count is in a reg expands
10286 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10287 ;;
10288 ;; If the shift count is a constant, we need never emit more than one
10289 ;; shift pair, instead using moves and sign extension for counts greater
10290 ;; than 31.
10291
10292 (define_expand "ashlti3"
10293   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10294                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10295                               (match_operand:QI 2 "nonmemory_operand" "")))
10296               (clobber (reg:CC FLAGS_REG))])]
10297   "TARGET_64BIT"
10298 {
10299   if (! immediate_operand (operands[2], QImode))
10300     {
10301       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10302       DONE;
10303     }
10304   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10305   DONE;
10306 })
10307
10308 (define_insn "ashlti3_1"
10309   [(set (match_operand:TI 0 "register_operand" "=r")
10310         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10311                    (match_operand:QI 2 "register_operand" "c")))
10312    (clobber (match_scratch:DI 3 "=&r"))
10313    (clobber (reg:CC FLAGS_REG))]
10314   "TARGET_64BIT"
10315   "#"
10316   [(set_attr "type" "multi")])
10317
10318 (define_insn "*ashlti3_2"
10319   [(set (match_operand:TI 0 "register_operand" "=r")
10320         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10321                    (match_operand:QI 2 "immediate_operand" "O")))
10322    (clobber (reg:CC FLAGS_REG))]
10323   "TARGET_64BIT"
10324   "#"
10325   [(set_attr "type" "multi")])
10326
10327 (define_split
10328   [(set (match_operand:TI 0 "register_operand" "")
10329         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10330                    (match_operand:QI 2 "register_operand" "")))
10331    (clobber (match_scratch:DI 3 ""))
10332    (clobber (reg:CC FLAGS_REG))]
10333   "TARGET_64BIT && reload_completed"
10334   [(const_int 0)]
10335   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10336
10337 (define_split
10338   [(set (match_operand:TI 0 "register_operand" "")
10339         (ashift:TI (match_operand:TI 1 "register_operand" "")
10340                    (match_operand:QI 2 "immediate_operand" "")))
10341    (clobber (reg:CC FLAGS_REG))]
10342   "TARGET_64BIT && reload_completed"
10343   [(const_int 0)]
10344   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10345
10346 (define_insn "x86_64_shld"
10347   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10348         (ior:DI (ashift:DI (match_dup 0)
10349                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10350                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10351                   (minus:QI (const_int 64) (match_dup 2)))))
10352    (clobber (reg:CC FLAGS_REG))]
10353   "TARGET_64BIT"
10354   "@
10355    shld{q}\t{%2, %1, %0|%0, %1, %2}
10356    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10357   [(set_attr "type" "ishift")
10358    (set_attr "prefix_0f" "1")
10359    (set_attr "mode" "DI")
10360    (set_attr "athlon_decode" "vector")])
10361
10362 (define_expand "x86_64_shift_adj"
10363   [(set (reg:CCZ FLAGS_REG)
10364         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10365                              (const_int 64))
10366                      (const_int 0)))
10367    (set (match_operand:DI 0 "register_operand" "")
10368         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10369                          (match_operand:DI 1 "register_operand" "")
10370                          (match_dup 0)))
10371    (set (match_dup 1)
10372         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10373                          (match_operand:DI 3 "register_operand" "r")
10374                          (match_dup 1)))]
10375   "TARGET_64BIT"
10376   "")
10377
10378 (define_expand "ashldi3"
10379   [(set (match_operand:DI 0 "shiftdi_operand" "")
10380         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10381                    (match_operand:QI 2 "nonmemory_operand" "")))]
10382   ""
10383   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10384
10385 (define_insn "*ashldi3_1_rex64"
10386   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10387         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10388                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10389    (clobber (reg:CC FLAGS_REG))]
10390   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10391 {
10392   switch (get_attr_type (insn))
10393     {
10394     case TYPE_ALU:
10395       gcc_assert (operands[2] == const1_rtx);
10396       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10397       return "add{q}\t{%0, %0|%0, %0}";
10398
10399     case TYPE_LEA:
10400       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10401       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10402       operands[1] = gen_rtx_MULT (DImode, operands[1],
10403                                   GEN_INT (1 << INTVAL (operands[2])));
10404       return "lea{q}\t{%a1, %0|%0, %a1}";
10405
10406     default:
10407       if (REG_P (operands[2]))
10408         return "sal{q}\t{%b2, %0|%0, %b2}";
10409       else if (operands[2] == const1_rtx
10410                && (TARGET_SHIFT1 || optimize_size))
10411         return "sal{q}\t%0";
10412       else
10413         return "sal{q}\t{%2, %0|%0, %2}";
10414     }
10415 }
10416   [(set (attr "type")
10417      (cond [(eq_attr "alternative" "1")
10418               (const_string "lea")
10419             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10420                           (const_int 0))
10421                       (match_operand 0 "register_operand" ""))
10422                  (match_operand 2 "const1_operand" ""))
10423               (const_string "alu")
10424            ]
10425            (const_string "ishift")))
10426    (set_attr "mode" "DI")])
10427
10428 ;; Convert lea to the lea pattern to avoid flags dependency.
10429 (define_split
10430   [(set (match_operand:DI 0 "register_operand" "")
10431         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10432                    (match_operand:QI 2 "immediate_operand" "")))
10433    (clobber (reg:CC FLAGS_REG))]
10434   "TARGET_64BIT && reload_completed
10435    && true_regnum (operands[0]) != true_regnum (operands[1])"
10436   [(set (match_dup 0)
10437         (mult:DI (match_dup 1)
10438                  (match_dup 2)))]
10439   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10440
10441 ;; This pattern can't accept a variable shift count, since shifts by
10442 ;; zero don't affect the flags.  We assume that shifts by constant
10443 ;; zero are optimized away.
10444 (define_insn "*ashldi3_cmp_rex64"
10445   [(set (reg FLAGS_REG)
10446         (compare
10447           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10448                      (match_operand:QI 2 "immediate_operand" "e"))
10449           (const_int 0)))
10450    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10451         (ashift:DI (match_dup 1) (match_dup 2)))]
10452   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10453    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10454    && (optimize_size
10455        || !TARGET_PARTIAL_FLAG_REG_STALL
10456        || (operands[2] == const1_rtx
10457            && (TARGET_SHIFT1
10458                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10459 {
10460   switch (get_attr_type (insn))
10461     {
10462     case TYPE_ALU:
10463       gcc_assert (operands[2] == const1_rtx);
10464       return "add{q}\t{%0, %0|%0, %0}";
10465
10466     default:
10467       if (REG_P (operands[2]))
10468         return "sal{q}\t{%b2, %0|%0, %b2}";
10469       else if (operands[2] == const1_rtx
10470                && (TARGET_SHIFT1 || optimize_size))
10471         return "sal{q}\t%0";
10472       else
10473         return "sal{q}\t{%2, %0|%0, %2}";
10474     }
10475 }
10476   [(set (attr "type")
10477      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10478                           (const_int 0))
10479                       (match_operand 0 "register_operand" ""))
10480                  (match_operand 2 "const1_operand" ""))
10481               (const_string "alu")
10482            ]
10483            (const_string "ishift")))
10484    (set_attr "mode" "DI")])
10485
10486 (define_insn "*ashldi3_cconly_rex64"
10487   [(set (reg FLAGS_REG)
10488         (compare
10489           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10490                      (match_operand:QI 2 "immediate_operand" "e"))
10491           (const_int 0)))
10492    (clobber (match_scratch:DI 0 "=r"))]
10493   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10494    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10495    && (optimize_size
10496        || !TARGET_PARTIAL_FLAG_REG_STALL
10497        || (operands[2] == const1_rtx
10498            && (TARGET_SHIFT1
10499                || TARGET_DOUBLE_WITH_ADD)))"
10500 {
10501   switch (get_attr_type (insn))
10502     {
10503     case TYPE_ALU:
10504       gcc_assert (operands[2] == const1_rtx);
10505       return "add{q}\t{%0, %0|%0, %0}";
10506
10507     default:
10508       if (REG_P (operands[2]))
10509         return "sal{q}\t{%b2, %0|%0, %b2}";
10510       else if (operands[2] == const1_rtx
10511                && (TARGET_SHIFT1 || optimize_size))
10512         return "sal{q}\t%0";
10513       else
10514         return "sal{q}\t{%2, %0|%0, %2}";
10515     }
10516 }
10517   [(set (attr "type")
10518      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10519                           (const_int 0))
10520                       (match_operand 0 "register_operand" ""))
10521                  (match_operand 2 "const1_operand" ""))
10522               (const_string "alu")
10523            ]
10524            (const_string "ishift")))
10525    (set_attr "mode" "DI")])
10526
10527 (define_insn "*ashldi3_1"
10528   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10529         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10530                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10531    (clobber (reg:CC FLAGS_REG))]
10532   "!TARGET_64BIT"
10533   "#"
10534   [(set_attr "type" "multi")])
10535
10536 ;; By default we don't ask for a scratch register, because when DImode
10537 ;; values are manipulated, registers are already at a premium.  But if
10538 ;; we have one handy, we won't turn it away.
10539 (define_peephole2
10540   [(match_scratch:SI 3 "r")
10541    (parallel [(set (match_operand:DI 0 "register_operand" "")
10542                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10543                               (match_operand:QI 2 "nonmemory_operand" "")))
10544               (clobber (reg:CC FLAGS_REG))])
10545    (match_dup 3)]
10546   "!TARGET_64BIT && TARGET_CMOVE"
10547   [(const_int 0)]
10548   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10549
10550 (define_split
10551   [(set (match_operand:DI 0 "register_operand" "")
10552         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10553                    (match_operand:QI 2 "nonmemory_operand" "")))
10554    (clobber (reg:CC FLAGS_REG))]
10555   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10556                      ? flow2_completed : reload_completed)"
10557   [(const_int 0)]
10558   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10559
10560 (define_insn "x86_shld_1"
10561   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10562         (ior:SI (ashift:SI (match_dup 0)
10563                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10564                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10565                   (minus:QI (const_int 32) (match_dup 2)))))
10566    (clobber (reg:CC FLAGS_REG))]
10567   ""
10568   "@
10569    shld{l}\t{%2, %1, %0|%0, %1, %2}
10570    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10571   [(set_attr "type" "ishift")
10572    (set_attr "prefix_0f" "1")
10573    (set_attr "mode" "SI")
10574    (set_attr "pent_pair" "np")
10575    (set_attr "athlon_decode" "vector")])
10576
10577 (define_expand "x86_shift_adj_1"
10578   [(set (reg:CCZ FLAGS_REG)
10579         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10580                              (const_int 32))
10581                      (const_int 0)))
10582    (set (match_operand:SI 0 "register_operand" "")
10583         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10584                          (match_operand:SI 1 "register_operand" "")
10585                          (match_dup 0)))
10586    (set (match_dup 1)
10587         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10588                          (match_operand:SI 3 "register_operand" "r")
10589                          (match_dup 1)))]
10590   "TARGET_CMOVE"
10591   "")
10592
10593 (define_expand "x86_shift_adj_2"
10594   [(use (match_operand:SI 0 "register_operand" ""))
10595    (use (match_operand:SI 1 "register_operand" ""))
10596    (use (match_operand:QI 2 "register_operand" ""))]
10597   ""
10598 {
10599   rtx label = gen_label_rtx ();
10600   rtx tmp;
10601
10602   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10603
10604   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10605   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10606   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10607                               gen_rtx_LABEL_REF (VOIDmode, label),
10608                               pc_rtx);
10609   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10610   JUMP_LABEL (tmp) = label;
10611
10612   emit_move_insn (operands[0], operands[1]);
10613   ix86_expand_clear (operands[1]);
10614
10615   emit_label (label);
10616   LABEL_NUSES (label) = 1;
10617
10618   DONE;
10619 })
10620
10621 (define_expand "ashlsi3"
10622   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10623         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10624                    (match_operand:QI 2 "nonmemory_operand" "")))
10625    (clobber (reg:CC FLAGS_REG))]
10626   ""
10627   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10628
10629 (define_insn "*ashlsi3_1"
10630   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10631         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10632                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10633    (clobber (reg:CC FLAGS_REG))]
10634   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10635 {
10636   switch (get_attr_type (insn))
10637     {
10638     case TYPE_ALU:
10639       gcc_assert (operands[2] == const1_rtx);
10640       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10641       return "add{l}\t{%0, %0|%0, %0}";
10642
10643     case TYPE_LEA:
10644       return "#";
10645
10646     default:
10647       if (REG_P (operands[2]))
10648         return "sal{l}\t{%b2, %0|%0, %b2}";
10649       else if (operands[2] == const1_rtx
10650                && (TARGET_SHIFT1 || optimize_size))
10651         return "sal{l}\t%0";
10652       else
10653         return "sal{l}\t{%2, %0|%0, %2}";
10654     }
10655 }
10656   [(set (attr "type")
10657      (cond [(eq_attr "alternative" "1")
10658               (const_string "lea")
10659             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10660                           (const_int 0))
10661                       (match_operand 0 "register_operand" ""))
10662                  (match_operand 2 "const1_operand" ""))
10663               (const_string "alu")
10664            ]
10665            (const_string "ishift")))
10666    (set_attr "mode" "SI")])
10667
10668 ;; Convert lea to the lea pattern to avoid flags dependency.
10669 (define_split
10670   [(set (match_operand 0 "register_operand" "")
10671         (ashift (match_operand 1 "index_register_operand" "")
10672                 (match_operand:QI 2 "const_int_operand" "")))
10673    (clobber (reg:CC FLAGS_REG))]
10674   "reload_completed
10675    && true_regnum (operands[0]) != true_regnum (operands[1])
10676    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10677   [(const_int 0)]
10678 {
10679   rtx pat;
10680   enum machine_mode mode = GET_MODE (operands[0]);
10681
10682   if (GET_MODE_SIZE (mode) < 4)
10683     operands[0] = gen_lowpart (SImode, operands[0]);
10684   if (mode != Pmode)
10685     operands[1] = gen_lowpart (Pmode, operands[1]);
10686   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10687
10688   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10689   if (Pmode != SImode)
10690     pat = gen_rtx_SUBREG (SImode, pat, 0);
10691   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10692   DONE;
10693 })
10694
10695 ;; Rare case of shifting RSP is handled by generating move and shift
10696 (define_split
10697   [(set (match_operand 0 "register_operand" "")
10698         (ashift (match_operand 1 "register_operand" "")
10699                 (match_operand:QI 2 "const_int_operand" "")))
10700    (clobber (reg:CC FLAGS_REG))]
10701   "reload_completed
10702    && true_regnum (operands[0]) != true_regnum (operands[1])"
10703   [(const_int 0)]
10704 {
10705   rtx pat, clob;
10706   emit_move_insn (operands[0], operands[1]);
10707   pat = gen_rtx_SET (VOIDmode, operands[0],
10708                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10709                                      operands[0], operands[2]));
10710   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10711   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10712   DONE;
10713 })
10714
10715 (define_insn "*ashlsi3_1_zext"
10716   [(set (match_operand:DI 0 "register_operand" "=r,r")
10717         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10718                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10719    (clobber (reg:CC FLAGS_REG))]
10720   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10721 {
10722   switch (get_attr_type (insn))
10723     {
10724     case TYPE_ALU:
10725       gcc_assert (operands[2] == const1_rtx);
10726       return "add{l}\t{%k0, %k0|%k0, %k0}";
10727
10728     case TYPE_LEA:
10729       return "#";
10730
10731     default:
10732       if (REG_P (operands[2]))
10733         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10734       else if (operands[2] == const1_rtx
10735                && (TARGET_SHIFT1 || optimize_size))
10736         return "sal{l}\t%k0";
10737       else
10738         return "sal{l}\t{%2, %k0|%k0, %2}";
10739     }
10740 }
10741   [(set (attr "type")
10742      (cond [(eq_attr "alternative" "1")
10743               (const_string "lea")
10744             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10745                      (const_int 0))
10746                  (match_operand 2 "const1_operand" ""))
10747               (const_string "alu")
10748            ]
10749            (const_string "ishift")))
10750    (set_attr "mode" "SI")])
10751
10752 ;; Convert lea to the lea pattern to avoid flags dependency.
10753 (define_split
10754   [(set (match_operand:DI 0 "register_operand" "")
10755         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10756                                 (match_operand:QI 2 "const_int_operand" ""))))
10757    (clobber (reg:CC FLAGS_REG))]
10758   "TARGET_64BIT && reload_completed
10759    && true_regnum (operands[0]) != true_regnum (operands[1])"
10760   [(set (match_dup 0) (zero_extend:DI
10761                         (subreg:SI (mult:SI (match_dup 1)
10762                                             (match_dup 2)) 0)))]
10763 {
10764   operands[1] = gen_lowpart (Pmode, operands[1]);
10765   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10766 })
10767
10768 ;; This pattern can't accept a variable shift count, since shifts by
10769 ;; zero don't affect the flags.  We assume that shifts by constant
10770 ;; zero are optimized away.
10771 (define_insn "*ashlsi3_cmp"
10772   [(set (reg FLAGS_REG)
10773         (compare
10774           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10775                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10776           (const_int 0)))
10777    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10778         (ashift:SI (match_dup 1) (match_dup 2)))]
10779   "ix86_match_ccmode (insn, CCGOCmode)
10780    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10781    && (optimize_size
10782        || !TARGET_PARTIAL_FLAG_REG_STALL
10783        || (operands[2] == const1_rtx
10784            && (TARGET_SHIFT1
10785                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10786 {
10787   switch (get_attr_type (insn))
10788     {
10789     case TYPE_ALU:
10790       gcc_assert (operands[2] == const1_rtx);
10791       return "add{l}\t{%0, %0|%0, %0}";
10792
10793     default:
10794       if (REG_P (operands[2]))
10795         return "sal{l}\t{%b2, %0|%0, %b2}";
10796       else if (operands[2] == const1_rtx
10797                && (TARGET_SHIFT1 || optimize_size))
10798         return "sal{l}\t%0";
10799       else
10800         return "sal{l}\t{%2, %0|%0, %2}";
10801     }
10802 }
10803   [(set (attr "type")
10804      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10805                           (const_int 0))
10806                       (match_operand 0 "register_operand" ""))
10807                  (match_operand 2 "const1_operand" ""))
10808               (const_string "alu")
10809            ]
10810            (const_string "ishift")))
10811    (set_attr "mode" "SI")])
10812
10813 (define_insn "*ashlsi3_cconly"
10814   [(set (reg FLAGS_REG)
10815         (compare
10816           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10817                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10818           (const_int 0)))
10819    (clobber (match_scratch:SI 0 "=r"))]
10820   "ix86_match_ccmode (insn, CCGOCmode)
10821    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10822    && (optimize_size
10823        || !TARGET_PARTIAL_FLAG_REG_STALL
10824        || (operands[2] == const1_rtx
10825            && (TARGET_SHIFT1
10826                || TARGET_DOUBLE_WITH_ADD)))"
10827 {
10828   switch (get_attr_type (insn))
10829     {
10830     case TYPE_ALU:
10831       gcc_assert (operands[2] == const1_rtx);
10832       return "add{l}\t{%0, %0|%0, %0}";
10833
10834     default:
10835       if (REG_P (operands[2]))
10836         return "sal{l}\t{%b2, %0|%0, %b2}";
10837       else if (operands[2] == const1_rtx
10838                && (TARGET_SHIFT1 || optimize_size))
10839         return "sal{l}\t%0";
10840       else
10841         return "sal{l}\t{%2, %0|%0, %2}";
10842     }
10843 }
10844   [(set (attr "type")
10845      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10846                           (const_int 0))
10847                       (match_operand 0 "register_operand" ""))
10848                  (match_operand 2 "const1_operand" ""))
10849               (const_string "alu")
10850            ]
10851            (const_string "ishift")))
10852    (set_attr "mode" "SI")])
10853
10854 (define_insn "*ashlsi3_cmp_zext"
10855   [(set (reg FLAGS_REG)
10856         (compare
10857           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10858                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10859           (const_int 0)))
10860    (set (match_operand:DI 0 "register_operand" "=r")
10861         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10862   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10863    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10864    && (optimize_size
10865        || !TARGET_PARTIAL_FLAG_REG_STALL
10866        || (operands[2] == const1_rtx
10867            && (TARGET_SHIFT1
10868                || TARGET_DOUBLE_WITH_ADD)))"
10869 {
10870   switch (get_attr_type (insn))
10871     {
10872     case TYPE_ALU:
10873       gcc_assert (operands[2] == const1_rtx);
10874       return "add{l}\t{%k0, %k0|%k0, %k0}";
10875
10876     default:
10877       if (REG_P (operands[2]))
10878         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10879       else if (operands[2] == const1_rtx
10880                && (TARGET_SHIFT1 || optimize_size))
10881         return "sal{l}\t%k0";
10882       else
10883         return "sal{l}\t{%2, %k0|%k0, %2}";
10884     }
10885 }
10886   [(set (attr "type")
10887      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10888                      (const_int 0))
10889                  (match_operand 2 "const1_operand" ""))
10890               (const_string "alu")
10891            ]
10892            (const_string "ishift")))
10893    (set_attr "mode" "SI")])
10894
10895 (define_expand "ashlhi3"
10896   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10897         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10898                    (match_operand:QI 2 "nonmemory_operand" "")))
10899    (clobber (reg:CC FLAGS_REG))]
10900   "TARGET_HIMODE_MATH"
10901   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10902
10903 (define_insn "*ashlhi3_1_lea"
10904   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10905         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10906                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10907    (clobber (reg:CC FLAGS_REG))]
10908   "!TARGET_PARTIAL_REG_STALL
10909    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10910 {
10911   switch (get_attr_type (insn))
10912     {
10913     case TYPE_LEA:
10914       return "#";
10915     case TYPE_ALU:
10916       gcc_assert (operands[2] == const1_rtx);
10917       return "add{w}\t{%0, %0|%0, %0}";
10918
10919     default:
10920       if (REG_P (operands[2]))
10921         return "sal{w}\t{%b2, %0|%0, %b2}";
10922       else if (operands[2] == const1_rtx
10923                && (TARGET_SHIFT1 || optimize_size))
10924         return "sal{w}\t%0";
10925       else
10926         return "sal{w}\t{%2, %0|%0, %2}";
10927     }
10928 }
10929   [(set (attr "type")
10930      (cond [(eq_attr "alternative" "1")
10931               (const_string "lea")
10932             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10933                           (const_int 0))
10934                       (match_operand 0 "register_operand" ""))
10935                  (match_operand 2 "const1_operand" ""))
10936               (const_string "alu")
10937            ]
10938            (const_string "ishift")))
10939    (set_attr "mode" "HI,SI")])
10940
10941 (define_insn "*ashlhi3_1"
10942   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10943         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10944                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10945    (clobber (reg:CC FLAGS_REG))]
10946   "TARGET_PARTIAL_REG_STALL
10947    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10948 {
10949   switch (get_attr_type (insn))
10950     {
10951     case TYPE_ALU:
10952       gcc_assert (operands[2] == const1_rtx);
10953       return "add{w}\t{%0, %0|%0, %0}";
10954
10955     default:
10956       if (REG_P (operands[2]))
10957         return "sal{w}\t{%b2, %0|%0, %b2}";
10958       else if (operands[2] == const1_rtx
10959                && (TARGET_SHIFT1 || optimize_size))
10960         return "sal{w}\t%0";
10961       else
10962         return "sal{w}\t{%2, %0|%0, %2}";
10963     }
10964 }
10965   [(set (attr "type")
10966      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10967                           (const_int 0))
10968                       (match_operand 0 "register_operand" ""))
10969                  (match_operand 2 "const1_operand" ""))
10970               (const_string "alu")
10971            ]
10972            (const_string "ishift")))
10973    (set_attr "mode" "HI")])
10974
10975 ;; This pattern can't accept a variable shift count, since shifts by
10976 ;; zero don't affect the flags.  We assume that shifts by constant
10977 ;; zero are optimized away.
10978 (define_insn "*ashlhi3_cmp"
10979   [(set (reg FLAGS_REG)
10980         (compare
10981           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10982                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10983           (const_int 0)))
10984    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10985         (ashift:HI (match_dup 1) (match_dup 2)))]
10986   "ix86_match_ccmode (insn, CCGOCmode)
10987    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10988    && (optimize_size
10989        || !TARGET_PARTIAL_FLAG_REG_STALL
10990        || (operands[2] == const1_rtx
10991            && (TARGET_SHIFT1
10992                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10993 {
10994   switch (get_attr_type (insn))
10995     {
10996     case TYPE_ALU:
10997       gcc_assert (operands[2] == const1_rtx);
10998       return "add{w}\t{%0, %0|%0, %0}";
10999
11000     default:
11001       if (REG_P (operands[2]))
11002         return "sal{w}\t{%b2, %0|%0, %b2}";
11003       else if (operands[2] == const1_rtx
11004                && (TARGET_SHIFT1 || optimize_size))
11005         return "sal{w}\t%0";
11006       else
11007         return "sal{w}\t{%2, %0|%0, %2}";
11008     }
11009 }
11010   [(set (attr "type")
11011      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11012                           (const_int 0))
11013                       (match_operand 0 "register_operand" ""))
11014                  (match_operand 2 "const1_operand" ""))
11015               (const_string "alu")
11016            ]
11017            (const_string "ishift")))
11018    (set_attr "mode" "HI")])
11019
11020 (define_insn "*ashlhi3_cconly"
11021   [(set (reg FLAGS_REG)
11022         (compare
11023           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11024                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11025           (const_int 0)))
11026    (clobber (match_scratch:HI 0 "=r"))]
11027   "ix86_match_ccmode (insn, CCGOCmode)
11028    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11029    && (optimize_size
11030        || !TARGET_PARTIAL_FLAG_REG_STALL
11031        || (operands[2] == const1_rtx
11032            && (TARGET_SHIFT1
11033                || TARGET_DOUBLE_WITH_ADD)))"
11034 {
11035   switch (get_attr_type (insn))
11036     {
11037     case TYPE_ALU:
11038       gcc_assert (operands[2] == const1_rtx);
11039       return "add{w}\t{%0, %0|%0, %0}";
11040
11041     default:
11042       if (REG_P (operands[2]))
11043         return "sal{w}\t{%b2, %0|%0, %b2}";
11044       else if (operands[2] == const1_rtx
11045                && (TARGET_SHIFT1 || optimize_size))
11046         return "sal{w}\t%0";
11047       else
11048         return "sal{w}\t{%2, %0|%0, %2}";
11049     }
11050 }
11051   [(set (attr "type")
11052      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11053                           (const_int 0))
11054                       (match_operand 0 "register_operand" ""))
11055                  (match_operand 2 "const1_operand" ""))
11056               (const_string "alu")
11057            ]
11058            (const_string "ishift")))
11059    (set_attr "mode" "HI")])
11060
11061 (define_expand "ashlqi3"
11062   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11063         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11064                    (match_operand:QI 2 "nonmemory_operand" "")))
11065    (clobber (reg:CC FLAGS_REG))]
11066   "TARGET_QIMODE_MATH"
11067   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11068
11069 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11070
11071 (define_insn "*ashlqi3_1_lea"
11072   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11073         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11074                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11075    (clobber (reg:CC FLAGS_REG))]
11076   "!TARGET_PARTIAL_REG_STALL
11077    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11078 {
11079   switch (get_attr_type (insn))
11080     {
11081     case TYPE_LEA:
11082       return "#";
11083     case TYPE_ALU:
11084       gcc_assert (operands[2] == const1_rtx);
11085       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11086         return "add{l}\t{%k0, %k0|%k0, %k0}";
11087       else
11088         return "add{b}\t{%0, %0|%0, %0}";
11089
11090     default:
11091       if (REG_P (operands[2]))
11092         {
11093           if (get_attr_mode (insn) == MODE_SI)
11094             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11095           else
11096             return "sal{b}\t{%b2, %0|%0, %b2}";
11097         }
11098       else if (operands[2] == const1_rtx
11099                && (TARGET_SHIFT1 || optimize_size))
11100         {
11101           if (get_attr_mode (insn) == MODE_SI)
11102             return "sal{l}\t%0";
11103           else
11104             return "sal{b}\t%0";
11105         }
11106       else
11107         {
11108           if (get_attr_mode (insn) == MODE_SI)
11109             return "sal{l}\t{%2, %k0|%k0, %2}";
11110           else
11111             return "sal{b}\t{%2, %0|%0, %2}";
11112         }
11113     }
11114 }
11115   [(set (attr "type")
11116      (cond [(eq_attr "alternative" "2")
11117               (const_string "lea")
11118             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11119                           (const_int 0))
11120                       (match_operand 0 "register_operand" ""))
11121                  (match_operand 2 "const1_operand" ""))
11122               (const_string "alu")
11123            ]
11124            (const_string "ishift")))
11125    (set_attr "mode" "QI,SI,SI")])
11126
11127 (define_insn "*ashlqi3_1"
11128   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11129         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11130                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11131    (clobber (reg:CC FLAGS_REG))]
11132   "TARGET_PARTIAL_REG_STALL
11133    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11134 {
11135   switch (get_attr_type (insn))
11136     {
11137     case TYPE_ALU:
11138       gcc_assert (operands[2] == const1_rtx);
11139       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11140         return "add{l}\t{%k0, %k0|%k0, %k0}";
11141       else
11142         return "add{b}\t{%0, %0|%0, %0}";
11143
11144     default:
11145       if (REG_P (operands[2]))
11146         {
11147           if (get_attr_mode (insn) == MODE_SI)
11148             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11149           else
11150             return "sal{b}\t{%b2, %0|%0, %b2}";
11151         }
11152       else if (operands[2] == const1_rtx
11153                && (TARGET_SHIFT1 || optimize_size))
11154         {
11155           if (get_attr_mode (insn) == MODE_SI)
11156             return "sal{l}\t%0";
11157           else
11158             return "sal{b}\t%0";
11159         }
11160       else
11161         {
11162           if (get_attr_mode (insn) == MODE_SI)
11163             return "sal{l}\t{%2, %k0|%k0, %2}";
11164           else
11165             return "sal{b}\t{%2, %0|%0, %2}";
11166         }
11167     }
11168 }
11169   [(set (attr "type")
11170      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11171                           (const_int 0))
11172                       (match_operand 0 "register_operand" ""))
11173                  (match_operand 2 "const1_operand" ""))
11174               (const_string "alu")
11175            ]
11176            (const_string "ishift")))
11177    (set_attr "mode" "QI,SI")])
11178
11179 ;; This pattern can't accept a variable shift count, since shifts by
11180 ;; zero don't affect the flags.  We assume that shifts by constant
11181 ;; zero are optimized away.
11182 (define_insn "*ashlqi3_cmp"
11183   [(set (reg FLAGS_REG)
11184         (compare
11185           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11186                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11187           (const_int 0)))
11188    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11189         (ashift:QI (match_dup 1) (match_dup 2)))]
11190   "ix86_match_ccmode (insn, CCGOCmode)
11191    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11192    && (optimize_size
11193        || !TARGET_PARTIAL_FLAG_REG_STALL
11194        || (operands[2] == const1_rtx
11195            && (TARGET_SHIFT1
11196                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11197 {
11198   switch (get_attr_type (insn))
11199     {
11200     case TYPE_ALU:
11201       gcc_assert (operands[2] == const1_rtx);
11202       return "add{b}\t{%0, %0|%0, %0}";
11203
11204     default:
11205       if (REG_P (operands[2]))
11206         return "sal{b}\t{%b2, %0|%0, %b2}";
11207       else if (operands[2] == const1_rtx
11208                && (TARGET_SHIFT1 || optimize_size))
11209         return "sal{b}\t%0";
11210       else
11211         return "sal{b}\t{%2, %0|%0, %2}";
11212     }
11213 }
11214   [(set (attr "type")
11215      (cond [(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")])
11223
11224 (define_insn "*ashlqi3_cconly"
11225   [(set (reg FLAGS_REG)
11226         (compare
11227           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11228                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11229           (const_int 0)))
11230    (clobber (match_scratch:QI 0 "=q"))]
11231   "ix86_match_ccmode (insn, CCGOCmode)
11232    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11233    && (optimize_size
11234        || !TARGET_PARTIAL_FLAG_REG_STALL
11235        || (operands[2] == const1_rtx
11236            && (TARGET_SHIFT1
11237                || TARGET_DOUBLE_WITH_ADD)))"
11238 {
11239   switch (get_attr_type (insn))
11240     {
11241     case TYPE_ALU:
11242       gcc_assert (operands[2] == const1_rtx);
11243       return "add{b}\t{%0, %0|%0, %0}";
11244
11245     default:
11246       if (REG_P (operands[2]))
11247         return "sal{b}\t{%b2, %0|%0, %b2}";
11248       else if (operands[2] == const1_rtx
11249                && (TARGET_SHIFT1 || optimize_size))
11250         return "sal{b}\t%0";
11251       else
11252         return "sal{b}\t{%2, %0|%0, %2}";
11253     }
11254 }
11255   [(set (attr "type")
11256      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11257                           (const_int 0))
11258                       (match_operand 0 "register_operand" ""))
11259                  (match_operand 2 "const1_operand" ""))
11260               (const_string "alu")
11261            ]
11262            (const_string "ishift")))
11263    (set_attr "mode" "QI")])
11264
11265 ;; See comment above `ashldi3' about how this works.
11266
11267 (define_expand "ashrti3"
11268   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11269                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11270                                 (match_operand:QI 2 "nonmemory_operand" "")))
11271               (clobber (reg:CC FLAGS_REG))])]
11272   "TARGET_64BIT"
11273 {
11274   if (! immediate_operand (operands[2], QImode))
11275     {
11276       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11277       DONE;
11278     }
11279   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11280   DONE;
11281 })
11282
11283 (define_insn "ashrti3_1"
11284   [(set (match_operand:TI 0 "register_operand" "=r")
11285         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11286                      (match_operand:QI 2 "register_operand" "c")))
11287    (clobber (match_scratch:DI 3 "=&r"))
11288    (clobber (reg:CC FLAGS_REG))]
11289   "TARGET_64BIT"
11290   "#"
11291   [(set_attr "type" "multi")])
11292
11293 (define_insn "*ashrti3_2"
11294   [(set (match_operand:TI 0 "register_operand" "=r")
11295         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11296                      (match_operand:QI 2 "immediate_operand" "O")))
11297    (clobber (reg:CC FLAGS_REG))]
11298   "TARGET_64BIT"
11299   "#"
11300   [(set_attr "type" "multi")])
11301
11302 (define_split
11303   [(set (match_operand:TI 0 "register_operand" "")
11304         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11305                      (match_operand:QI 2 "register_operand" "")))
11306    (clobber (match_scratch:DI 3 ""))
11307    (clobber (reg:CC FLAGS_REG))]
11308   "TARGET_64BIT && reload_completed"
11309   [(const_int 0)]
11310   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11311
11312 (define_split
11313   [(set (match_operand:TI 0 "register_operand" "")
11314         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11315                      (match_operand:QI 2 "immediate_operand" "")))
11316    (clobber (reg:CC FLAGS_REG))]
11317   "TARGET_64BIT && reload_completed"
11318   [(const_int 0)]
11319   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11320
11321 (define_insn "x86_64_shrd"
11322   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11323         (ior:DI (ashiftrt:DI (match_dup 0)
11324                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11325                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11326                   (minus:QI (const_int 64) (match_dup 2)))))
11327    (clobber (reg:CC FLAGS_REG))]
11328   "TARGET_64BIT"
11329   "@
11330    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11331    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11332   [(set_attr "type" "ishift")
11333    (set_attr "prefix_0f" "1")
11334    (set_attr "mode" "DI")
11335    (set_attr "athlon_decode" "vector")])
11336
11337 (define_expand "ashrdi3"
11338   [(set (match_operand:DI 0 "shiftdi_operand" "")
11339         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11340                      (match_operand:QI 2 "nonmemory_operand" "")))]
11341   ""
11342   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11343
11344 (define_insn "*ashrdi3_63_rex64"
11345   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11346         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11347                      (match_operand:DI 2 "const_int_operand" "i,i")))
11348    (clobber (reg:CC FLAGS_REG))]
11349   "TARGET_64BIT && INTVAL (operands[2]) == 63
11350    && (TARGET_USE_CLTD || optimize_size)
11351    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11352   "@
11353    {cqto|cqo}
11354    sar{q}\t{%2, %0|%0, %2}"
11355   [(set_attr "type" "imovx,ishift")
11356    (set_attr "prefix_0f" "0,*")
11357    (set_attr "length_immediate" "0,*")
11358    (set_attr "modrm" "0,1")
11359    (set_attr "mode" "DI")])
11360
11361 (define_insn "*ashrdi3_1_one_bit_rex64"
11362   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11363         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11364                      (match_operand:QI 2 "const1_operand" "")))
11365    (clobber (reg:CC FLAGS_REG))]
11366   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11367    && (TARGET_SHIFT1 || optimize_size)"
11368   "sar{q}\t%0"
11369   [(set_attr "type" "ishift")
11370    (set (attr "length")
11371      (if_then_else (match_operand:DI 0 "register_operand" "")
11372         (const_string "2")
11373         (const_string "*")))])
11374
11375 (define_insn "*ashrdi3_1_rex64"
11376   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11377         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11378                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11379    (clobber (reg:CC FLAGS_REG))]
11380   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11381   "@
11382    sar{q}\t{%2, %0|%0, %2}
11383    sar{q}\t{%b2, %0|%0, %b2}"
11384   [(set_attr "type" "ishift")
11385    (set_attr "mode" "DI")])
11386
11387 ;; This pattern can't accept a variable shift count, since shifts by
11388 ;; zero don't affect the flags.  We assume that shifts by constant
11389 ;; zero are optimized away.
11390 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11391   [(set (reg FLAGS_REG)
11392         (compare
11393           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11394                        (match_operand:QI 2 "const1_operand" ""))
11395           (const_int 0)))
11396    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11397         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11398   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11399    && (TARGET_SHIFT1 || optimize_size)
11400    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11401   "sar{q}\t%0"
11402   [(set_attr "type" "ishift")
11403    (set (attr "length")
11404      (if_then_else (match_operand:DI 0 "register_operand" "")
11405         (const_string "2")
11406         (const_string "*")))])
11407
11408 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11409   [(set (reg FLAGS_REG)
11410         (compare
11411           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11412                        (match_operand:QI 2 "const1_operand" ""))
11413           (const_int 0)))
11414    (clobber (match_scratch:DI 0 "=r"))]
11415   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11416    && (TARGET_SHIFT1 || optimize_size)
11417    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11418   "sar{q}\t%0"
11419   [(set_attr "type" "ishift")
11420    (set_attr "length" "2")])
11421
11422 ;; This pattern can't accept a variable shift count, since shifts by
11423 ;; zero don't affect the flags.  We assume that shifts by constant
11424 ;; zero are optimized away.
11425 (define_insn "*ashrdi3_cmp_rex64"
11426   [(set (reg FLAGS_REG)
11427         (compare
11428           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11429                        (match_operand:QI 2 "const_int_operand" "n"))
11430           (const_int 0)))
11431    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11432         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11433   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11434    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11435    && (optimize_size
11436        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11437   "sar{q}\t{%2, %0|%0, %2}"
11438   [(set_attr "type" "ishift")
11439    (set_attr "mode" "DI")])
11440
11441 (define_insn "*ashrdi3_cconly_rex64"
11442   [(set (reg FLAGS_REG)
11443         (compare
11444           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11445                        (match_operand:QI 2 "const_int_operand" "n"))
11446           (const_int 0)))
11447    (clobber (match_scratch:DI 0 "=r"))]
11448   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11449    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11450    && (optimize_size
11451        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11452   "sar{q}\t{%2, %0|%0, %2}"
11453   [(set_attr "type" "ishift")
11454    (set_attr "mode" "DI")])
11455
11456 (define_insn "*ashrdi3_1"
11457   [(set (match_operand:DI 0 "register_operand" "=r")
11458         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11459                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11460    (clobber (reg:CC FLAGS_REG))]
11461   "!TARGET_64BIT"
11462   "#"
11463   [(set_attr "type" "multi")])
11464
11465 ;; By default we don't ask for a scratch register, because when DImode
11466 ;; values are manipulated, registers are already at a premium.  But if
11467 ;; we have one handy, we won't turn it away.
11468 (define_peephole2
11469   [(match_scratch:SI 3 "r")
11470    (parallel [(set (match_operand:DI 0 "register_operand" "")
11471                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11472                                 (match_operand:QI 2 "nonmemory_operand" "")))
11473               (clobber (reg:CC FLAGS_REG))])
11474    (match_dup 3)]
11475   "!TARGET_64BIT && TARGET_CMOVE"
11476   [(const_int 0)]
11477   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11478
11479 (define_split
11480   [(set (match_operand:DI 0 "register_operand" "")
11481         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11482                      (match_operand:QI 2 "nonmemory_operand" "")))
11483    (clobber (reg:CC FLAGS_REG))]
11484   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11485                      ? flow2_completed : reload_completed)"
11486   [(const_int 0)]
11487   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11488
11489 (define_insn "x86_shrd_1"
11490   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11491         (ior:SI (ashiftrt:SI (match_dup 0)
11492                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11493                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11494                   (minus:QI (const_int 32) (match_dup 2)))))
11495    (clobber (reg:CC FLAGS_REG))]
11496   ""
11497   "@
11498    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11499    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11500   [(set_attr "type" "ishift")
11501    (set_attr "prefix_0f" "1")
11502    (set_attr "pent_pair" "np")
11503    (set_attr "mode" "SI")])
11504
11505 (define_expand "x86_shift_adj_3"
11506   [(use (match_operand:SI 0 "register_operand" ""))
11507    (use (match_operand:SI 1 "register_operand" ""))
11508    (use (match_operand:QI 2 "register_operand" ""))]
11509   ""
11510 {
11511   rtx label = gen_label_rtx ();
11512   rtx tmp;
11513
11514   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11515
11516   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11517   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11518   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11519                               gen_rtx_LABEL_REF (VOIDmode, label),
11520                               pc_rtx);
11521   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11522   JUMP_LABEL (tmp) = label;
11523
11524   emit_move_insn (operands[0], operands[1]);
11525   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11526
11527   emit_label (label);
11528   LABEL_NUSES (label) = 1;
11529
11530   DONE;
11531 })
11532
11533 (define_insn "ashrsi3_31"
11534   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11535         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11536                      (match_operand:SI 2 "const_int_operand" "i,i")))
11537    (clobber (reg:CC FLAGS_REG))]
11538   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11539    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11540   "@
11541    {cltd|cdq}
11542    sar{l}\t{%2, %0|%0, %2}"
11543   [(set_attr "type" "imovx,ishift")
11544    (set_attr "prefix_0f" "0,*")
11545    (set_attr "length_immediate" "0,*")
11546    (set_attr "modrm" "0,1")
11547    (set_attr "mode" "SI")])
11548
11549 (define_insn "*ashrsi3_31_zext"
11550   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11551         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11552                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11553    (clobber (reg:CC FLAGS_REG))]
11554   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11555    && INTVAL (operands[2]) == 31
11556    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11557   "@
11558    {cltd|cdq}
11559    sar{l}\t{%2, %k0|%k0, %2}"
11560   [(set_attr "type" "imovx,ishift")
11561    (set_attr "prefix_0f" "0,*")
11562    (set_attr "length_immediate" "0,*")
11563    (set_attr "modrm" "0,1")
11564    (set_attr "mode" "SI")])
11565
11566 (define_expand "ashrsi3"
11567   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11568         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11569                      (match_operand:QI 2 "nonmemory_operand" "")))
11570    (clobber (reg:CC FLAGS_REG))]
11571   ""
11572   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11573
11574 (define_insn "*ashrsi3_1_one_bit"
11575   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11576         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11577                      (match_operand:QI 2 "const1_operand" "")))
11578    (clobber (reg:CC FLAGS_REG))]
11579   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11580    && (TARGET_SHIFT1 || optimize_size)"
11581   "sar{l}\t%0"
11582   [(set_attr "type" "ishift")
11583    (set (attr "length")
11584      (if_then_else (match_operand:SI 0 "register_operand" "")
11585         (const_string "2")
11586         (const_string "*")))])
11587
11588 (define_insn "*ashrsi3_1_one_bit_zext"
11589   [(set (match_operand:DI 0 "register_operand" "=r")
11590         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11591                                      (match_operand:QI 2 "const1_operand" ""))))
11592    (clobber (reg:CC FLAGS_REG))]
11593   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11594    && (TARGET_SHIFT1 || optimize_size)"
11595   "sar{l}\t%k0"
11596   [(set_attr "type" "ishift")
11597    (set_attr "length" "2")])
11598
11599 (define_insn "*ashrsi3_1"
11600   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11601         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11602                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11603    (clobber (reg:CC FLAGS_REG))]
11604   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11605   "@
11606    sar{l}\t{%2, %0|%0, %2}
11607    sar{l}\t{%b2, %0|%0, %b2}"
11608   [(set_attr "type" "ishift")
11609    (set_attr "mode" "SI")])
11610
11611 (define_insn "*ashrsi3_1_zext"
11612   [(set (match_operand:DI 0 "register_operand" "=r,r")
11613         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11614                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11615    (clobber (reg:CC FLAGS_REG))]
11616   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11617   "@
11618    sar{l}\t{%2, %k0|%k0, %2}
11619    sar{l}\t{%b2, %k0|%k0, %b2}"
11620   [(set_attr "type" "ishift")
11621    (set_attr "mode" "SI")])
11622
11623 ;; This pattern can't accept a variable shift count, since shifts by
11624 ;; zero don't affect the flags.  We assume that shifts by constant
11625 ;; zero are optimized away.
11626 (define_insn "*ashrsi3_one_bit_cmp"
11627   [(set (reg FLAGS_REG)
11628         (compare
11629           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11630                        (match_operand:QI 2 "const1_operand" ""))
11631           (const_int 0)))
11632    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11633         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11634   "ix86_match_ccmode (insn, CCGOCmode)
11635    && (TARGET_SHIFT1 || optimize_size)
11636    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11637   "sar{l}\t%0"
11638   [(set_attr "type" "ishift")
11639    (set (attr "length")
11640      (if_then_else (match_operand:SI 0 "register_operand" "")
11641         (const_string "2")
11642         (const_string "*")))])
11643
11644 (define_insn "*ashrsi3_one_bit_cconly"
11645   [(set (reg FLAGS_REG)
11646         (compare
11647           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11648                        (match_operand:QI 2 "const1_operand" ""))
11649           (const_int 0)))
11650    (clobber (match_scratch:SI 0 "=r"))]
11651   "ix86_match_ccmode (insn, CCGOCmode)
11652    && (TARGET_SHIFT1 || optimize_size)
11653    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11654   "sar{l}\t%0"
11655   [(set_attr "type" "ishift")
11656    (set_attr "length" "2")])
11657
11658 (define_insn "*ashrsi3_one_bit_cmp_zext"
11659   [(set (reg FLAGS_REG)
11660         (compare
11661           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11662                        (match_operand:QI 2 "const1_operand" ""))
11663           (const_int 0)))
11664    (set (match_operand:DI 0 "register_operand" "=r")
11665         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11666   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11667    && (TARGET_SHIFT1 || optimize_size)
11668    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11669   "sar{l}\t%k0"
11670   [(set_attr "type" "ishift")
11671    (set_attr "length" "2")])
11672
11673 ;; This pattern can't accept a variable shift count, since shifts by
11674 ;; zero don't affect the flags.  We assume that shifts by constant
11675 ;; zero are optimized away.
11676 (define_insn "*ashrsi3_cmp"
11677   [(set (reg FLAGS_REG)
11678         (compare
11679           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11680                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11681           (const_int 0)))
11682    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11683         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11684   "ix86_match_ccmode (insn, CCGOCmode)
11685    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11686    && (optimize_size
11687        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11688   "sar{l}\t{%2, %0|%0, %2}"
11689   [(set_attr "type" "ishift")
11690    (set_attr "mode" "SI")])
11691
11692 (define_insn "*ashrsi3_cconly"
11693   [(set (reg FLAGS_REG)
11694         (compare
11695           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11696                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11697           (const_int 0)))
11698    (clobber (match_scratch:SI 0 "=r"))]
11699   "ix86_match_ccmode (insn, CCGOCmode)
11700    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11701    && (optimize_size
11702        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11703   "sar{l}\t{%2, %0|%0, %2}"
11704   [(set_attr "type" "ishift")
11705    (set_attr "mode" "SI")])
11706
11707 (define_insn "*ashrsi3_cmp_zext"
11708   [(set (reg FLAGS_REG)
11709         (compare
11710           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11711                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11712           (const_int 0)))
11713    (set (match_operand:DI 0 "register_operand" "=r")
11714         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11715   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11716    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11717    && (optimize_size
11718        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11719   "sar{l}\t{%2, %k0|%k0, %2}"
11720   [(set_attr "type" "ishift")
11721    (set_attr "mode" "SI")])
11722
11723 (define_expand "ashrhi3"
11724   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11725         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11726                      (match_operand:QI 2 "nonmemory_operand" "")))
11727    (clobber (reg:CC FLAGS_REG))]
11728   "TARGET_HIMODE_MATH"
11729   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11730
11731 (define_insn "*ashrhi3_1_one_bit"
11732   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11733         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11734                      (match_operand:QI 2 "const1_operand" "")))
11735    (clobber (reg:CC FLAGS_REG))]
11736   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11737    && (TARGET_SHIFT1 || optimize_size)"
11738   "sar{w}\t%0"
11739   [(set_attr "type" "ishift")
11740    (set (attr "length")
11741      (if_then_else (match_operand 0 "register_operand" "")
11742         (const_string "2")
11743         (const_string "*")))])
11744
11745 (define_insn "*ashrhi3_1"
11746   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11747         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11748                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11749    (clobber (reg:CC FLAGS_REG))]
11750   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11751   "@
11752    sar{w}\t{%2, %0|%0, %2}
11753    sar{w}\t{%b2, %0|%0, %b2}"
11754   [(set_attr "type" "ishift")
11755    (set_attr "mode" "HI")])
11756
11757 ;; This pattern can't accept a variable shift count, since shifts by
11758 ;; zero don't affect the flags.  We assume that shifts by constant
11759 ;; zero are optimized away.
11760 (define_insn "*ashrhi3_one_bit_cmp"
11761   [(set (reg FLAGS_REG)
11762         (compare
11763           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11764                        (match_operand:QI 2 "const1_operand" ""))
11765           (const_int 0)))
11766    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11767         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11768   "ix86_match_ccmode (insn, CCGOCmode)
11769    && (TARGET_SHIFT1 || optimize_size)
11770    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11771   "sar{w}\t%0"
11772   [(set_attr "type" "ishift")
11773    (set (attr "length")
11774      (if_then_else (match_operand 0 "register_operand" "")
11775         (const_string "2")
11776         (const_string "*")))])
11777
11778 (define_insn "*ashrhi3_one_bit_cconly"
11779   [(set (reg FLAGS_REG)
11780         (compare
11781           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11782                        (match_operand:QI 2 "const1_operand" ""))
11783           (const_int 0)))
11784    (clobber (match_scratch:HI 0 "=r"))]
11785   "ix86_match_ccmode (insn, CCGOCmode)
11786    && (TARGET_SHIFT1 || optimize_size)
11787    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11788   "sar{w}\t%0"
11789   [(set_attr "type" "ishift")
11790    (set_attr "length" "2")])
11791
11792 ;; This pattern can't accept a variable shift count, since shifts by
11793 ;; zero don't affect the flags.  We assume that shifts by constant
11794 ;; zero are optimized away.
11795 (define_insn "*ashrhi3_cmp"
11796   [(set (reg FLAGS_REG)
11797         (compare
11798           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11799                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11800           (const_int 0)))
11801    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11802         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11803   "ix86_match_ccmode (insn, CCGOCmode)
11804    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11805    && (optimize_size
11806        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11807   "sar{w}\t{%2, %0|%0, %2}"
11808   [(set_attr "type" "ishift")
11809    (set_attr "mode" "HI")])
11810
11811 (define_insn "*ashrhi3_cconly"
11812   [(set (reg FLAGS_REG)
11813         (compare
11814           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11815                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11816           (const_int 0)))
11817    (clobber (match_scratch:HI 0 "=r"))]
11818   "ix86_match_ccmode (insn, CCGOCmode)
11819    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11820    && (optimize_size
11821        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11822   "sar{w}\t{%2, %0|%0, %2}"
11823   [(set_attr "type" "ishift")
11824    (set_attr "mode" "HI")])
11825
11826 (define_expand "ashrqi3"
11827   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11828         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11829                      (match_operand:QI 2 "nonmemory_operand" "")))
11830    (clobber (reg:CC FLAGS_REG))]
11831   "TARGET_QIMODE_MATH"
11832   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11833
11834 (define_insn "*ashrqi3_1_one_bit"
11835   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11836         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11837                      (match_operand:QI 2 "const1_operand" "")))
11838    (clobber (reg:CC FLAGS_REG))]
11839   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11840    && (TARGET_SHIFT1 || optimize_size)"
11841   "sar{b}\t%0"
11842   [(set_attr "type" "ishift")
11843    (set (attr "length")
11844      (if_then_else (match_operand 0 "register_operand" "")
11845         (const_string "2")
11846         (const_string "*")))])
11847
11848 (define_insn "*ashrqi3_1_one_bit_slp"
11849   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11850         (ashiftrt:QI (match_dup 0)
11851                      (match_operand:QI 1 "const1_operand" "")))
11852    (clobber (reg:CC FLAGS_REG))]
11853   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11854    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11855    && (TARGET_SHIFT1 || optimize_size)"
11856   "sar{b}\t%0"
11857   [(set_attr "type" "ishift1")
11858    (set (attr "length")
11859      (if_then_else (match_operand 0 "register_operand" "")
11860         (const_string "2")
11861         (const_string "*")))])
11862
11863 (define_insn "*ashrqi3_1"
11864   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11865         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11866                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11867    (clobber (reg:CC FLAGS_REG))]
11868   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11869   "@
11870    sar{b}\t{%2, %0|%0, %2}
11871    sar{b}\t{%b2, %0|%0, %b2}"
11872   [(set_attr "type" "ishift")
11873    (set_attr "mode" "QI")])
11874
11875 (define_insn "*ashrqi3_1_slp"
11876   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11877         (ashiftrt:QI (match_dup 0)
11878                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11879    (clobber (reg:CC FLAGS_REG))]
11880   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11881    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11882   "@
11883    sar{b}\t{%1, %0|%0, %1}
11884    sar{b}\t{%b1, %0|%0, %b1}"
11885   [(set_attr "type" "ishift1")
11886    (set_attr "mode" "QI")])
11887
11888 ;; This pattern can't accept a variable shift count, since shifts by
11889 ;; zero don't affect the flags.  We assume that shifts by constant
11890 ;; zero are optimized away.
11891 (define_insn "*ashrqi3_one_bit_cmp"
11892   [(set (reg FLAGS_REG)
11893         (compare
11894           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11895                        (match_operand:QI 2 "const1_operand" "I"))
11896           (const_int 0)))
11897    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11898         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11899   "ix86_match_ccmode (insn, CCGOCmode)
11900    && (TARGET_SHIFT1 || optimize_size)
11901    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11902   "sar{b}\t%0"
11903   [(set_attr "type" "ishift")
11904    (set (attr "length")
11905      (if_then_else (match_operand 0 "register_operand" "")
11906         (const_string "2")
11907         (const_string "*")))])
11908
11909 (define_insn "*ashrqi3_one_bit_cconly"
11910   [(set (reg FLAGS_REG)
11911         (compare
11912           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11913                        (match_operand:QI 2 "const1_operand" "I"))
11914           (const_int 0)))
11915    (clobber (match_scratch:QI 0 "=q"))]
11916   "ix86_match_ccmode (insn, CCGOCmode)
11917    && (TARGET_SHIFT1 || optimize_size)
11918    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11919   "sar{b}\t%0"
11920   [(set_attr "type" "ishift")
11921    (set_attr "length" "2")])
11922
11923 ;; This pattern can't accept a variable shift count, since shifts by
11924 ;; zero don't affect the flags.  We assume that shifts by constant
11925 ;; zero are optimized away.
11926 (define_insn "*ashrqi3_cmp"
11927   [(set (reg FLAGS_REG)
11928         (compare
11929           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11930                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11931           (const_int 0)))
11932    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11933         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11934   "ix86_match_ccmode (insn, CCGOCmode)
11935    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11936    && (optimize_size
11937        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11938   "sar{b}\t{%2, %0|%0, %2}"
11939   [(set_attr "type" "ishift")
11940    (set_attr "mode" "QI")])
11941
11942 (define_insn "*ashrqi3_cconly"
11943   [(set (reg FLAGS_REG)
11944         (compare
11945           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11946                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11947           (const_int 0)))
11948    (clobber (match_scratch:QI 0 "=q"))]
11949   "ix86_match_ccmode (insn, CCGOCmode)
11950    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11951    && (optimize_size
11952        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11953   "sar{b}\t{%2, %0|%0, %2}"
11954   [(set_attr "type" "ishift")
11955    (set_attr "mode" "QI")])
11956
11957 \f
11958 ;; Logical shift instructions
11959
11960 ;; See comment above `ashldi3' about how this works.
11961
11962 (define_expand "lshrti3"
11963   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11964                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11965                                 (match_operand:QI 2 "nonmemory_operand" "")))
11966               (clobber (reg:CC FLAGS_REG))])]
11967   "TARGET_64BIT"
11968 {
11969   if (! immediate_operand (operands[2], QImode))
11970     {
11971       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11972       DONE;
11973     }
11974   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11975   DONE;
11976 })
11977
11978 (define_insn "lshrti3_1"
11979   [(set (match_operand:TI 0 "register_operand" "=r")
11980         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11981                      (match_operand:QI 2 "register_operand" "c")))
11982    (clobber (match_scratch:DI 3 "=&r"))
11983    (clobber (reg:CC FLAGS_REG))]
11984   "TARGET_64BIT"
11985   "#"
11986   [(set_attr "type" "multi")])
11987
11988 (define_insn "*lshrti3_2"
11989   [(set (match_operand:TI 0 "register_operand" "=r")
11990         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11991                      (match_operand:QI 2 "immediate_operand" "O")))
11992    (clobber (reg:CC FLAGS_REG))]
11993   "TARGET_64BIT"
11994   "#"
11995   [(set_attr "type" "multi")])
11996
11997 (define_split
11998   [(set (match_operand:TI 0 "register_operand" "")
11999         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12000                      (match_operand:QI 2 "register_operand" "")))
12001    (clobber (match_scratch:DI 3 ""))
12002    (clobber (reg:CC FLAGS_REG))]
12003   "TARGET_64BIT && reload_completed"
12004   [(const_int 0)]
12005   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12006
12007 (define_split
12008   [(set (match_operand:TI 0 "register_operand" "")
12009         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12010                      (match_operand:QI 2 "immediate_operand" "")))
12011    (clobber (reg:CC FLAGS_REG))]
12012   "TARGET_64BIT && reload_completed"
12013   [(const_int 0)]
12014   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12015
12016 (define_expand "lshrdi3"
12017   [(set (match_operand:DI 0 "shiftdi_operand" "")
12018         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12019                      (match_operand:QI 2 "nonmemory_operand" "")))]
12020   ""
12021   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12022
12023 (define_insn "*lshrdi3_1_one_bit_rex64"
12024   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12025         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12026                      (match_operand:QI 2 "const1_operand" "")))
12027    (clobber (reg:CC FLAGS_REG))]
12028   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12029    && (TARGET_SHIFT1 || optimize_size)"
12030   "shr{q}\t%0"
12031   [(set_attr "type" "ishift")
12032    (set (attr "length")
12033      (if_then_else (match_operand:DI 0 "register_operand" "")
12034         (const_string "2")
12035         (const_string "*")))])
12036
12037 (define_insn "*lshrdi3_1_rex64"
12038   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12039         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12040                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12041    (clobber (reg:CC FLAGS_REG))]
12042   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12043   "@
12044    shr{q}\t{%2, %0|%0, %2}
12045    shr{q}\t{%b2, %0|%0, %b2}"
12046   [(set_attr "type" "ishift")
12047    (set_attr "mode" "DI")])
12048
12049 ;; This pattern can't accept a variable shift count, since shifts by
12050 ;; zero don't affect the flags.  We assume that shifts by constant
12051 ;; zero are optimized away.
12052 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12053   [(set (reg FLAGS_REG)
12054         (compare
12055           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12056                        (match_operand:QI 2 "const1_operand" ""))
12057           (const_int 0)))
12058    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12059         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12060   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12061    && (TARGET_SHIFT1 || optimize_size)
12062    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12063   "shr{q}\t%0"
12064   [(set_attr "type" "ishift")
12065    (set (attr "length")
12066      (if_then_else (match_operand:DI 0 "register_operand" "")
12067         (const_string "2")
12068         (const_string "*")))])
12069
12070 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12071   [(set (reg FLAGS_REG)
12072         (compare
12073           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12074                        (match_operand:QI 2 "const1_operand" ""))
12075           (const_int 0)))
12076    (clobber (match_scratch:DI 0 "=r"))]
12077   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12078    && (TARGET_SHIFT1 || optimize_size)
12079    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12080   "shr{q}\t%0"
12081   [(set_attr "type" "ishift")
12082    (set_attr "length" "2")])
12083
12084 ;; This pattern can't accept a variable shift count, since shifts by
12085 ;; zero don't affect the flags.  We assume that shifts by constant
12086 ;; zero are optimized away.
12087 (define_insn "*lshrdi3_cmp_rex64"
12088   [(set (reg FLAGS_REG)
12089         (compare
12090           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12091                        (match_operand:QI 2 "const_int_operand" "e"))
12092           (const_int 0)))
12093    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12094         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12095   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12096    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12097    && (optimize_size
12098        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12099   "shr{q}\t{%2, %0|%0, %2}"
12100   [(set_attr "type" "ishift")
12101    (set_attr "mode" "DI")])
12102
12103 (define_insn "*lshrdi3_cconly_rex64"
12104   [(set (reg FLAGS_REG)
12105         (compare
12106           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12107                        (match_operand:QI 2 "const_int_operand" "e"))
12108           (const_int 0)))
12109    (clobber (match_scratch:DI 0 "=r"))]
12110   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12111    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12112    && (optimize_size
12113        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12114   "shr{q}\t{%2, %0|%0, %2}"
12115   [(set_attr "type" "ishift")
12116    (set_attr "mode" "DI")])
12117
12118 (define_insn "*lshrdi3_1"
12119   [(set (match_operand:DI 0 "register_operand" "=r")
12120         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12121                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12122    (clobber (reg:CC FLAGS_REG))]
12123   "!TARGET_64BIT"
12124   "#"
12125   [(set_attr "type" "multi")])
12126
12127 ;; By default we don't ask for a scratch register, because when DImode
12128 ;; values are manipulated, registers are already at a premium.  But if
12129 ;; we have one handy, we won't turn it away.
12130 (define_peephole2
12131   [(match_scratch:SI 3 "r")
12132    (parallel [(set (match_operand:DI 0 "register_operand" "")
12133                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12134                                 (match_operand:QI 2 "nonmemory_operand" "")))
12135               (clobber (reg:CC FLAGS_REG))])
12136    (match_dup 3)]
12137   "!TARGET_64BIT && TARGET_CMOVE"
12138   [(const_int 0)]
12139   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12140
12141 (define_split
12142   [(set (match_operand:DI 0 "register_operand" "")
12143         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12144                      (match_operand:QI 2 "nonmemory_operand" "")))
12145    (clobber (reg:CC FLAGS_REG))]
12146   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12147                      ? flow2_completed : reload_completed)"
12148   [(const_int 0)]
12149   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12150
12151 (define_expand "lshrsi3"
12152   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12153         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12154                      (match_operand:QI 2 "nonmemory_operand" "")))
12155    (clobber (reg:CC FLAGS_REG))]
12156   ""
12157   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12158
12159 (define_insn "*lshrsi3_1_one_bit"
12160   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12161         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12162                      (match_operand:QI 2 "const1_operand" "")))
12163    (clobber (reg:CC FLAGS_REG))]
12164   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12165    && (TARGET_SHIFT1 || optimize_size)"
12166   "shr{l}\t%0"
12167   [(set_attr "type" "ishift")
12168    (set (attr "length")
12169      (if_then_else (match_operand:SI 0 "register_operand" "")
12170         (const_string "2")
12171         (const_string "*")))])
12172
12173 (define_insn "*lshrsi3_1_one_bit_zext"
12174   [(set (match_operand:DI 0 "register_operand" "=r")
12175         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12176                      (match_operand:QI 2 "const1_operand" "")))
12177    (clobber (reg:CC FLAGS_REG))]
12178   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12179    && (TARGET_SHIFT1 || optimize_size)"
12180   "shr{l}\t%k0"
12181   [(set_attr "type" "ishift")
12182    (set_attr "length" "2")])
12183
12184 (define_insn "*lshrsi3_1"
12185   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12186         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12187                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12188    (clobber (reg:CC FLAGS_REG))]
12189   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12190   "@
12191    shr{l}\t{%2, %0|%0, %2}
12192    shr{l}\t{%b2, %0|%0, %b2}"
12193   [(set_attr "type" "ishift")
12194    (set_attr "mode" "SI")])
12195
12196 (define_insn "*lshrsi3_1_zext"
12197   [(set (match_operand:DI 0 "register_operand" "=r,r")
12198         (zero_extend:DI
12199           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12200                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12201    (clobber (reg:CC FLAGS_REG))]
12202   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12203   "@
12204    shr{l}\t{%2, %k0|%k0, %2}
12205    shr{l}\t{%b2, %k0|%k0, %b2}"
12206   [(set_attr "type" "ishift")
12207    (set_attr "mode" "SI")])
12208
12209 ;; This pattern can't accept a variable shift count, since shifts by
12210 ;; zero don't affect the flags.  We assume that shifts by constant
12211 ;; zero are optimized away.
12212 (define_insn "*lshrsi3_one_bit_cmp"
12213   [(set (reg FLAGS_REG)
12214         (compare
12215           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12216                        (match_operand:QI 2 "const1_operand" ""))
12217           (const_int 0)))
12218    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12219         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12220   "ix86_match_ccmode (insn, CCGOCmode)
12221    && (TARGET_SHIFT1 || optimize_size)
12222    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12223   "shr{l}\t%0"
12224   [(set_attr "type" "ishift")
12225    (set (attr "length")
12226      (if_then_else (match_operand:SI 0 "register_operand" "")
12227         (const_string "2")
12228         (const_string "*")))])
12229
12230 (define_insn "*lshrsi3_one_bit_cconly"
12231   [(set (reg FLAGS_REG)
12232         (compare
12233           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12234                        (match_operand:QI 2 "const1_operand" ""))
12235           (const_int 0)))
12236    (clobber (match_scratch:SI 0 "=r"))]
12237   "ix86_match_ccmode (insn, CCGOCmode)
12238    && (TARGET_SHIFT1 || optimize_size)
12239    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12240   "shr{l}\t%0"
12241   [(set_attr "type" "ishift")
12242    (set_attr "length" "2")])
12243
12244 (define_insn "*lshrsi3_cmp_one_bit_zext"
12245   [(set (reg FLAGS_REG)
12246         (compare
12247           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12248                        (match_operand:QI 2 "const1_operand" ""))
12249           (const_int 0)))
12250    (set (match_operand:DI 0 "register_operand" "=r")
12251         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12252   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12253    && (TARGET_SHIFT1 || optimize_size)
12254    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12255   "shr{l}\t%k0"
12256   [(set_attr "type" "ishift")
12257    (set_attr "length" "2")])
12258
12259 ;; This pattern can't accept a variable shift count, since shifts by
12260 ;; zero don't affect the flags.  We assume that shifts by constant
12261 ;; zero are optimized away.
12262 (define_insn "*lshrsi3_cmp"
12263   [(set (reg FLAGS_REG)
12264         (compare
12265           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12266                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12267           (const_int 0)))
12268    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12269         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12270   "ix86_match_ccmode (insn, CCGOCmode)
12271    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12272    && (optimize_size
12273        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12274   "shr{l}\t{%2, %0|%0, %2}"
12275   [(set_attr "type" "ishift")
12276    (set_attr "mode" "SI")])
12277
12278 (define_insn "*lshrsi3_cconly"
12279   [(set (reg FLAGS_REG)
12280       (compare
12281         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12282                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12283         (const_int 0)))
12284    (clobber (match_scratch:SI 0 "=r"))]
12285   "ix86_match_ccmode (insn, CCGOCmode)
12286    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12287    && (optimize_size
12288        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12289   "shr{l}\t{%2, %0|%0, %2}"
12290   [(set_attr "type" "ishift")
12291    (set_attr "mode" "SI")])
12292
12293 (define_insn "*lshrsi3_cmp_zext"
12294   [(set (reg FLAGS_REG)
12295         (compare
12296           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12297                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12298           (const_int 0)))
12299    (set (match_operand:DI 0 "register_operand" "=r")
12300         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12301   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12302    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12303    && (optimize_size
12304        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12305   "shr{l}\t{%2, %k0|%k0, %2}"
12306   [(set_attr "type" "ishift")
12307    (set_attr "mode" "SI")])
12308
12309 (define_expand "lshrhi3"
12310   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12311         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12312                      (match_operand:QI 2 "nonmemory_operand" "")))
12313    (clobber (reg:CC FLAGS_REG))]
12314   "TARGET_HIMODE_MATH"
12315   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12316
12317 (define_insn "*lshrhi3_1_one_bit"
12318   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12319         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12320                      (match_operand:QI 2 "const1_operand" "")))
12321    (clobber (reg:CC FLAGS_REG))]
12322   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12323    && (TARGET_SHIFT1 || optimize_size)"
12324   "shr{w}\t%0"
12325   [(set_attr "type" "ishift")
12326    (set (attr "length")
12327      (if_then_else (match_operand 0 "register_operand" "")
12328         (const_string "2")
12329         (const_string "*")))])
12330
12331 (define_insn "*lshrhi3_1"
12332   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12333         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12334                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12335    (clobber (reg:CC FLAGS_REG))]
12336   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12337   "@
12338    shr{w}\t{%2, %0|%0, %2}
12339    shr{w}\t{%b2, %0|%0, %b2}"
12340   [(set_attr "type" "ishift")
12341    (set_attr "mode" "HI")])
12342
12343 ;; This pattern can't accept a variable shift count, since shifts by
12344 ;; zero don't affect the flags.  We assume that shifts by constant
12345 ;; zero are optimized away.
12346 (define_insn "*lshrhi3_one_bit_cmp"
12347   [(set (reg FLAGS_REG)
12348         (compare
12349           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12350                        (match_operand:QI 2 "const1_operand" ""))
12351           (const_int 0)))
12352    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12353         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12354   "ix86_match_ccmode (insn, CCGOCmode)
12355    && (TARGET_SHIFT1 || optimize_size)
12356    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12357   "shr{w}\t%0"
12358   [(set_attr "type" "ishift")
12359    (set (attr "length")
12360      (if_then_else (match_operand:SI 0 "register_operand" "")
12361         (const_string "2")
12362         (const_string "*")))])
12363
12364 (define_insn "*lshrhi3_one_bit_cconly"
12365   [(set (reg FLAGS_REG)
12366         (compare
12367           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368                        (match_operand:QI 2 "const1_operand" ""))
12369           (const_int 0)))
12370    (clobber (match_scratch:HI 0 "=r"))]
12371   "ix86_match_ccmode (insn, CCGOCmode)
12372    && (TARGET_SHIFT1 || optimize_size)
12373    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12374   "shr{w}\t%0"
12375   [(set_attr "type" "ishift")
12376    (set_attr "length" "2")])
12377
12378 ;; This pattern can't accept a variable shift count, since shifts by
12379 ;; zero don't affect the flags.  We assume that shifts by constant
12380 ;; zero are optimized away.
12381 (define_insn "*lshrhi3_cmp"
12382   [(set (reg FLAGS_REG)
12383         (compare
12384           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12385                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12386           (const_int 0)))
12387    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12388         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12389   "ix86_match_ccmode (insn, CCGOCmode)
12390    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12391    && (optimize_size
12392        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12393   "shr{w}\t{%2, %0|%0, %2}"
12394   [(set_attr "type" "ishift")
12395    (set_attr "mode" "HI")])
12396
12397 (define_insn "*lshrhi3_cconly"
12398   [(set (reg FLAGS_REG)
12399         (compare
12400           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12401                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12402           (const_int 0)))
12403    (clobber (match_scratch:HI 0 "=r"))]
12404   "ix86_match_ccmode (insn, CCGOCmode)
12405    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12406    && (optimize_size
12407        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12408   "shr{w}\t{%2, %0|%0, %2}"
12409   [(set_attr "type" "ishift")
12410    (set_attr "mode" "HI")])
12411
12412 (define_expand "lshrqi3"
12413   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12414         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12415                      (match_operand:QI 2 "nonmemory_operand" "")))
12416    (clobber (reg:CC FLAGS_REG))]
12417   "TARGET_QIMODE_MATH"
12418   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12419
12420 (define_insn "*lshrqi3_1_one_bit"
12421   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12422         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12423                      (match_operand:QI 2 "const1_operand" "")))
12424    (clobber (reg:CC FLAGS_REG))]
12425   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12426    && (TARGET_SHIFT1 || optimize_size)"
12427   "shr{b}\t%0"
12428   [(set_attr "type" "ishift")
12429    (set (attr "length")
12430      (if_then_else (match_operand 0 "register_operand" "")
12431         (const_string "2")
12432         (const_string "*")))])
12433
12434 (define_insn "*lshrqi3_1_one_bit_slp"
12435   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12436         (lshiftrt:QI (match_dup 0)
12437                      (match_operand:QI 1 "const1_operand" "")))
12438    (clobber (reg:CC FLAGS_REG))]
12439   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12440    && (TARGET_SHIFT1 || optimize_size)"
12441   "shr{b}\t%0"
12442   [(set_attr "type" "ishift1")
12443    (set (attr "length")
12444      (if_then_else (match_operand 0 "register_operand" "")
12445         (const_string "2")
12446         (const_string "*")))])
12447
12448 (define_insn "*lshrqi3_1"
12449   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12450         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12451                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12452    (clobber (reg:CC FLAGS_REG))]
12453   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12454   "@
12455    shr{b}\t{%2, %0|%0, %2}
12456    shr{b}\t{%b2, %0|%0, %b2}"
12457   [(set_attr "type" "ishift")
12458    (set_attr "mode" "QI")])
12459
12460 (define_insn "*lshrqi3_1_slp"
12461   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12462         (lshiftrt:QI (match_dup 0)
12463                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12464    (clobber (reg:CC FLAGS_REG))]
12465   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12466    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12467   "@
12468    shr{b}\t{%1, %0|%0, %1}
12469    shr{b}\t{%b1, %0|%0, %b1}"
12470   [(set_attr "type" "ishift1")
12471    (set_attr "mode" "QI")])
12472
12473 ;; This pattern can't accept a variable shift count, since shifts by
12474 ;; zero don't affect the flags.  We assume that shifts by constant
12475 ;; zero are optimized away.
12476 (define_insn "*lshrqi2_one_bit_cmp"
12477   [(set (reg FLAGS_REG)
12478         (compare
12479           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12480                        (match_operand:QI 2 "const1_operand" ""))
12481           (const_int 0)))
12482    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12483         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12484   "ix86_match_ccmode (insn, CCGOCmode)
12485    && (TARGET_SHIFT1 || optimize_size)
12486    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12487   "shr{b}\t%0"
12488   [(set_attr "type" "ishift")
12489    (set (attr "length")
12490      (if_then_else (match_operand:SI 0 "register_operand" "")
12491         (const_string "2")
12492         (const_string "*")))])
12493
12494 (define_insn "*lshrqi2_one_bit_cconly"
12495   [(set (reg FLAGS_REG)
12496         (compare
12497           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12498                        (match_operand:QI 2 "const1_operand" ""))
12499           (const_int 0)))
12500    (clobber (match_scratch:QI 0 "=q"))]
12501   "ix86_match_ccmode (insn, CCGOCmode)
12502    && (TARGET_SHIFT1 || optimize_size)
12503    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12504   "shr{b}\t%0"
12505   [(set_attr "type" "ishift")
12506    (set_attr "length" "2")])
12507
12508 ;; This pattern can't accept a variable shift count, since shifts by
12509 ;; zero don't affect the flags.  We assume that shifts by constant
12510 ;; zero are optimized away.
12511 (define_insn "*lshrqi2_cmp"
12512   [(set (reg FLAGS_REG)
12513         (compare
12514           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12515                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12516           (const_int 0)))
12517    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12518         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12519   "ix86_match_ccmode (insn, CCGOCmode)
12520    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12521    && (optimize_size
12522        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12523   "shr{b}\t{%2, %0|%0, %2}"
12524   [(set_attr "type" "ishift")
12525    (set_attr "mode" "QI")])
12526
12527 (define_insn "*lshrqi2_cconly"
12528   [(set (reg FLAGS_REG)
12529         (compare
12530           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12531                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12532           (const_int 0)))
12533    (clobber (match_scratch:QI 0 "=q"))]
12534   "ix86_match_ccmode (insn, CCGOCmode)
12535    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12536    && (optimize_size
12537        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12538   "shr{b}\t{%2, %0|%0, %2}"
12539   [(set_attr "type" "ishift")
12540    (set_attr "mode" "QI")])
12541 \f
12542 ;; Rotate instructions
12543
12544 (define_expand "rotldi3"
12545   [(set (match_operand:DI 0 "shiftdi_operand" "")
12546         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12547                    (match_operand:QI 2 "nonmemory_operand" "")))
12548    (clobber (reg:CC FLAGS_REG))]
12549  ""
12550 {
12551   if (TARGET_64BIT)
12552     {
12553       ix86_expand_binary_operator (ROTATE, DImode, operands);
12554       DONE;
12555     }
12556   if (!const_1_to_31_operand (operands[2], VOIDmode))
12557     FAIL;
12558   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12559   DONE;
12560 })
12561
12562 ;; Implement rotation using two double-precision shift instructions
12563 ;; and a scratch register.
12564 (define_insn_and_split "ix86_rotldi3"
12565  [(set (match_operand:DI 0 "register_operand" "=r")
12566        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12567                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12568   (clobber (reg:CC FLAGS_REG))
12569   (clobber (match_scratch:SI 3 "=&r"))]
12570  "!TARGET_64BIT"
12571  ""
12572  "&& reload_completed"
12573  [(set (match_dup 3) (match_dup 4))
12574   (parallel
12575    [(set (match_dup 4)
12576          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12577                  (lshiftrt:SI (match_dup 5)
12578                               (minus:QI (const_int 32) (match_dup 2)))))
12579     (clobber (reg:CC FLAGS_REG))])
12580   (parallel
12581    [(set (match_dup 5)
12582          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12583                  (lshiftrt:SI (match_dup 3)
12584                               (minus:QI (const_int 32) (match_dup 2)))))
12585     (clobber (reg:CC FLAGS_REG))])]
12586  "split_di (operands, 1, operands + 4, operands + 5);")
12587
12588 (define_insn "*rotlsi3_1_one_bit_rex64"
12589   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12590         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12591                    (match_operand:QI 2 "const1_operand" "")))
12592    (clobber (reg:CC FLAGS_REG))]
12593   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12594    && (TARGET_SHIFT1 || optimize_size)"
12595   "rol{q}\t%0"
12596   [(set_attr "type" "rotate")
12597    (set (attr "length")
12598      (if_then_else (match_operand:DI 0 "register_operand" "")
12599         (const_string "2")
12600         (const_string "*")))])
12601
12602 (define_insn "*rotldi3_1_rex64"
12603   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12604         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12605                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12606    (clobber (reg:CC FLAGS_REG))]
12607   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12608   "@
12609    rol{q}\t{%2, %0|%0, %2}
12610    rol{q}\t{%b2, %0|%0, %b2}"
12611   [(set_attr "type" "rotate")
12612    (set_attr "mode" "DI")])
12613
12614 (define_expand "rotlsi3"
12615   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12616         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12617                    (match_operand:QI 2 "nonmemory_operand" "")))
12618    (clobber (reg:CC FLAGS_REG))]
12619   ""
12620   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12621
12622 (define_insn "*rotlsi3_1_one_bit"
12623   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12624         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12625                    (match_operand:QI 2 "const1_operand" "")))
12626    (clobber (reg:CC FLAGS_REG))]
12627   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12628    && (TARGET_SHIFT1 || optimize_size)"
12629   "rol{l}\t%0"
12630   [(set_attr "type" "rotate")
12631    (set (attr "length")
12632      (if_then_else (match_operand:SI 0 "register_operand" "")
12633         (const_string "2")
12634         (const_string "*")))])
12635
12636 (define_insn "*rotlsi3_1_one_bit_zext"
12637   [(set (match_operand:DI 0 "register_operand" "=r")
12638         (zero_extend:DI
12639           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12640                      (match_operand:QI 2 "const1_operand" ""))))
12641    (clobber (reg:CC FLAGS_REG))]
12642   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12643    && (TARGET_SHIFT1 || optimize_size)"
12644   "rol{l}\t%k0"
12645   [(set_attr "type" "rotate")
12646    (set_attr "length" "2")])
12647
12648 (define_insn "*rotlsi3_1"
12649   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12650         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12651                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12652    (clobber (reg:CC FLAGS_REG))]
12653   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12654   "@
12655    rol{l}\t{%2, %0|%0, %2}
12656    rol{l}\t{%b2, %0|%0, %b2}"
12657   [(set_attr "type" "rotate")
12658    (set_attr "mode" "SI")])
12659
12660 (define_insn "*rotlsi3_1_zext"
12661   [(set (match_operand:DI 0 "register_operand" "=r,r")
12662         (zero_extend:DI
12663           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12664                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12665    (clobber (reg:CC FLAGS_REG))]
12666   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12667   "@
12668    rol{l}\t{%2, %k0|%k0, %2}
12669    rol{l}\t{%b2, %k0|%k0, %b2}"
12670   [(set_attr "type" "rotate")
12671    (set_attr "mode" "SI")])
12672
12673 (define_expand "rotlhi3"
12674   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12675         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12676                    (match_operand:QI 2 "nonmemory_operand" "")))
12677    (clobber (reg:CC FLAGS_REG))]
12678   "TARGET_HIMODE_MATH"
12679   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12680
12681 (define_insn "*rotlhi3_1_one_bit"
12682   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12683         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12684                    (match_operand:QI 2 "const1_operand" "")))
12685    (clobber (reg:CC FLAGS_REG))]
12686   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12687    && (TARGET_SHIFT1 || optimize_size)"
12688   "rol{w}\t%0"
12689   [(set_attr "type" "rotate")
12690    (set (attr "length")
12691      (if_then_else (match_operand 0 "register_operand" "")
12692         (const_string "2")
12693         (const_string "*")))])
12694
12695 (define_insn "*rotlhi3_1"
12696   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12697         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12698                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12699    (clobber (reg:CC FLAGS_REG))]
12700   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12701   "@
12702    rol{w}\t{%2, %0|%0, %2}
12703    rol{w}\t{%b2, %0|%0, %b2}"
12704   [(set_attr "type" "rotate")
12705    (set_attr "mode" "HI")])
12706
12707 (define_expand "rotlqi3"
12708   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12709         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12710                    (match_operand:QI 2 "nonmemory_operand" "")))
12711    (clobber (reg:CC FLAGS_REG))]
12712   "TARGET_QIMODE_MATH"
12713   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12714
12715 (define_insn "*rotlqi3_1_one_bit_slp"
12716   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12717         (rotate:QI (match_dup 0)
12718                    (match_operand:QI 1 "const1_operand" "")))
12719    (clobber (reg:CC FLAGS_REG))]
12720   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12721    && (TARGET_SHIFT1 || optimize_size)"
12722   "rol{b}\t%0"
12723   [(set_attr "type" "rotate1")
12724    (set (attr "length")
12725      (if_then_else (match_operand 0 "register_operand" "")
12726         (const_string "2")
12727         (const_string "*")))])
12728
12729 (define_insn "*rotlqi3_1_one_bit"
12730   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12731         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12732                    (match_operand:QI 2 "const1_operand" "")))
12733    (clobber (reg:CC FLAGS_REG))]
12734   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12735    && (TARGET_SHIFT1 || optimize_size)"
12736   "rol{b}\t%0"
12737   [(set_attr "type" "rotate")
12738    (set (attr "length")
12739      (if_then_else (match_operand 0 "register_operand" "")
12740         (const_string "2")
12741         (const_string "*")))])
12742
12743 (define_insn "*rotlqi3_1_slp"
12744   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12745         (rotate:QI (match_dup 0)
12746                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12747    (clobber (reg:CC FLAGS_REG))]
12748   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12749    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12750   "@
12751    rol{b}\t{%1, %0|%0, %1}
12752    rol{b}\t{%b1, %0|%0, %b1}"
12753   [(set_attr "type" "rotate1")
12754    (set_attr "mode" "QI")])
12755
12756 (define_insn "*rotlqi3_1"
12757   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12758         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12759                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12760    (clobber (reg:CC FLAGS_REG))]
12761   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12762   "@
12763    rol{b}\t{%2, %0|%0, %2}
12764    rol{b}\t{%b2, %0|%0, %b2}"
12765   [(set_attr "type" "rotate")
12766    (set_attr "mode" "QI")])
12767
12768 (define_expand "rotrdi3"
12769   [(set (match_operand:DI 0 "shiftdi_operand" "")
12770         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12771                    (match_operand:QI 2 "nonmemory_operand" "")))
12772    (clobber (reg:CC FLAGS_REG))]
12773  ""
12774 {
12775   if (TARGET_64BIT)
12776     {
12777       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12778       DONE;
12779     }
12780   if (!const_1_to_31_operand (operands[2], VOIDmode))
12781     FAIL;
12782   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12783   DONE;
12784 })
12785
12786 ;; Implement rotation using two double-precision shift instructions
12787 ;; and a scratch register.
12788 (define_insn_and_split "ix86_rotrdi3"
12789  [(set (match_operand:DI 0 "register_operand" "=r")
12790        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12791                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12792   (clobber (reg:CC FLAGS_REG))
12793   (clobber (match_scratch:SI 3 "=&r"))]
12794  "!TARGET_64BIT"
12795  ""
12796  "&& reload_completed"
12797  [(set (match_dup 3) (match_dup 4))
12798   (parallel
12799    [(set (match_dup 4)
12800          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12801                  (ashift:SI (match_dup 5)
12802                             (minus:QI (const_int 32) (match_dup 2)))))
12803     (clobber (reg:CC FLAGS_REG))])
12804   (parallel
12805    [(set (match_dup 5)
12806          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12807                  (ashift:SI (match_dup 3)
12808                             (minus:QI (const_int 32) (match_dup 2)))))
12809     (clobber (reg:CC FLAGS_REG))])]
12810  "split_di (operands, 1, operands + 4, operands + 5);")
12811
12812 (define_insn "*rotrdi3_1_one_bit_rex64"
12813   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12814         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12815                      (match_operand:QI 2 "const1_operand" "")))
12816    (clobber (reg:CC FLAGS_REG))]
12817   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12818    && (TARGET_SHIFT1 || optimize_size)"
12819   "ror{q}\t%0"
12820   [(set_attr "type" "rotate")
12821    (set (attr "length")
12822      (if_then_else (match_operand:DI 0 "register_operand" "")
12823         (const_string "2")
12824         (const_string "*")))])
12825
12826 (define_insn "*rotrdi3_1_rex64"
12827   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12828         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12829                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12830    (clobber (reg:CC FLAGS_REG))]
12831   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12832   "@
12833    ror{q}\t{%2, %0|%0, %2}
12834    ror{q}\t{%b2, %0|%0, %b2}"
12835   [(set_attr "type" "rotate")
12836    (set_attr "mode" "DI")])
12837
12838 (define_expand "rotrsi3"
12839   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12840         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12841                      (match_operand:QI 2 "nonmemory_operand" "")))
12842    (clobber (reg:CC FLAGS_REG))]
12843   ""
12844   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12845
12846 (define_insn "*rotrsi3_1_one_bit"
12847   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12848         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12849                      (match_operand:QI 2 "const1_operand" "")))
12850    (clobber (reg:CC FLAGS_REG))]
12851   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12852    && (TARGET_SHIFT1 || optimize_size)"
12853   "ror{l}\t%0"
12854   [(set_attr "type" "rotate")
12855    (set (attr "length")
12856      (if_then_else (match_operand:SI 0 "register_operand" "")
12857         (const_string "2")
12858         (const_string "*")))])
12859
12860 (define_insn "*rotrsi3_1_one_bit_zext"
12861   [(set (match_operand:DI 0 "register_operand" "=r")
12862         (zero_extend:DI
12863           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12864                        (match_operand:QI 2 "const1_operand" ""))))
12865    (clobber (reg:CC FLAGS_REG))]
12866   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12867    && (TARGET_SHIFT1 || optimize_size)"
12868   "ror{l}\t%k0"
12869   [(set_attr "type" "rotate")
12870    (set (attr "length")
12871      (if_then_else (match_operand:SI 0 "register_operand" "")
12872         (const_string "2")
12873         (const_string "*")))])
12874
12875 (define_insn "*rotrsi3_1"
12876   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12877         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12878                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12879    (clobber (reg:CC FLAGS_REG))]
12880   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12881   "@
12882    ror{l}\t{%2, %0|%0, %2}
12883    ror{l}\t{%b2, %0|%0, %b2}"
12884   [(set_attr "type" "rotate")
12885    (set_attr "mode" "SI")])
12886
12887 (define_insn "*rotrsi3_1_zext"
12888   [(set (match_operand:DI 0 "register_operand" "=r,r")
12889         (zero_extend:DI
12890           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12891                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12892    (clobber (reg:CC FLAGS_REG))]
12893   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12894   "@
12895    ror{l}\t{%2, %k0|%k0, %2}
12896    ror{l}\t{%b2, %k0|%k0, %b2}"
12897   [(set_attr "type" "rotate")
12898    (set_attr "mode" "SI")])
12899
12900 (define_expand "rotrhi3"
12901   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12902         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12903                      (match_operand:QI 2 "nonmemory_operand" "")))
12904    (clobber (reg:CC FLAGS_REG))]
12905   "TARGET_HIMODE_MATH"
12906   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12907
12908 (define_insn "*rotrhi3_one_bit"
12909   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12910         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12911                      (match_operand:QI 2 "const1_operand" "")))
12912    (clobber (reg:CC FLAGS_REG))]
12913   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12914    && (TARGET_SHIFT1 || optimize_size)"
12915   "ror{w}\t%0"
12916   [(set_attr "type" "rotate")
12917    (set (attr "length")
12918      (if_then_else (match_operand 0 "register_operand" "")
12919         (const_string "2")
12920         (const_string "*")))])
12921
12922 (define_insn "*rotrhi3"
12923   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12924         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12925                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12926    (clobber (reg:CC FLAGS_REG))]
12927   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12928   "@
12929    ror{w}\t{%2, %0|%0, %2}
12930    ror{w}\t{%b2, %0|%0, %b2}"
12931   [(set_attr "type" "rotate")
12932    (set_attr "mode" "HI")])
12933
12934 (define_expand "rotrqi3"
12935   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12936         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12937                      (match_operand:QI 2 "nonmemory_operand" "")))
12938    (clobber (reg:CC FLAGS_REG))]
12939   "TARGET_QIMODE_MATH"
12940   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12941
12942 (define_insn "*rotrqi3_1_one_bit"
12943   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12944         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12945                      (match_operand:QI 2 "const1_operand" "")))
12946    (clobber (reg:CC FLAGS_REG))]
12947   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12948    && (TARGET_SHIFT1 || optimize_size)"
12949   "ror{b}\t%0"
12950   [(set_attr "type" "rotate")
12951    (set (attr "length")
12952      (if_then_else (match_operand 0 "register_operand" "")
12953         (const_string "2")
12954         (const_string "*")))])
12955
12956 (define_insn "*rotrqi3_1_one_bit_slp"
12957   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12958         (rotatert:QI (match_dup 0)
12959                      (match_operand:QI 1 "const1_operand" "")))
12960    (clobber (reg:CC FLAGS_REG))]
12961   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12962    && (TARGET_SHIFT1 || optimize_size)"
12963   "ror{b}\t%0"
12964   [(set_attr "type" "rotate1")
12965    (set (attr "length")
12966      (if_then_else (match_operand 0 "register_operand" "")
12967         (const_string "2")
12968         (const_string "*")))])
12969
12970 (define_insn "*rotrqi3_1"
12971   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12972         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12973                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12974    (clobber (reg:CC FLAGS_REG))]
12975   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12976   "@
12977    ror{b}\t{%2, %0|%0, %2}
12978    ror{b}\t{%b2, %0|%0, %b2}"
12979   [(set_attr "type" "rotate")
12980    (set_attr "mode" "QI")])
12981
12982 (define_insn "*rotrqi3_1_slp"
12983   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12984         (rotatert:QI (match_dup 0)
12985                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12986    (clobber (reg:CC FLAGS_REG))]
12987   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12988    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12989   "@
12990    ror{b}\t{%1, %0|%0, %1}
12991    ror{b}\t{%b1, %0|%0, %b1}"
12992   [(set_attr "type" "rotate1")
12993    (set_attr "mode" "QI")])
12994 \f
12995 ;; Bit set / bit test instructions
12996
12997 (define_expand "extv"
12998   [(set (match_operand:SI 0 "register_operand" "")
12999         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13000                          (match_operand:SI 2 "const8_operand" "")
13001                          (match_operand:SI 3 "const8_operand" "")))]
13002   ""
13003 {
13004   /* Handle extractions from %ah et al.  */
13005   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13006     FAIL;
13007
13008   /* From mips.md: extract_bit_field doesn't verify that our source
13009      matches the predicate, so check it again here.  */
13010   if (! ext_register_operand (operands[1], VOIDmode))
13011     FAIL;
13012 })
13013
13014 (define_expand "extzv"
13015   [(set (match_operand:SI 0 "register_operand" "")
13016         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13017                          (match_operand:SI 2 "const8_operand" "")
13018                          (match_operand:SI 3 "const8_operand" "")))]
13019   ""
13020 {
13021   /* Handle extractions from %ah et al.  */
13022   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13023     FAIL;
13024
13025   /* From mips.md: extract_bit_field doesn't verify that our source
13026      matches the predicate, so check it again here.  */
13027   if (! ext_register_operand (operands[1], VOIDmode))
13028     FAIL;
13029 })
13030
13031 (define_expand "insv"
13032   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13033                       (match_operand 1 "const8_operand" "")
13034                       (match_operand 2 "const8_operand" ""))
13035         (match_operand 3 "register_operand" ""))]
13036   ""
13037 {
13038   /* Handle insertions to %ah et al.  */
13039   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13040     FAIL;
13041
13042   /* From mips.md: insert_bit_field doesn't verify that our source
13043      matches the predicate, so check it again here.  */
13044   if (! ext_register_operand (operands[0], VOIDmode))
13045     FAIL;
13046
13047   if (TARGET_64BIT)
13048     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13049   else
13050     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13051
13052   DONE;
13053 })
13054
13055 ;; %%% bts, btr, btc, bt.
13056 ;; In general these instructions are *slow* when applied to memory,
13057 ;; since they enforce atomic operation.  When applied to registers,
13058 ;; it depends on the cpu implementation.  They're never faster than
13059 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13060 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13061 ;; within the instruction itself, so operating on bits in the high
13062 ;; 32-bits of a register becomes easier.
13063 ;;
13064 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13065 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13066 ;; negdf respectively, so they can never be disabled entirely.
13067
13068 (define_insn "*btsq"
13069   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13070                          (const_int 1)
13071                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13072         (const_int 1))
13073    (clobber (reg:CC FLAGS_REG))]
13074   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13075   "bts{q} %1,%0"
13076   [(set_attr "type" "alu1")])
13077
13078 (define_insn "*btrq"
13079   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13080                          (const_int 1)
13081                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13082         (const_int 0))
13083    (clobber (reg:CC FLAGS_REG))]
13084   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13085   "btr{q} %1,%0"
13086   [(set_attr "type" "alu1")])
13087
13088 (define_insn "*btcq"
13089   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13090                          (const_int 1)
13091                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13092         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13093    (clobber (reg:CC FLAGS_REG))]
13094   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13095   "btc{q} %1,%0"
13096   [(set_attr "type" "alu1")])
13097
13098 ;; Allow Nocona to avoid these instructions if a register is available.
13099
13100 (define_peephole2
13101   [(match_scratch:DI 2 "r")
13102    (parallel [(set (zero_extract:DI
13103                      (match_operand:DI 0 "register_operand" "")
13104                      (const_int 1)
13105                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13106                    (const_int 1))
13107               (clobber (reg:CC FLAGS_REG))])]
13108   "TARGET_64BIT && !TARGET_USE_BT"
13109   [(const_int 0)]
13110 {
13111   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13112   rtx op1;
13113
13114   if (HOST_BITS_PER_WIDE_INT >= 64)
13115     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13116   else if (i < HOST_BITS_PER_WIDE_INT)
13117     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13118   else
13119     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13120
13121   op1 = immed_double_const (lo, hi, DImode);
13122   if (i >= 31)
13123     {
13124       emit_move_insn (operands[2], op1);
13125       op1 = operands[2];
13126     }
13127
13128   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13129   DONE;
13130 })
13131
13132 (define_peephole2
13133   [(match_scratch:DI 2 "r")
13134    (parallel [(set (zero_extract:DI
13135                      (match_operand:DI 0 "register_operand" "")
13136                      (const_int 1)
13137                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13138                    (const_int 0))
13139               (clobber (reg:CC FLAGS_REG))])]
13140   "TARGET_64BIT && !TARGET_USE_BT"
13141   [(const_int 0)]
13142 {
13143   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13144   rtx op1;
13145
13146   if (HOST_BITS_PER_WIDE_INT >= 64)
13147     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13148   else if (i < HOST_BITS_PER_WIDE_INT)
13149     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13150   else
13151     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13152
13153   op1 = immed_double_const (~lo, ~hi, DImode);
13154   if (i >= 32)
13155     {
13156       emit_move_insn (operands[2], op1);
13157       op1 = operands[2];
13158     }
13159
13160   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13161   DONE;
13162 })
13163
13164 (define_peephole2
13165   [(match_scratch:DI 2 "r")
13166    (parallel [(set (zero_extract:DI
13167                      (match_operand:DI 0 "register_operand" "")
13168                      (const_int 1)
13169                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13170               (not:DI (zero_extract:DI
13171                         (match_dup 0) (const_int 1) (match_dup 1))))
13172               (clobber (reg:CC FLAGS_REG))])]
13173   "TARGET_64BIT && !TARGET_USE_BT"
13174   [(const_int 0)]
13175 {
13176   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13177   rtx op1;
13178
13179   if (HOST_BITS_PER_WIDE_INT >= 64)
13180     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13181   else if (i < HOST_BITS_PER_WIDE_INT)
13182     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13183   else
13184     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13185
13186   op1 = immed_double_const (lo, hi, DImode);
13187   if (i >= 31)
13188     {
13189       emit_move_insn (operands[2], op1);
13190       op1 = operands[2];
13191     }
13192
13193   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13194   DONE;
13195 })
13196 \f
13197 ;; Store-flag instructions.
13198
13199 ;; For all sCOND expanders, also expand the compare or test insn that
13200 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13201
13202 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13203 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13204 ;; way, which can later delete the movzx if only QImode is needed.
13205
13206 (define_expand "seq"
13207   [(set (match_operand:QI 0 "register_operand" "")
13208         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13209   ""
13210   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13211
13212 (define_expand "sne"
13213   [(set (match_operand:QI 0 "register_operand" "")
13214         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13215   ""
13216   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13217
13218 (define_expand "sgt"
13219   [(set (match_operand:QI 0 "register_operand" "")
13220         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13221   ""
13222   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13223
13224 (define_expand "sgtu"
13225   [(set (match_operand:QI 0 "register_operand" "")
13226         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13227   ""
13228   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13229
13230 (define_expand "slt"
13231   [(set (match_operand:QI 0 "register_operand" "")
13232         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13233   ""
13234   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13235
13236 (define_expand "sltu"
13237   [(set (match_operand:QI 0 "register_operand" "")
13238         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13239   ""
13240   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13241
13242 (define_expand "sge"
13243   [(set (match_operand:QI 0 "register_operand" "")
13244         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13245   ""
13246   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13247
13248 (define_expand "sgeu"
13249   [(set (match_operand:QI 0 "register_operand" "")
13250         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13251   ""
13252   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13253
13254 (define_expand "sle"
13255   [(set (match_operand:QI 0 "register_operand" "")
13256         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257   ""
13258   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13259
13260 (define_expand "sleu"
13261   [(set (match_operand:QI 0 "register_operand" "")
13262         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13263   ""
13264   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13265
13266 (define_expand "sunordered"
13267   [(set (match_operand:QI 0 "register_operand" "")
13268         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13269   "TARGET_80387 || TARGET_SSE"
13270   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13271
13272 (define_expand "sordered"
13273   [(set (match_operand:QI 0 "register_operand" "")
13274         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13275   "TARGET_80387"
13276   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13277
13278 (define_expand "suneq"
13279   [(set (match_operand:QI 0 "register_operand" "")
13280         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13281   "TARGET_80387 || TARGET_SSE"
13282   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13283
13284 (define_expand "sunge"
13285   [(set (match_operand:QI 0 "register_operand" "")
13286         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13287   "TARGET_80387 || TARGET_SSE"
13288   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13289
13290 (define_expand "sungt"
13291   [(set (match_operand:QI 0 "register_operand" "")
13292         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13293   "TARGET_80387 || TARGET_SSE"
13294   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13295
13296 (define_expand "sunle"
13297   [(set (match_operand:QI 0 "register_operand" "")
13298         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13299   "TARGET_80387 || TARGET_SSE"
13300   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13301
13302 (define_expand "sunlt"
13303   [(set (match_operand:QI 0 "register_operand" "")
13304         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13305   "TARGET_80387 || TARGET_SSE"
13306   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13307
13308 (define_expand "sltgt"
13309   [(set (match_operand:QI 0 "register_operand" "")
13310         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13311   "TARGET_80387 || TARGET_SSE"
13312   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13313
13314 (define_insn "*setcc_1"
13315   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13316         (match_operator:QI 1 "ix86_comparison_operator"
13317           [(reg FLAGS_REG) (const_int 0)]))]
13318   ""
13319   "set%C1\t%0"
13320   [(set_attr "type" "setcc")
13321    (set_attr "mode" "QI")])
13322
13323 (define_insn "*setcc_2"
13324   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13325         (match_operator:QI 1 "ix86_comparison_operator"
13326           [(reg FLAGS_REG) (const_int 0)]))]
13327   ""
13328   "set%C1\t%0"
13329   [(set_attr "type" "setcc")
13330    (set_attr "mode" "QI")])
13331
13332 ;; In general it is not safe to assume too much about CCmode registers,
13333 ;; so simplify-rtx stops when it sees a second one.  Under certain
13334 ;; conditions this is safe on x86, so help combine not create
13335 ;;
13336 ;;      seta    %al
13337 ;;      testb   %al, %al
13338 ;;      sete    %al
13339
13340 (define_split
13341   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13342         (ne:QI (match_operator 1 "ix86_comparison_operator"
13343                  [(reg FLAGS_REG) (const_int 0)])
13344             (const_int 0)))]
13345   ""
13346   [(set (match_dup 0) (match_dup 1))]
13347 {
13348   PUT_MODE (operands[1], QImode);
13349 })
13350
13351 (define_split
13352   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13353         (ne:QI (match_operator 1 "ix86_comparison_operator"
13354                  [(reg FLAGS_REG) (const_int 0)])
13355             (const_int 0)))]
13356   ""
13357   [(set (match_dup 0) (match_dup 1))]
13358 {
13359   PUT_MODE (operands[1], QImode);
13360 })
13361
13362 (define_split
13363   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13364         (eq:QI (match_operator 1 "ix86_comparison_operator"
13365                  [(reg FLAGS_REG) (const_int 0)])
13366             (const_int 0)))]
13367   ""
13368   [(set (match_dup 0) (match_dup 1))]
13369 {
13370   rtx new_op1 = copy_rtx (operands[1]);
13371   operands[1] = new_op1;
13372   PUT_MODE (new_op1, QImode);
13373   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13374                                              GET_MODE (XEXP (new_op1, 0))));
13375
13376   /* Make sure that (a) the CCmode we have for the flags is strong
13377      enough for the reversed compare or (b) we have a valid FP compare.  */
13378   if (! ix86_comparison_operator (new_op1, VOIDmode))
13379     FAIL;
13380 })
13381
13382 (define_split
13383   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13384         (eq:QI (match_operator 1 "ix86_comparison_operator"
13385                  [(reg FLAGS_REG) (const_int 0)])
13386             (const_int 0)))]
13387   ""
13388   [(set (match_dup 0) (match_dup 1))]
13389 {
13390   rtx new_op1 = copy_rtx (operands[1]);
13391   operands[1] = new_op1;
13392   PUT_MODE (new_op1, QImode);
13393   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13394                                              GET_MODE (XEXP (new_op1, 0))));
13395
13396   /* Make sure that (a) the CCmode we have for the flags is strong
13397      enough for the reversed compare or (b) we have a valid FP compare.  */
13398   if (! ix86_comparison_operator (new_op1, VOIDmode))
13399     FAIL;
13400 })
13401
13402 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13403 ;; subsequent logical operations are used to imitate conditional moves.
13404 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13405 ;; it directly.
13406
13407 (define_insn "*sse_setccsf"
13408   [(set (match_operand:SF 0 "register_operand" "=x")
13409         (match_operator:SF 1 "sse_comparison_operator"
13410           [(match_operand:SF 2 "register_operand" "0")
13411            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13412   "TARGET_SSE"
13413   "cmp%D1ss\t{%3, %0|%0, %3}"
13414   [(set_attr "type" "ssecmp")
13415    (set_attr "mode" "SF")])
13416
13417 (define_insn "*sse_setccdf"
13418   [(set (match_operand:DF 0 "register_operand" "=Y")
13419         (match_operator:DF 1 "sse_comparison_operator"
13420           [(match_operand:DF 2 "register_operand" "0")
13421            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13422   "TARGET_SSE2"
13423   "cmp%D1sd\t{%3, %0|%0, %3}"
13424   [(set_attr "type" "ssecmp")
13425    (set_attr "mode" "DF")])
13426 \f
13427 ;; Basic conditional jump instructions.
13428 ;; We ignore the overflow flag for signed branch instructions.
13429
13430 ;; For all bCOND expanders, also expand the compare or test insn that
13431 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13432
13433 (define_expand "beq"
13434   [(set (pc)
13435         (if_then_else (match_dup 1)
13436                       (label_ref (match_operand 0 "" ""))
13437                       (pc)))]
13438   ""
13439   "ix86_expand_branch (EQ, operands[0]); DONE;")
13440
13441 (define_expand "bne"
13442   [(set (pc)
13443         (if_then_else (match_dup 1)
13444                       (label_ref (match_operand 0 "" ""))
13445                       (pc)))]
13446   ""
13447   "ix86_expand_branch (NE, operands[0]); DONE;")
13448
13449 (define_expand "bgt"
13450   [(set (pc)
13451         (if_then_else (match_dup 1)
13452                       (label_ref (match_operand 0 "" ""))
13453                       (pc)))]
13454   ""
13455   "ix86_expand_branch (GT, operands[0]); DONE;")
13456
13457 (define_expand "bgtu"
13458   [(set (pc)
13459         (if_then_else (match_dup 1)
13460                       (label_ref (match_operand 0 "" ""))
13461                       (pc)))]
13462   ""
13463   "ix86_expand_branch (GTU, operands[0]); DONE;")
13464
13465 (define_expand "blt"
13466   [(set (pc)
13467         (if_then_else (match_dup 1)
13468                       (label_ref (match_operand 0 "" ""))
13469                       (pc)))]
13470   ""
13471   "ix86_expand_branch (LT, operands[0]); DONE;")
13472
13473 (define_expand "bltu"
13474   [(set (pc)
13475         (if_then_else (match_dup 1)
13476                       (label_ref (match_operand 0 "" ""))
13477                       (pc)))]
13478   ""
13479   "ix86_expand_branch (LTU, operands[0]); DONE;")
13480
13481 (define_expand "bge"
13482   [(set (pc)
13483         (if_then_else (match_dup 1)
13484                       (label_ref (match_operand 0 "" ""))
13485                       (pc)))]
13486   ""
13487   "ix86_expand_branch (GE, operands[0]); DONE;")
13488
13489 (define_expand "bgeu"
13490   [(set (pc)
13491         (if_then_else (match_dup 1)
13492                       (label_ref (match_operand 0 "" ""))
13493                       (pc)))]
13494   ""
13495   "ix86_expand_branch (GEU, operands[0]); DONE;")
13496
13497 (define_expand "ble"
13498   [(set (pc)
13499         (if_then_else (match_dup 1)
13500                       (label_ref (match_operand 0 "" ""))
13501                       (pc)))]
13502   ""
13503   "ix86_expand_branch (LE, operands[0]); DONE;")
13504
13505 (define_expand "bleu"
13506   [(set (pc)
13507         (if_then_else (match_dup 1)
13508                       (label_ref (match_operand 0 "" ""))
13509                       (pc)))]
13510   ""
13511   "ix86_expand_branch (LEU, operands[0]); DONE;")
13512
13513 (define_expand "bunordered"
13514   [(set (pc)
13515         (if_then_else (match_dup 1)
13516                       (label_ref (match_operand 0 "" ""))
13517                       (pc)))]
13518   "TARGET_80387 || TARGET_SSE_MATH"
13519   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13520
13521 (define_expand "bordered"
13522   [(set (pc)
13523         (if_then_else (match_dup 1)
13524                       (label_ref (match_operand 0 "" ""))
13525                       (pc)))]
13526   "TARGET_80387 || TARGET_SSE_MATH"
13527   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13528
13529 (define_expand "buneq"
13530   [(set (pc)
13531         (if_then_else (match_dup 1)
13532                       (label_ref (match_operand 0 "" ""))
13533                       (pc)))]
13534   "TARGET_80387 || TARGET_SSE_MATH"
13535   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13536
13537 (define_expand "bunge"
13538   [(set (pc)
13539         (if_then_else (match_dup 1)
13540                       (label_ref (match_operand 0 "" ""))
13541                       (pc)))]
13542   "TARGET_80387 || TARGET_SSE_MATH"
13543   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13544
13545 (define_expand "bungt"
13546   [(set (pc)
13547         (if_then_else (match_dup 1)
13548                       (label_ref (match_operand 0 "" ""))
13549                       (pc)))]
13550   "TARGET_80387 || TARGET_SSE_MATH"
13551   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13552
13553 (define_expand "bunle"
13554   [(set (pc)
13555         (if_then_else (match_dup 1)
13556                       (label_ref (match_operand 0 "" ""))
13557                       (pc)))]
13558   "TARGET_80387 || TARGET_SSE_MATH"
13559   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13560
13561 (define_expand "bunlt"
13562   [(set (pc)
13563         (if_then_else (match_dup 1)
13564                       (label_ref (match_operand 0 "" ""))
13565                       (pc)))]
13566   "TARGET_80387 || TARGET_SSE_MATH"
13567   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13568
13569 (define_expand "bltgt"
13570   [(set (pc)
13571         (if_then_else (match_dup 1)
13572                       (label_ref (match_operand 0 "" ""))
13573                       (pc)))]
13574   "TARGET_80387 || TARGET_SSE_MATH"
13575   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13576
13577 (define_insn "*jcc_1"
13578   [(set (pc)
13579         (if_then_else (match_operator 1 "ix86_comparison_operator"
13580                                       [(reg FLAGS_REG) (const_int 0)])
13581                       (label_ref (match_operand 0 "" ""))
13582                       (pc)))]
13583   ""
13584   "%+j%C1\t%l0"
13585   [(set_attr "type" "ibr")
13586    (set_attr "modrm" "0")
13587    (set (attr "length")
13588            (if_then_else (and (ge (minus (match_dup 0) (pc))
13589                                   (const_int -126))
13590                               (lt (minus (match_dup 0) (pc))
13591                                   (const_int 128)))
13592              (const_int 2)
13593              (const_int 6)))])
13594
13595 (define_insn "*jcc_2"
13596   [(set (pc)
13597         (if_then_else (match_operator 1 "ix86_comparison_operator"
13598                                       [(reg FLAGS_REG) (const_int 0)])
13599                       (pc)
13600                       (label_ref (match_operand 0 "" ""))))]
13601   ""
13602   "%+j%c1\t%l0"
13603   [(set_attr "type" "ibr")
13604    (set_attr "modrm" "0")
13605    (set (attr "length")
13606            (if_then_else (and (ge (minus (match_dup 0) (pc))
13607                                   (const_int -126))
13608                               (lt (minus (match_dup 0) (pc))
13609                                   (const_int 128)))
13610              (const_int 2)
13611              (const_int 6)))])
13612
13613 ;; In general it is not safe to assume too much about CCmode registers,
13614 ;; so simplify-rtx stops when it sees a second one.  Under certain
13615 ;; conditions this is safe on x86, so help combine not create
13616 ;;
13617 ;;      seta    %al
13618 ;;      testb   %al, %al
13619 ;;      je      Lfoo
13620
13621 (define_split
13622   [(set (pc)
13623         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13624                                       [(reg FLAGS_REG) (const_int 0)])
13625                           (const_int 0))
13626                       (label_ref (match_operand 1 "" ""))
13627                       (pc)))]
13628   ""
13629   [(set (pc)
13630         (if_then_else (match_dup 0)
13631                       (label_ref (match_dup 1))
13632                       (pc)))]
13633 {
13634   PUT_MODE (operands[0], VOIDmode);
13635 })
13636
13637 (define_split
13638   [(set (pc)
13639         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13640                                       [(reg FLAGS_REG) (const_int 0)])
13641                           (const_int 0))
13642                       (label_ref (match_operand 1 "" ""))
13643                       (pc)))]
13644   ""
13645   [(set (pc)
13646         (if_then_else (match_dup 0)
13647                       (label_ref (match_dup 1))
13648                       (pc)))]
13649 {
13650   rtx new_op0 = copy_rtx (operands[0]);
13651   operands[0] = new_op0;
13652   PUT_MODE (new_op0, VOIDmode);
13653   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13654                                              GET_MODE (XEXP (new_op0, 0))));
13655
13656   /* Make sure that (a) the CCmode we have for the flags is strong
13657      enough for the reversed compare or (b) we have a valid FP compare.  */
13658   if (! ix86_comparison_operator (new_op0, VOIDmode))
13659     FAIL;
13660 })
13661
13662 ;; Define combination compare-and-branch fp compare instructions to use
13663 ;; during early optimization.  Splitting the operation apart early makes
13664 ;; for bad code when we want to reverse the operation.
13665
13666 (define_insn "*fp_jcc_1_mixed"
13667   [(set (pc)
13668         (if_then_else (match_operator 0 "comparison_operator"
13669                         [(match_operand 1 "register_operand" "f,x")
13670                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13671           (label_ref (match_operand 3 "" ""))
13672           (pc)))
13673    (clobber (reg:CCFP FPSR_REG))
13674    (clobber (reg:CCFP FLAGS_REG))]
13675   "TARGET_MIX_SSE_I387
13676    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13677    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13678    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13679   "#")
13680
13681 (define_insn "*fp_jcc_1_sse"
13682   [(set (pc)
13683         (if_then_else (match_operator 0 "comparison_operator"
13684                         [(match_operand 1 "register_operand" "x")
13685                          (match_operand 2 "nonimmediate_operand" "xm")])
13686           (label_ref (match_operand 3 "" ""))
13687           (pc)))
13688    (clobber (reg:CCFP FPSR_REG))
13689    (clobber (reg:CCFP FLAGS_REG))]
13690   "TARGET_SSE_MATH
13691    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13692    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13693    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13694   "#")
13695
13696 (define_insn "*fp_jcc_1_387"
13697   [(set (pc)
13698         (if_then_else (match_operator 0 "comparison_operator"
13699                         [(match_operand 1 "register_operand" "f")
13700                          (match_operand 2 "register_operand" "f")])
13701           (label_ref (match_operand 3 "" ""))
13702           (pc)))
13703    (clobber (reg:CCFP FPSR_REG))
13704    (clobber (reg:CCFP FLAGS_REG))]
13705   "TARGET_CMOVE && TARGET_80387
13706    && FLOAT_MODE_P (GET_MODE (operands[1]))
13707    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13708    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13709   "#")
13710
13711 (define_insn "*fp_jcc_2_mixed"
13712   [(set (pc)
13713         (if_then_else (match_operator 0 "comparison_operator"
13714                         [(match_operand 1 "register_operand" "f,x")
13715                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13716           (pc)
13717           (label_ref (match_operand 3 "" ""))))
13718    (clobber (reg:CCFP FPSR_REG))
13719    (clobber (reg:CCFP FLAGS_REG))]
13720   "TARGET_MIX_SSE_I387
13721    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13722    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13723    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13724   "#")
13725
13726 (define_insn "*fp_jcc_2_sse"
13727   [(set (pc)
13728         (if_then_else (match_operator 0 "comparison_operator"
13729                         [(match_operand 1 "register_operand" "x")
13730                          (match_operand 2 "nonimmediate_operand" "xm")])
13731           (pc)
13732           (label_ref (match_operand 3 "" ""))))
13733    (clobber (reg:CCFP FPSR_REG))
13734    (clobber (reg:CCFP FLAGS_REG))]
13735   "TARGET_SSE_MATH
13736    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13737    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13738    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13739   "#")
13740
13741 (define_insn "*fp_jcc_2_387"
13742   [(set (pc)
13743         (if_then_else (match_operator 0 "comparison_operator"
13744                         [(match_operand 1 "register_operand" "f")
13745                          (match_operand 2 "register_operand" "f")])
13746           (pc)
13747           (label_ref (match_operand 3 "" ""))))
13748    (clobber (reg:CCFP FPSR_REG))
13749    (clobber (reg:CCFP FLAGS_REG))]
13750   "TARGET_CMOVE && TARGET_80387
13751    && FLOAT_MODE_P (GET_MODE (operands[1]))
13752    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13753    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13754   "#")
13755
13756 (define_insn "*fp_jcc_3_387"
13757   [(set (pc)
13758         (if_then_else (match_operator 0 "comparison_operator"
13759                         [(match_operand 1 "register_operand" "f")
13760                          (match_operand 2 "nonimmediate_operand" "fm")])
13761           (label_ref (match_operand 3 "" ""))
13762           (pc)))
13763    (clobber (reg:CCFP FPSR_REG))
13764    (clobber (reg:CCFP FLAGS_REG))
13765    (clobber (match_scratch:HI 4 "=a"))]
13766   "TARGET_80387
13767    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13768    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13769    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13770    && SELECT_CC_MODE (GET_CODE (operands[0]),
13771                       operands[1], operands[2]) == CCFPmode
13772    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13773   "#")
13774
13775 (define_insn "*fp_jcc_4_387"
13776   [(set (pc)
13777         (if_then_else (match_operator 0 "comparison_operator"
13778                         [(match_operand 1 "register_operand" "f")
13779                          (match_operand 2 "nonimmediate_operand" "fm")])
13780           (pc)
13781           (label_ref (match_operand 3 "" ""))))
13782    (clobber (reg:CCFP FPSR_REG))
13783    (clobber (reg:CCFP FLAGS_REG))
13784    (clobber (match_scratch:HI 4 "=a"))]
13785   "TARGET_80387
13786    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13787    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13788    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13789    && SELECT_CC_MODE (GET_CODE (operands[0]),
13790                       operands[1], operands[2]) == CCFPmode
13791    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13792   "#")
13793
13794 (define_insn "*fp_jcc_5_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    (clobber (match_scratch:HI 4 "=a"))]
13804   "TARGET_80387
13805    && FLOAT_MODE_P (GET_MODE (operands[1]))
13806    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13807    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13808   "#")
13809
13810 (define_insn "*fp_jcc_6_387"
13811   [(set (pc)
13812         (if_then_else (match_operator 0 "comparison_operator"
13813                         [(match_operand 1 "register_operand" "f")
13814                          (match_operand 2 "register_operand" "f")])
13815           (pc)
13816           (label_ref (match_operand 3 "" ""))))
13817    (clobber (reg:CCFP FPSR_REG))
13818    (clobber (reg:CCFP FLAGS_REG))
13819    (clobber (match_scratch:HI 4 "=a"))]
13820   "TARGET_80387
13821    && FLOAT_MODE_P (GET_MODE (operands[1]))
13822    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13823    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13824   "#")
13825
13826 (define_insn "*fp_jcc_7_387"
13827   [(set (pc)
13828         (if_then_else (match_operator 0 "comparison_operator"
13829                         [(match_operand 1 "register_operand" "f")
13830                          (match_operand 2 "const0_operand" "X")])
13831           (label_ref (match_operand 3 "" ""))
13832           (pc)))
13833    (clobber (reg:CCFP FPSR_REG))
13834    (clobber (reg:CCFP FLAGS_REG))
13835    (clobber (match_scratch:HI 4 "=a"))]
13836   "TARGET_80387
13837    && FLOAT_MODE_P (GET_MODE (operands[1]))
13838    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13839    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13840    && SELECT_CC_MODE (GET_CODE (operands[0]),
13841                       operands[1], operands[2]) == CCFPmode
13842    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13843   "#")
13844
13845 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13846 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13847 ;; with a precedence over other operators and is always put in the first
13848 ;; place. Swap condition and operands to match ficom instruction.
13849
13850 (define_insn "*fp_jcc_8<mode>_387"
13851   [(set (pc)
13852         (if_then_else (match_operator 0 "comparison_operator"
13853                         [(match_operator 1 "float_operator"
13854                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13855                            (match_operand 3 "register_operand" "f,f")])
13856           (label_ref (match_operand 4 "" ""))
13857           (pc)))
13858    (clobber (reg:CCFP FPSR_REG))
13859    (clobber (reg:CCFP FLAGS_REG))
13860    (clobber (match_scratch:HI 5 "=a,a"))]
13861   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13862    && FLOAT_MODE_P (GET_MODE (operands[3]))
13863    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13864    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13865    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13866    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13867   "#")
13868
13869 (define_split
13870   [(set (pc)
13871         (if_then_else (match_operator 0 "comparison_operator"
13872                         [(match_operand 1 "register_operand" "")
13873                          (match_operand 2 "nonimmediate_operand" "")])
13874           (match_operand 3 "" "")
13875           (match_operand 4 "" "")))
13876    (clobber (reg:CCFP FPSR_REG))
13877    (clobber (reg:CCFP FLAGS_REG))]
13878   "reload_completed"
13879   [(const_int 0)]
13880 {
13881   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13882                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13883   DONE;
13884 })
13885
13886 (define_split
13887   [(set (pc)
13888         (if_then_else (match_operator 0 "comparison_operator"
13889                         [(match_operand 1 "register_operand" "")
13890                          (match_operand 2 "general_operand" "")])
13891           (match_operand 3 "" "")
13892           (match_operand 4 "" "")))
13893    (clobber (reg:CCFP FPSR_REG))
13894    (clobber (reg:CCFP FLAGS_REG))
13895    (clobber (match_scratch:HI 5 "=a"))]
13896   "reload_completed"
13897   [(const_int 0)]
13898 {
13899   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13900                         operands[3], operands[4], operands[5], NULL_RTX);
13901   DONE;
13902 })
13903
13904 (define_split
13905   [(set (pc)
13906         (if_then_else (match_operator 0 "comparison_operator"
13907                         [(match_operator 1 "float_operator"
13908                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13909                            (match_operand 3 "register_operand" "")])
13910           (match_operand 4 "" "")
13911           (match_operand 5 "" "")))
13912    (clobber (reg:CCFP FPSR_REG))
13913    (clobber (reg:CCFP FLAGS_REG))
13914    (clobber (match_scratch:HI 6 "=a"))]
13915   "reload_completed"
13916   [(const_int 0)]
13917 {
13918   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13919   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13920                         operands[3], operands[7],
13921                         operands[4], operands[5], operands[6], NULL_RTX);
13922   DONE;
13923 })
13924
13925 ;; %%% Kill this when reload knows how to do it.
13926 (define_split
13927   [(set (pc)
13928         (if_then_else (match_operator 0 "comparison_operator"
13929                         [(match_operator 1 "float_operator"
13930                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13931                            (match_operand 3 "register_operand" "")])
13932           (match_operand 4 "" "")
13933           (match_operand 5 "" "")))
13934    (clobber (reg:CCFP FPSR_REG))
13935    (clobber (reg:CCFP FLAGS_REG))
13936    (clobber (match_scratch:HI 6 "=a"))]
13937   "reload_completed"
13938   [(const_int 0)]
13939 {
13940   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13941   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13942   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13943                         operands[3], operands[7],
13944                         operands[4], operands[5], operands[6], operands[2]);
13945   DONE;
13946 })
13947 \f
13948 ;; Unconditional and other jump instructions
13949
13950 (define_insn "jump"
13951   [(set (pc)
13952         (label_ref (match_operand 0 "" "")))]
13953   ""
13954   "jmp\t%l0"
13955   [(set_attr "type" "ibr")
13956    (set (attr "length")
13957            (if_then_else (and (ge (minus (match_dup 0) (pc))
13958                                   (const_int -126))
13959                               (lt (minus (match_dup 0) (pc))
13960                                   (const_int 128)))
13961              (const_int 2)
13962              (const_int 5)))
13963    (set_attr "modrm" "0")])
13964
13965 (define_expand "indirect_jump"
13966   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13967   ""
13968   "")
13969
13970 (define_insn "*indirect_jump"
13971   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13972   "!TARGET_64BIT"
13973   "jmp\t%A0"
13974   [(set_attr "type" "ibr")
13975    (set_attr "length_immediate" "0")])
13976
13977 (define_insn "*indirect_jump_rtx64"
13978   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13979   "TARGET_64BIT"
13980   "jmp\t%A0"
13981   [(set_attr "type" "ibr")
13982    (set_attr "length_immediate" "0")])
13983
13984 (define_expand "tablejump"
13985   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13986               (use (label_ref (match_operand 1 "" "")))])]
13987   ""
13988 {
13989   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13990      relative.  Convert the relative address to an absolute address.  */
13991   if (flag_pic)
13992     {
13993       rtx op0, op1;
13994       enum rtx_code code;
13995
13996       if (TARGET_64BIT)
13997         {
13998           code = PLUS;
13999           op0 = operands[0];
14000           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14001         }
14002       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14003         {
14004           code = PLUS;
14005           op0 = operands[0];
14006           op1 = pic_offset_table_rtx;
14007         }
14008       else
14009         {
14010           code = MINUS;
14011           op0 = pic_offset_table_rtx;
14012           op1 = operands[0];
14013         }
14014
14015       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14016                                          OPTAB_DIRECT);
14017     }
14018 })
14019
14020 (define_insn "*tablejump_1"
14021   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14022    (use (label_ref (match_operand 1 "" "")))]
14023   "!TARGET_64BIT"
14024   "jmp\t%A0"
14025   [(set_attr "type" "ibr")
14026    (set_attr "length_immediate" "0")])
14027
14028 (define_insn "*tablejump_1_rtx64"
14029   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14030    (use (label_ref (match_operand 1 "" "")))]
14031   "TARGET_64BIT"
14032   "jmp\t%A0"
14033   [(set_attr "type" "ibr")
14034    (set_attr "length_immediate" "0")])
14035 \f
14036 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14037
14038 (define_peephole2
14039   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14040    (set (match_operand:QI 1 "register_operand" "")
14041         (match_operator:QI 2 "ix86_comparison_operator"
14042           [(reg FLAGS_REG) (const_int 0)]))
14043    (set (match_operand 3 "q_regs_operand" "")
14044         (zero_extend (match_dup 1)))]
14045   "(peep2_reg_dead_p (3, operands[1])
14046     || operands_match_p (operands[1], operands[3]))
14047    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14048   [(set (match_dup 4) (match_dup 0))
14049    (set (strict_low_part (match_dup 5))
14050         (match_dup 2))]
14051 {
14052   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14053   operands[5] = gen_lowpart (QImode, operands[3]);
14054   ix86_expand_clear (operands[3]);
14055 })
14056
14057 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14058
14059 (define_peephole2
14060   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14061    (set (match_operand:QI 1 "register_operand" "")
14062         (match_operator:QI 2 "ix86_comparison_operator"
14063           [(reg FLAGS_REG) (const_int 0)]))
14064    (parallel [(set (match_operand 3 "q_regs_operand" "")
14065                    (zero_extend (match_dup 1)))
14066               (clobber (reg:CC FLAGS_REG))])]
14067   "(peep2_reg_dead_p (3, operands[1])
14068     || operands_match_p (operands[1], operands[3]))
14069    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14070   [(set (match_dup 4) (match_dup 0))
14071    (set (strict_low_part (match_dup 5))
14072         (match_dup 2))]
14073 {
14074   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14075   operands[5] = gen_lowpart (QImode, operands[3]);
14076   ix86_expand_clear (operands[3]);
14077 })
14078 \f
14079 ;; Call instructions.
14080
14081 ;; The predicates normally associated with named expanders are not properly
14082 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14083 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14084
14085 ;; Call subroutine returning no value.
14086
14087 (define_expand "call_pop"
14088   [(parallel [(call (match_operand:QI 0 "" "")
14089                     (match_operand:SI 1 "" ""))
14090               (set (reg:SI SP_REG)
14091                    (plus:SI (reg:SI SP_REG)
14092                             (match_operand:SI 3 "" "")))])]
14093   "!TARGET_64BIT"
14094 {
14095   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14096   DONE;
14097 })
14098
14099 (define_insn "*call_pop_0"
14100   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14101          (match_operand:SI 1 "" ""))
14102    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14103                             (match_operand:SI 2 "immediate_operand" "")))]
14104   "!TARGET_64BIT"
14105 {
14106   if (SIBLING_CALL_P (insn))
14107     return "jmp\t%P0";
14108   else
14109     return "call\t%P0";
14110 }
14111   [(set_attr "type" "call")])
14112
14113 (define_insn "*call_pop_1"
14114   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14115          (match_operand:SI 1 "" ""))
14116    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14117                             (match_operand:SI 2 "immediate_operand" "i")))]
14118   "!TARGET_64BIT"
14119 {
14120   if (constant_call_address_operand (operands[0], Pmode))
14121     {
14122       if (SIBLING_CALL_P (insn))
14123         return "jmp\t%P0";
14124       else
14125         return "call\t%P0";
14126     }
14127   if (SIBLING_CALL_P (insn))
14128     return "jmp\t%A0";
14129   else
14130     return "call\t%A0";
14131 }
14132   [(set_attr "type" "call")])
14133
14134 (define_expand "call"
14135   [(call (match_operand:QI 0 "" "")
14136          (match_operand 1 "" ""))
14137    (use (match_operand 2 "" ""))]
14138   ""
14139 {
14140   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14141   DONE;
14142 })
14143
14144 (define_expand "sibcall"
14145   [(call (match_operand:QI 0 "" "")
14146          (match_operand 1 "" ""))
14147    (use (match_operand 2 "" ""))]
14148   ""
14149 {
14150   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14151   DONE;
14152 })
14153
14154 (define_insn "*call_0"
14155   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14156          (match_operand 1 "" ""))]
14157   ""
14158 {
14159   if (SIBLING_CALL_P (insn))
14160     return "jmp\t%P0";
14161   else
14162     return "call\t%P0";
14163 }
14164   [(set_attr "type" "call")])
14165
14166 (define_insn "*call_1"
14167   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14168          (match_operand 1 "" ""))]
14169   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14170 {
14171   if (constant_call_address_operand (operands[0], Pmode))
14172     return "call\t%P0";
14173   return "call\t%A0";
14174 }
14175   [(set_attr "type" "call")])
14176
14177 (define_insn "*sibcall_1"
14178   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14179          (match_operand 1 "" ""))]
14180   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14181 {
14182   if (constant_call_address_operand (operands[0], Pmode))
14183     return "jmp\t%P0";
14184   return "jmp\t%A0";
14185 }
14186   [(set_attr "type" "call")])
14187
14188 (define_insn "*call_1_rex64"
14189   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14190          (match_operand 1 "" ""))]
14191   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14192 {
14193   if (constant_call_address_operand (operands[0], Pmode))
14194     return "call\t%P0";
14195   return "call\t%A0";
14196 }
14197   [(set_attr "type" "call")])
14198
14199 (define_insn "*sibcall_1_rex64"
14200   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14201          (match_operand 1 "" ""))]
14202   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14203   "jmp\t%P0"
14204   [(set_attr "type" "call")])
14205
14206 (define_insn "*sibcall_1_rex64_v"
14207   [(call (mem:QI (reg:DI R11_REG))
14208          (match_operand 0 "" ""))]
14209   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14210   "jmp\t*%%r11"
14211   [(set_attr "type" "call")])
14212
14213
14214 ;; Call subroutine, returning value in operand 0
14215
14216 (define_expand "call_value_pop"
14217   [(parallel [(set (match_operand 0 "" "")
14218                    (call (match_operand:QI 1 "" "")
14219                          (match_operand:SI 2 "" "")))
14220               (set (reg:SI SP_REG)
14221                    (plus:SI (reg:SI SP_REG)
14222                             (match_operand:SI 4 "" "")))])]
14223   "!TARGET_64BIT"
14224 {
14225   ix86_expand_call (operands[0], operands[1], operands[2],
14226                     operands[3], operands[4], 0);
14227   DONE;
14228 })
14229
14230 (define_expand "call_value"
14231   [(set (match_operand 0 "" "")
14232         (call (match_operand:QI 1 "" "")
14233               (match_operand:SI 2 "" "")))
14234    (use (match_operand:SI 3 "" ""))]
14235   ;; Operand 2 not used on the i386.
14236   ""
14237 {
14238   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14239   DONE;
14240 })
14241
14242 (define_expand "sibcall_value"
14243   [(set (match_operand 0 "" "")
14244         (call (match_operand:QI 1 "" "")
14245               (match_operand:SI 2 "" "")))
14246    (use (match_operand:SI 3 "" ""))]
14247   ;; Operand 2 not used on the i386.
14248   ""
14249 {
14250   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14251   DONE;
14252 })
14253
14254 ;; Call subroutine returning any type.
14255
14256 (define_expand "untyped_call"
14257   [(parallel [(call (match_operand 0 "" "")
14258                     (const_int 0))
14259               (match_operand 1 "" "")
14260               (match_operand 2 "" "")])]
14261   ""
14262 {
14263   int i;
14264
14265   /* In order to give reg-stack an easier job in validating two
14266      coprocessor registers as containing a possible return value,
14267      simply pretend the untyped call returns a complex long double
14268      value.  */
14269
14270   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14271                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14272                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14273                     NULL, 0);
14274
14275   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14276     {
14277       rtx set = XVECEXP (operands[2], 0, i);
14278       emit_move_insn (SET_DEST (set), SET_SRC (set));
14279     }
14280
14281   /* The optimizer does not know that the call sets the function value
14282      registers we stored in the result block.  We avoid problems by
14283      claiming that all hard registers are used and clobbered at this
14284      point.  */
14285   emit_insn (gen_blockage (const0_rtx));
14286
14287   DONE;
14288 })
14289 \f
14290 ;; Prologue and epilogue instructions
14291
14292 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14293 ;; all of memory.  This blocks insns from being moved across this point.
14294
14295 (define_insn "blockage"
14296   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14297   ""
14298   ""
14299   [(set_attr "length" "0")])
14300
14301 ;; Insn emitted into the body of a function to return from a function.
14302 ;; This is only done if the function's epilogue is known to be simple.
14303 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14304
14305 (define_expand "return"
14306   [(return)]
14307   "ix86_can_use_return_insn_p ()"
14308 {
14309   if (current_function_pops_args)
14310     {
14311       rtx popc = GEN_INT (current_function_pops_args);
14312       emit_jump_insn (gen_return_pop_internal (popc));
14313       DONE;
14314     }
14315 })
14316
14317 (define_insn "return_internal"
14318   [(return)]
14319   "reload_completed"
14320   "ret"
14321   [(set_attr "length" "1")
14322    (set_attr "length_immediate" "0")
14323    (set_attr "modrm" "0")])
14324
14325 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14326 ;; instruction Athlon and K8 have.
14327
14328 (define_insn "return_internal_long"
14329   [(return)
14330    (unspec [(const_int 0)] UNSPEC_REP)]
14331   "reload_completed"
14332   "rep {;} ret"
14333   [(set_attr "length" "1")
14334    (set_attr "length_immediate" "0")
14335    (set_attr "prefix_rep" "1")
14336    (set_attr "modrm" "0")])
14337
14338 (define_insn "return_pop_internal"
14339   [(return)
14340    (use (match_operand:SI 0 "const_int_operand" ""))]
14341   "reload_completed"
14342   "ret\t%0"
14343   [(set_attr "length" "3")
14344    (set_attr "length_immediate" "2")
14345    (set_attr "modrm" "0")])
14346
14347 (define_insn "return_indirect_internal"
14348   [(return)
14349    (use (match_operand:SI 0 "register_operand" "r"))]
14350   "reload_completed"
14351   "jmp\t%A0"
14352   [(set_attr "type" "ibr")
14353    (set_attr "length_immediate" "0")])
14354
14355 (define_insn "nop"
14356   [(const_int 0)]
14357   ""
14358   "nop"
14359   [(set_attr "length" "1")
14360    (set_attr "length_immediate" "0")
14361    (set_attr "modrm" "0")])
14362
14363 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14364 ;; branch prediction penalty for the third jump in a 16-byte
14365 ;; block on K8.
14366
14367 (define_insn "align"
14368   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14369   ""
14370 {
14371 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14372   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14373 #else
14374   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14375      The align insn is used to avoid 3 jump instructions in the row to improve
14376      branch prediction and the benefits hardly outweigh the cost of extra 8
14377      nops on the average inserted by full alignment pseudo operation.  */
14378 #endif
14379   return "";
14380 }
14381   [(set_attr "length" "16")])
14382
14383 (define_expand "prologue"
14384   [(const_int 1)]
14385   ""
14386   "ix86_expand_prologue (); DONE;")
14387
14388 (define_insn "set_got"
14389   [(set (match_operand:SI 0 "register_operand" "=r")
14390         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14391    (clobber (reg:CC FLAGS_REG))]
14392   "!TARGET_64BIT"
14393   { return output_set_got (operands[0], NULL_RTX); }
14394   [(set_attr "type" "multi")
14395    (set_attr "length" "12")])
14396
14397 (define_insn "set_got_labelled"
14398   [(set (match_operand:SI 0 "register_operand" "=r")
14399         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14400          UNSPEC_SET_GOT))
14401    (clobber (reg:CC FLAGS_REG))]
14402   "!TARGET_64BIT"
14403   { return output_set_got (operands[0], operands[1]); }
14404   [(set_attr "type" "multi")
14405    (set_attr "length" "12")])
14406
14407 (define_insn "set_got_rex64"
14408   [(set (match_operand:DI 0 "register_operand" "=r")
14409         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14410   "TARGET_64BIT"
14411   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14412   [(set_attr "type" "lea")
14413    (set_attr "length" "6")])
14414
14415 (define_expand "epilogue"
14416   [(const_int 1)]
14417   ""
14418   "ix86_expand_epilogue (1); DONE;")
14419
14420 (define_expand "sibcall_epilogue"
14421   [(const_int 1)]
14422   ""
14423   "ix86_expand_epilogue (0); DONE;")
14424
14425 (define_expand "eh_return"
14426   [(use (match_operand 0 "register_operand" ""))]
14427   ""
14428 {
14429   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14430
14431   /* Tricky bit: we write the address of the handler to which we will
14432      be returning into someone else's stack frame, one word below the
14433      stack address we wish to restore.  */
14434   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14435   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14436   tmp = gen_rtx_MEM (Pmode, tmp);
14437   emit_move_insn (tmp, ra);
14438
14439   if (Pmode == SImode)
14440     emit_jump_insn (gen_eh_return_si (sa));
14441   else
14442     emit_jump_insn (gen_eh_return_di (sa));
14443   emit_barrier ();
14444   DONE;
14445 })
14446
14447 (define_insn_and_split "eh_return_si"
14448   [(set (pc)
14449         (unspec [(match_operand:SI 0 "register_operand" "c")]
14450                  UNSPEC_EH_RETURN))]
14451   "!TARGET_64BIT"
14452   "#"
14453   "reload_completed"
14454   [(const_int 1)]
14455   "ix86_expand_epilogue (2); DONE;")
14456
14457 (define_insn_and_split "eh_return_di"
14458   [(set (pc)
14459         (unspec [(match_operand:DI 0 "register_operand" "c")]
14460                  UNSPEC_EH_RETURN))]
14461   "TARGET_64BIT"
14462   "#"
14463   "reload_completed"
14464   [(const_int 1)]
14465   "ix86_expand_epilogue (2); DONE;")
14466
14467 (define_insn "leave"
14468   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14469    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14470    (clobber (mem:BLK (scratch)))]
14471   "!TARGET_64BIT"
14472   "leave"
14473   [(set_attr "type" "leave")])
14474
14475 (define_insn "leave_rex64"
14476   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14477    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14478    (clobber (mem:BLK (scratch)))]
14479   "TARGET_64BIT"
14480   "leave"
14481   [(set_attr "type" "leave")])
14482 \f
14483 (define_expand "ffssi2"
14484   [(parallel
14485      [(set (match_operand:SI 0 "register_operand" "")
14486            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14487       (clobber (match_scratch:SI 2 ""))
14488       (clobber (reg:CC FLAGS_REG))])]
14489   ""
14490   "")
14491
14492 (define_insn_and_split "*ffs_cmove"
14493   [(set (match_operand:SI 0 "register_operand" "=r")
14494         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14495    (clobber (match_scratch:SI 2 "=&r"))
14496    (clobber (reg:CC FLAGS_REG))]
14497   "TARGET_CMOVE"
14498   "#"
14499   "&& reload_completed"
14500   [(set (match_dup 2) (const_int -1))
14501    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14502               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14503    (set (match_dup 0) (if_then_else:SI
14504                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14505                         (match_dup 2)
14506                         (match_dup 0)))
14507    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14508               (clobber (reg:CC FLAGS_REG))])]
14509   "")
14510
14511 (define_insn_and_split "*ffs_no_cmove"
14512   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14513         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14514    (clobber (match_scratch:SI 2 "=&q"))
14515    (clobber (reg:CC FLAGS_REG))]
14516   ""
14517   "#"
14518   "reload_completed"
14519   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14520               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14521    (set (strict_low_part (match_dup 3))
14522         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14523    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14524               (clobber (reg:CC FLAGS_REG))])
14525    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14526               (clobber (reg:CC FLAGS_REG))])
14527    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14528               (clobber (reg:CC FLAGS_REG))])]
14529 {
14530   operands[3] = gen_lowpart (QImode, operands[2]);
14531   ix86_expand_clear (operands[2]);
14532 })
14533
14534 (define_insn "*ffssi_1"
14535   [(set (reg:CCZ FLAGS_REG)
14536         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14537                      (const_int 0)))
14538    (set (match_operand:SI 0 "register_operand" "=r")
14539         (ctz:SI (match_dup 1)))]
14540   ""
14541   "bsf{l}\t{%1, %0|%0, %1}"
14542   [(set_attr "prefix_0f" "1")])
14543
14544 (define_expand "ffsdi2"
14545   [(parallel
14546      [(set (match_operand:DI 0 "register_operand" "")
14547            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14548       (clobber (match_scratch:DI 2 ""))
14549       (clobber (reg:CC FLAGS_REG))])]
14550   "TARGET_64BIT && TARGET_CMOVE"
14551   "")
14552
14553 (define_insn_and_split "*ffs_rex64"
14554   [(set (match_operand:DI 0 "register_operand" "=r")
14555         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14556    (clobber (match_scratch:DI 2 "=&r"))
14557    (clobber (reg:CC FLAGS_REG))]
14558   "TARGET_64BIT && TARGET_CMOVE"
14559   "#"
14560   "&& reload_completed"
14561   [(set (match_dup 2) (const_int -1))
14562    (parallel [(set (reg:CCZ FLAGS_REG)
14563                    (compare:CCZ (match_dup 1) (const_int 0)))
14564               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14565    (set (match_dup 0) (if_then_else:DI
14566                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14567                         (match_dup 2)
14568                         (match_dup 0)))
14569    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14570               (clobber (reg:CC FLAGS_REG))])]
14571   "")
14572
14573 (define_insn "*ffsdi_1"
14574   [(set (reg:CCZ FLAGS_REG)
14575         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14576                      (const_int 0)))
14577    (set (match_operand:DI 0 "register_operand" "=r")
14578         (ctz:DI (match_dup 1)))]
14579   "TARGET_64BIT"
14580   "bsf{q}\t{%1, %0|%0, %1}"
14581   [(set_attr "prefix_0f" "1")])
14582
14583 (define_insn "ctzsi2"
14584   [(set (match_operand:SI 0 "register_operand" "=r")
14585         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14586    (clobber (reg:CC FLAGS_REG))]
14587   ""
14588   "bsf{l}\t{%1, %0|%0, %1}"
14589   [(set_attr "prefix_0f" "1")])
14590
14591 (define_insn "ctzdi2"
14592   [(set (match_operand:DI 0 "register_operand" "=r")
14593         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14594    (clobber (reg:CC FLAGS_REG))]
14595   "TARGET_64BIT"
14596   "bsf{q}\t{%1, %0|%0, %1}"
14597   [(set_attr "prefix_0f" "1")])
14598
14599 (define_expand "clzsi2"
14600   [(parallel
14601      [(set (match_operand:SI 0 "register_operand" "")
14602            (minus:SI (const_int 31)
14603                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14604       (clobber (reg:CC FLAGS_REG))])
14605    (parallel
14606      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14607       (clobber (reg:CC FLAGS_REG))])]
14608   ""
14609   "")
14610
14611 (define_insn "*bsr"
14612   [(set (match_operand:SI 0 "register_operand" "=r")
14613         (minus:SI (const_int 31)
14614                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14615    (clobber (reg:CC FLAGS_REG))]
14616   ""
14617   "bsr{l}\t{%1, %0|%0, %1}"
14618   [(set_attr "prefix_0f" "1")])
14619
14620 (define_insn "bswapsi2"
14621   [(set (match_operand:SI 0 "register_operand" "=r")
14622         (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14623    (clobber (reg:CC FLAGS_REG))]
14624   "TARGET_BSWAP"
14625   "bswap\t%k0"
14626   [(set_attr "prefix_0f" "1")
14627    (set_attr "length" "2")])
14628
14629 (define_insn "bswapdi2"
14630   [(set (match_operand:DI 0 "register_operand" "=r")
14631         (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14632    (clobber (reg:CC FLAGS_REG))]
14633   "TARGET_64BIT && TARGET_BSWAP"
14634   "bswap\t%0"
14635   [(set_attr "prefix_0f" "1")
14636    (set_attr "length" "3")])
14637
14638 (define_expand "clzdi2"
14639   [(parallel
14640      [(set (match_operand:DI 0 "register_operand" "")
14641            (minus:DI (const_int 63)
14642                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14643       (clobber (reg:CC FLAGS_REG))])
14644    (parallel
14645      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14646       (clobber (reg:CC FLAGS_REG))])]
14647   "TARGET_64BIT"
14648   "")
14649
14650 (define_insn "*bsr_rex64"
14651   [(set (match_operand:DI 0 "register_operand" "=r")
14652         (minus:DI (const_int 63)
14653                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14654    (clobber (reg:CC FLAGS_REG))]
14655   "TARGET_64BIT"
14656   "bsr{q}\t{%1, %0|%0, %1}"
14657   [(set_attr "prefix_0f" "1")])
14658 \f
14659 ;; Thread-local storage patterns for ELF.
14660 ;;
14661 ;; Note that these code sequences must appear exactly as shown
14662 ;; in order to allow linker relaxation.
14663
14664 (define_insn "*tls_global_dynamic_32_gnu"
14665   [(set (match_operand:SI 0 "register_operand" "=a")
14666         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14667                     (match_operand:SI 2 "tls_symbolic_operand" "")
14668                     (match_operand:SI 3 "call_insn_operand" "")]
14669                     UNSPEC_TLS_GD))
14670    (clobber (match_scratch:SI 4 "=d"))
14671    (clobber (match_scratch:SI 5 "=c"))
14672    (clobber (reg:CC FLAGS_REG))]
14673   "!TARGET_64BIT && TARGET_GNU_TLS"
14674   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14675   [(set_attr "type" "multi")
14676    (set_attr "length" "12")])
14677
14678 (define_insn "*tls_global_dynamic_32_sun"
14679   [(set (match_operand:SI 0 "register_operand" "=a")
14680         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14681                     (match_operand:SI 2 "tls_symbolic_operand" "")
14682                     (match_operand:SI 3 "call_insn_operand" "")]
14683                     UNSPEC_TLS_GD))
14684    (clobber (match_scratch:SI 4 "=d"))
14685    (clobber (match_scratch:SI 5 "=c"))
14686    (clobber (reg:CC FLAGS_REG))]
14687   "!TARGET_64BIT && TARGET_SUN_TLS"
14688   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14689         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14690   [(set_attr "type" "multi")
14691    (set_attr "length" "14")])
14692
14693 (define_expand "tls_global_dynamic_32"
14694   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14695                    (unspec:SI
14696                     [(match_dup 2)
14697                      (match_operand:SI 1 "tls_symbolic_operand" "")
14698                      (match_dup 3)]
14699                     UNSPEC_TLS_GD))
14700               (clobber (match_scratch:SI 4 ""))
14701               (clobber (match_scratch:SI 5 ""))
14702               (clobber (reg:CC FLAGS_REG))])]
14703   ""
14704 {
14705   if (flag_pic)
14706     operands[2] = pic_offset_table_rtx;
14707   else
14708     {
14709       operands[2] = gen_reg_rtx (Pmode);
14710       emit_insn (gen_set_got (operands[2]));
14711     }
14712   if (TARGET_GNU2_TLS)
14713     {
14714        emit_insn (gen_tls_dynamic_gnu2_32
14715                   (operands[0], operands[1], operands[2]));
14716        DONE;
14717     }
14718   operands[3] = ix86_tls_get_addr ();
14719 })
14720
14721 (define_insn "*tls_global_dynamic_64"
14722   [(set (match_operand:DI 0 "register_operand" "=a")
14723         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14724                  (match_operand:DI 3 "" "")))
14725    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14726               UNSPEC_TLS_GD)]
14727   "TARGET_64BIT"
14728   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14729   [(set_attr "type" "multi")
14730    (set_attr "length" "16")])
14731
14732 (define_expand "tls_global_dynamic_64"
14733   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14734                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14735               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14736                          UNSPEC_TLS_GD)])]
14737   ""
14738 {
14739   if (TARGET_GNU2_TLS)
14740     {
14741        emit_insn (gen_tls_dynamic_gnu2_64
14742                   (operands[0], operands[1]));
14743        DONE;
14744     }
14745   operands[2] = ix86_tls_get_addr ();
14746 })
14747
14748 (define_insn "*tls_local_dynamic_base_32_gnu"
14749   [(set (match_operand:SI 0 "register_operand" "=a")
14750         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14751                     (match_operand:SI 2 "call_insn_operand" "")]
14752                    UNSPEC_TLS_LD_BASE))
14753    (clobber (match_scratch:SI 3 "=d"))
14754    (clobber (match_scratch:SI 4 "=c"))
14755    (clobber (reg:CC FLAGS_REG))]
14756   "!TARGET_64BIT && TARGET_GNU_TLS"
14757   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14758   [(set_attr "type" "multi")
14759    (set_attr "length" "11")])
14760
14761 (define_insn "*tls_local_dynamic_base_32_sun"
14762   [(set (match_operand:SI 0 "register_operand" "=a")
14763         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14764                     (match_operand:SI 2 "call_insn_operand" "")]
14765                    UNSPEC_TLS_LD_BASE))
14766    (clobber (match_scratch:SI 3 "=d"))
14767    (clobber (match_scratch:SI 4 "=c"))
14768    (clobber (reg:CC FLAGS_REG))]
14769   "!TARGET_64BIT && TARGET_SUN_TLS"
14770   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14771         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14772   [(set_attr "type" "multi")
14773    (set_attr "length" "13")])
14774
14775 (define_expand "tls_local_dynamic_base_32"
14776   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14777                    (unspec:SI [(match_dup 1) (match_dup 2)]
14778                               UNSPEC_TLS_LD_BASE))
14779               (clobber (match_scratch:SI 3 ""))
14780               (clobber (match_scratch:SI 4 ""))
14781               (clobber (reg:CC FLAGS_REG))])]
14782   ""
14783 {
14784   if (flag_pic)
14785     operands[1] = pic_offset_table_rtx;
14786   else
14787     {
14788       operands[1] = gen_reg_rtx (Pmode);
14789       emit_insn (gen_set_got (operands[1]));
14790     }
14791   if (TARGET_GNU2_TLS)
14792     {
14793        emit_insn (gen_tls_dynamic_gnu2_32
14794                   (operands[0], ix86_tls_module_base (), operands[1]));
14795        DONE;
14796     }
14797   operands[2] = ix86_tls_get_addr ();
14798 })
14799
14800 (define_insn "*tls_local_dynamic_base_64"
14801   [(set (match_operand:DI 0 "register_operand" "=a")
14802         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14803                  (match_operand:DI 2 "" "")))
14804    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14805   "TARGET_64BIT"
14806   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14807   [(set_attr "type" "multi")
14808    (set_attr "length" "12")])
14809
14810 (define_expand "tls_local_dynamic_base_64"
14811   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14812                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14813               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14814   ""
14815 {
14816   if (TARGET_GNU2_TLS)
14817     {
14818        emit_insn (gen_tls_dynamic_gnu2_64
14819                   (operands[0], ix86_tls_module_base ()));
14820        DONE;
14821     }
14822   operands[1] = ix86_tls_get_addr ();
14823 })
14824
14825 ;; Local dynamic of a single variable is a lose.  Show combine how
14826 ;; to convert that back to global dynamic.
14827
14828 (define_insn_and_split "*tls_local_dynamic_32_once"
14829   [(set (match_operand:SI 0 "register_operand" "=a")
14830         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14831                              (match_operand:SI 2 "call_insn_operand" "")]
14832                             UNSPEC_TLS_LD_BASE)
14833                  (const:SI (unspec:SI
14834                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14835                             UNSPEC_DTPOFF))))
14836    (clobber (match_scratch:SI 4 "=d"))
14837    (clobber (match_scratch:SI 5 "=c"))
14838    (clobber (reg:CC FLAGS_REG))]
14839   ""
14840   "#"
14841   ""
14842   [(parallel [(set (match_dup 0)
14843                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14844                               UNSPEC_TLS_GD))
14845               (clobber (match_dup 4))
14846               (clobber (match_dup 5))
14847               (clobber (reg:CC FLAGS_REG))])]
14848   "")
14849
14850 ;; Load and add the thread base pointer from %gs:0.
14851
14852 (define_insn "*load_tp_si"
14853   [(set (match_operand:SI 0 "register_operand" "=r")
14854         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14855   "!TARGET_64BIT"
14856   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14857   [(set_attr "type" "imov")
14858    (set_attr "modrm" "0")
14859    (set_attr "length" "7")
14860    (set_attr "memory" "load")
14861    (set_attr "imm_disp" "false")])
14862
14863 (define_insn "*add_tp_si"
14864   [(set (match_operand:SI 0 "register_operand" "=r")
14865         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14866                  (match_operand:SI 1 "register_operand" "0")))
14867    (clobber (reg:CC FLAGS_REG))]
14868   "!TARGET_64BIT"
14869   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14870   [(set_attr "type" "alu")
14871    (set_attr "modrm" "0")
14872    (set_attr "length" "7")
14873    (set_attr "memory" "load")
14874    (set_attr "imm_disp" "false")])
14875
14876 (define_insn "*load_tp_di"
14877   [(set (match_operand:DI 0 "register_operand" "=r")
14878         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14879   "TARGET_64BIT"
14880   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14881   [(set_attr "type" "imov")
14882    (set_attr "modrm" "0")
14883    (set_attr "length" "7")
14884    (set_attr "memory" "load")
14885    (set_attr "imm_disp" "false")])
14886
14887 (define_insn "*add_tp_di"
14888   [(set (match_operand:DI 0 "register_operand" "=r")
14889         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14890                  (match_operand:DI 1 "register_operand" "0")))
14891    (clobber (reg:CC FLAGS_REG))]
14892   "TARGET_64BIT"
14893   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14894   [(set_attr "type" "alu")
14895    (set_attr "modrm" "0")
14896    (set_attr "length" "7")
14897    (set_attr "memory" "load")
14898    (set_attr "imm_disp" "false")])
14899
14900 ;; GNU2 TLS patterns can be split.
14901
14902 (define_expand "tls_dynamic_gnu2_32"
14903   [(set (match_dup 3)
14904         (plus:SI (match_operand:SI 2 "register_operand" "")
14905                  (const:SI
14906                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14907                              UNSPEC_TLSDESC))))
14908    (parallel
14909     [(set (match_operand:SI 0 "register_operand" "")
14910           (unspec:SI [(match_dup 1) (match_dup 3)
14911                       (match_dup 2) (reg:SI SP_REG)]
14912                       UNSPEC_TLSDESC))
14913      (clobber (reg:CC FLAGS_REG))])]
14914   "!TARGET_64BIT && TARGET_GNU2_TLS"
14915 {
14916   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14917   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14918 })
14919
14920 (define_insn "*tls_dynamic_lea_32"
14921   [(set (match_operand:SI 0 "register_operand" "=r")
14922         (plus:SI (match_operand:SI 1 "register_operand" "b")
14923                  (const:SI
14924                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14925                               UNSPEC_TLSDESC))))]
14926   "!TARGET_64BIT && TARGET_GNU2_TLS"
14927   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14928   [(set_attr "type" "lea")
14929    (set_attr "mode" "SI")
14930    (set_attr "length" "6")
14931    (set_attr "length_address" "4")])
14932
14933 (define_insn "*tls_dynamic_call_32"
14934   [(set (match_operand:SI 0 "register_operand" "=a")
14935         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14936                     (match_operand:SI 2 "register_operand" "0")
14937                     ;; we have to make sure %ebx still points to the GOT
14938                     (match_operand:SI 3 "register_operand" "b")
14939                     (reg:SI SP_REG)]
14940                    UNSPEC_TLSDESC))
14941    (clobber (reg:CC FLAGS_REG))]
14942   "!TARGET_64BIT && TARGET_GNU2_TLS"
14943   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14944   [(set_attr "type" "call")
14945    (set_attr "length" "2")
14946    (set_attr "length_address" "0")])
14947
14948 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14949   [(set (match_operand:SI 0 "register_operand" "=&a")
14950         (plus:SI
14951          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14952                      (match_operand:SI 4 "" "")
14953                      (match_operand:SI 2 "register_operand" "b")
14954                      (reg:SI SP_REG)]
14955                     UNSPEC_TLSDESC)
14956          (const:SI (unspec:SI
14957                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14958                     UNSPEC_DTPOFF))))
14959    (clobber (reg:CC FLAGS_REG))]
14960   "!TARGET_64BIT && TARGET_GNU2_TLS"
14961   "#"
14962   ""
14963   [(set (match_dup 0) (match_dup 5))]
14964 {
14965   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14966   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14967 })
14968
14969 (define_expand "tls_dynamic_gnu2_64"
14970   [(set (match_dup 2)
14971         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14972                    UNSPEC_TLSDESC))
14973    (parallel
14974     [(set (match_operand:DI 0 "register_operand" "")
14975           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14976                      UNSPEC_TLSDESC))
14977      (clobber (reg:CC FLAGS_REG))])]
14978   "TARGET_64BIT && TARGET_GNU2_TLS"
14979 {
14980   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14981   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14982 })
14983
14984 (define_insn "*tls_dynamic_lea_64"
14985   [(set (match_operand:DI 0 "register_operand" "=r")
14986         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14987                    UNSPEC_TLSDESC))]
14988   "TARGET_64BIT && TARGET_GNU2_TLS"
14989   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14990   [(set_attr "type" "lea")
14991    (set_attr "mode" "DI")
14992    (set_attr "length" "7")
14993    (set_attr "length_address" "4")])
14994
14995 (define_insn "*tls_dynamic_call_64"
14996   [(set (match_operand:DI 0 "register_operand" "=a")
14997         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14998                     (match_operand:DI 2 "register_operand" "0")
14999                     (reg:DI SP_REG)]
15000                    UNSPEC_TLSDESC))
15001    (clobber (reg:CC FLAGS_REG))]
15002   "TARGET_64BIT && TARGET_GNU2_TLS"
15003   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15004   [(set_attr "type" "call")
15005    (set_attr "length" "2")
15006    (set_attr "length_address" "0")])
15007
15008 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15009   [(set (match_operand:DI 0 "register_operand" "=&a")
15010         (plus:DI
15011          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15012                      (match_operand:DI 3 "" "")
15013                      (reg:DI SP_REG)]
15014                     UNSPEC_TLSDESC)
15015          (const:DI (unspec:DI
15016                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15017                     UNSPEC_DTPOFF))))
15018    (clobber (reg:CC FLAGS_REG))]
15019   "TARGET_64BIT && TARGET_GNU2_TLS"
15020   "#"
15021   ""
15022   [(set (match_dup 0) (match_dup 4))]
15023 {
15024   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15025   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15026 })
15027
15028 ;;
15029 \f
15030 ;; These patterns match the binary 387 instructions for addM3, subM3,
15031 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15032 ;; SFmode.  The first is the normal insn, the second the same insn but
15033 ;; with one operand a conversion, and the third the same insn but with
15034 ;; the other operand a conversion.  The conversion may be SFmode or
15035 ;; SImode if the target mode DFmode, but only SImode if the target mode
15036 ;; is SFmode.
15037
15038 ;; Gcc is slightly more smart about handling normal two address instructions
15039 ;; so use special patterns for add and mull.
15040
15041 (define_insn "*fop_sf_comm_mixed"
15042   [(set (match_operand:SF 0 "register_operand" "=f,x")
15043         (match_operator:SF 3 "binary_fp_operator"
15044                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15045                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15046   "TARGET_MIX_SSE_I387
15047    && COMMUTATIVE_ARITH_P (operands[3])
15048    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15049   "* return output_387_binary_op (insn, operands);"
15050   [(set (attr "type")
15051         (if_then_else (eq_attr "alternative" "1")
15052            (if_then_else (match_operand:SF 3 "mult_operator" "")
15053               (const_string "ssemul")
15054               (const_string "sseadd"))
15055            (if_then_else (match_operand:SF 3 "mult_operator" "")
15056               (const_string "fmul")
15057               (const_string "fop"))))
15058    (set_attr "mode" "SF")])
15059
15060 (define_insn "*fop_sf_comm_sse"
15061   [(set (match_operand:SF 0 "register_operand" "=x")
15062         (match_operator:SF 3 "binary_fp_operator"
15063                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15064                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15065   "TARGET_SSE_MATH
15066    && COMMUTATIVE_ARITH_P (operands[3])
15067    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15068   "* return output_387_binary_op (insn, operands);"
15069   [(set (attr "type")
15070         (if_then_else (match_operand:SF 3 "mult_operator" "")
15071            (const_string "ssemul")
15072            (const_string "sseadd")))
15073    (set_attr "mode" "SF")])
15074
15075 (define_insn "*fop_sf_comm_i387"
15076   [(set (match_operand:SF 0 "register_operand" "=f")
15077         (match_operator:SF 3 "binary_fp_operator"
15078                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15079                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15080   "TARGET_80387
15081    && COMMUTATIVE_ARITH_P (operands[3])
15082    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15083   "* return output_387_binary_op (insn, operands);"
15084   [(set (attr "type")
15085         (if_then_else (match_operand:SF 3 "mult_operator" "")
15086            (const_string "fmul")
15087            (const_string "fop")))
15088    (set_attr "mode" "SF")])
15089
15090 (define_insn "*fop_sf_1_mixed"
15091   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15092         (match_operator:SF 3 "binary_fp_operator"
15093                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15094                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15095   "TARGET_MIX_SSE_I387
15096    && !COMMUTATIVE_ARITH_P (operands[3])
15097    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15098   "* return output_387_binary_op (insn, operands);"
15099   [(set (attr "type")
15100         (cond [(and (eq_attr "alternative" "2")
15101                     (match_operand:SF 3 "mult_operator" ""))
15102                  (const_string "ssemul")
15103                (and (eq_attr "alternative" "2")
15104                     (match_operand:SF 3 "div_operator" ""))
15105                  (const_string "ssediv")
15106                (eq_attr "alternative" "2")
15107                  (const_string "sseadd")
15108                (match_operand:SF 3 "mult_operator" "")
15109                  (const_string "fmul")
15110                (match_operand:SF 3 "div_operator" "")
15111                  (const_string "fdiv")
15112               ]
15113               (const_string "fop")))
15114    (set_attr "mode" "SF")])
15115
15116 (define_insn "*fop_sf_1_sse"
15117   [(set (match_operand:SF 0 "register_operand" "=x")
15118         (match_operator:SF 3 "binary_fp_operator"
15119                         [(match_operand:SF 1 "register_operand" "0")
15120                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15121   "TARGET_SSE_MATH
15122    && !COMMUTATIVE_ARITH_P (operands[3])"
15123   "* return output_387_binary_op (insn, operands);"
15124   [(set (attr "type")
15125         (cond [(match_operand:SF 3 "mult_operator" "")
15126                  (const_string "ssemul")
15127                (match_operand:SF 3 "div_operator" "")
15128                  (const_string "ssediv")
15129               ]
15130               (const_string "sseadd")))
15131    (set_attr "mode" "SF")])
15132
15133 ;; This pattern is not fully shadowed by the pattern above.
15134 (define_insn "*fop_sf_1_i387"
15135   [(set (match_operand:SF 0 "register_operand" "=f,f")
15136         (match_operator:SF 3 "binary_fp_operator"
15137                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15138                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15139   "TARGET_80387 && !TARGET_SSE_MATH
15140    && !COMMUTATIVE_ARITH_P (operands[3])
15141    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15142   "* return output_387_binary_op (insn, operands);"
15143   [(set (attr "type")
15144         (cond [(match_operand:SF 3 "mult_operator" "")
15145                  (const_string "fmul")
15146                (match_operand:SF 3 "div_operator" "")
15147                  (const_string "fdiv")
15148               ]
15149               (const_string "fop")))
15150    (set_attr "mode" "SF")])
15151
15152 ;; ??? Add SSE splitters for these!
15153 (define_insn "*fop_sf_2<mode>_i387"
15154   [(set (match_operand:SF 0 "register_operand" "=f,f")
15155         (match_operator:SF 3 "binary_fp_operator"
15156           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15157            (match_operand:SF 2 "register_operand" "0,0")]))]
15158   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15159   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15160   [(set (attr "type")
15161         (cond [(match_operand:SF 3 "mult_operator" "")
15162                  (const_string "fmul")
15163                (match_operand:SF 3 "div_operator" "")
15164                  (const_string "fdiv")
15165               ]
15166               (const_string "fop")))
15167    (set_attr "fp_int_src" "true")
15168    (set_attr "mode" "<MODE>")])
15169
15170 (define_insn "*fop_sf_3<mode>_i387"
15171   [(set (match_operand:SF 0 "register_operand" "=f,f")
15172         (match_operator:SF 3 "binary_fp_operator"
15173           [(match_operand:SF 1 "register_operand" "0,0")
15174            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15175   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15176   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15177   [(set (attr "type")
15178         (cond [(match_operand:SF 3 "mult_operator" "")
15179                  (const_string "fmul")
15180                (match_operand:SF 3 "div_operator" "")
15181                  (const_string "fdiv")
15182               ]
15183               (const_string "fop")))
15184    (set_attr "fp_int_src" "true")
15185    (set_attr "mode" "<MODE>")])
15186
15187 (define_insn "*fop_df_comm_mixed"
15188   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15189         (match_operator:DF 3 "binary_fp_operator"
15190                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15191                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15192   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15193    && COMMUTATIVE_ARITH_P (operands[3])
15194    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15195   "* return output_387_binary_op (insn, operands);"
15196   [(set (attr "type")
15197         (if_then_else (eq_attr "alternative" "1")
15198            (if_then_else (match_operand:DF 3 "mult_operator" "")
15199               (const_string "ssemul")
15200               (const_string "sseadd"))
15201            (if_then_else (match_operand:DF 3 "mult_operator" "")
15202               (const_string "fmul")
15203               (const_string "fop"))))
15204    (set_attr "mode" "DF")])
15205
15206 (define_insn "*fop_df_comm_sse"
15207   [(set (match_operand:DF 0 "register_operand" "=Y")
15208         (match_operator:DF 3 "binary_fp_operator"
15209                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15210                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15211   "TARGET_SSE2 && TARGET_SSE_MATH
15212    && COMMUTATIVE_ARITH_P (operands[3])
15213    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15214   "* return output_387_binary_op (insn, operands);"
15215   [(set (attr "type")
15216         (if_then_else (match_operand:DF 3 "mult_operator" "")
15217            (const_string "ssemul")
15218            (const_string "sseadd")))
15219    (set_attr "mode" "DF")])
15220
15221 (define_insn "*fop_df_comm_i387"
15222   [(set (match_operand:DF 0 "register_operand" "=f")
15223         (match_operator:DF 3 "binary_fp_operator"
15224                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15225                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15226   "TARGET_80387
15227    && COMMUTATIVE_ARITH_P (operands[3])
15228    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15229   "* return output_387_binary_op (insn, operands);"
15230   [(set (attr "type")
15231         (if_then_else (match_operand:DF 3 "mult_operator" "")
15232            (const_string "fmul")
15233            (const_string "fop")))
15234    (set_attr "mode" "DF")])
15235
15236 (define_insn "*fop_df_1_mixed"
15237   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15238         (match_operator:DF 3 "binary_fp_operator"
15239                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15240                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15241   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15242    && !COMMUTATIVE_ARITH_P (operands[3])
15243    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15244   "* return output_387_binary_op (insn, operands);"
15245   [(set (attr "type")
15246         (cond [(and (eq_attr "alternative" "2")
15247                     (match_operand:DF 3 "mult_operator" ""))
15248                  (const_string "ssemul")
15249                (and (eq_attr "alternative" "2")
15250                     (match_operand:DF 3 "div_operator" ""))
15251                  (const_string "ssediv")
15252                (eq_attr "alternative" "2")
15253                  (const_string "sseadd")
15254                (match_operand:DF 3 "mult_operator" "")
15255                  (const_string "fmul")
15256                (match_operand:DF 3 "div_operator" "")
15257                  (const_string "fdiv")
15258               ]
15259               (const_string "fop")))
15260    (set_attr "mode" "DF")])
15261
15262 (define_insn "*fop_df_1_sse"
15263   [(set (match_operand:DF 0 "register_operand" "=Y")
15264         (match_operator:DF 3 "binary_fp_operator"
15265                         [(match_operand:DF 1 "register_operand" "0")
15266                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15267   "TARGET_SSE2 && TARGET_SSE_MATH
15268    && !COMMUTATIVE_ARITH_P (operands[3])"
15269   "* return output_387_binary_op (insn, operands);"
15270   [(set_attr "mode" "DF")
15271    (set (attr "type")
15272         (cond [(match_operand:DF 3 "mult_operator" "")
15273                  (const_string "ssemul")
15274                (match_operand:DF 3 "div_operator" "")
15275                  (const_string "ssediv")
15276               ]
15277               (const_string "sseadd")))])
15278
15279 ;; This pattern is not fully shadowed by the pattern above.
15280 (define_insn "*fop_df_1_i387"
15281   [(set (match_operand:DF 0 "register_operand" "=f,f")
15282         (match_operator:DF 3 "binary_fp_operator"
15283                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15284                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15285   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15286    && !COMMUTATIVE_ARITH_P (operands[3])
15287    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15288   "* return output_387_binary_op (insn, operands);"
15289   [(set (attr "type")
15290         (cond [(match_operand:DF 3 "mult_operator" "")
15291                  (const_string "fmul")
15292                (match_operand:DF 3 "div_operator" "")
15293                  (const_string "fdiv")
15294               ]
15295               (const_string "fop")))
15296    (set_attr "mode" "DF")])
15297
15298 ;; ??? Add SSE splitters for these!
15299 (define_insn "*fop_df_2<mode>_i387"
15300   [(set (match_operand:DF 0 "register_operand" "=f,f")
15301         (match_operator:DF 3 "binary_fp_operator"
15302            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15303             (match_operand:DF 2 "register_operand" "0,0")]))]
15304   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15305    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15306   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15307   [(set (attr "type")
15308         (cond [(match_operand:DF 3 "mult_operator" "")
15309                  (const_string "fmul")
15310                (match_operand:DF 3 "div_operator" "")
15311                  (const_string "fdiv")
15312               ]
15313               (const_string "fop")))
15314    (set_attr "fp_int_src" "true")
15315    (set_attr "mode" "<MODE>")])
15316
15317 (define_insn "*fop_df_3<mode>_i387"
15318   [(set (match_operand:DF 0 "register_operand" "=f,f")
15319         (match_operator:DF 3 "binary_fp_operator"
15320            [(match_operand:DF 1 "register_operand" "0,0")
15321             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15322   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15323    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15324   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15325   [(set (attr "type")
15326         (cond [(match_operand:DF 3 "mult_operator" "")
15327                  (const_string "fmul")
15328                (match_operand:DF 3 "div_operator" "")
15329                  (const_string "fdiv")
15330               ]
15331               (const_string "fop")))
15332    (set_attr "fp_int_src" "true")
15333    (set_attr "mode" "<MODE>")])
15334
15335 (define_insn "*fop_df_4_i387"
15336   [(set (match_operand:DF 0 "register_operand" "=f,f")
15337         (match_operator:DF 3 "binary_fp_operator"
15338            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15339             (match_operand:DF 2 "register_operand" "0,f")]))]
15340   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15341    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15342   "* return output_387_binary_op (insn, operands);"
15343   [(set (attr "type")
15344         (cond [(match_operand:DF 3 "mult_operator" "")
15345                  (const_string "fmul")
15346                (match_operand:DF 3 "div_operator" "")
15347                  (const_string "fdiv")
15348               ]
15349               (const_string "fop")))
15350    (set_attr "mode" "SF")])
15351
15352 (define_insn "*fop_df_5_i387"
15353   [(set (match_operand:DF 0 "register_operand" "=f,f")
15354         (match_operator:DF 3 "binary_fp_operator"
15355           [(match_operand:DF 1 "register_operand" "0,f")
15356            (float_extend:DF
15357             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15358   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15359   "* return output_387_binary_op (insn, operands);"
15360   [(set (attr "type")
15361         (cond [(match_operand:DF 3 "mult_operator" "")
15362                  (const_string "fmul")
15363                (match_operand:DF 3 "div_operator" "")
15364                  (const_string "fdiv")
15365               ]
15366               (const_string "fop")))
15367    (set_attr "mode" "SF")])
15368
15369 (define_insn "*fop_df_6_i387"
15370   [(set (match_operand:DF 0 "register_operand" "=f,f")
15371         (match_operator:DF 3 "binary_fp_operator"
15372           [(float_extend:DF
15373             (match_operand:SF 1 "register_operand" "0,f"))
15374            (float_extend:DF
15375             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15376   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15377   "* return output_387_binary_op (insn, operands);"
15378   [(set (attr "type")
15379         (cond [(match_operand:DF 3 "mult_operator" "")
15380                  (const_string "fmul")
15381                (match_operand:DF 3 "div_operator" "")
15382                  (const_string "fdiv")
15383               ]
15384               (const_string "fop")))
15385    (set_attr "mode" "SF")])
15386
15387 (define_insn "*fop_xf_comm_i387"
15388   [(set (match_operand:XF 0 "register_operand" "=f")
15389         (match_operator:XF 3 "binary_fp_operator"
15390                         [(match_operand:XF 1 "register_operand" "%0")
15391                          (match_operand:XF 2 "register_operand" "f")]))]
15392   "TARGET_80387
15393    && COMMUTATIVE_ARITH_P (operands[3])"
15394   "* return output_387_binary_op (insn, operands);"
15395   [(set (attr "type")
15396         (if_then_else (match_operand:XF 3 "mult_operator" "")
15397            (const_string "fmul")
15398            (const_string "fop")))
15399    (set_attr "mode" "XF")])
15400
15401 (define_insn "*fop_xf_1_i387"
15402   [(set (match_operand:XF 0 "register_operand" "=f,f")
15403         (match_operator:XF 3 "binary_fp_operator"
15404                         [(match_operand:XF 1 "register_operand" "0,f")
15405                          (match_operand:XF 2 "register_operand" "f,0")]))]
15406   "TARGET_80387
15407    && !COMMUTATIVE_ARITH_P (operands[3])"
15408   "* return output_387_binary_op (insn, operands);"
15409   [(set (attr "type")
15410         (cond [(match_operand:XF 3 "mult_operator" "")
15411                  (const_string "fmul")
15412                (match_operand:XF 3 "div_operator" "")
15413                  (const_string "fdiv")
15414               ]
15415               (const_string "fop")))
15416    (set_attr "mode" "XF")])
15417
15418 (define_insn "*fop_xf_2<mode>_i387"
15419   [(set (match_operand:XF 0 "register_operand" "=f,f")
15420         (match_operator:XF 3 "binary_fp_operator"
15421            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15422             (match_operand:XF 2 "register_operand" "0,0")]))]
15423   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15424   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15425   [(set (attr "type")
15426         (cond [(match_operand:XF 3 "mult_operator" "")
15427                  (const_string "fmul")
15428                (match_operand:XF 3 "div_operator" "")
15429                  (const_string "fdiv")
15430               ]
15431               (const_string "fop")))
15432    (set_attr "fp_int_src" "true")
15433    (set_attr "mode" "<MODE>")])
15434
15435 (define_insn "*fop_xf_3<mode>_i387"
15436   [(set (match_operand:XF 0 "register_operand" "=f,f")
15437         (match_operator:XF 3 "binary_fp_operator"
15438           [(match_operand:XF 1 "register_operand" "0,0")
15439            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15440   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15441   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15442   [(set (attr "type")
15443         (cond [(match_operand:XF 3 "mult_operator" "")
15444                  (const_string "fmul")
15445                (match_operand:XF 3 "div_operator" "")
15446                  (const_string "fdiv")
15447               ]
15448               (const_string "fop")))
15449    (set_attr "fp_int_src" "true")
15450    (set_attr "mode" "<MODE>")])
15451
15452 (define_insn "*fop_xf_4_i387"
15453   [(set (match_operand:XF 0 "register_operand" "=f,f")
15454         (match_operator:XF 3 "binary_fp_operator"
15455            [(float_extend:XF
15456               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15457             (match_operand:XF 2 "register_operand" "0,f")]))]
15458   "TARGET_80387"
15459   "* return output_387_binary_op (insn, operands);"
15460   [(set (attr "type")
15461         (cond [(match_operand:XF 3 "mult_operator" "")
15462                  (const_string "fmul")
15463                (match_operand:XF 3 "div_operator" "")
15464                  (const_string "fdiv")
15465               ]
15466               (const_string "fop")))
15467    (set_attr "mode" "SF")])
15468
15469 (define_insn "*fop_xf_5_i387"
15470   [(set (match_operand:XF 0 "register_operand" "=f,f")
15471         (match_operator:XF 3 "binary_fp_operator"
15472           [(match_operand:XF 1 "register_operand" "0,f")
15473            (float_extend:XF
15474              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15475   "TARGET_80387"
15476   "* return output_387_binary_op (insn, operands);"
15477   [(set (attr "type")
15478         (cond [(match_operand:XF 3 "mult_operator" "")
15479                  (const_string "fmul")
15480                (match_operand:XF 3 "div_operator" "")
15481                  (const_string "fdiv")
15482               ]
15483               (const_string "fop")))
15484    (set_attr "mode" "SF")])
15485
15486 (define_insn "*fop_xf_6_i387"
15487   [(set (match_operand:XF 0 "register_operand" "=f,f")
15488         (match_operator:XF 3 "binary_fp_operator"
15489           [(float_extend:XF
15490              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15491            (float_extend:XF
15492              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15493   "TARGET_80387"
15494   "* return output_387_binary_op (insn, operands);"
15495   [(set (attr "type")
15496         (cond [(match_operand:XF 3 "mult_operator" "")
15497                  (const_string "fmul")
15498                (match_operand:XF 3 "div_operator" "")
15499                  (const_string "fdiv")
15500               ]
15501               (const_string "fop")))
15502    (set_attr "mode" "SF")])
15503
15504 (define_split
15505   [(set (match_operand 0 "register_operand" "")
15506         (match_operator 3 "binary_fp_operator"
15507            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15508             (match_operand 2 "register_operand" "")]))]
15509   "TARGET_80387 && reload_completed
15510    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15511   [(const_int 0)]
15512 {
15513   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15514   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15515   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15516                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15517                                           GET_MODE (operands[3]),
15518                                           operands[4],
15519                                           operands[2])));
15520   ix86_free_from_memory (GET_MODE (operands[1]));
15521   DONE;
15522 })
15523
15524 (define_split
15525   [(set (match_operand 0 "register_operand" "")
15526         (match_operator 3 "binary_fp_operator"
15527            [(match_operand 1 "register_operand" "")
15528             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15529   "TARGET_80387 && reload_completed
15530    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15531   [(const_int 0)]
15532 {
15533   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15534   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15535   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15536                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15537                                           GET_MODE (operands[3]),
15538                                           operands[1],
15539                                           operands[4])));
15540   ix86_free_from_memory (GET_MODE (operands[2]));
15541   DONE;
15542 })
15543 \f
15544 ;; FPU special functions.
15545
15546 ;; This pattern implements a no-op XFmode truncation for
15547 ;; all fancy i386 XFmode math functions.
15548
15549 (define_insn "truncxf<mode>2_i387_noop_unspec"
15550   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15551         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15552         UNSPEC_TRUNC_NOOP))]
15553   "TARGET_USE_FANCY_MATH_387"
15554   "* return output_387_reg_move (insn, operands);"
15555   [(set_attr "type" "fmov")
15556    (set_attr "mode" "<MODE>")])
15557
15558 (define_insn "sqrtxf2"
15559   [(set (match_operand:XF 0 "register_operand" "=f")
15560         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15561   "TARGET_USE_FANCY_MATH_387"
15562   "fsqrt"
15563   [(set_attr "type" "fpspc")
15564    (set_attr "mode" "XF")
15565    (set_attr "athlon_decode" "direct")])
15566
15567 (define_insn "sqrt_extend<mode>xf2_i387"
15568   [(set (match_operand:XF 0 "register_operand" "=f")
15569         (sqrt:XF
15570           (float_extend:XF
15571             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15572   "TARGET_USE_FANCY_MATH_387"
15573   "fsqrt"
15574   [(set_attr "type" "fpspc")
15575    (set_attr "mode" "XF")
15576    (set_attr "athlon_decode" "direct")])
15577
15578 (define_insn "*sqrt<mode>2_sse"
15579   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15580         (sqrt:SSEMODEF
15581           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15582   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15583   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15584   [(set_attr "type" "sse")
15585    (set_attr "mode" "<MODE>")
15586    (set_attr "athlon_decode" "*")])
15587
15588 (define_expand "sqrt<mode>2"
15589   [(set (match_operand:X87MODEF12 0 "register_operand" "")
15590         (sqrt:X87MODEF12
15591           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15592   "TARGET_USE_FANCY_MATH_387
15593    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15594 {
15595   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15596     {
15597       rtx op0 = gen_reg_rtx (XFmode);
15598       rtx op1 = force_reg (<MODE>mode, operands[1]);
15599
15600       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15601       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15602       DONE;
15603    }
15604 })
15605
15606 (define_insn "fpremxf4_i387"
15607   [(set (match_operand:XF 0 "register_operand" "=f")
15608         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15609                     (match_operand:XF 3 "register_operand" "1")]
15610                    UNSPEC_FPREM_F))
15611    (set (match_operand:XF 1 "register_operand" "=u")
15612         (unspec:XF [(match_dup 2) (match_dup 3)]
15613                    UNSPEC_FPREM_U))
15614    (set (reg:CCFP FPSR_REG)
15615         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15616   "TARGET_USE_FANCY_MATH_387"
15617   "fprem"
15618   [(set_attr "type" "fpspc")
15619    (set_attr "mode" "XF")])
15620
15621 (define_expand "fmodxf3"
15622   [(use (match_operand:XF 0 "register_operand" ""))
15623    (use (match_operand:XF 1 "register_operand" ""))
15624    (use (match_operand:XF 2 "register_operand" ""))]
15625   "TARGET_USE_FANCY_MATH_387"
15626 {
15627   rtx label = gen_label_rtx ();
15628
15629   emit_label (label);
15630
15631   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15632                                 operands[1], operands[2]));
15633   ix86_emit_fp_unordered_jump (label);
15634
15635   emit_move_insn (operands[0], operands[1]);
15636   DONE;
15637 })
15638
15639 (define_expand "fmod<mode>3"
15640   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15641    (use (match_operand:X87MODEF12 1 "general_operand" ""))
15642    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15643   "TARGET_USE_FANCY_MATH_387"
15644 {
15645   rtx label = gen_label_rtx ();
15646
15647   rtx op1 = gen_reg_rtx (XFmode);
15648   rtx op2 = gen_reg_rtx (XFmode);
15649
15650   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15651   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15652
15653   emit_label (label);
15654   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15655   ix86_emit_fp_unordered_jump (label);
15656
15657   /* Truncate the result properly for strict SSE math.  */
15658   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15659       && !TARGET_MIX_SSE_I387)
15660     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15661   else
15662     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15663
15664   DONE;
15665 })
15666
15667 (define_insn "fprem1xf4_i387"
15668   [(set (match_operand:XF 0 "register_operand" "=f")
15669         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15670                     (match_operand:XF 3 "register_operand" "1")]
15671                    UNSPEC_FPREM1_F))
15672    (set (match_operand:XF 1 "register_operand" "=u")
15673         (unspec:XF [(match_dup 2) (match_dup 3)]
15674                    UNSPEC_FPREM1_U))
15675    (set (reg:CCFP FPSR_REG)
15676         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15677   "TARGET_USE_FANCY_MATH_387"
15678   "fprem1"
15679   [(set_attr "type" "fpspc")
15680    (set_attr "mode" "XF")])
15681
15682 (define_expand "remainderxf3"
15683   [(use (match_operand:XF 0 "register_operand" ""))
15684    (use (match_operand:XF 1 "register_operand" ""))
15685    (use (match_operand:XF 2 "register_operand" ""))]
15686   "TARGET_USE_FANCY_MATH_387"
15687 {
15688   rtx label = gen_label_rtx ();
15689
15690   emit_label (label);
15691
15692   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15693                                  operands[1], operands[2]));
15694   ix86_emit_fp_unordered_jump (label);
15695
15696   emit_move_insn (operands[0], operands[1]);
15697   DONE;
15698 })
15699
15700 (define_expand "remainder<mode>3"
15701   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15702    (use (match_operand:X87MODEF12 1 "general_operand" ""))
15703    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15704   "TARGET_USE_FANCY_MATH_387"
15705 {
15706   rtx label = gen_label_rtx ();
15707
15708   rtx op1 = gen_reg_rtx (XFmode);
15709   rtx op2 = gen_reg_rtx (XFmode);
15710
15711   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15712   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15713
15714   emit_label (label);
15715
15716   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15717   ix86_emit_fp_unordered_jump (label);
15718
15719   /* Truncate the result properly for strict SSE math.  */
15720   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15721       && !TARGET_MIX_SSE_I387)
15722     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15723   else
15724     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15725
15726   DONE;
15727 })
15728
15729 (define_insn "*sindf2"
15730   [(set (match_operand:DF 0 "register_operand" "=f")
15731         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15732   "TARGET_USE_FANCY_MATH_387
15733    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15734    && flag_unsafe_math_optimizations"
15735   "fsin"
15736   [(set_attr "type" "fpspc")
15737    (set_attr "mode" "DF")])
15738
15739 (define_insn "*sinsf2"
15740   [(set (match_operand:SF 0 "register_operand" "=f")
15741         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15742   "TARGET_USE_FANCY_MATH_387
15743    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15744    && flag_unsafe_math_optimizations"
15745   "fsin"
15746   [(set_attr "type" "fpspc")
15747    (set_attr "mode" "SF")])
15748
15749 (define_insn "*sinextendsfdf2"
15750   [(set (match_operand:DF 0 "register_operand" "=f")
15751         (unspec:DF [(float_extend:DF
15752                      (match_operand:SF 1 "register_operand" "0"))]
15753                    UNSPEC_SIN))]
15754   "TARGET_USE_FANCY_MATH_387
15755    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15756    && flag_unsafe_math_optimizations"
15757   "fsin"
15758   [(set_attr "type" "fpspc")
15759    (set_attr "mode" "DF")])
15760
15761 (define_insn "*sinxf2"
15762   [(set (match_operand:XF 0 "register_operand" "=f")
15763         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15764   "TARGET_USE_FANCY_MATH_387
15765    && flag_unsafe_math_optimizations"
15766   "fsin"
15767   [(set_attr "type" "fpspc")
15768    (set_attr "mode" "XF")])
15769
15770 (define_insn "*cosdf2"
15771   [(set (match_operand:DF 0 "register_operand" "=f")
15772         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15773   "TARGET_USE_FANCY_MATH_387
15774    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15775    && flag_unsafe_math_optimizations"
15776   "fcos"
15777   [(set_attr "type" "fpspc")
15778    (set_attr "mode" "DF")])
15779
15780 (define_insn "*cossf2"
15781   [(set (match_operand:SF 0 "register_operand" "=f")
15782         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15783   "TARGET_USE_FANCY_MATH_387
15784    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15785    && flag_unsafe_math_optimizations"
15786   "fcos"
15787   [(set_attr "type" "fpspc")
15788    (set_attr "mode" "SF")])
15789
15790 (define_insn "*cosextendsfdf2"
15791   [(set (match_operand:DF 0 "register_operand" "=f")
15792         (unspec:DF [(float_extend:DF
15793                      (match_operand:SF 1 "register_operand" "0"))]
15794                    UNSPEC_COS))]
15795   "TARGET_USE_FANCY_MATH_387
15796    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15797    && flag_unsafe_math_optimizations"
15798   "fcos"
15799   [(set_attr "type" "fpspc")
15800    (set_attr "mode" "DF")])
15801
15802 (define_insn "*cosxf2"
15803   [(set (match_operand:XF 0 "register_operand" "=f")
15804         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15805   "TARGET_USE_FANCY_MATH_387
15806    && flag_unsafe_math_optimizations"
15807   "fcos"
15808   [(set_attr "type" "fpspc")
15809    (set_attr "mode" "XF")])
15810
15811 ;; With sincos pattern defined, sin and cos builtin function will be
15812 ;; expanded to sincos pattern with one of its outputs left unused.
15813 ;; Cse pass  will detected, if two sincos patterns can be combined,
15814 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15815 ;; depending on the unused output.
15816
15817 (define_insn "sincosdf3"
15818   [(set (match_operand:DF 0 "register_operand" "=f")
15819         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15820                    UNSPEC_SINCOS_COS))
15821    (set (match_operand:DF 1 "register_operand" "=u")
15822         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15823   "TARGET_USE_FANCY_MATH_387
15824    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15825    && flag_unsafe_math_optimizations"
15826   "fsincos"
15827   [(set_attr "type" "fpspc")
15828    (set_attr "mode" "DF")])
15829
15830 (define_split
15831   [(set (match_operand:DF 0 "register_operand" "")
15832         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15833                    UNSPEC_SINCOS_COS))
15834    (set (match_operand:DF 1 "register_operand" "")
15835         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15836   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15837    && !reload_completed && !reload_in_progress"
15838   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15839   "")
15840
15841 (define_split
15842   [(set (match_operand:DF 0 "register_operand" "")
15843         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15844                    UNSPEC_SINCOS_COS))
15845    (set (match_operand:DF 1 "register_operand" "")
15846         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15847   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15848    && !reload_completed && !reload_in_progress"
15849   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15850   "")
15851
15852 (define_insn "sincossf3"
15853   [(set (match_operand:SF 0 "register_operand" "=f")
15854         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15855                    UNSPEC_SINCOS_COS))
15856    (set (match_operand:SF 1 "register_operand" "=u")
15857         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15858   "TARGET_USE_FANCY_MATH_387
15859    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15860    && flag_unsafe_math_optimizations"
15861   "fsincos"
15862   [(set_attr "type" "fpspc")
15863    (set_attr "mode" "SF")])
15864
15865 (define_split
15866   [(set (match_operand:SF 0 "register_operand" "")
15867         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15868                    UNSPEC_SINCOS_COS))
15869    (set (match_operand:SF 1 "register_operand" "")
15870         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15871   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15872    && !reload_completed && !reload_in_progress"
15873   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15874   "")
15875
15876 (define_split
15877   [(set (match_operand:SF 0 "register_operand" "")
15878         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15879                    UNSPEC_SINCOS_COS))
15880    (set (match_operand:SF 1 "register_operand" "")
15881         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15882   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15883    && !reload_completed && !reload_in_progress"
15884   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15885   "")
15886
15887 (define_insn "*sincosextendsfdf3"
15888   [(set (match_operand:DF 0 "register_operand" "=f")
15889         (unspec:DF [(float_extend:DF
15890                      (match_operand:SF 2 "register_operand" "0"))]
15891                    UNSPEC_SINCOS_COS))
15892    (set (match_operand:DF 1 "register_operand" "=u")
15893         (unspec:DF [(float_extend:DF
15894                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15895   "TARGET_USE_FANCY_MATH_387
15896    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15897    && flag_unsafe_math_optimizations"
15898   "fsincos"
15899   [(set_attr "type" "fpspc")
15900    (set_attr "mode" "DF")])
15901
15902 (define_split
15903   [(set (match_operand:DF 0 "register_operand" "")
15904         (unspec:DF [(float_extend:DF
15905                      (match_operand:SF 2 "register_operand" ""))]
15906                    UNSPEC_SINCOS_COS))
15907    (set (match_operand:DF 1 "register_operand" "")
15908         (unspec:DF [(float_extend:DF
15909                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15910   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15911    && !reload_completed && !reload_in_progress"
15912   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15913                                    (match_dup 2))] UNSPEC_SIN))]
15914   "")
15915
15916 (define_split
15917   [(set (match_operand:DF 0 "register_operand" "")
15918         (unspec:DF [(float_extend:DF
15919                      (match_operand:SF 2 "register_operand" ""))]
15920                    UNSPEC_SINCOS_COS))
15921    (set (match_operand:DF 1 "register_operand" "")
15922         (unspec:DF [(float_extend:DF
15923                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15924   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15925    && !reload_completed && !reload_in_progress"
15926   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15927                                    (match_dup 2))] UNSPEC_COS))]
15928   "")
15929
15930 (define_insn "sincosxf3"
15931   [(set (match_operand:XF 0 "register_operand" "=f")
15932         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15933                    UNSPEC_SINCOS_COS))
15934    (set (match_operand:XF 1 "register_operand" "=u")
15935         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15936   "TARGET_USE_FANCY_MATH_387
15937    && flag_unsafe_math_optimizations"
15938   "fsincos"
15939   [(set_attr "type" "fpspc")
15940    (set_attr "mode" "XF")])
15941
15942 (define_split
15943   [(set (match_operand:XF 0 "register_operand" "")
15944         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15945                    UNSPEC_SINCOS_COS))
15946    (set (match_operand:XF 1 "register_operand" "")
15947         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15948   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15949    && !reload_completed && !reload_in_progress"
15950   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15951   "")
15952
15953 (define_split
15954   [(set (match_operand:XF 0 "register_operand" "")
15955         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15956                    UNSPEC_SINCOS_COS))
15957    (set (match_operand:XF 1 "register_operand" "")
15958         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15959   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15960    && !reload_completed && !reload_in_progress"
15961   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15962   "")
15963
15964 (define_insn "*tandf3_1"
15965   [(set (match_operand:DF 0 "register_operand" "=f")
15966         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15967                    UNSPEC_TAN_ONE))
15968    (set (match_operand:DF 1 "register_operand" "=u")
15969         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15970   "TARGET_USE_FANCY_MATH_387
15971    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15972    && flag_unsafe_math_optimizations"
15973   "fptan"
15974   [(set_attr "type" "fpspc")
15975    (set_attr "mode" "DF")])
15976
15977 ;; optimize sequence: fptan
15978 ;;                    fstp    %st(0)
15979 ;;                    fld1
15980 ;; into fptan insn.
15981
15982 (define_peephole2
15983   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15984                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15985                              UNSPEC_TAN_ONE))
15986              (set (match_operand:DF 1 "register_operand" "")
15987                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15988    (set (match_dup 0)
15989         (match_operand:DF 3 "immediate_operand" ""))]
15990   "standard_80387_constant_p (operands[3]) == 2"
15991   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15992              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15993   "")
15994
15995 (define_expand "tandf2"
15996   [(parallel [(set (match_dup 2)
15997                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15998                               UNSPEC_TAN_ONE))
15999               (set (match_operand:DF 0 "register_operand" "")
16000                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16001   "TARGET_USE_FANCY_MATH_387
16002    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16003    && flag_unsafe_math_optimizations"
16004 {
16005   operands[2] = gen_reg_rtx (DFmode);
16006 })
16007
16008 (define_insn "*tansf3_1"
16009   [(set (match_operand:SF 0 "register_operand" "=f")
16010         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16011                    UNSPEC_TAN_ONE))
16012    (set (match_operand:SF 1 "register_operand" "=u")
16013         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16014   "TARGET_USE_FANCY_MATH_387
16015    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16016    && flag_unsafe_math_optimizations"
16017   "fptan"
16018   [(set_attr "type" "fpspc")
16019    (set_attr "mode" "SF")])
16020
16021 ;; optimize sequence: fptan
16022 ;;                    fstp    %st(0)
16023 ;;                    fld1
16024 ;; into fptan insn.
16025
16026 (define_peephole2
16027   [(parallel[(set (match_operand:SF 0 "register_operand" "")
16028                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16029                              UNSPEC_TAN_ONE))
16030              (set (match_operand:SF 1 "register_operand" "")
16031                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16032    (set (match_dup 0)
16033         (match_operand:SF 3 "immediate_operand" ""))]
16034   "standard_80387_constant_p (operands[3]) == 2"
16035   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16036              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16037   "")
16038
16039 (define_expand "tansf2"
16040   [(parallel [(set (match_dup 2)
16041                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16042                               UNSPEC_TAN_ONE))
16043               (set (match_operand:SF 0 "register_operand" "")
16044                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16045   "TARGET_USE_FANCY_MATH_387
16046    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16047    && flag_unsafe_math_optimizations"
16048 {
16049   operands[2] = gen_reg_rtx (SFmode);
16050 })
16051
16052 (define_insn "*tanxf3_1"
16053   [(set (match_operand:XF 0 "register_operand" "=f")
16054         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16055                    UNSPEC_TAN_ONE))
16056    (set (match_operand:XF 1 "register_operand" "=u")
16057         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16058   "TARGET_USE_FANCY_MATH_387
16059    && flag_unsafe_math_optimizations"
16060   "fptan"
16061   [(set_attr "type" "fpspc")
16062    (set_attr "mode" "XF")])
16063
16064 ;; optimize sequence: fptan
16065 ;;                    fstp    %st(0)
16066 ;;                    fld1
16067 ;; into fptan insn.
16068
16069 (define_peephole2
16070   [(parallel[(set (match_operand:XF 0 "register_operand" "")
16071                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16072                              UNSPEC_TAN_ONE))
16073              (set (match_operand:XF 1 "register_operand" "")
16074                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16075    (set (match_dup 0)
16076         (match_operand:XF 3 "immediate_operand" ""))]
16077   "standard_80387_constant_p (operands[3]) == 2"
16078   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16079              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16080   "")
16081
16082 (define_expand "tanxf2"
16083   [(parallel [(set (match_dup 2)
16084                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16085                               UNSPEC_TAN_ONE))
16086               (set (match_operand:XF 0 "register_operand" "")
16087                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16088   "TARGET_USE_FANCY_MATH_387
16089    && flag_unsafe_math_optimizations"
16090 {
16091   operands[2] = gen_reg_rtx (XFmode);
16092 })
16093
16094 (define_insn "atan2df3_1"
16095   [(set (match_operand:DF 0 "register_operand" "=f")
16096         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16097                     (match_operand:DF 1 "register_operand" "u")]
16098                    UNSPEC_FPATAN))
16099    (clobber (match_scratch:DF 3 "=1"))]
16100   "TARGET_USE_FANCY_MATH_387
16101    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16102    && flag_unsafe_math_optimizations"
16103   "fpatan"
16104   [(set_attr "type" "fpspc")
16105    (set_attr "mode" "DF")])
16106
16107 (define_expand "atan2df3"
16108   [(use (match_operand:DF 0 "register_operand" ""))
16109    (use (match_operand:DF 2 "register_operand" ""))
16110    (use (match_operand:DF 1 "register_operand" ""))]
16111   "TARGET_USE_FANCY_MATH_387
16112    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16113    && flag_unsafe_math_optimizations"
16114 {
16115   rtx copy = gen_reg_rtx (DFmode);
16116   emit_move_insn (copy, operands[1]);
16117   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16118   DONE;
16119 })
16120
16121 (define_expand "atandf2"
16122   [(parallel [(set (match_operand:DF 0 "register_operand" "")
16123                    (unspec:DF [(match_dup 2)
16124                                (match_operand:DF 1 "register_operand" "")]
16125                     UNSPEC_FPATAN))
16126               (clobber (match_scratch:DF 3 ""))])]
16127   "TARGET_USE_FANCY_MATH_387
16128    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16129    && flag_unsafe_math_optimizations"
16130 {
16131   operands[2] = gen_reg_rtx (DFmode);
16132   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16133 })
16134
16135 (define_insn "atan2sf3_1"
16136   [(set (match_operand:SF 0 "register_operand" "=f")
16137         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16138                     (match_operand:SF 1 "register_operand" "u")]
16139                    UNSPEC_FPATAN))
16140    (clobber (match_scratch:SF 3 "=1"))]
16141   "TARGET_USE_FANCY_MATH_387
16142    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16143    && flag_unsafe_math_optimizations"
16144   "fpatan"
16145   [(set_attr "type" "fpspc")
16146    (set_attr "mode" "SF")])
16147
16148 (define_expand "atan2sf3"
16149   [(use (match_operand:SF 0 "register_operand" ""))
16150    (use (match_operand:SF 2 "register_operand" ""))
16151    (use (match_operand:SF 1 "register_operand" ""))]
16152   "TARGET_USE_FANCY_MATH_387
16153    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16154    && flag_unsafe_math_optimizations"
16155 {
16156   rtx copy = gen_reg_rtx (SFmode);
16157   emit_move_insn (copy, operands[1]);
16158   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16159   DONE;
16160 })
16161
16162 (define_expand "atansf2"
16163   [(parallel [(set (match_operand:SF 0 "register_operand" "")
16164                    (unspec:SF [(match_dup 2)
16165                                (match_operand:SF 1 "register_operand" "")]
16166                     UNSPEC_FPATAN))
16167               (clobber (match_scratch:SF 3 ""))])]
16168   "TARGET_USE_FANCY_MATH_387
16169    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16170    && flag_unsafe_math_optimizations"
16171 {
16172   operands[2] = gen_reg_rtx (SFmode);
16173   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16174 })
16175
16176 (define_insn "atan2xf3_1"
16177   [(set (match_operand:XF 0 "register_operand" "=f")
16178         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16179                     (match_operand:XF 1 "register_operand" "u")]
16180                    UNSPEC_FPATAN))
16181    (clobber (match_scratch:XF 3 "=1"))]
16182   "TARGET_USE_FANCY_MATH_387
16183    && flag_unsafe_math_optimizations"
16184   "fpatan"
16185   [(set_attr "type" "fpspc")
16186    (set_attr "mode" "XF")])
16187
16188 (define_expand "atan2xf3"
16189   [(use (match_operand:XF 0 "register_operand" ""))
16190    (use (match_operand:XF 2 "register_operand" ""))
16191    (use (match_operand:XF 1 "register_operand" ""))]
16192   "TARGET_USE_FANCY_MATH_387
16193    && flag_unsafe_math_optimizations"
16194 {
16195   rtx copy = gen_reg_rtx (XFmode);
16196   emit_move_insn (copy, operands[1]);
16197   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16198   DONE;
16199 })
16200
16201 (define_expand "atanxf2"
16202   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16203                    (unspec:XF [(match_dup 2)
16204                                (match_operand:XF 1 "register_operand" "")]
16205                     UNSPEC_FPATAN))
16206               (clobber (match_scratch:XF 3 ""))])]
16207   "TARGET_USE_FANCY_MATH_387
16208    && flag_unsafe_math_optimizations"
16209 {
16210   operands[2] = gen_reg_rtx (XFmode);
16211   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16212 })
16213
16214 (define_expand "asindf2"
16215   [(set (match_dup 2)
16216         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16217    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16218    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16219    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16220    (parallel [(set (match_dup 7)
16221                    (unspec:XF [(match_dup 6) (match_dup 2)]
16222                               UNSPEC_FPATAN))
16223               (clobber (match_scratch:XF 8 ""))])
16224    (set (match_operand:DF 0 "register_operand" "")
16225         (float_truncate:DF (match_dup 7)))]
16226   "TARGET_USE_FANCY_MATH_387
16227    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16228    && flag_unsafe_math_optimizations && !optimize_size"
16229 {
16230   int i;
16231
16232   for (i=2; i<8; i++)
16233     operands[i] = gen_reg_rtx (XFmode);
16234
16235   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16236 })
16237
16238 (define_expand "asinsf2"
16239   [(set (match_dup 2)
16240         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16241    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16242    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16243    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16244    (parallel [(set (match_dup 7)
16245                    (unspec:XF [(match_dup 6) (match_dup 2)]
16246                               UNSPEC_FPATAN))
16247               (clobber (match_scratch:XF 8 ""))])
16248    (set (match_operand:SF 0 "register_operand" "")
16249         (float_truncate:SF (match_dup 7)))]
16250   "TARGET_USE_FANCY_MATH_387
16251    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16252    && flag_unsafe_math_optimizations && !optimize_size"
16253 {
16254   int i;
16255
16256   for (i=2; i<8; i++)
16257     operands[i] = gen_reg_rtx (XFmode);
16258
16259   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16260 })
16261
16262 (define_expand "asinxf2"
16263   [(set (match_dup 2)
16264         (mult:XF (match_operand:XF 1 "register_operand" "")
16265                  (match_dup 1)))
16266    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16267    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16268    (parallel [(set (match_operand:XF 0 "register_operand" "")
16269                    (unspec:XF [(match_dup 5) (match_dup 1)]
16270                               UNSPEC_FPATAN))
16271               (clobber (match_scratch:XF 6 ""))])]
16272   "TARGET_USE_FANCY_MATH_387
16273    && flag_unsafe_math_optimizations && !optimize_size"
16274 {
16275   int i;
16276
16277   for (i=2; i<6; i++)
16278     operands[i] = gen_reg_rtx (XFmode);
16279
16280   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16281 })
16282
16283 (define_expand "acosdf2"
16284   [(set (match_dup 2)
16285         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16286    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16287    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16288    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16289    (parallel [(set (match_dup 7)
16290                    (unspec:XF [(match_dup 2) (match_dup 6)]
16291                               UNSPEC_FPATAN))
16292               (clobber (match_scratch:XF 8 ""))])
16293    (set (match_operand:DF 0 "register_operand" "")
16294         (float_truncate:DF (match_dup 7)))]
16295   "TARGET_USE_FANCY_MATH_387
16296    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16297    && flag_unsafe_math_optimizations && !optimize_size"
16298 {
16299   int i;
16300
16301   for (i=2; i<8; i++)
16302     operands[i] = gen_reg_rtx (XFmode);
16303
16304   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16305 })
16306
16307 (define_expand "acossf2"
16308   [(set (match_dup 2)
16309         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16310    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16311    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16312    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16313    (parallel [(set (match_dup 7)
16314                    (unspec:XF [(match_dup 2) (match_dup 6)]
16315                               UNSPEC_FPATAN))
16316               (clobber (match_scratch:XF 8 ""))])
16317    (set (match_operand:SF 0 "register_operand" "")
16318         (float_truncate:SF (match_dup 7)))]
16319   "TARGET_USE_FANCY_MATH_387
16320    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16321    && flag_unsafe_math_optimizations && !optimize_size"
16322 {
16323   int i;
16324
16325   for (i=2; i<8; i++)
16326     operands[i] = gen_reg_rtx (XFmode);
16327
16328   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16329 })
16330
16331 (define_expand "acosxf2"
16332   [(set (match_dup 2)
16333         (mult:XF (match_operand:XF 1 "register_operand" "")
16334                  (match_dup 1)))
16335    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16336    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16337    (parallel [(set (match_operand:XF 0 "register_operand" "")
16338                    (unspec:XF [(match_dup 1) (match_dup 5)]
16339                               UNSPEC_FPATAN))
16340               (clobber (match_scratch:XF 6 ""))])]
16341   "TARGET_USE_FANCY_MATH_387
16342    && flag_unsafe_math_optimizations && !optimize_size"
16343 {
16344   int i;
16345
16346   for (i=2; i<6; i++)
16347     operands[i] = gen_reg_rtx (XFmode);
16348
16349   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16350 })
16351
16352 (define_insn "fyl2x_xf3"
16353   [(set (match_operand:XF 0 "register_operand" "=f")
16354         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16355                     (match_operand:XF 1 "register_operand" "u")]
16356                    UNSPEC_FYL2X))
16357    (clobber (match_scratch:XF 3 "=1"))]
16358   "TARGET_USE_FANCY_MATH_387
16359    && flag_unsafe_math_optimizations"
16360   "fyl2x"
16361   [(set_attr "type" "fpspc")
16362    (set_attr "mode" "XF")])
16363
16364 (define_expand "logsf2"
16365   [(set (match_dup 2)
16366         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16367    (parallel [(set (match_dup 4)
16368                    (unspec:XF [(match_dup 2)
16369                                (match_dup 3)] UNSPEC_FYL2X))
16370               (clobber (match_scratch:XF 5 ""))])
16371    (set (match_operand:SF 0 "register_operand" "")
16372         (float_truncate:SF (match_dup 4)))]
16373   "TARGET_USE_FANCY_MATH_387
16374    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16375    && flag_unsafe_math_optimizations"
16376 {
16377   rtx temp;
16378
16379   operands[2] = gen_reg_rtx (XFmode);
16380   operands[3] = gen_reg_rtx (XFmode);
16381   operands[4] = gen_reg_rtx (XFmode);
16382
16383   temp = standard_80387_constant_rtx (4); /* fldln2 */
16384   emit_move_insn (operands[3], temp);
16385 })
16386
16387 (define_expand "logdf2"
16388   [(set (match_dup 2)
16389         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16390    (parallel [(set (match_dup 4)
16391                    (unspec:XF [(match_dup 2)
16392                                (match_dup 3)] UNSPEC_FYL2X))
16393               (clobber (match_scratch:XF 5 ""))])
16394    (set (match_operand:DF 0 "register_operand" "")
16395         (float_truncate:DF (match_dup 4)))]
16396   "TARGET_USE_FANCY_MATH_387
16397    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16398    && flag_unsafe_math_optimizations"
16399 {
16400   rtx temp;
16401
16402   operands[2] = gen_reg_rtx (XFmode);
16403   operands[3] = gen_reg_rtx (XFmode);
16404   operands[4] = gen_reg_rtx (XFmode);
16405
16406   temp = standard_80387_constant_rtx (4); /* fldln2 */
16407   emit_move_insn (operands[3], temp);
16408 })
16409
16410 (define_expand "logxf2"
16411   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16412                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16413                                (match_dup 2)] UNSPEC_FYL2X))
16414               (clobber (match_scratch:XF 3 ""))])]
16415   "TARGET_USE_FANCY_MATH_387
16416    && flag_unsafe_math_optimizations"
16417 {
16418   rtx temp;
16419
16420   operands[2] = gen_reg_rtx (XFmode);
16421   temp = standard_80387_constant_rtx (4); /* fldln2 */
16422   emit_move_insn (operands[2], temp);
16423 })
16424
16425 (define_expand "log10sf2"
16426   [(set (match_dup 2)
16427         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16428    (parallel [(set (match_dup 4)
16429                    (unspec:XF [(match_dup 2)
16430                                (match_dup 3)] UNSPEC_FYL2X))
16431               (clobber (match_scratch:XF 5 ""))])
16432    (set (match_operand:SF 0 "register_operand" "")
16433         (float_truncate:SF (match_dup 4)))]
16434   "TARGET_USE_FANCY_MATH_387
16435    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16436    && flag_unsafe_math_optimizations"
16437 {
16438   rtx temp;
16439
16440   operands[2] = gen_reg_rtx (XFmode);
16441   operands[3] = gen_reg_rtx (XFmode);
16442   operands[4] = gen_reg_rtx (XFmode);
16443
16444   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16445   emit_move_insn (operands[3], temp);
16446 })
16447
16448 (define_expand "log10df2"
16449   [(set (match_dup 2)
16450         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16451    (parallel [(set (match_dup 4)
16452                    (unspec:XF [(match_dup 2)
16453                                (match_dup 3)] UNSPEC_FYL2X))
16454               (clobber (match_scratch:XF 5 ""))])
16455    (set (match_operand:DF 0 "register_operand" "")
16456         (float_truncate:DF (match_dup 4)))]
16457   "TARGET_USE_FANCY_MATH_387
16458    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16459    && flag_unsafe_math_optimizations"
16460 {
16461   rtx temp;
16462
16463   operands[2] = gen_reg_rtx (XFmode);
16464   operands[3] = gen_reg_rtx (XFmode);
16465   operands[4] = gen_reg_rtx (XFmode);
16466
16467   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16468   emit_move_insn (operands[3], temp);
16469 })
16470
16471 (define_expand "log10xf2"
16472   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16473                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16474                                (match_dup 2)] UNSPEC_FYL2X))
16475               (clobber (match_scratch:XF 3 ""))])]
16476   "TARGET_USE_FANCY_MATH_387
16477    && flag_unsafe_math_optimizations"
16478 {
16479   rtx temp;
16480
16481   operands[2] = gen_reg_rtx (XFmode);
16482   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16483   emit_move_insn (operands[2], temp);
16484 })
16485
16486 (define_expand "log2sf2"
16487   [(set (match_dup 2)
16488         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16489    (parallel [(set (match_dup 4)
16490                    (unspec:XF [(match_dup 2)
16491                                (match_dup 3)] UNSPEC_FYL2X))
16492               (clobber (match_scratch:XF 5 ""))])
16493    (set (match_operand:SF 0 "register_operand" "")
16494         (float_truncate:SF (match_dup 4)))]
16495   "TARGET_USE_FANCY_MATH_387
16496    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16497    && flag_unsafe_math_optimizations"
16498 {
16499   operands[2] = gen_reg_rtx (XFmode);
16500   operands[3] = gen_reg_rtx (XFmode);
16501   operands[4] = gen_reg_rtx (XFmode);
16502
16503   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16504 })
16505
16506 (define_expand "log2df2"
16507   [(set (match_dup 2)
16508         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16509    (parallel [(set (match_dup 4)
16510                    (unspec:XF [(match_dup 2)
16511                                (match_dup 3)] UNSPEC_FYL2X))
16512               (clobber (match_scratch:XF 5 ""))])
16513    (set (match_operand:DF 0 "register_operand" "")
16514         (float_truncate:DF (match_dup 4)))]
16515   "TARGET_USE_FANCY_MATH_387
16516    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16517    && flag_unsafe_math_optimizations"
16518 {
16519   operands[2] = gen_reg_rtx (XFmode);
16520   operands[3] = gen_reg_rtx (XFmode);
16521   operands[4] = gen_reg_rtx (XFmode);
16522
16523   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16524 })
16525
16526 (define_expand "log2xf2"
16527   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16528                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16529                                (match_dup 2)] UNSPEC_FYL2X))
16530               (clobber (match_scratch:XF 3 ""))])]
16531   "TARGET_USE_FANCY_MATH_387
16532    && flag_unsafe_math_optimizations"
16533 {
16534   operands[2] = gen_reg_rtx (XFmode);
16535   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16536 })
16537
16538 (define_insn "fyl2xp1_xf3"
16539   [(set (match_operand:XF 0 "register_operand" "=f")
16540         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16541                     (match_operand:XF 1 "register_operand" "u")]
16542                    UNSPEC_FYL2XP1))
16543    (clobber (match_scratch:XF 3 "=1"))]
16544   "TARGET_USE_FANCY_MATH_387
16545    && flag_unsafe_math_optimizations"
16546   "fyl2xp1"
16547   [(set_attr "type" "fpspc")
16548    (set_attr "mode" "XF")])
16549
16550 (define_expand "log1psf2"
16551   [(use (match_operand:SF 0 "register_operand" ""))
16552    (use (match_operand:SF 1 "register_operand" ""))]
16553   "TARGET_USE_FANCY_MATH_387
16554    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16555    && flag_unsafe_math_optimizations && !optimize_size"
16556 {
16557   rtx op0 = gen_reg_rtx (XFmode);
16558   rtx op1 = gen_reg_rtx (XFmode);
16559
16560   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16561   ix86_emit_i387_log1p (op0, op1);
16562   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16563   DONE;
16564 })
16565
16566 (define_expand "log1pdf2"
16567   [(use (match_operand:DF 0 "register_operand" ""))
16568    (use (match_operand:DF 1 "register_operand" ""))]
16569   "TARGET_USE_FANCY_MATH_387
16570    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16571    && flag_unsafe_math_optimizations && !optimize_size"
16572 {
16573   rtx op0 = gen_reg_rtx (XFmode);
16574   rtx op1 = gen_reg_rtx (XFmode);
16575
16576   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16577   ix86_emit_i387_log1p (op0, op1);
16578   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16579   DONE;
16580 })
16581
16582 (define_expand "log1pxf2"
16583   [(use (match_operand:XF 0 "register_operand" ""))
16584    (use (match_operand:XF 1 "register_operand" ""))]
16585   "TARGET_USE_FANCY_MATH_387
16586    && flag_unsafe_math_optimizations && !optimize_size"
16587 {
16588   ix86_emit_i387_log1p (operands[0], operands[1]);
16589   DONE;
16590 })
16591
16592 (define_insn "*fxtractxf3"
16593   [(set (match_operand:XF 0 "register_operand" "=f")
16594         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16595                    UNSPEC_XTRACT_FRACT))
16596    (set (match_operand:XF 1 "register_operand" "=u")
16597         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16598   "TARGET_USE_FANCY_MATH_387
16599    && flag_unsafe_math_optimizations"
16600   "fxtract"
16601   [(set_attr "type" "fpspc")
16602    (set_attr "mode" "XF")])
16603
16604 (define_expand "logbsf2"
16605   [(set (match_dup 2)
16606         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16607    (parallel [(set (match_dup 3)
16608                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16609               (set (match_dup 4)
16610                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16611    (set (match_operand:SF 0 "register_operand" "")
16612         (float_truncate:SF (match_dup 4)))]
16613   "TARGET_USE_FANCY_MATH_387
16614    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16615    && flag_unsafe_math_optimizations"
16616 {
16617   operands[2] = gen_reg_rtx (XFmode);
16618   operands[3] = gen_reg_rtx (XFmode);
16619   operands[4] = gen_reg_rtx (XFmode);
16620 })
16621
16622 (define_expand "logbdf2"
16623   [(set (match_dup 2)
16624         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16625    (parallel [(set (match_dup 3)
16626                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16627               (set (match_dup 4)
16628                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16629    (set (match_operand:DF 0 "register_operand" "")
16630         (float_truncate:DF (match_dup 4)))]
16631   "TARGET_USE_FANCY_MATH_387
16632    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16633    && flag_unsafe_math_optimizations"
16634 {
16635   operands[2] = gen_reg_rtx (XFmode);
16636   operands[3] = gen_reg_rtx (XFmode);
16637   operands[4] = gen_reg_rtx (XFmode);
16638 })
16639
16640 (define_expand "logbxf2"
16641   [(parallel [(set (match_dup 2)
16642                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16643                               UNSPEC_XTRACT_FRACT))
16644               (set (match_operand:XF 0 "register_operand" "")
16645                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16646   "TARGET_USE_FANCY_MATH_387
16647    && flag_unsafe_math_optimizations"
16648 {
16649   operands[2] = gen_reg_rtx (XFmode);
16650 })
16651
16652 (define_expand "ilogbsi2"
16653   [(parallel [(set (match_dup 2)
16654                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16655                               UNSPEC_XTRACT_FRACT))
16656               (set (match_operand:XF 3 "register_operand" "")
16657                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16658    (parallel [(set (match_operand:SI 0 "register_operand" "")
16659                    (fix:SI (match_dup 3)))
16660               (clobber (reg:CC FLAGS_REG))])]
16661   "TARGET_USE_FANCY_MATH_387
16662    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16663    && flag_unsafe_math_optimizations && !optimize_size"
16664 {
16665   operands[2] = gen_reg_rtx (XFmode);
16666   operands[3] = gen_reg_rtx (XFmode);
16667 })
16668
16669 (define_insn "*f2xm1xf2"
16670   [(set (match_operand:XF 0 "register_operand" "=f")
16671         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16672          UNSPEC_F2XM1))]
16673   "TARGET_USE_FANCY_MATH_387
16674    && flag_unsafe_math_optimizations"
16675   "f2xm1"
16676   [(set_attr "type" "fpspc")
16677    (set_attr "mode" "XF")])
16678
16679 (define_insn "*fscalexf4"
16680   [(set (match_operand:XF 0 "register_operand" "=f")
16681         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16682                     (match_operand:XF 3 "register_operand" "1")]
16683                    UNSPEC_FSCALE_FRACT))
16684    (set (match_operand:XF 1 "register_operand" "=u")
16685         (unspec:XF [(match_dup 2) (match_dup 3)]
16686                    UNSPEC_FSCALE_EXP))]
16687   "TARGET_USE_FANCY_MATH_387
16688    && flag_unsafe_math_optimizations"
16689   "fscale"
16690   [(set_attr "type" "fpspc")
16691    (set_attr "mode" "XF")])
16692
16693 (define_expand "expsf2"
16694   [(set (match_dup 2)
16695         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16696    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16697    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16698    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16699    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16700    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16701    (parallel [(set (match_dup 10)
16702                    (unspec:XF [(match_dup 9) (match_dup 5)]
16703                               UNSPEC_FSCALE_FRACT))
16704               (set (match_dup 11)
16705                    (unspec:XF [(match_dup 9) (match_dup 5)]
16706                               UNSPEC_FSCALE_EXP))])
16707    (set (match_operand:SF 0 "register_operand" "")
16708         (float_truncate:SF (match_dup 10)))]
16709   "TARGET_USE_FANCY_MATH_387
16710    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16711    && flag_unsafe_math_optimizations && !optimize_size"
16712 {
16713   rtx temp;
16714   int i;
16715
16716   for (i=2; i<12; i++)
16717     operands[i] = gen_reg_rtx (XFmode);
16718   temp = standard_80387_constant_rtx (5); /* fldl2e */
16719   emit_move_insn (operands[3], temp);
16720   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16721 })
16722
16723 (define_expand "expdf2"
16724   [(set (match_dup 2)
16725         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16726    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16727    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16728    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16729    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16730    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16731    (parallel [(set (match_dup 10)
16732                    (unspec:XF [(match_dup 9) (match_dup 5)]
16733                               UNSPEC_FSCALE_FRACT))
16734               (set (match_dup 11)
16735                    (unspec:XF [(match_dup 9) (match_dup 5)]
16736                               UNSPEC_FSCALE_EXP))])
16737    (set (match_operand:DF 0 "register_operand" "")
16738         (float_truncate:DF (match_dup 10)))]
16739   "TARGET_USE_FANCY_MATH_387
16740    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16741    && flag_unsafe_math_optimizations && !optimize_size"
16742 {
16743   rtx temp;
16744   int i;
16745
16746   for (i=2; i<12; i++)
16747     operands[i] = gen_reg_rtx (XFmode);
16748   temp = standard_80387_constant_rtx (5); /* fldl2e */
16749   emit_move_insn (operands[3], temp);
16750   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16751 })
16752
16753 (define_expand "expxf2"
16754   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16755                                (match_dup 2)))
16756    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16757    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16758    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16759    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16760    (parallel [(set (match_operand:XF 0 "register_operand" "")
16761                    (unspec:XF [(match_dup 8) (match_dup 4)]
16762                               UNSPEC_FSCALE_FRACT))
16763               (set (match_dup 9)
16764                    (unspec:XF [(match_dup 8) (match_dup 4)]
16765                               UNSPEC_FSCALE_EXP))])]
16766   "TARGET_USE_FANCY_MATH_387
16767    && flag_unsafe_math_optimizations && !optimize_size"
16768 {
16769   rtx temp;
16770   int i;
16771
16772   for (i=2; i<10; i++)
16773     operands[i] = gen_reg_rtx (XFmode);
16774   temp = standard_80387_constant_rtx (5); /* fldl2e */
16775   emit_move_insn (operands[2], temp);
16776   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16777 })
16778
16779 (define_expand "exp10sf2"
16780   [(set (match_dup 2)
16781         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16782    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16783    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16784    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16785    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16786    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16787    (parallel [(set (match_dup 10)
16788                    (unspec:XF [(match_dup 9) (match_dup 5)]
16789                               UNSPEC_FSCALE_FRACT))
16790               (set (match_dup 11)
16791                    (unspec:XF [(match_dup 9) (match_dup 5)]
16792                               UNSPEC_FSCALE_EXP))])
16793    (set (match_operand:SF 0 "register_operand" "")
16794         (float_truncate:SF (match_dup 10)))]
16795   "TARGET_USE_FANCY_MATH_387
16796    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16797    && flag_unsafe_math_optimizations && !optimize_size"
16798 {
16799   rtx temp;
16800   int i;
16801
16802   for (i=2; i<12; i++)
16803     operands[i] = gen_reg_rtx (XFmode);
16804   temp = standard_80387_constant_rtx (6); /* fldl2t */
16805   emit_move_insn (operands[3], temp);
16806   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16807 })
16808
16809 (define_expand "exp10df2"
16810   [(set (match_dup 2)
16811         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16812    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16813    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16814    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16815    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16816    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16817    (parallel [(set (match_dup 10)
16818                    (unspec:XF [(match_dup 9) (match_dup 5)]
16819                               UNSPEC_FSCALE_FRACT))
16820               (set (match_dup 11)
16821                    (unspec:XF [(match_dup 9) (match_dup 5)]
16822                               UNSPEC_FSCALE_EXP))])
16823    (set (match_operand:DF 0 "register_operand" "")
16824         (float_truncate:DF (match_dup 10)))]
16825   "TARGET_USE_FANCY_MATH_387
16826    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16827    && flag_unsafe_math_optimizations && !optimize_size"
16828 {
16829   rtx temp;
16830   int i;
16831
16832   for (i=2; i<12; i++)
16833     operands[i] = gen_reg_rtx (XFmode);
16834   temp = standard_80387_constant_rtx (6); /* fldl2t */
16835   emit_move_insn (operands[3], temp);
16836   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16837 })
16838
16839 (define_expand "exp10xf2"
16840   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16841                                (match_dup 2)))
16842    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16843    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16844    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16845    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16846    (parallel [(set (match_operand:XF 0 "register_operand" "")
16847                    (unspec:XF [(match_dup 8) (match_dup 4)]
16848                               UNSPEC_FSCALE_FRACT))
16849               (set (match_dup 9)
16850                    (unspec:XF [(match_dup 8) (match_dup 4)]
16851                               UNSPEC_FSCALE_EXP))])]
16852   "TARGET_USE_FANCY_MATH_387
16853    && flag_unsafe_math_optimizations && !optimize_size"
16854 {
16855   rtx temp;
16856   int i;
16857
16858   for (i=2; i<10; i++)
16859     operands[i] = gen_reg_rtx (XFmode);
16860   temp = standard_80387_constant_rtx (6); /* fldl2t */
16861   emit_move_insn (operands[2], temp);
16862   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16863 })
16864
16865 (define_expand "exp2sf2"
16866   [(set (match_dup 2)
16867         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16868    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16869    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16870    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16871    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16872    (parallel [(set (match_dup 8)
16873                    (unspec:XF [(match_dup 7) (match_dup 3)]
16874                               UNSPEC_FSCALE_FRACT))
16875               (set (match_dup 9)
16876                    (unspec:XF [(match_dup 7) (match_dup 3)]
16877                               UNSPEC_FSCALE_EXP))])
16878    (set (match_operand:SF 0 "register_operand" "")
16879         (float_truncate:SF (match_dup 8)))]
16880   "TARGET_USE_FANCY_MATH_387
16881    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16882    && flag_unsafe_math_optimizations && !optimize_size"
16883 {
16884   int i;
16885
16886   for (i=2; i<10; i++)
16887     operands[i] = gen_reg_rtx (XFmode);
16888   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16889 })
16890
16891 (define_expand "exp2df2"
16892   [(set (match_dup 2)
16893         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16894    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16895    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16896    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16897    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16898    (parallel [(set (match_dup 8)
16899                    (unspec:XF [(match_dup 7) (match_dup 3)]
16900                               UNSPEC_FSCALE_FRACT))
16901               (set (match_dup 9)
16902                    (unspec:XF [(match_dup 7) (match_dup 3)]
16903                               UNSPEC_FSCALE_EXP))])
16904    (set (match_operand:DF 0 "register_operand" "")
16905         (float_truncate:DF (match_dup 8)))]
16906   "TARGET_USE_FANCY_MATH_387
16907    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16908    && flag_unsafe_math_optimizations && !optimize_size"
16909 {
16910   int i;
16911
16912   for (i=2; i<10; i++)
16913     operands[i] = gen_reg_rtx (XFmode);
16914   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16915 })
16916
16917 (define_expand "exp2xf2"
16918   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16919    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16920    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16921    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16922    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16923    (parallel [(set (match_operand:XF 0 "register_operand" "")
16924                    (unspec:XF [(match_dup 7) (match_dup 3)]
16925                               UNSPEC_FSCALE_FRACT))
16926               (set (match_dup 8)
16927                    (unspec:XF [(match_dup 7) (match_dup 3)]
16928                               UNSPEC_FSCALE_EXP))])]
16929   "TARGET_USE_FANCY_MATH_387
16930    && flag_unsafe_math_optimizations && !optimize_size"
16931 {
16932   int i;
16933
16934   for (i=2; i<9; i++)
16935     operands[i] = gen_reg_rtx (XFmode);
16936   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16937 })
16938
16939 (define_expand "expm1df2"
16940   [(set (match_dup 2)
16941         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16942    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16943    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16944    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16945    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16946    (parallel [(set (match_dup 8)
16947                    (unspec:XF [(match_dup 7) (match_dup 5)]
16948                               UNSPEC_FSCALE_FRACT))
16949                    (set (match_dup 9)
16950                    (unspec:XF [(match_dup 7) (match_dup 5)]
16951                               UNSPEC_FSCALE_EXP))])
16952    (parallel [(set (match_dup 11)
16953                    (unspec:XF [(match_dup 10) (match_dup 9)]
16954                               UNSPEC_FSCALE_FRACT))
16955               (set (match_dup 12)
16956                    (unspec:XF [(match_dup 10) (match_dup 9)]
16957                               UNSPEC_FSCALE_EXP))])
16958    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16959    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16960    (set (match_operand:DF 0 "register_operand" "")
16961         (float_truncate:DF (match_dup 14)))]
16962   "TARGET_USE_FANCY_MATH_387
16963    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16964    && flag_unsafe_math_optimizations && !optimize_size"
16965 {
16966   rtx temp;
16967   int i;
16968
16969   for (i=2; i<15; i++)
16970     operands[i] = gen_reg_rtx (XFmode);
16971   temp = standard_80387_constant_rtx (5); /* fldl2e */
16972   emit_move_insn (operands[3], temp);
16973   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16974 })
16975
16976 (define_expand "expm1sf2"
16977   [(set (match_dup 2)
16978         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16979    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16980    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16981    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16982    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16983    (parallel [(set (match_dup 8)
16984                    (unspec:XF [(match_dup 7) (match_dup 5)]
16985                               UNSPEC_FSCALE_FRACT))
16986                    (set (match_dup 9)
16987                    (unspec:XF [(match_dup 7) (match_dup 5)]
16988                               UNSPEC_FSCALE_EXP))])
16989    (parallel [(set (match_dup 11)
16990                    (unspec:XF [(match_dup 10) (match_dup 9)]
16991                               UNSPEC_FSCALE_FRACT))
16992               (set (match_dup 12)
16993                    (unspec:XF [(match_dup 10) (match_dup 9)]
16994                               UNSPEC_FSCALE_EXP))])
16995    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16996    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16997    (set (match_operand:SF 0 "register_operand" "")
16998         (float_truncate:SF (match_dup 14)))]
16999   "TARGET_USE_FANCY_MATH_387
17000    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17001    && flag_unsafe_math_optimizations && !optimize_size"
17002 {
17003   rtx temp;
17004   int i;
17005
17006   for (i=2; i<15; i++)
17007     operands[i] = gen_reg_rtx (XFmode);
17008   temp = standard_80387_constant_rtx (5); /* fldl2e */
17009   emit_move_insn (operands[3], temp);
17010   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17011 })
17012
17013 (define_expand "expm1xf2"
17014   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17015                                (match_dup 2)))
17016    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17017    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17018    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17019    (parallel [(set (match_dup 7)
17020                    (unspec:XF [(match_dup 6) (match_dup 4)]
17021                               UNSPEC_FSCALE_FRACT))
17022                    (set (match_dup 8)
17023                    (unspec:XF [(match_dup 6) (match_dup 4)]
17024                               UNSPEC_FSCALE_EXP))])
17025    (parallel [(set (match_dup 10)
17026                    (unspec:XF [(match_dup 9) (match_dup 8)]
17027                               UNSPEC_FSCALE_FRACT))
17028               (set (match_dup 11)
17029                    (unspec:XF [(match_dup 9) (match_dup 8)]
17030                               UNSPEC_FSCALE_EXP))])
17031    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17032    (set (match_operand:XF 0 "register_operand" "")
17033         (plus:XF (match_dup 12) (match_dup 7)))]
17034   "TARGET_USE_FANCY_MATH_387
17035    && flag_unsafe_math_optimizations && !optimize_size"
17036 {
17037   rtx temp;
17038   int i;
17039
17040   for (i=2; i<13; i++)
17041     operands[i] = gen_reg_rtx (XFmode);
17042   temp = standard_80387_constant_rtx (5); /* fldl2e */
17043   emit_move_insn (operands[2], temp);
17044   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17045 })
17046
17047 (define_expand "ldexpdf3"
17048   [(set (match_dup 3)
17049         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17050    (set (match_dup 4)
17051         (float:XF (match_operand:SI 2 "register_operand" "")))
17052    (parallel [(set (match_dup 5)
17053                    (unspec:XF [(match_dup 3) (match_dup 4)]
17054                               UNSPEC_FSCALE_FRACT))
17055               (set (match_dup 6)
17056                    (unspec:XF [(match_dup 3) (match_dup 4)]
17057                               UNSPEC_FSCALE_EXP))])
17058    (set (match_operand:DF 0 "register_operand" "")
17059         (float_truncate:DF (match_dup 5)))]
17060   "TARGET_USE_FANCY_MATH_387
17061    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17062    && flag_unsafe_math_optimizations && !optimize_size"
17063 {
17064   int i;
17065
17066   for (i=3; i<7; i++)
17067     operands[i] = gen_reg_rtx (XFmode);
17068 })
17069
17070 (define_expand "ldexpsf3"
17071   [(set (match_dup 3)
17072         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17073    (set (match_dup 4)
17074         (float:XF (match_operand:SI 2 "register_operand" "")))
17075    (parallel [(set (match_dup 5)
17076                    (unspec:XF [(match_dup 3) (match_dup 4)]
17077                               UNSPEC_FSCALE_FRACT))
17078               (set (match_dup 6)
17079                    (unspec:XF [(match_dup 3) (match_dup 4)]
17080                               UNSPEC_FSCALE_EXP))])
17081    (set (match_operand:SF 0 "register_operand" "")
17082         (float_truncate:SF (match_dup 5)))]
17083   "TARGET_USE_FANCY_MATH_387
17084    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17085    && flag_unsafe_math_optimizations && !optimize_size"
17086 {
17087   int i;
17088
17089   for (i=3; i<7; i++)
17090     operands[i] = gen_reg_rtx (XFmode);
17091 })
17092
17093 (define_expand "ldexpxf3"
17094   [(set (match_dup 3)
17095         (float:XF (match_operand:SI 2 "register_operand" "")))
17096    (parallel [(set (match_operand:XF 0 " register_operand" "")
17097                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17098                                (match_dup 3)]
17099                               UNSPEC_FSCALE_FRACT))
17100               (set (match_dup 4)
17101                    (unspec:XF [(match_dup 1) (match_dup 3)]
17102                               UNSPEC_FSCALE_EXP))])]
17103   "TARGET_USE_FANCY_MATH_387
17104    && flag_unsafe_math_optimizations && !optimize_size"
17105 {
17106   int i;
17107
17108   for (i=3; i<5; i++)
17109     operands[i] = gen_reg_rtx (XFmode);
17110 })
17111 \f
17112
17113 (define_insn "frndintxf2"
17114   [(set (match_operand:XF 0 "register_operand" "=f")
17115         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17116          UNSPEC_FRNDINT))]
17117   "TARGET_USE_FANCY_MATH_387
17118    && flag_unsafe_math_optimizations"
17119   "frndint"
17120   [(set_attr "type" "fpspc")
17121    (set_attr "mode" "XF")])
17122
17123 (define_expand "rintdf2"
17124   [(use (match_operand:DF 0 "register_operand" ""))
17125    (use (match_operand:DF 1 "register_operand" ""))]
17126   "(TARGET_USE_FANCY_MATH_387
17127     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17128     && flag_unsafe_math_optimizations)
17129    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17130        && !flag_trapping_math
17131        && !optimize_size)"
17132 {
17133   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17134       && !flag_trapping_math
17135       && !optimize_size)
17136     ix86_expand_rint (operand0, operand1);
17137   else
17138     {
17139       rtx op0 = gen_reg_rtx (XFmode);
17140       rtx op1 = gen_reg_rtx (XFmode);
17141
17142       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17143       emit_insn (gen_frndintxf2 (op0, op1));
17144
17145       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17146     }
17147   DONE;
17148 })
17149
17150 (define_expand "rintsf2"
17151   [(use (match_operand:SF 0 "register_operand" ""))
17152    (use (match_operand:SF 1 "register_operand" ""))]
17153   "(TARGET_USE_FANCY_MATH_387
17154     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17155     && flag_unsafe_math_optimizations)
17156    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17157        && !flag_trapping_math
17158        && !optimize_size)"
17159 {
17160   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17161       && !flag_trapping_math
17162       && !optimize_size)
17163     ix86_expand_rint (operand0, operand1);
17164   else
17165     {
17166       rtx op0 = gen_reg_rtx (XFmode);
17167       rtx op1 = gen_reg_rtx (XFmode);
17168
17169       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17170       emit_insn (gen_frndintxf2 (op0, op1));
17171
17172       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17173     }
17174   DONE;
17175 })
17176
17177 (define_expand "rintxf2"
17178   [(use (match_operand:XF 0 "register_operand" ""))
17179    (use (match_operand:XF 1 "register_operand" ""))]
17180   "TARGET_USE_FANCY_MATH_387
17181    && flag_unsafe_math_optimizations && !optimize_size"
17182 {
17183   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17184   DONE;
17185 })
17186
17187 (define_expand "roundsf2"
17188   [(match_operand:SF 0 "register_operand" "")
17189    (match_operand:SF 1 "nonimmediate_operand" "")]
17190   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17191    && !flag_trapping_math && !flag_rounding_math
17192    && !optimize_size"
17193 {
17194   ix86_expand_round (operand0, operand1);
17195   DONE;
17196 })
17197
17198 (define_expand "rounddf2"
17199   [(match_operand:DF 0 "register_operand" "")
17200    (match_operand:DF 1 "nonimmediate_operand" "")]
17201   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17202    && !flag_trapping_math && !flag_rounding_math
17203    && !optimize_size"
17204 {
17205   if (TARGET_64BIT)
17206     ix86_expand_round (operand0, operand1);
17207   else
17208     ix86_expand_rounddf_32 (operand0, operand1);
17209   DONE;
17210 })
17211
17212 (define_insn_and_split "*fistdi2_1"
17213   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17214         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17215          UNSPEC_FIST))]
17216   "TARGET_USE_FANCY_MATH_387
17217    && !(reload_completed || reload_in_progress)"
17218   "#"
17219   "&& 1"
17220   [(const_int 0)]
17221 {
17222   if (memory_operand (operands[0], VOIDmode))
17223     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17224   else
17225     {
17226       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17227       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17228                                          operands[2]));
17229     }
17230   DONE;
17231 }
17232   [(set_attr "type" "fpspc")
17233    (set_attr "mode" "DI")])
17234
17235 (define_insn "fistdi2"
17236   [(set (match_operand:DI 0 "memory_operand" "=m")
17237         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17238          UNSPEC_FIST))
17239    (clobber (match_scratch:XF 2 "=&1f"))]
17240   "TARGET_USE_FANCY_MATH_387"
17241   "* return output_fix_trunc (insn, operands, 0);"
17242   [(set_attr "type" "fpspc")
17243    (set_attr "mode" "DI")])
17244
17245 (define_insn "fistdi2_with_temp"
17246   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17247         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17248          UNSPEC_FIST))
17249    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17250    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17251   "TARGET_USE_FANCY_MATH_387"
17252   "#"
17253   [(set_attr "type" "fpspc")
17254    (set_attr "mode" "DI")])
17255
17256 (define_split
17257   [(set (match_operand:DI 0 "register_operand" "")
17258         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17259          UNSPEC_FIST))
17260    (clobber (match_operand:DI 2 "memory_operand" ""))
17261    (clobber (match_scratch 3 ""))]
17262   "reload_completed"
17263   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17264               (clobber (match_dup 3))])
17265    (set (match_dup 0) (match_dup 2))]
17266   "")
17267
17268 (define_split
17269   [(set (match_operand:DI 0 "memory_operand" "")
17270         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17271          UNSPEC_FIST))
17272    (clobber (match_operand:DI 2 "memory_operand" ""))
17273    (clobber (match_scratch 3 ""))]
17274   "reload_completed"
17275   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17276               (clobber (match_dup 3))])]
17277   "")
17278
17279 (define_insn_and_split "*fist<mode>2_1"
17280   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17281         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17282          UNSPEC_FIST))]
17283   "TARGET_USE_FANCY_MATH_387
17284    && !(reload_completed || reload_in_progress)"
17285   "#"
17286   "&& 1"
17287   [(const_int 0)]
17288 {
17289   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17290   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17291                                         operands[2]));
17292   DONE;
17293 }
17294   [(set_attr "type" "fpspc")
17295    (set_attr "mode" "<MODE>")])
17296
17297 (define_insn "fist<mode>2"
17298   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17299         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17300          UNSPEC_FIST))]
17301   "TARGET_USE_FANCY_MATH_387"
17302   "* return output_fix_trunc (insn, operands, 0);"
17303   [(set_attr "type" "fpspc")
17304    (set_attr "mode" "<MODE>")])
17305
17306 (define_insn "fist<mode>2_with_temp"
17307   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17308         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17309          UNSPEC_FIST))
17310    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17311   "TARGET_USE_FANCY_MATH_387"
17312   "#"
17313   [(set_attr "type" "fpspc")
17314    (set_attr "mode" "<MODE>")])
17315
17316 (define_split
17317   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17318         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17319          UNSPEC_FIST))
17320    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17321   "reload_completed"
17322   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17323                        UNSPEC_FIST))
17324    (set (match_dup 0) (match_dup 2))]
17325   "")
17326
17327 (define_split
17328   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17329         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17330          UNSPEC_FIST))
17331    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17332   "reload_completed"
17333   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17334                        UNSPEC_FIST))]
17335   "")
17336
17337 (define_expand "lrintxf<mode>2"
17338   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17339      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17340       UNSPEC_FIST))]
17341   "TARGET_USE_FANCY_MATH_387"
17342   "")
17343
17344 (define_expand "lrint<mode>di2"
17345   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17346      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17347       UNSPEC_FIX_NOTRUNC))]
17348   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17349   "")
17350
17351 (define_expand "lrint<mode>si2"
17352   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17353      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17354       UNSPEC_FIX_NOTRUNC))]
17355   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17356   "")
17357
17358 (define_expand "lround<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 && !flag_rounding_math
17363    && !optimize_size"
17364 {
17365   ix86_expand_lround (operand0, operand1);
17366   DONE;
17367 })
17368
17369 (define_expand "lround<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 && !flag_rounding_math
17374    && !optimize_size"
17375 {
17376   ix86_expand_lround (operand0, operand1);
17377   DONE;
17378 })
17379
17380 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17381 (define_insn_and_split "frndintxf2_floor"
17382   [(set (match_operand:XF 0 "register_operand" "=f")
17383         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17384          UNSPEC_FRNDINT_FLOOR))
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_FLOOR] = 1;
17394
17395   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17396   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17397
17398   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17399                                         operands[2], operands[3]));
17400   DONE;
17401 }
17402   [(set_attr "type" "frndint")
17403    (set_attr "i387_cw" "floor")
17404    (set_attr "mode" "XF")])
17405
17406 (define_insn "frndintxf2_floor_i387"
17407   [(set (match_operand:XF 0 "register_operand" "=f")
17408         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17409          UNSPEC_FRNDINT_FLOOR))
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" "floor")
17417    (set_attr "mode" "XF")])
17418
17419 (define_expand "floorxf2"
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_floor (operands[0], operands[1]));
17426   DONE;
17427 })
17428
17429 (define_expand "floordf2"
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, true);
17444       else
17445         ix86_expand_floorceildf_32 (operand0, operand1, true);
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_floor (op0, op1));
17454
17455       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17456     }
17457   DONE;
17458 })
17459
17460 (define_expand "floorsf2"
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, true);
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_floor (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_floor_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_FLOOR))
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_FLOOR] = 1;
17499
17500   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17501   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17502   if (memory_operand (operands[0], VOIDmode))
17503     emit_insn (gen_fist<mode>2_floor (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_floor_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" "floor")
17516    (set_attr "mode" "<MODE>")])
17517
17518 (define_insn "fistdi2_floor"
17519   [(set (match_operand:DI 0 "memory_operand" "=m")
17520         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17521          UNSPEC_FIST_FLOOR))
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" "floor")
17530    (set_attr "mode" "DI")])
17531
17532 (define_insn "fistdi2_floor_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_FLOOR))
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" "floor")
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_FLOOR))
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_FLOOR))
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_FLOOR))
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_FLOOR))
17573               (use (match_dup 2))
17574               (use (match_dup 3))
17575               (clobber (match_dup 5))])]
17576   "")
17577
17578 (define_insn "fist<mode>2_floor"
17579   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17580         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17581          UNSPEC_FIST_FLOOR))
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" "floor")
17589    (set_attr "mode" "<MODE>")])
17590
17591 (define_insn "fist<mode>2_floor_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_FLOOR))
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" "floor")
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_FLOOR))
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_FLOOR))
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_FLOOR))
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_FLOOR))
17630               (use (match_dup 2))
17631               (use (match_dup 3))])]
17632   "")
17633
17634 (define_expand "lfloorxf<mode>2"
17635   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17636                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17637                     UNSPEC_FIST_FLOOR))
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 "lfloor<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    && !optimize_size"
17650 {
17651   ix86_expand_lfloorceil (operand0, operand1, true);
17652   DONE;
17653 })
17654
17655 (define_expand "lfloor<mode>si2"
17656   [(match_operand:SI 0 "nonimmediate_operand" "")
17657    (match_operand:SSEMODEF 1 "register_operand" "")]
17658   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17659    && !flag_trapping_math
17660    && (!optimize_size || !TARGET_64BIT)"
17661 {
17662   ix86_expand_lfloorceil (operand0, operand1, true);
17663   DONE;
17664 })
17665
17666 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17667 (define_insn_and_split "frndintxf2_ceil"
17668   [(set (match_operand:XF 0 "register_operand" "=f")
17669         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17670          UNSPEC_FRNDINT_CEIL))
17671    (clobber (reg:CC FLAGS_REG))]
17672   "TARGET_USE_FANCY_MATH_387
17673    && flag_unsafe_math_optimizations
17674    && !(reload_completed || reload_in_progress)"
17675   "#"
17676   "&& 1"
17677   [(const_int 0)]
17678 {
17679   ix86_optimize_mode_switching[I387_CEIL] = 1;
17680
17681   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17682   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17683
17684   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17685                                        operands[2], operands[3]));
17686   DONE;
17687 }
17688   [(set_attr "type" "frndint")
17689    (set_attr "i387_cw" "ceil")
17690    (set_attr "mode" "XF")])
17691
17692 (define_insn "frndintxf2_ceil_i387"
17693   [(set (match_operand:XF 0 "register_operand" "=f")
17694         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17695          UNSPEC_FRNDINT_CEIL))
17696    (use (match_operand:HI 2 "memory_operand" "m"))
17697    (use (match_operand:HI 3 "memory_operand" "m"))]
17698   "TARGET_USE_FANCY_MATH_387
17699    && flag_unsafe_math_optimizations"
17700   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17701   [(set_attr "type" "frndint")
17702    (set_attr "i387_cw" "ceil")
17703    (set_attr "mode" "XF")])
17704
17705 (define_expand "ceilxf2"
17706   [(use (match_operand:XF 0 "register_operand" ""))
17707    (use (match_operand:XF 1 "register_operand" ""))]
17708   "TARGET_USE_FANCY_MATH_387
17709    && flag_unsafe_math_optimizations && !optimize_size"
17710 {
17711   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17712   DONE;
17713 })
17714
17715 (define_expand "ceildf2"
17716   [(use (match_operand:DF 0 "register_operand" ""))
17717    (use (match_operand:DF 1 "register_operand" ""))]
17718   "((TARGET_USE_FANCY_MATH_387
17719      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17720      && flag_unsafe_math_optimizations)
17721     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17722         && !flag_trapping_math))
17723    && !optimize_size"
17724 {
17725   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17726       && !flag_trapping_math)
17727     {
17728       if (TARGET_64BIT)
17729         ix86_expand_floorceil (operand0, operand1, false);
17730       else
17731         ix86_expand_floorceildf_32 (operand0, operand1, false);
17732     }
17733   else
17734     {
17735       rtx op0 = gen_reg_rtx (XFmode);
17736       rtx op1 = gen_reg_rtx (XFmode);
17737
17738       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17739       emit_insn (gen_frndintxf2_ceil (op0, op1));
17740
17741       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17742     }
17743   DONE;
17744 })
17745
17746 (define_expand "ceilsf2"
17747   [(use (match_operand:SF 0 "register_operand" ""))
17748    (use (match_operand:SF 1 "register_operand" ""))]
17749   "((TARGET_USE_FANCY_MATH_387
17750      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17751      && flag_unsafe_math_optimizations)
17752     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17753         && !flag_trapping_math))
17754    && !optimize_size"
17755 {
17756   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17757       && !flag_trapping_math)
17758     ix86_expand_floorceil (operand0, operand1, false);
17759   else
17760     {
17761       rtx op0 = gen_reg_rtx (XFmode);
17762       rtx op1 = gen_reg_rtx (XFmode);
17763
17764       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17765       emit_insn (gen_frndintxf2_ceil (op0, op1));
17766
17767       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17768     }
17769   DONE;
17770 })
17771
17772 (define_insn_and_split "*fist<mode>2_ceil_1"
17773   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17774         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17775          UNSPEC_FIST_CEIL))
17776    (clobber (reg:CC FLAGS_REG))]
17777   "TARGET_USE_FANCY_MATH_387
17778    && flag_unsafe_math_optimizations
17779    && !(reload_completed || reload_in_progress)"
17780   "#"
17781   "&& 1"
17782   [(const_int 0)]
17783 {
17784   ix86_optimize_mode_switching[I387_CEIL] = 1;
17785
17786   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17787   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17788   if (memory_operand (operands[0], VOIDmode))
17789     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17790                                      operands[2], operands[3]));
17791   else
17792     {
17793       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17794       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17795                                                  operands[2], operands[3],
17796                                                  operands[4]));
17797     }
17798   DONE;
17799 }
17800   [(set_attr "type" "fistp")
17801    (set_attr "i387_cw" "ceil")
17802    (set_attr "mode" "<MODE>")])
17803
17804 (define_insn "fistdi2_ceil"
17805   [(set (match_operand:DI 0 "memory_operand" "=m")
17806         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17807          UNSPEC_FIST_CEIL))
17808    (use (match_operand:HI 2 "memory_operand" "m"))
17809    (use (match_operand:HI 3 "memory_operand" "m"))
17810    (clobber (match_scratch:XF 4 "=&1f"))]
17811   "TARGET_USE_FANCY_MATH_387
17812    && flag_unsafe_math_optimizations"
17813   "* return output_fix_trunc (insn, operands, 0);"
17814   [(set_attr "type" "fistp")
17815    (set_attr "i387_cw" "ceil")
17816    (set_attr "mode" "DI")])
17817
17818 (define_insn "fistdi2_ceil_with_temp"
17819   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17820         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17821          UNSPEC_FIST_CEIL))
17822    (use (match_operand:HI 2 "memory_operand" "m,m"))
17823    (use (match_operand:HI 3 "memory_operand" "m,m"))
17824    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17825    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17826   "TARGET_USE_FANCY_MATH_387
17827    && flag_unsafe_math_optimizations"
17828   "#"
17829   [(set_attr "type" "fistp")
17830    (set_attr "i387_cw" "ceil")
17831    (set_attr "mode" "DI")])
17832
17833 (define_split
17834   [(set (match_operand:DI 0 "register_operand" "")
17835         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17836          UNSPEC_FIST_CEIL))
17837    (use (match_operand:HI 2 "memory_operand" ""))
17838    (use (match_operand:HI 3 "memory_operand" ""))
17839    (clobber (match_operand:DI 4 "memory_operand" ""))
17840    (clobber (match_scratch 5 ""))]
17841   "reload_completed"
17842   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17843               (use (match_dup 2))
17844               (use (match_dup 3))
17845               (clobber (match_dup 5))])
17846    (set (match_dup 0) (match_dup 4))]
17847   "")
17848
17849 (define_split
17850   [(set (match_operand:DI 0 "memory_operand" "")
17851         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17852          UNSPEC_FIST_CEIL))
17853    (use (match_operand:HI 2 "memory_operand" ""))
17854    (use (match_operand:HI 3 "memory_operand" ""))
17855    (clobber (match_operand:DI 4 "memory_operand" ""))
17856    (clobber (match_scratch 5 ""))]
17857   "reload_completed"
17858   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17859               (use (match_dup 2))
17860               (use (match_dup 3))
17861               (clobber (match_dup 5))])]
17862   "")
17863
17864 (define_insn "fist<mode>2_ceil"
17865   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17866         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17867          UNSPEC_FIST_CEIL))
17868    (use (match_operand:HI 2 "memory_operand" "m"))
17869    (use (match_operand:HI 3 "memory_operand" "m"))]
17870   "TARGET_USE_FANCY_MATH_387
17871    && flag_unsafe_math_optimizations"
17872   "* return output_fix_trunc (insn, operands, 0);"
17873   [(set_attr "type" "fistp")
17874    (set_attr "i387_cw" "ceil")
17875    (set_attr "mode" "<MODE>")])
17876
17877 (define_insn "fist<mode>2_ceil_with_temp"
17878   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17879         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17880          UNSPEC_FIST_CEIL))
17881    (use (match_operand:HI 2 "memory_operand" "m,m"))
17882    (use (match_operand:HI 3 "memory_operand" "m,m"))
17883    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17884   "TARGET_USE_FANCY_MATH_387
17885    && flag_unsafe_math_optimizations"
17886   "#"
17887   [(set_attr "type" "fistp")
17888    (set_attr "i387_cw" "ceil")
17889    (set_attr "mode" "<MODE>")])
17890
17891 (define_split
17892   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17893         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17894          UNSPEC_FIST_CEIL))
17895    (use (match_operand:HI 2 "memory_operand" ""))
17896    (use (match_operand:HI 3 "memory_operand" ""))
17897    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17898   "reload_completed"
17899   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17900                                   UNSPEC_FIST_CEIL))
17901               (use (match_dup 2))
17902               (use (match_dup 3))])
17903    (set (match_dup 0) (match_dup 4))]
17904   "")
17905
17906 (define_split
17907   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17908         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17909          UNSPEC_FIST_CEIL))
17910    (use (match_operand:HI 2 "memory_operand" ""))
17911    (use (match_operand:HI 3 "memory_operand" ""))
17912    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17913   "reload_completed"
17914   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17915                                   UNSPEC_FIST_CEIL))
17916               (use (match_dup 2))
17917               (use (match_dup 3))])]
17918   "")
17919
17920 (define_expand "lceilxf<mode>2"
17921   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17922                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17923                     UNSPEC_FIST_CEIL))
17924               (clobber (reg:CC FLAGS_REG))])]
17925   "TARGET_USE_FANCY_MATH_387
17926    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17927    && flag_unsafe_math_optimizations"
17928   "")
17929
17930 (define_expand "lceil<mode>di2"
17931   [(match_operand:DI 0 "nonimmediate_operand" "")
17932    (match_operand:SSEMODEF 1 "register_operand" "")]
17933   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17934    && !flag_trapping_math"
17935 {
17936   ix86_expand_lfloorceil (operand0, operand1, false);
17937   DONE;
17938 })
17939
17940 (define_expand "lceil<mode>si2"
17941   [(match_operand:SI 0 "nonimmediate_operand" "")
17942    (match_operand:SSEMODEF 1 "register_operand" "")]
17943   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17944    && !flag_trapping_math"
17945 {
17946   ix86_expand_lfloorceil (operand0, operand1, false);
17947   DONE;
17948 })
17949
17950 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17951 (define_insn_and_split "frndintxf2_trunc"
17952   [(set (match_operand:XF 0 "register_operand" "=f")
17953         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17954          UNSPEC_FRNDINT_TRUNC))
17955    (clobber (reg:CC FLAGS_REG))]
17956   "TARGET_USE_FANCY_MATH_387
17957    && flag_unsafe_math_optimizations
17958    && !(reload_completed || reload_in_progress)"
17959   "#"
17960   "&& 1"
17961   [(const_int 0)]
17962 {
17963   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17964
17965   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17966   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17967
17968   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17969                                         operands[2], operands[3]));
17970   DONE;
17971 }
17972   [(set_attr "type" "frndint")
17973    (set_attr "i387_cw" "trunc")
17974    (set_attr "mode" "XF")])
17975
17976 (define_insn "frndintxf2_trunc_i387"
17977   [(set (match_operand:XF 0 "register_operand" "=f")
17978         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17979          UNSPEC_FRNDINT_TRUNC))
17980    (use (match_operand:HI 2 "memory_operand" "m"))
17981    (use (match_operand:HI 3 "memory_operand" "m"))]
17982   "TARGET_USE_FANCY_MATH_387
17983    && flag_unsafe_math_optimizations"
17984   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17985   [(set_attr "type" "frndint")
17986    (set_attr "i387_cw" "trunc")
17987    (set_attr "mode" "XF")])
17988
17989 (define_expand "btruncxf2"
17990   [(use (match_operand:XF 0 "register_operand" ""))
17991    (use (match_operand:XF 1 "register_operand" ""))]
17992   "TARGET_USE_FANCY_MATH_387
17993    && flag_unsafe_math_optimizations && !optimize_size"
17994 {
17995   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17996   DONE;
17997 })
17998
17999 (define_expand "btruncdf2"
18000   [(use (match_operand:DF 0 "register_operand" ""))
18001    (use (match_operand:DF 1 "register_operand" ""))]
18002   "((TARGET_USE_FANCY_MATH_387
18003      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18004      && flag_unsafe_math_optimizations)
18005     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18006         && !flag_trapping_math))
18007    && !optimize_size"
18008 {
18009   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18010       && !flag_trapping_math)
18011     {
18012       if (TARGET_64BIT)
18013         ix86_expand_trunc (operand0, operand1);
18014       else
18015         ix86_expand_truncdf_32 (operand0, operand1);
18016     }
18017   else
18018     {
18019       rtx op0 = gen_reg_rtx (XFmode);
18020       rtx op1 = gen_reg_rtx (XFmode);
18021
18022       emit_insn (gen_extenddfxf2 (op1, operands[1]));
18023       emit_insn (gen_frndintxf2_trunc (op0, op1));
18024
18025       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18026     }
18027   DONE;
18028 })
18029
18030 (define_expand "btruncsf2"
18031   [(use (match_operand:SF 0 "register_operand" ""))
18032    (use (match_operand:SF 1 "register_operand" ""))]
18033   "((TARGET_USE_FANCY_MATH_387
18034      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18035      && flag_unsafe_math_optimizations)
18036     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18037         && !flag_trapping_math))
18038    && !optimize_size"
18039 {
18040   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18041       && !flag_trapping_math)
18042     ix86_expand_trunc (operand0, operand1);
18043   else
18044     {
18045       rtx op0 = gen_reg_rtx (XFmode);
18046       rtx op1 = gen_reg_rtx (XFmode);
18047
18048       emit_insn (gen_extendsfxf2 (op1, operands[1]));
18049       emit_insn (gen_frndintxf2_trunc (op0, op1));
18050
18051       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18052     }
18053   DONE;
18054 })
18055
18056 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18057 (define_insn_and_split "frndintxf2_mask_pm"
18058   [(set (match_operand:XF 0 "register_operand" "=f")
18059         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18060          UNSPEC_FRNDINT_MASK_PM))
18061    (clobber (reg:CC FLAGS_REG))]
18062   "TARGET_USE_FANCY_MATH_387
18063    && flag_unsafe_math_optimizations
18064    && !(reload_completed || reload_in_progress)"
18065   "#"
18066   "&& 1"
18067   [(const_int 0)]
18068 {
18069   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18070
18071   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18072   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18073
18074   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18075                                           operands[2], operands[3]));
18076   DONE;
18077 }
18078   [(set_attr "type" "frndint")
18079    (set_attr "i387_cw" "mask_pm")
18080    (set_attr "mode" "XF")])
18081
18082 (define_insn "frndintxf2_mask_pm_i387"
18083   [(set (match_operand:XF 0 "register_operand" "=f")
18084         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18085          UNSPEC_FRNDINT_MASK_PM))
18086    (use (match_operand:HI 2 "memory_operand" "m"))
18087    (use (match_operand:HI 3 "memory_operand" "m"))]
18088   "TARGET_USE_FANCY_MATH_387
18089    && flag_unsafe_math_optimizations"
18090   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18091   [(set_attr "type" "frndint")
18092    (set_attr "i387_cw" "mask_pm")
18093    (set_attr "mode" "XF")])
18094
18095 (define_expand "nearbyintxf2"
18096   [(use (match_operand:XF 0 "register_operand" ""))
18097    (use (match_operand:XF 1 "register_operand" ""))]
18098   "TARGET_USE_FANCY_MATH_387
18099    && flag_unsafe_math_optimizations"
18100 {
18101   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18102
18103   DONE;
18104 })
18105
18106 (define_expand "nearbyintdf2"
18107   [(use (match_operand:DF 0 "register_operand" ""))
18108    (use (match_operand:DF 1 "register_operand" ""))]
18109   "TARGET_USE_FANCY_MATH_387
18110    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18111    && flag_unsafe_math_optimizations"
18112 {
18113   rtx op0 = gen_reg_rtx (XFmode);
18114   rtx op1 = gen_reg_rtx (XFmode);
18115
18116   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18117   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18118
18119   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18120   DONE;
18121 })
18122
18123 (define_expand "nearbyintsf2"
18124   [(use (match_operand:SF 0 "register_operand" ""))
18125    (use (match_operand:SF 1 "register_operand" ""))]
18126   "TARGET_USE_FANCY_MATH_387
18127    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18128    && flag_unsafe_math_optimizations"
18129 {
18130   rtx op0 = gen_reg_rtx (XFmode);
18131   rtx op1 = gen_reg_rtx (XFmode);
18132
18133   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18134   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18135
18136   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18137   DONE;
18138 })
18139
18140 \f
18141 ;; Block operation instructions
18142
18143 (define_expand "movmemsi"
18144   [(use (match_operand:BLK 0 "memory_operand" ""))
18145    (use (match_operand:BLK 1 "memory_operand" ""))
18146    (use (match_operand:SI 2 "nonmemory_operand" ""))
18147    (use (match_operand:SI 3 "const_int_operand" ""))]
18148   ""
18149 {
18150  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18151                          operands[3], constm1_rtx))
18152    DONE;
18153  else
18154    FAIL;
18155 })
18156
18157 (define_expand "movmemdi"
18158   [(use (match_operand:BLK 0 "memory_operand" ""))
18159    (use (match_operand:BLK 1 "memory_operand" ""))
18160    (use (match_operand:DI 2 "nonmemory_operand" ""))
18161    (use (match_operand:DI 3 "const_int_operand" ""))]
18162   "TARGET_64BIT"
18163 {
18164  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18165                          operands[3], constm1_rtx))
18166    DONE;
18167  else
18168    FAIL;
18169 })
18170
18171 ;; Most CPUs don't like single string operations
18172 ;; Handle this case here to simplify previous expander.
18173
18174 (define_expand "strmov"
18175   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18176    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18177    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18178               (clobber (reg:CC FLAGS_REG))])
18179    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18180               (clobber (reg:CC FLAGS_REG))])]
18181   ""
18182 {
18183   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18184
18185   /* If .md ever supports :P for Pmode, these can be directly
18186      in the pattern above.  */
18187   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18188   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18189
18190   if (TARGET_SINGLE_STRINGOP || optimize_size)
18191     {
18192       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18193                                       operands[2], operands[3],
18194                                       operands[5], operands[6]));
18195       DONE;
18196     }
18197
18198   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18199 })
18200
18201 (define_expand "strmov_singleop"
18202   [(parallel [(set (match_operand 1 "memory_operand" "")
18203                    (match_operand 3 "memory_operand" ""))
18204               (set (match_operand 0 "register_operand" "")
18205                    (match_operand 4 "" ""))
18206               (set (match_operand 2 "register_operand" "")
18207                    (match_operand 5 "" ""))])]
18208   "TARGET_SINGLE_STRINGOP || optimize_size"
18209   "")
18210
18211 (define_insn "*strmovdi_rex_1"
18212   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18213         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18214    (set (match_operand:DI 0 "register_operand" "=D")
18215         (plus:DI (match_dup 2)
18216                  (const_int 8)))
18217    (set (match_operand:DI 1 "register_operand" "=S")
18218         (plus:DI (match_dup 3)
18219                  (const_int 8)))]
18220   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18221   "movsq"
18222   [(set_attr "type" "str")
18223    (set_attr "mode" "DI")
18224    (set_attr "memory" "both")])
18225
18226 (define_insn "*strmovsi_1"
18227   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18228         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18229    (set (match_operand:SI 0 "register_operand" "=D")
18230         (plus:SI (match_dup 2)
18231                  (const_int 4)))
18232    (set (match_operand:SI 1 "register_operand" "=S")
18233         (plus:SI (match_dup 3)
18234                  (const_int 4)))]
18235   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18236   "{movsl|movsd}"
18237   [(set_attr "type" "str")
18238    (set_attr "mode" "SI")
18239    (set_attr "memory" "both")])
18240
18241 (define_insn "*strmovsi_rex_1"
18242   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18243         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18244    (set (match_operand:DI 0 "register_operand" "=D")
18245         (plus:DI (match_dup 2)
18246                  (const_int 4)))
18247    (set (match_operand:DI 1 "register_operand" "=S")
18248         (plus:DI (match_dup 3)
18249                  (const_int 4)))]
18250   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18251   "{movsl|movsd}"
18252   [(set_attr "type" "str")
18253    (set_attr "mode" "SI")
18254    (set_attr "memory" "both")])
18255
18256 (define_insn "*strmovhi_1"
18257   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18258         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18259    (set (match_operand:SI 0 "register_operand" "=D")
18260         (plus:SI (match_dup 2)
18261                  (const_int 2)))
18262    (set (match_operand:SI 1 "register_operand" "=S")
18263         (plus:SI (match_dup 3)
18264                  (const_int 2)))]
18265   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18266   "movsw"
18267   [(set_attr "type" "str")
18268    (set_attr "memory" "both")
18269    (set_attr "mode" "HI")])
18270
18271 (define_insn "*strmovhi_rex_1"
18272   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18273         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18274    (set (match_operand:DI 0 "register_operand" "=D")
18275         (plus:DI (match_dup 2)
18276                  (const_int 2)))
18277    (set (match_operand:DI 1 "register_operand" "=S")
18278         (plus:DI (match_dup 3)
18279                  (const_int 2)))]
18280   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18281   "movsw"
18282   [(set_attr "type" "str")
18283    (set_attr "memory" "both")
18284    (set_attr "mode" "HI")])
18285
18286 (define_insn "*strmovqi_1"
18287   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18288         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18289    (set (match_operand:SI 0 "register_operand" "=D")
18290         (plus:SI (match_dup 2)
18291                  (const_int 1)))
18292    (set (match_operand:SI 1 "register_operand" "=S")
18293         (plus:SI (match_dup 3)
18294                  (const_int 1)))]
18295   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18296   "movsb"
18297   [(set_attr "type" "str")
18298    (set_attr "memory" "both")
18299    (set_attr "mode" "QI")])
18300
18301 (define_insn "*strmovqi_rex_1"
18302   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18303         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18304    (set (match_operand:DI 0 "register_operand" "=D")
18305         (plus:DI (match_dup 2)
18306                  (const_int 1)))
18307    (set (match_operand:DI 1 "register_operand" "=S")
18308         (plus:DI (match_dup 3)
18309                  (const_int 1)))]
18310   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18311   "movsb"
18312   [(set_attr "type" "str")
18313    (set_attr "memory" "both")
18314    (set_attr "mode" "QI")])
18315
18316 (define_expand "rep_mov"
18317   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18318               (set (match_operand 0 "register_operand" "")
18319                    (match_operand 5 "" ""))
18320               (set (match_operand 2 "register_operand" "")
18321                    (match_operand 6 "" ""))
18322               (set (match_operand 1 "memory_operand" "")
18323                    (match_operand 3 "memory_operand" ""))
18324               (use (match_dup 4))])]
18325   ""
18326   "")
18327
18328 (define_insn "*rep_movdi_rex64"
18329   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18330    (set (match_operand:DI 0 "register_operand" "=D")
18331         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18332                             (const_int 3))
18333                  (match_operand:DI 3 "register_operand" "0")))
18334    (set (match_operand:DI 1 "register_operand" "=S")
18335         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18336                  (match_operand:DI 4 "register_operand" "1")))
18337    (set (mem:BLK (match_dup 3))
18338         (mem:BLK (match_dup 4)))
18339    (use (match_dup 5))]
18340   "TARGET_64BIT"
18341   "{rep\;movsq|rep movsq}"
18342   [(set_attr "type" "str")
18343    (set_attr "prefix_rep" "1")
18344    (set_attr "memory" "both")
18345    (set_attr "mode" "DI")])
18346
18347 (define_insn "*rep_movsi"
18348   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18349    (set (match_operand:SI 0 "register_operand" "=D")
18350         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18351                             (const_int 2))
18352                  (match_operand:SI 3 "register_operand" "0")))
18353    (set (match_operand:SI 1 "register_operand" "=S")
18354         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18355                  (match_operand:SI 4 "register_operand" "1")))
18356    (set (mem:BLK (match_dup 3))
18357         (mem:BLK (match_dup 4)))
18358    (use (match_dup 5))]
18359   "!TARGET_64BIT"
18360   "{rep\;movsl|rep movsd}"
18361   [(set_attr "type" "str")
18362    (set_attr "prefix_rep" "1")
18363    (set_attr "memory" "both")
18364    (set_attr "mode" "SI")])
18365
18366 (define_insn "*rep_movsi_rex64"
18367   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18368    (set (match_operand:DI 0 "register_operand" "=D")
18369         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18370                             (const_int 2))
18371                  (match_operand:DI 3 "register_operand" "0")))
18372    (set (match_operand:DI 1 "register_operand" "=S")
18373         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18374                  (match_operand:DI 4 "register_operand" "1")))
18375    (set (mem:BLK (match_dup 3))
18376         (mem:BLK (match_dup 4)))
18377    (use (match_dup 5))]
18378   "TARGET_64BIT"
18379   "{rep\;movsl|rep movsd}"
18380   [(set_attr "type" "str")
18381    (set_attr "prefix_rep" "1")
18382    (set_attr "memory" "both")
18383    (set_attr "mode" "SI")])
18384
18385 (define_insn "*rep_movqi"
18386   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18387    (set (match_operand:SI 0 "register_operand" "=D")
18388         (plus:SI (match_operand:SI 3 "register_operand" "0")
18389                  (match_operand:SI 5 "register_operand" "2")))
18390    (set (match_operand:SI 1 "register_operand" "=S")
18391         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18392    (set (mem:BLK (match_dup 3))
18393         (mem:BLK (match_dup 4)))
18394    (use (match_dup 5))]
18395   "!TARGET_64BIT"
18396   "{rep\;movsb|rep movsb}"
18397   [(set_attr "type" "str")
18398    (set_attr "prefix_rep" "1")
18399    (set_attr "memory" "both")
18400    (set_attr "mode" "SI")])
18401
18402 (define_insn "*rep_movqi_rex64"
18403   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18404    (set (match_operand:DI 0 "register_operand" "=D")
18405         (plus:DI (match_operand:DI 3 "register_operand" "0")
18406                  (match_operand:DI 5 "register_operand" "2")))
18407    (set (match_operand:DI 1 "register_operand" "=S")
18408         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18409    (set (mem:BLK (match_dup 3))
18410         (mem:BLK (match_dup 4)))
18411    (use (match_dup 5))]
18412   "TARGET_64BIT"
18413   "{rep\;movsb|rep movsb}"
18414   [(set_attr "type" "str")
18415    (set_attr "prefix_rep" "1")
18416    (set_attr "memory" "both")
18417    (set_attr "mode" "SI")])
18418
18419 (define_expand "setmemsi"
18420    [(use (match_operand:BLK 0 "memory_operand" ""))
18421     (use (match_operand:SI 1 "nonmemory_operand" ""))
18422     (use (match_operand 2 "const_int_operand" ""))
18423     (use (match_operand 3 "const_int_operand" ""))]
18424   ""
18425 {
18426  if (ix86_expand_setmem (operands[0], operands[1],
18427                          operands[2], operands[3],
18428                          operands[3], constm1_rtx))
18429    DONE;
18430  else
18431    FAIL;
18432 })
18433
18434 (define_expand "setmemdi"
18435    [(use (match_operand:BLK 0 "memory_operand" ""))
18436     (use (match_operand:DI 1 "nonmemory_operand" ""))
18437     (use (match_operand 2 "const_int_operand" ""))
18438     (use (match_operand 3 "const_int_operand" ""))
18439     (use (match_operand 4 "const_int_operand" ""))
18440     (use (match_operand 5 "const_int_operand" ""))]
18441   "TARGET_64BIT"
18442 {
18443  if (ix86_expand_setmem (operands[0], operands[1],
18444                          operands[2], operands[3],
18445                          operands[3], constm1_rtx))
18446    DONE;
18447  else
18448    FAIL;
18449 })
18450
18451 ;; Most CPUs don't like single string operations
18452 ;; Handle this case here to simplify previous expander.
18453
18454 (define_expand "strset"
18455   [(set (match_operand 1 "memory_operand" "")
18456         (match_operand 2 "register_operand" ""))
18457    (parallel [(set (match_operand 0 "register_operand" "")
18458                    (match_dup 3))
18459               (clobber (reg:CC FLAGS_REG))])]
18460   ""
18461 {
18462   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18463     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18464
18465   /* If .md ever supports :P for Pmode, this can be directly
18466      in the pattern above.  */
18467   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18468                               GEN_INT (GET_MODE_SIZE (GET_MODE
18469                                                       (operands[2]))));
18470   if (TARGET_SINGLE_STRINGOP || optimize_size)
18471     {
18472       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18473                                       operands[3]));
18474       DONE;
18475     }
18476 })
18477
18478 (define_expand "strset_singleop"
18479   [(parallel [(set (match_operand 1 "memory_operand" "")
18480                    (match_operand 2 "register_operand" ""))
18481               (set (match_operand 0 "register_operand" "")
18482                    (match_operand 3 "" ""))])]
18483   "TARGET_SINGLE_STRINGOP || optimize_size"
18484   "")
18485
18486 (define_insn "*strsetdi_rex_1"
18487   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18488         (match_operand:DI 2 "register_operand" "a"))
18489    (set (match_operand:DI 0 "register_operand" "=D")
18490         (plus:DI (match_dup 1)
18491                  (const_int 8)))]
18492   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18493   "stosq"
18494   [(set_attr "type" "str")
18495    (set_attr "memory" "store")
18496    (set_attr "mode" "DI")])
18497
18498 (define_insn "*strsetsi_1"
18499   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18500         (match_operand:SI 2 "register_operand" "a"))
18501    (set (match_operand:SI 0 "register_operand" "=D")
18502         (plus:SI (match_dup 1)
18503                  (const_int 4)))]
18504   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18505   "{stosl|stosd}"
18506   [(set_attr "type" "str")
18507    (set_attr "memory" "store")
18508    (set_attr "mode" "SI")])
18509
18510 (define_insn "*strsetsi_rex_1"
18511   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18512         (match_operand:SI 2 "register_operand" "a"))
18513    (set (match_operand:DI 0 "register_operand" "=D")
18514         (plus:DI (match_dup 1)
18515                  (const_int 4)))]
18516   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18517   "{stosl|stosd}"
18518   [(set_attr "type" "str")
18519    (set_attr "memory" "store")
18520    (set_attr "mode" "SI")])
18521
18522 (define_insn "*strsethi_1"
18523   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18524         (match_operand:HI 2 "register_operand" "a"))
18525    (set (match_operand:SI 0 "register_operand" "=D")
18526         (plus:SI (match_dup 1)
18527                  (const_int 2)))]
18528   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18529   "stosw"
18530   [(set_attr "type" "str")
18531    (set_attr "memory" "store")
18532    (set_attr "mode" "HI")])
18533
18534 (define_insn "*strsethi_rex_1"
18535   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18536         (match_operand:HI 2 "register_operand" "a"))
18537    (set (match_operand:DI 0 "register_operand" "=D")
18538         (plus:DI (match_dup 1)
18539                  (const_int 2)))]
18540   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18541   "stosw"
18542   [(set_attr "type" "str")
18543    (set_attr "memory" "store")
18544    (set_attr "mode" "HI")])
18545
18546 (define_insn "*strsetqi_1"
18547   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18548         (match_operand:QI 2 "register_operand" "a"))
18549    (set (match_operand:SI 0 "register_operand" "=D")
18550         (plus:SI (match_dup 1)
18551                  (const_int 1)))]
18552   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18553   "stosb"
18554   [(set_attr "type" "str")
18555    (set_attr "memory" "store")
18556    (set_attr "mode" "QI")])
18557
18558 (define_insn "*strsetqi_rex_1"
18559   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18560         (match_operand:QI 2 "register_operand" "a"))
18561    (set (match_operand:DI 0 "register_operand" "=D")
18562         (plus:DI (match_dup 1)
18563                  (const_int 1)))]
18564   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18565   "stosb"
18566   [(set_attr "type" "str")
18567    (set_attr "memory" "store")
18568    (set_attr "mode" "QI")])
18569
18570 (define_expand "rep_stos"
18571   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18572               (set (match_operand 0 "register_operand" "")
18573                    (match_operand 4 "" ""))
18574               (set (match_operand 2 "memory_operand" "") (const_int 0))
18575               (use (match_operand 3 "register_operand" ""))
18576               (use (match_dup 1))])]
18577   ""
18578   "")
18579
18580 (define_insn "*rep_stosdi_rex64"
18581   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18582    (set (match_operand:DI 0 "register_operand" "=D")
18583         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18584                             (const_int 3))
18585                  (match_operand:DI 3 "register_operand" "0")))
18586    (set (mem:BLK (match_dup 3))
18587         (const_int 0))
18588    (use (match_operand:DI 2 "register_operand" "a"))
18589    (use (match_dup 4))]
18590   "TARGET_64BIT"
18591   "{rep\;stosq|rep stosq}"
18592   [(set_attr "type" "str")
18593    (set_attr "prefix_rep" "1")
18594    (set_attr "memory" "store")
18595    (set_attr "mode" "DI")])
18596
18597 (define_insn "*rep_stossi"
18598   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18599    (set (match_operand:SI 0 "register_operand" "=D")
18600         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18601                             (const_int 2))
18602                  (match_operand:SI 3 "register_operand" "0")))
18603    (set (mem:BLK (match_dup 3))
18604         (const_int 0))
18605    (use (match_operand:SI 2 "register_operand" "a"))
18606    (use (match_dup 4))]
18607   "!TARGET_64BIT"
18608   "{rep\;stosl|rep stosd}"
18609   [(set_attr "type" "str")
18610    (set_attr "prefix_rep" "1")
18611    (set_attr "memory" "store")
18612    (set_attr "mode" "SI")])
18613
18614 (define_insn "*rep_stossi_rex64"
18615   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18616    (set (match_operand:DI 0 "register_operand" "=D")
18617         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18618                             (const_int 2))
18619                  (match_operand:DI 3 "register_operand" "0")))
18620    (set (mem:BLK (match_dup 3))
18621         (const_int 0))
18622    (use (match_operand:SI 2 "register_operand" "a"))
18623    (use (match_dup 4))]
18624   "TARGET_64BIT"
18625   "{rep\;stosl|rep stosd}"
18626   [(set_attr "type" "str")
18627    (set_attr "prefix_rep" "1")
18628    (set_attr "memory" "store")
18629    (set_attr "mode" "SI")])
18630
18631 (define_insn "*rep_stosqi"
18632   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18633    (set (match_operand:SI 0 "register_operand" "=D")
18634         (plus:SI (match_operand:SI 3 "register_operand" "0")
18635                  (match_operand:SI 4 "register_operand" "1")))
18636    (set (mem:BLK (match_dup 3))
18637         (const_int 0))
18638    (use (match_operand:QI 2 "register_operand" "a"))
18639    (use (match_dup 4))]
18640   "!TARGET_64BIT"
18641   "{rep\;stosb|rep stosb}"
18642   [(set_attr "type" "str")
18643    (set_attr "prefix_rep" "1")
18644    (set_attr "memory" "store")
18645    (set_attr "mode" "QI")])
18646
18647 (define_insn "*rep_stosqi_rex64"
18648   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18649    (set (match_operand:DI 0 "register_operand" "=D")
18650         (plus:DI (match_operand:DI 3 "register_operand" "0")
18651                  (match_operand:DI 4 "register_operand" "1")))
18652    (set (mem:BLK (match_dup 3))
18653         (const_int 0))
18654    (use (match_operand:QI 2 "register_operand" "a"))
18655    (use (match_dup 4))]
18656   "TARGET_64BIT"
18657   "{rep\;stosb|rep stosb}"
18658   [(set_attr "type" "str")
18659    (set_attr "prefix_rep" "1")
18660    (set_attr "memory" "store")
18661    (set_attr "mode" "QI")])
18662
18663 (define_expand "cmpstrnsi"
18664   [(set (match_operand:SI 0 "register_operand" "")
18665         (compare:SI (match_operand:BLK 1 "general_operand" "")
18666                     (match_operand:BLK 2 "general_operand" "")))
18667    (use (match_operand 3 "general_operand" ""))
18668    (use (match_operand 4 "immediate_operand" ""))]
18669   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18670 {
18671   rtx addr1, addr2, out, outlow, count, countreg, align;
18672
18673   /* Can't use this if the user has appropriated esi or edi.  */
18674   if (global_regs[4] || global_regs[5])
18675     FAIL;
18676
18677   out = operands[0];
18678   if (GET_CODE (out) != REG)
18679     out = gen_reg_rtx (SImode);
18680
18681   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18682   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18683   if (addr1 != XEXP (operands[1], 0))
18684     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18685   if (addr2 != XEXP (operands[2], 0))
18686     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18687
18688   count = operands[3];
18689   countreg = ix86_zero_extend_to_Pmode (count);
18690
18691   /* %%% Iff we are testing strict equality, we can use known alignment
18692      to good advantage.  This may be possible with combine, particularly
18693      once cc0 is dead.  */
18694   align = operands[4];
18695
18696   if (GET_CODE (count) == CONST_INT)
18697     {
18698       if (INTVAL (count) == 0)
18699         {
18700           emit_move_insn (operands[0], const0_rtx);
18701           DONE;
18702         }
18703       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18704                                      operands[1], operands[2]));
18705     }
18706   else
18707     {
18708       if (TARGET_64BIT)
18709         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18710       else
18711         emit_insn (gen_cmpsi_1 (countreg, countreg));
18712       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18713                                   operands[1], operands[2]));
18714     }
18715
18716   outlow = gen_lowpart (QImode, out);
18717   emit_insn (gen_cmpintqi (outlow));
18718   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18719
18720   if (operands[0] != out)
18721     emit_move_insn (operands[0], out);
18722
18723   DONE;
18724 })
18725
18726 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18727
18728 (define_expand "cmpintqi"
18729   [(set (match_dup 1)
18730         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18731    (set (match_dup 2)
18732         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18733    (parallel [(set (match_operand:QI 0 "register_operand" "")
18734                    (minus:QI (match_dup 1)
18735                              (match_dup 2)))
18736               (clobber (reg:CC FLAGS_REG))])]
18737   ""
18738   "operands[1] = gen_reg_rtx (QImode);
18739    operands[2] = gen_reg_rtx (QImode);")
18740
18741 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18742 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18743
18744 (define_expand "cmpstrnqi_nz_1"
18745   [(parallel [(set (reg:CC FLAGS_REG)
18746                    (compare:CC (match_operand 4 "memory_operand" "")
18747                                (match_operand 5 "memory_operand" "")))
18748               (use (match_operand 2 "register_operand" ""))
18749               (use (match_operand:SI 3 "immediate_operand" ""))
18750               (clobber (match_operand 0 "register_operand" ""))
18751               (clobber (match_operand 1 "register_operand" ""))
18752               (clobber (match_dup 2))])]
18753   ""
18754   "")
18755
18756 (define_insn "*cmpstrnqi_nz_1"
18757   [(set (reg:CC FLAGS_REG)
18758         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18759                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18760    (use (match_operand:SI 6 "register_operand" "2"))
18761    (use (match_operand:SI 3 "immediate_operand" "i"))
18762    (clobber (match_operand:SI 0 "register_operand" "=S"))
18763    (clobber (match_operand:SI 1 "register_operand" "=D"))
18764    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18765   "!TARGET_64BIT"
18766   "repz{\;| }cmpsb"
18767   [(set_attr "type" "str")
18768    (set_attr "mode" "QI")
18769    (set_attr "prefix_rep" "1")])
18770
18771 (define_insn "*cmpstrnqi_nz_rex_1"
18772   [(set (reg:CC FLAGS_REG)
18773         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18774                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18775    (use (match_operand:DI 6 "register_operand" "2"))
18776    (use (match_operand:SI 3 "immediate_operand" "i"))
18777    (clobber (match_operand:DI 0 "register_operand" "=S"))
18778    (clobber (match_operand:DI 1 "register_operand" "=D"))
18779    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18780   "TARGET_64BIT"
18781   "repz{\;| }cmpsb"
18782   [(set_attr "type" "str")
18783    (set_attr "mode" "QI")
18784    (set_attr "prefix_rep" "1")])
18785
18786 ;; The same, but the count is not known to not be zero.
18787
18788 (define_expand "cmpstrnqi_1"
18789   [(parallel [(set (reg:CC FLAGS_REG)
18790                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18791                                      (const_int 0))
18792                   (compare:CC (match_operand 4 "memory_operand" "")
18793                               (match_operand 5 "memory_operand" ""))
18794                   (const_int 0)))
18795               (use (match_operand:SI 3 "immediate_operand" ""))
18796               (use (reg:CC FLAGS_REG))
18797               (clobber (match_operand 0 "register_operand" ""))
18798               (clobber (match_operand 1 "register_operand" ""))
18799               (clobber (match_dup 2))])]
18800   ""
18801   "")
18802
18803 (define_insn "*cmpstrnqi_1"
18804   [(set (reg:CC FLAGS_REG)
18805         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18806                              (const_int 0))
18807           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18808                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18809           (const_int 0)))
18810    (use (match_operand:SI 3 "immediate_operand" "i"))
18811    (use (reg:CC FLAGS_REG))
18812    (clobber (match_operand:SI 0 "register_operand" "=S"))
18813    (clobber (match_operand:SI 1 "register_operand" "=D"))
18814    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18815   "!TARGET_64BIT"
18816   "repz{\;| }cmpsb"
18817   [(set_attr "type" "str")
18818    (set_attr "mode" "QI")
18819    (set_attr "prefix_rep" "1")])
18820
18821 (define_insn "*cmpstrnqi_rex_1"
18822   [(set (reg:CC FLAGS_REG)
18823         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18824                              (const_int 0))
18825           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18826                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18827           (const_int 0)))
18828    (use (match_operand:SI 3 "immediate_operand" "i"))
18829    (use (reg:CC FLAGS_REG))
18830    (clobber (match_operand:DI 0 "register_operand" "=S"))
18831    (clobber (match_operand:DI 1 "register_operand" "=D"))
18832    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18833   "TARGET_64BIT"
18834   "repz{\;| }cmpsb"
18835   [(set_attr "type" "str")
18836    (set_attr "mode" "QI")
18837    (set_attr "prefix_rep" "1")])
18838
18839 (define_expand "strlensi"
18840   [(set (match_operand:SI 0 "register_operand" "")
18841         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18842                     (match_operand:QI 2 "immediate_operand" "")
18843                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18844   ""
18845 {
18846  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18847    DONE;
18848  else
18849    FAIL;
18850 })
18851
18852 (define_expand "strlendi"
18853   [(set (match_operand:DI 0 "register_operand" "")
18854         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18855                     (match_operand:QI 2 "immediate_operand" "")
18856                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18857   ""
18858 {
18859  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18860    DONE;
18861  else
18862    FAIL;
18863 })
18864
18865 (define_expand "strlenqi_1"
18866   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18867               (clobber (match_operand 1 "register_operand" ""))
18868               (clobber (reg:CC FLAGS_REG))])]
18869   ""
18870   "")
18871
18872 (define_insn "*strlenqi_1"
18873   [(set (match_operand:SI 0 "register_operand" "=&c")
18874         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18875                     (match_operand:QI 2 "register_operand" "a")
18876                     (match_operand:SI 3 "immediate_operand" "i")
18877                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18878    (clobber (match_operand:SI 1 "register_operand" "=D"))
18879    (clobber (reg:CC FLAGS_REG))]
18880   "!TARGET_64BIT"
18881   "repnz{\;| }scasb"
18882   [(set_attr "type" "str")
18883    (set_attr "mode" "QI")
18884    (set_attr "prefix_rep" "1")])
18885
18886 (define_insn "*strlenqi_rex_1"
18887   [(set (match_operand:DI 0 "register_operand" "=&c")
18888         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18889                     (match_operand:QI 2 "register_operand" "a")
18890                     (match_operand:DI 3 "immediate_operand" "i")
18891                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18892    (clobber (match_operand:DI 1 "register_operand" "=D"))
18893    (clobber (reg:CC FLAGS_REG))]
18894   "TARGET_64BIT"
18895   "repnz{\;| }scasb"
18896   [(set_attr "type" "str")
18897    (set_attr "mode" "QI")
18898    (set_attr "prefix_rep" "1")])
18899
18900 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18901 ;; handled in combine, but it is not currently up to the task.
18902 ;; When used for their truth value, the cmpstrn* expanders generate
18903 ;; code like this:
18904 ;;
18905 ;;   repz cmpsb
18906 ;;   seta       %al
18907 ;;   setb       %dl
18908 ;;   cmpb       %al, %dl
18909 ;;   jcc        label
18910 ;;
18911 ;; The intermediate three instructions are unnecessary.
18912
18913 ;; This one handles cmpstrn*_nz_1...
18914 (define_peephole2
18915   [(parallel[
18916      (set (reg:CC FLAGS_REG)
18917           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18918                       (mem:BLK (match_operand 5 "register_operand" ""))))
18919      (use (match_operand 6 "register_operand" ""))
18920      (use (match_operand:SI 3 "immediate_operand" ""))
18921      (clobber (match_operand 0 "register_operand" ""))
18922      (clobber (match_operand 1 "register_operand" ""))
18923      (clobber (match_operand 2 "register_operand" ""))])
18924    (set (match_operand:QI 7 "register_operand" "")
18925         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18926    (set (match_operand:QI 8 "register_operand" "")
18927         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18928    (set (reg FLAGS_REG)
18929         (compare (match_dup 7) (match_dup 8)))
18930   ]
18931   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18932   [(parallel[
18933      (set (reg:CC FLAGS_REG)
18934           (compare:CC (mem:BLK (match_dup 4))
18935                       (mem:BLK (match_dup 5))))
18936      (use (match_dup 6))
18937      (use (match_dup 3))
18938      (clobber (match_dup 0))
18939      (clobber (match_dup 1))
18940      (clobber (match_dup 2))])]
18941   "")
18942
18943 ;; ...and this one handles cmpstrn*_1.
18944 (define_peephole2
18945   [(parallel[
18946      (set (reg:CC FLAGS_REG)
18947           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18948                                (const_int 0))
18949             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18950                         (mem:BLK (match_operand 5 "register_operand" "")))
18951             (const_int 0)))
18952      (use (match_operand:SI 3 "immediate_operand" ""))
18953      (use (reg:CC FLAGS_REG))
18954      (clobber (match_operand 0 "register_operand" ""))
18955      (clobber (match_operand 1 "register_operand" ""))
18956      (clobber (match_operand 2 "register_operand" ""))])
18957    (set (match_operand:QI 7 "register_operand" "")
18958         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18959    (set (match_operand:QI 8 "register_operand" "")
18960         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18961    (set (reg FLAGS_REG)
18962         (compare (match_dup 7) (match_dup 8)))
18963   ]
18964   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18965   [(parallel[
18966      (set (reg:CC FLAGS_REG)
18967           (if_then_else:CC (ne (match_dup 6)
18968                                (const_int 0))
18969             (compare:CC (mem:BLK (match_dup 4))
18970                         (mem:BLK (match_dup 5)))
18971             (const_int 0)))
18972      (use (match_dup 3))
18973      (use (reg:CC FLAGS_REG))
18974      (clobber (match_dup 0))
18975      (clobber (match_dup 1))
18976      (clobber (match_dup 2))])]
18977   "")
18978
18979
18980 \f
18981 ;; Conditional move instructions.
18982
18983 (define_expand "movdicc"
18984   [(set (match_operand:DI 0 "register_operand" "")
18985         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18986                          (match_operand:DI 2 "general_operand" "")
18987                          (match_operand:DI 3 "general_operand" "")))]
18988   "TARGET_64BIT"
18989   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18990
18991 (define_insn "x86_movdicc_0_m1_rex64"
18992   [(set (match_operand:DI 0 "register_operand" "=r")
18993         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18994           (const_int -1)
18995           (const_int 0)))
18996    (clobber (reg:CC FLAGS_REG))]
18997   "TARGET_64BIT"
18998   "sbb{q}\t%0, %0"
18999   ; Since we don't have the proper number of operands for an alu insn,
19000   ; fill in all the blanks.
19001   [(set_attr "type" "alu")
19002    (set_attr "pent_pair" "pu")
19003    (set_attr "memory" "none")
19004    (set_attr "imm_disp" "false")
19005    (set_attr "mode" "DI")
19006    (set_attr "length_immediate" "0")])
19007
19008 (define_insn "*movdicc_c_rex64"
19009   [(set (match_operand:DI 0 "register_operand" "=r,r")
19010         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19011                                 [(reg FLAGS_REG) (const_int 0)])
19012                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19013                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19014   "TARGET_64BIT && TARGET_CMOVE
19015    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19016   "@
19017    cmov%O2%C1\t{%2, %0|%0, %2}
19018    cmov%O2%c1\t{%3, %0|%0, %3}"
19019   [(set_attr "type" "icmov")
19020    (set_attr "mode" "DI")])
19021
19022 (define_expand "movsicc"
19023   [(set (match_operand:SI 0 "register_operand" "")
19024         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19025                          (match_operand:SI 2 "general_operand" "")
19026                          (match_operand:SI 3 "general_operand" "")))]
19027   ""
19028   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19029
19030 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19031 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19032 ;; So just document what we're doing explicitly.
19033
19034 (define_insn "x86_movsicc_0_m1"
19035   [(set (match_operand:SI 0 "register_operand" "=r")
19036         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19037           (const_int -1)
19038           (const_int 0)))
19039    (clobber (reg:CC FLAGS_REG))]
19040   ""
19041   "sbb{l}\t%0, %0"
19042   ; Since we don't have the proper number of operands for an alu insn,
19043   ; fill in all the blanks.
19044   [(set_attr "type" "alu")
19045    (set_attr "pent_pair" "pu")
19046    (set_attr "memory" "none")
19047    (set_attr "imm_disp" "false")
19048    (set_attr "mode" "SI")
19049    (set_attr "length_immediate" "0")])
19050
19051 (define_insn "*movsicc_noc"
19052   [(set (match_operand:SI 0 "register_operand" "=r,r")
19053         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19054                                 [(reg FLAGS_REG) (const_int 0)])
19055                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19056                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19057   "TARGET_CMOVE
19058    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19059   "@
19060    cmov%O2%C1\t{%2, %0|%0, %2}
19061    cmov%O2%c1\t{%3, %0|%0, %3}"
19062   [(set_attr "type" "icmov")
19063    (set_attr "mode" "SI")])
19064
19065 (define_expand "movhicc"
19066   [(set (match_operand:HI 0 "register_operand" "")
19067         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19068                          (match_operand:HI 2 "general_operand" "")
19069                          (match_operand:HI 3 "general_operand" "")))]
19070   "TARGET_HIMODE_MATH"
19071   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19072
19073 (define_insn "*movhicc_noc"
19074   [(set (match_operand:HI 0 "register_operand" "=r,r")
19075         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19076                                 [(reg FLAGS_REG) (const_int 0)])
19077                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19078                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19079   "TARGET_CMOVE
19080    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19081   "@
19082    cmov%O2%C1\t{%2, %0|%0, %2}
19083    cmov%O2%c1\t{%3, %0|%0, %3}"
19084   [(set_attr "type" "icmov")
19085    (set_attr "mode" "HI")])
19086
19087 (define_expand "movqicc"
19088   [(set (match_operand:QI 0 "register_operand" "")
19089         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19090                          (match_operand:QI 2 "general_operand" "")
19091                          (match_operand:QI 3 "general_operand" "")))]
19092   "TARGET_QIMODE_MATH"
19093   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19094
19095 (define_insn_and_split "*movqicc_noc"
19096   [(set (match_operand:QI 0 "register_operand" "=r,r")
19097         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19098                                 [(match_operand 4 "flags_reg_operand" "")
19099                                  (const_int 0)])
19100                       (match_operand:QI 2 "register_operand" "r,0")
19101                       (match_operand:QI 3 "register_operand" "0,r")))]
19102   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19103   "#"
19104   "&& reload_completed"
19105   [(set (match_dup 0)
19106         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19107                       (match_dup 2)
19108                       (match_dup 3)))]
19109   "operands[0] = gen_lowpart (SImode, operands[0]);
19110    operands[2] = gen_lowpart (SImode, operands[2]);
19111    operands[3] = gen_lowpart (SImode, operands[3]);"
19112   [(set_attr "type" "icmov")
19113    (set_attr "mode" "SI")])
19114
19115 (define_expand "movsfcc"
19116   [(set (match_operand:SF 0 "register_operand" "")
19117         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19118                          (match_operand:SF 2 "register_operand" "")
19119                          (match_operand:SF 3 "register_operand" "")))]
19120   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19121   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19122
19123 (define_insn "*movsfcc_1_387"
19124   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19125         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19126                                 [(reg FLAGS_REG) (const_int 0)])
19127                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19128                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19129   "TARGET_80387 && TARGET_CMOVE
19130    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19131   "@
19132    fcmov%F1\t{%2, %0|%0, %2}
19133    fcmov%f1\t{%3, %0|%0, %3}
19134    cmov%O2%C1\t{%2, %0|%0, %2}
19135    cmov%O2%c1\t{%3, %0|%0, %3}"
19136   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19137    (set_attr "mode" "SF,SF,SI,SI")])
19138
19139 (define_expand "movdfcc"
19140   [(set (match_operand:DF 0 "register_operand" "")
19141         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19142                          (match_operand:DF 2 "register_operand" "")
19143                          (match_operand:DF 3 "register_operand" "")))]
19144   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19145   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19146
19147 (define_insn "*movdfcc_1"
19148   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19149         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19150                                 [(reg FLAGS_REG) (const_int 0)])
19151                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19152                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19153   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19154    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19155   "@
19156    fcmov%F1\t{%2, %0|%0, %2}
19157    fcmov%f1\t{%3, %0|%0, %3}
19158    #
19159    #"
19160   [(set_attr "type" "fcmov,fcmov,multi,multi")
19161    (set_attr "mode" "DF")])
19162
19163 (define_insn "*movdfcc_1_rex64"
19164   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19165         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19166                                 [(reg FLAGS_REG) (const_int 0)])
19167                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19168                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19169   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19170    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19171   "@
19172    fcmov%F1\t{%2, %0|%0, %2}
19173    fcmov%f1\t{%3, %0|%0, %3}
19174    cmov%O2%C1\t{%2, %0|%0, %2}
19175    cmov%O2%c1\t{%3, %0|%0, %3}"
19176   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19177    (set_attr "mode" "DF")])
19178
19179 (define_split
19180   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19181         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19182                                 [(match_operand 4 "flags_reg_operand" "")
19183                                  (const_int 0)])
19184                       (match_operand:DF 2 "nonimmediate_operand" "")
19185                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19186   "!TARGET_64BIT && reload_completed"
19187   [(set (match_dup 2)
19188         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19189                       (match_dup 5)
19190                       (match_dup 7)))
19191    (set (match_dup 3)
19192         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19193                       (match_dup 6)
19194                       (match_dup 8)))]
19195   "split_di (operands+2, 1, operands+5, operands+6);
19196    split_di (operands+3, 1, operands+7, operands+8);
19197    split_di (operands, 1, operands+2, operands+3);")
19198
19199 (define_expand "movxfcc"
19200   [(set (match_operand:XF 0 "register_operand" "")
19201         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19202                          (match_operand:XF 2 "register_operand" "")
19203                          (match_operand:XF 3 "register_operand" "")))]
19204   "TARGET_80387 && TARGET_CMOVE"
19205   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19206
19207 (define_insn "*movxfcc_1"
19208   [(set (match_operand:XF 0 "register_operand" "=f,f")
19209         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19210                                 [(reg FLAGS_REG) (const_int 0)])
19211                       (match_operand:XF 2 "register_operand" "f,0")
19212                       (match_operand:XF 3 "register_operand" "0,f")))]
19213   "TARGET_80387 && TARGET_CMOVE"
19214   "@
19215    fcmov%F1\t{%2, %0|%0, %2}
19216    fcmov%f1\t{%3, %0|%0, %3}"
19217   [(set_attr "type" "fcmov")
19218    (set_attr "mode" "XF")])
19219
19220 ;; These versions of the min/max patterns are intentionally ignorant of
19221 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19222 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19223 ;; are undefined in this condition, we're certain this is correct.
19224
19225 (define_insn "sminsf3"
19226   [(set (match_operand:SF 0 "register_operand" "=x")
19227         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19228                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19229   "TARGET_SSE_MATH"
19230   "minss\t{%2, %0|%0, %2}"
19231   [(set_attr "type" "sseadd")
19232    (set_attr "mode" "SF")])
19233
19234 (define_insn "smaxsf3"
19235   [(set (match_operand:SF 0 "register_operand" "=x")
19236         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19237                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19238   "TARGET_SSE_MATH"
19239   "maxss\t{%2, %0|%0, %2}"
19240   [(set_attr "type" "sseadd")
19241    (set_attr "mode" "SF")])
19242
19243 (define_insn "smindf3"
19244   [(set (match_operand:DF 0 "register_operand" "=x")
19245         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19246                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19247   "TARGET_SSE2 && TARGET_SSE_MATH"
19248   "minsd\t{%2, %0|%0, %2}"
19249   [(set_attr "type" "sseadd")
19250    (set_attr "mode" "DF")])
19251
19252 (define_insn "smaxdf3"
19253   [(set (match_operand:DF 0 "register_operand" "=x")
19254         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19255                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19256   "TARGET_SSE2 && TARGET_SSE_MATH"
19257   "maxsd\t{%2, %0|%0, %2}"
19258   [(set_attr "type" "sseadd")
19259    (set_attr "mode" "DF")])
19260
19261 ;; These versions of the min/max patterns implement exactly the operations
19262 ;;   min = (op1 < op2 ? op1 : op2)
19263 ;;   max = (!(op1 < op2) ? op1 : op2)
19264 ;; Their operands are not commutative, and thus they may be used in the
19265 ;; presence of -0.0 and NaN.
19266
19267 (define_insn "*ieee_sminsf3"
19268   [(set (match_operand:SF 0 "register_operand" "=x")
19269         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19270                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19271                    UNSPEC_IEEE_MIN))]
19272   "TARGET_SSE_MATH"
19273   "minss\t{%2, %0|%0, %2}"
19274   [(set_attr "type" "sseadd")
19275    (set_attr "mode" "SF")])
19276
19277 (define_insn "*ieee_smaxsf3"
19278   [(set (match_operand:SF 0 "register_operand" "=x")
19279         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19280                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19281                    UNSPEC_IEEE_MAX))]
19282   "TARGET_SSE_MATH"
19283   "maxss\t{%2, %0|%0, %2}"
19284   [(set_attr "type" "sseadd")
19285    (set_attr "mode" "SF")])
19286
19287 (define_insn "*ieee_smindf3"
19288   [(set (match_operand:DF 0 "register_operand" "=x")
19289         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19290                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19291                    UNSPEC_IEEE_MIN))]
19292   "TARGET_SSE2 && TARGET_SSE_MATH"
19293   "minsd\t{%2, %0|%0, %2}"
19294   [(set_attr "type" "sseadd")
19295    (set_attr "mode" "DF")])
19296
19297 (define_insn "*ieee_smaxdf3"
19298   [(set (match_operand:DF 0 "register_operand" "=x")
19299         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19300                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19301                    UNSPEC_IEEE_MAX))]
19302   "TARGET_SSE2 && TARGET_SSE_MATH"
19303   "maxsd\t{%2, %0|%0, %2}"
19304   [(set_attr "type" "sseadd")
19305    (set_attr "mode" "DF")])
19306
19307 ;; Make two stack loads independent:
19308 ;;   fld aa              fld aa
19309 ;;   fld %st(0)     ->   fld bb
19310 ;;   fmul bb             fmul %st(1), %st
19311 ;;
19312 ;; Actually we only match the last two instructions for simplicity.
19313 (define_peephole2
19314   [(set (match_operand 0 "fp_register_operand" "")
19315         (match_operand 1 "fp_register_operand" ""))
19316    (set (match_dup 0)
19317         (match_operator 2 "binary_fp_operator"
19318            [(match_dup 0)
19319             (match_operand 3 "memory_operand" "")]))]
19320   "REGNO (operands[0]) != REGNO (operands[1])"
19321   [(set (match_dup 0) (match_dup 3))
19322    (set (match_dup 0) (match_dup 4))]
19323
19324   ;; The % modifier is not operational anymore in peephole2's, so we have to
19325   ;; swap the operands manually in the case of addition and multiplication.
19326   "if (COMMUTATIVE_ARITH_P (operands[2]))
19327      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19328                                  operands[0], operands[1]);
19329    else
19330      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19331                                  operands[1], operands[0]);")
19332
19333 ;; Conditional addition patterns
19334 (define_expand "addqicc"
19335   [(match_operand:QI 0 "register_operand" "")
19336    (match_operand 1 "comparison_operator" "")
19337    (match_operand:QI 2 "register_operand" "")
19338    (match_operand:QI 3 "const_int_operand" "")]
19339   ""
19340   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19341
19342 (define_expand "addhicc"
19343   [(match_operand:HI 0 "register_operand" "")
19344    (match_operand 1 "comparison_operator" "")
19345    (match_operand:HI 2 "register_operand" "")
19346    (match_operand:HI 3 "const_int_operand" "")]
19347   ""
19348   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19349
19350 (define_expand "addsicc"
19351   [(match_operand:SI 0 "register_operand" "")
19352    (match_operand 1 "comparison_operator" "")
19353    (match_operand:SI 2 "register_operand" "")
19354    (match_operand:SI 3 "const_int_operand" "")]
19355   ""
19356   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19357
19358 (define_expand "adddicc"
19359   [(match_operand:DI 0 "register_operand" "")
19360    (match_operand 1 "comparison_operator" "")
19361    (match_operand:DI 2 "register_operand" "")
19362    (match_operand:DI 3 "const_int_operand" "")]
19363   "TARGET_64BIT"
19364   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19365
19366 \f
19367 ;; Misc patterns (?)
19368
19369 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19370 ;; Otherwise there will be nothing to keep
19371 ;;
19372 ;; [(set (reg ebp) (reg esp))]
19373 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19374 ;;  (clobber (eflags)]
19375 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19376 ;;
19377 ;; in proper program order.
19378 (define_insn "pro_epilogue_adjust_stack_1"
19379   [(set (match_operand:SI 0 "register_operand" "=r,r")
19380         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19381                  (match_operand:SI 2 "immediate_operand" "i,i")))
19382    (clobber (reg:CC FLAGS_REG))
19383    (clobber (mem:BLK (scratch)))]
19384   "!TARGET_64BIT"
19385 {
19386   switch (get_attr_type (insn))
19387     {
19388     case TYPE_IMOV:
19389       return "mov{l}\t{%1, %0|%0, %1}";
19390
19391     case TYPE_ALU:
19392       if (GET_CODE (operands[2]) == CONST_INT
19393           && (INTVAL (operands[2]) == 128
19394               || (INTVAL (operands[2]) < 0
19395                   && INTVAL (operands[2]) != -128)))
19396         {
19397           operands[2] = GEN_INT (-INTVAL (operands[2]));
19398           return "sub{l}\t{%2, %0|%0, %2}";
19399         }
19400       return "add{l}\t{%2, %0|%0, %2}";
19401
19402     case TYPE_LEA:
19403       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19404       return "lea{l}\t{%a2, %0|%0, %a2}";
19405
19406     default:
19407       gcc_unreachable ();
19408     }
19409 }
19410   [(set (attr "type")
19411         (cond [(eq_attr "alternative" "0")
19412                  (const_string "alu")
19413                (match_operand:SI 2 "const0_operand" "")
19414                  (const_string "imov")
19415               ]
19416               (const_string "lea")))
19417    (set_attr "mode" "SI")])
19418
19419 (define_insn "pro_epilogue_adjust_stack_rex64"
19420   [(set (match_operand:DI 0 "register_operand" "=r,r")
19421         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19422                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19423    (clobber (reg:CC FLAGS_REG))
19424    (clobber (mem:BLK (scratch)))]
19425   "TARGET_64BIT"
19426 {
19427   switch (get_attr_type (insn))
19428     {
19429     case TYPE_IMOV:
19430       return "mov{q}\t{%1, %0|%0, %1}";
19431
19432     case TYPE_ALU:
19433       if (GET_CODE (operands[2]) == CONST_INT
19434           /* Avoid overflows.  */
19435           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19436           && (INTVAL (operands[2]) == 128
19437               || (INTVAL (operands[2]) < 0
19438                   && INTVAL (operands[2]) != -128)))
19439         {
19440           operands[2] = GEN_INT (-INTVAL (operands[2]));
19441           return "sub{q}\t{%2, %0|%0, %2}";
19442         }
19443       return "add{q}\t{%2, %0|%0, %2}";
19444
19445     case TYPE_LEA:
19446       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19447       return "lea{q}\t{%a2, %0|%0, %a2}";
19448
19449     default:
19450       gcc_unreachable ();
19451     }
19452 }
19453   [(set (attr "type")
19454         (cond [(eq_attr "alternative" "0")
19455                  (const_string "alu")
19456                (match_operand:DI 2 "const0_operand" "")
19457                  (const_string "imov")
19458               ]
19459               (const_string "lea")))
19460    (set_attr "mode" "DI")])
19461
19462 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19463   [(set (match_operand:DI 0 "register_operand" "=r,r")
19464         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19465                  (match_operand:DI 3 "immediate_operand" "i,i")))
19466    (use (match_operand:DI 2 "register_operand" "r,r"))
19467    (clobber (reg:CC FLAGS_REG))
19468    (clobber (mem:BLK (scratch)))]
19469   "TARGET_64BIT"
19470 {
19471   switch (get_attr_type (insn))
19472     {
19473     case TYPE_ALU:
19474       return "add{q}\t{%2, %0|%0, %2}";
19475
19476     case TYPE_LEA:
19477       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19478       return "lea{q}\t{%a2, %0|%0, %a2}";
19479
19480     default:
19481       gcc_unreachable ();
19482     }
19483 }
19484   [(set_attr "type" "alu,lea")
19485    (set_attr "mode" "DI")])
19486
19487 (define_expand "allocate_stack_worker"
19488   [(match_operand:SI 0 "register_operand" "")]
19489   "TARGET_STACK_PROBE"
19490 {
19491   if (reload_completed)
19492     {
19493       if (TARGET_64BIT)
19494         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19495       else
19496         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19497     }
19498   else
19499     {
19500       if (TARGET_64BIT)
19501         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19502       else
19503         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19504     }
19505   DONE;
19506 })
19507
19508 (define_insn "allocate_stack_worker_1"
19509   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19510     UNSPECV_STACK_PROBE)
19511    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19512    (clobber (match_scratch:SI 1 "=0"))
19513    (clobber (reg:CC FLAGS_REG))]
19514   "!TARGET_64BIT && TARGET_STACK_PROBE"
19515   "call\t__alloca"
19516   [(set_attr "type" "multi")
19517    (set_attr "length" "5")])
19518
19519 (define_expand "allocate_stack_worker_postreload"
19520   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19521                                     UNSPECV_STACK_PROBE)
19522               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19523               (clobber (match_dup 0))
19524               (clobber (reg:CC FLAGS_REG))])]
19525   ""
19526   "")
19527
19528 (define_insn "allocate_stack_worker_rex64"
19529   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19530     UNSPECV_STACK_PROBE)
19531    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19532    (clobber (match_scratch:DI 1 "=0"))
19533    (clobber (reg:CC FLAGS_REG))]
19534   "TARGET_64BIT && TARGET_STACK_PROBE"
19535   "call\t__alloca"
19536   [(set_attr "type" "multi")
19537    (set_attr "length" "5")])
19538
19539 (define_expand "allocate_stack_worker_rex64_postreload"
19540   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19541                                     UNSPECV_STACK_PROBE)
19542               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19543               (clobber (match_dup 0))
19544               (clobber (reg:CC FLAGS_REG))])]
19545   ""
19546   "")
19547
19548 (define_expand "allocate_stack"
19549   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19550                    (minus:SI (reg:SI SP_REG)
19551                              (match_operand:SI 1 "general_operand" "")))
19552               (clobber (reg:CC FLAGS_REG))])
19553    (parallel [(set (reg:SI SP_REG)
19554                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19555               (clobber (reg:CC FLAGS_REG))])]
19556   "TARGET_STACK_PROBE"
19557 {
19558 #ifdef CHECK_STACK_LIMIT
19559   if (GET_CODE (operands[1]) == CONST_INT
19560       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19561     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19562                            operands[1]));
19563   else
19564 #endif
19565     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19566                                                             operands[1])));
19567
19568   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19569   DONE;
19570 })
19571
19572 (define_expand "builtin_setjmp_receiver"
19573   [(label_ref (match_operand 0 "" ""))]
19574   "!TARGET_64BIT && flag_pic"
19575 {
19576   if (TARGET_MACHO)
19577     {
19578       rtx xops[3];
19579       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19580       rtx label_rtx = gen_label_rtx ();
19581       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19582       xops[0] = xops[1] = picreg;
19583       xops[2] = gen_rtx_CONST (SImode,
19584                   gen_rtx_MINUS (SImode,
19585                     gen_rtx_LABEL_REF (SImode, label_rtx),
19586                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19587       ix86_expand_binary_operator (MINUS, SImode, xops);
19588     }
19589   else
19590     emit_insn (gen_set_got (pic_offset_table_rtx));
19591   DONE;
19592 })
19593 \f
19594 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19595
19596 (define_split
19597   [(set (match_operand 0 "register_operand" "")
19598         (match_operator 3 "promotable_binary_operator"
19599            [(match_operand 1 "register_operand" "")
19600             (match_operand 2 "aligned_operand" "")]))
19601    (clobber (reg:CC FLAGS_REG))]
19602   "! TARGET_PARTIAL_REG_STALL && reload_completed
19603    && ((GET_MODE (operands[0]) == HImode
19604         && ((!optimize_size && !TARGET_FAST_PREFIX)
19605             /* ??? next two lines just !satisfies_constraint_K (...) */
19606             || GET_CODE (operands[2]) != CONST_INT
19607             || satisfies_constraint_K (operands[2])))
19608        || (GET_MODE (operands[0]) == QImode
19609            && (TARGET_PROMOTE_QImode || optimize_size)))"
19610   [(parallel [(set (match_dup 0)
19611                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19612               (clobber (reg:CC FLAGS_REG))])]
19613   "operands[0] = gen_lowpart (SImode, operands[0]);
19614    operands[1] = gen_lowpart (SImode, operands[1]);
19615    if (GET_CODE (operands[3]) != ASHIFT)
19616      operands[2] = gen_lowpart (SImode, operands[2]);
19617    PUT_MODE (operands[3], SImode);")
19618
19619 ; Promote the QImode tests, as i386 has encoding of the AND
19620 ; instruction with 32-bit sign-extended immediate and thus the
19621 ; instruction size is unchanged, except in the %eax case for
19622 ; which it is increased by one byte, hence the ! optimize_size.
19623 (define_split
19624   [(set (match_operand 0 "flags_reg_operand" "")
19625         (match_operator 2 "compare_operator"
19626           [(and (match_operand 3 "aligned_operand" "")
19627                 (match_operand 4 "const_int_operand" ""))
19628            (const_int 0)]))
19629    (set (match_operand 1 "register_operand" "")
19630         (and (match_dup 3) (match_dup 4)))]
19631   "! TARGET_PARTIAL_REG_STALL && reload_completed
19632    /* Ensure that the operand will remain sign-extended immediate.  */
19633    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19634    && ! optimize_size
19635    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19636        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19637   [(parallel [(set (match_dup 0)
19638                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19639                                     (const_int 0)]))
19640               (set (match_dup 1)
19641                    (and:SI (match_dup 3) (match_dup 4)))])]
19642 {
19643   operands[4]
19644     = gen_int_mode (INTVAL (operands[4])
19645                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19646   operands[1] = gen_lowpart (SImode, operands[1]);
19647   operands[3] = gen_lowpart (SImode, operands[3]);
19648 })
19649
19650 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19651 ; the TEST instruction with 32-bit sign-extended immediate and thus
19652 ; the instruction size would at least double, which is not what we
19653 ; want even with ! optimize_size.
19654 (define_split
19655   [(set (match_operand 0 "flags_reg_operand" "")
19656         (match_operator 1 "compare_operator"
19657           [(and (match_operand:HI 2 "aligned_operand" "")
19658                 (match_operand:HI 3 "const_int_operand" ""))
19659            (const_int 0)]))]
19660   "! TARGET_PARTIAL_REG_STALL && reload_completed
19661    /* Ensure that the operand will remain sign-extended immediate.  */
19662    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19663    && ! TARGET_FAST_PREFIX
19664    && ! optimize_size"
19665   [(set (match_dup 0)
19666         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19667                          (const_int 0)]))]
19668 {
19669   operands[3]
19670     = gen_int_mode (INTVAL (operands[3])
19671                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19672   operands[2] = gen_lowpart (SImode, operands[2]);
19673 })
19674
19675 (define_split
19676   [(set (match_operand 0 "register_operand" "")
19677         (neg (match_operand 1 "register_operand" "")))
19678    (clobber (reg:CC FLAGS_REG))]
19679   "! TARGET_PARTIAL_REG_STALL && reload_completed
19680    && (GET_MODE (operands[0]) == HImode
19681        || (GET_MODE (operands[0]) == QImode
19682            && (TARGET_PROMOTE_QImode || optimize_size)))"
19683   [(parallel [(set (match_dup 0)
19684                    (neg:SI (match_dup 1)))
19685               (clobber (reg:CC FLAGS_REG))])]
19686   "operands[0] = gen_lowpart (SImode, operands[0]);
19687    operands[1] = gen_lowpart (SImode, operands[1]);")
19688
19689 (define_split
19690   [(set (match_operand 0 "register_operand" "")
19691         (not (match_operand 1 "register_operand" "")))]
19692   "! TARGET_PARTIAL_REG_STALL && reload_completed
19693    && (GET_MODE (operands[0]) == HImode
19694        || (GET_MODE (operands[0]) == QImode
19695            && (TARGET_PROMOTE_QImode || optimize_size)))"
19696   [(set (match_dup 0)
19697         (not:SI (match_dup 1)))]
19698   "operands[0] = gen_lowpart (SImode, operands[0]);
19699    operands[1] = gen_lowpart (SImode, operands[1]);")
19700
19701 (define_split
19702   [(set (match_operand 0 "register_operand" "")
19703         (if_then_else (match_operator 1 "comparison_operator"
19704                                 [(reg FLAGS_REG) (const_int 0)])
19705                       (match_operand 2 "register_operand" "")
19706                       (match_operand 3 "register_operand" "")))]
19707   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19708    && (GET_MODE (operands[0]) == HImode
19709        || (GET_MODE (operands[0]) == QImode
19710            && (TARGET_PROMOTE_QImode || optimize_size)))"
19711   [(set (match_dup 0)
19712         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19713   "operands[0] = gen_lowpart (SImode, operands[0]);
19714    operands[2] = gen_lowpart (SImode, operands[2]);
19715    operands[3] = gen_lowpart (SImode, operands[3]);")
19716
19717 \f
19718 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19719 ;; transform a complex memory operation into two memory to register operations.
19720
19721 ;; Don't push memory operands
19722 (define_peephole2
19723   [(set (match_operand:SI 0 "push_operand" "")
19724         (match_operand:SI 1 "memory_operand" ""))
19725    (match_scratch:SI 2 "r")]
19726   "!optimize_size && !TARGET_PUSH_MEMORY
19727    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19728   [(set (match_dup 2) (match_dup 1))
19729    (set (match_dup 0) (match_dup 2))]
19730   "")
19731
19732 (define_peephole2
19733   [(set (match_operand:DI 0 "push_operand" "")
19734         (match_operand:DI 1 "memory_operand" ""))
19735    (match_scratch:DI 2 "r")]
19736   "!optimize_size && !TARGET_PUSH_MEMORY
19737    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19738   [(set (match_dup 2) (match_dup 1))
19739    (set (match_dup 0) (match_dup 2))]
19740   "")
19741
19742 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19743 ;; SImode pushes.
19744 (define_peephole2
19745   [(set (match_operand:SF 0 "push_operand" "")
19746         (match_operand:SF 1 "memory_operand" ""))
19747    (match_scratch:SF 2 "r")]
19748   "!optimize_size && !TARGET_PUSH_MEMORY
19749    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19750   [(set (match_dup 2) (match_dup 1))
19751    (set (match_dup 0) (match_dup 2))]
19752   "")
19753
19754 (define_peephole2
19755   [(set (match_operand:HI 0 "push_operand" "")
19756         (match_operand:HI 1 "memory_operand" ""))
19757    (match_scratch:HI 2 "r")]
19758   "!optimize_size && !TARGET_PUSH_MEMORY
19759    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19760   [(set (match_dup 2) (match_dup 1))
19761    (set (match_dup 0) (match_dup 2))]
19762   "")
19763
19764 (define_peephole2
19765   [(set (match_operand:QI 0 "push_operand" "")
19766         (match_operand:QI 1 "memory_operand" ""))
19767    (match_scratch:QI 2 "q")]
19768   "!optimize_size && !TARGET_PUSH_MEMORY
19769    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19770   [(set (match_dup 2) (match_dup 1))
19771    (set (match_dup 0) (match_dup 2))]
19772   "")
19773
19774 ;; Don't move an immediate directly to memory when the instruction
19775 ;; gets too big.
19776 (define_peephole2
19777   [(match_scratch:SI 1 "r")
19778    (set (match_operand:SI 0 "memory_operand" "")
19779         (const_int 0))]
19780   "! optimize_size
19781    && ! TARGET_USE_MOV0
19782    && TARGET_SPLIT_LONG_MOVES
19783    && get_attr_length (insn) >= ix86_cost->large_insn
19784    && peep2_regno_dead_p (0, FLAGS_REG)"
19785   [(parallel [(set (match_dup 1) (const_int 0))
19786               (clobber (reg:CC FLAGS_REG))])
19787    (set (match_dup 0) (match_dup 1))]
19788   "")
19789
19790 (define_peephole2
19791   [(match_scratch:HI 1 "r")
19792    (set (match_operand:HI 0 "memory_operand" "")
19793         (const_int 0))]
19794   "! optimize_size
19795    && ! TARGET_USE_MOV0
19796    && TARGET_SPLIT_LONG_MOVES
19797    && get_attr_length (insn) >= ix86_cost->large_insn
19798    && peep2_regno_dead_p (0, FLAGS_REG)"
19799   [(parallel [(set (match_dup 2) (const_int 0))
19800               (clobber (reg:CC FLAGS_REG))])
19801    (set (match_dup 0) (match_dup 1))]
19802   "operands[2] = gen_lowpart (SImode, operands[1]);")
19803
19804 (define_peephole2
19805   [(match_scratch:QI 1 "q")
19806    (set (match_operand:QI 0 "memory_operand" "")
19807         (const_int 0))]
19808   "! optimize_size
19809    && ! TARGET_USE_MOV0
19810    && TARGET_SPLIT_LONG_MOVES
19811    && get_attr_length (insn) >= ix86_cost->large_insn
19812    && peep2_regno_dead_p (0, FLAGS_REG)"
19813   [(parallel [(set (match_dup 2) (const_int 0))
19814               (clobber (reg:CC FLAGS_REG))])
19815    (set (match_dup 0) (match_dup 1))]
19816   "operands[2] = gen_lowpart (SImode, operands[1]);")
19817
19818 (define_peephole2
19819   [(match_scratch:SI 2 "r")
19820    (set (match_operand:SI 0 "memory_operand" "")
19821         (match_operand:SI 1 "immediate_operand" ""))]
19822   "! optimize_size
19823    && get_attr_length (insn) >= ix86_cost->large_insn
19824    && TARGET_SPLIT_LONG_MOVES"
19825   [(set (match_dup 2) (match_dup 1))
19826    (set (match_dup 0) (match_dup 2))]
19827   "")
19828
19829 (define_peephole2
19830   [(match_scratch:HI 2 "r")
19831    (set (match_operand:HI 0 "memory_operand" "")
19832         (match_operand:HI 1 "immediate_operand" ""))]
19833   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19834   && TARGET_SPLIT_LONG_MOVES"
19835   [(set (match_dup 2) (match_dup 1))
19836    (set (match_dup 0) (match_dup 2))]
19837   "")
19838
19839 (define_peephole2
19840   [(match_scratch:QI 2 "q")
19841    (set (match_operand:QI 0 "memory_operand" "")
19842         (match_operand:QI 1 "immediate_operand" ""))]
19843   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19844   && TARGET_SPLIT_LONG_MOVES"
19845   [(set (match_dup 2) (match_dup 1))
19846    (set (match_dup 0) (match_dup 2))]
19847   "")
19848
19849 ;; Don't compare memory with zero, load and use a test instead.
19850 (define_peephole2
19851   [(set (match_operand 0 "flags_reg_operand" "")
19852         (match_operator 1 "compare_operator"
19853           [(match_operand:SI 2 "memory_operand" "")
19854            (const_int 0)]))
19855    (match_scratch:SI 3 "r")]
19856   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19857   [(set (match_dup 3) (match_dup 2))
19858    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19859   "")
19860
19861 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19862 ;; Don't split NOTs with a displacement operand, because resulting XOR
19863 ;; will not be pairable anyway.
19864 ;;
19865 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19866 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19867 ;; so this split helps here as well.
19868 ;;
19869 ;; Note: Can't do this as a regular split because we can't get proper
19870 ;; lifetime information then.
19871
19872 (define_peephole2
19873   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19874         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19875   "!optimize_size
19876    && peep2_regno_dead_p (0, FLAGS_REG)
19877    && ((TARGET_PENTIUM
19878         && (GET_CODE (operands[0]) != MEM
19879             || !memory_displacement_operand (operands[0], SImode)))
19880        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19881   [(parallel [(set (match_dup 0)
19882                    (xor:SI (match_dup 1) (const_int -1)))
19883               (clobber (reg:CC FLAGS_REG))])]
19884   "")
19885
19886 (define_peephole2
19887   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19888         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19889   "!optimize_size
19890    && peep2_regno_dead_p (0, FLAGS_REG)
19891    && ((TARGET_PENTIUM
19892         && (GET_CODE (operands[0]) != MEM
19893             || !memory_displacement_operand (operands[0], HImode)))
19894        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19895   [(parallel [(set (match_dup 0)
19896                    (xor:HI (match_dup 1) (const_int -1)))
19897               (clobber (reg:CC FLAGS_REG))])]
19898   "")
19899
19900 (define_peephole2
19901   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19902         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19903   "!optimize_size
19904    && peep2_regno_dead_p (0, FLAGS_REG)
19905    && ((TARGET_PENTIUM
19906         && (GET_CODE (operands[0]) != MEM
19907             || !memory_displacement_operand (operands[0], QImode)))
19908        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19909   [(parallel [(set (match_dup 0)
19910                    (xor:QI (match_dup 1) (const_int -1)))
19911               (clobber (reg:CC FLAGS_REG))])]
19912   "")
19913
19914 ;; Non pairable "test imm, reg" instructions can be translated to
19915 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19916 ;; byte opcode instead of two, have a short form for byte operands),
19917 ;; so do it for other CPUs as well.  Given that the value was dead,
19918 ;; this should not create any new dependencies.  Pass on the sub-word
19919 ;; versions if we're concerned about partial register stalls.
19920
19921 (define_peephole2
19922   [(set (match_operand 0 "flags_reg_operand" "")
19923         (match_operator 1 "compare_operator"
19924           [(and:SI (match_operand:SI 2 "register_operand" "")
19925                    (match_operand:SI 3 "immediate_operand" ""))
19926            (const_int 0)]))]
19927   "ix86_match_ccmode (insn, CCNOmode)
19928    && (true_regnum (operands[2]) != 0
19929        || satisfies_constraint_K (operands[3]))
19930    && peep2_reg_dead_p (1, operands[2])"
19931   [(parallel
19932      [(set (match_dup 0)
19933            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19934                             (const_int 0)]))
19935       (set (match_dup 2)
19936            (and:SI (match_dup 2) (match_dup 3)))])]
19937   "")
19938
19939 ;; We don't need to handle HImode case, because it will be promoted to SImode
19940 ;; on ! TARGET_PARTIAL_REG_STALL
19941
19942 (define_peephole2
19943   [(set (match_operand 0 "flags_reg_operand" "")
19944         (match_operator 1 "compare_operator"
19945           [(and:QI (match_operand:QI 2 "register_operand" "")
19946                    (match_operand:QI 3 "immediate_operand" ""))
19947            (const_int 0)]))]
19948   "! TARGET_PARTIAL_REG_STALL
19949    && ix86_match_ccmode (insn, CCNOmode)
19950    && true_regnum (operands[2]) != 0
19951    && peep2_reg_dead_p (1, operands[2])"
19952   [(parallel
19953      [(set (match_dup 0)
19954            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19955                             (const_int 0)]))
19956       (set (match_dup 2)
19957            (and:QI (match_dup 2) (match_dup 3)))])]
19958   "")
19959
19960 (define_peephole2
19961   [(set (match_operand 0 "flags_reg_operand" "")
19962         (match_operator 1 "compare_operator"
19963           [(and:SI
19964              (zero_extract:SI
19965                (match_operand 2 "ext_register_operand" "")
19966                (const_int 8)
19967                (const_int 8))
19968              (match_operand 3 "const_int_operand" ""))
19969            (const_int 0)]))]
19970   "! TARGET_PARTIAL_REG_STALL
19971    && ix86_match_ccmode (insn, CCNOmode)
19972    && true_regnum (operands[2]) != 0
19973    && peep2_reg_dead_p (1, operands[2])"
19974   [(parallel [(set (match_dup 0)
19975                    (match_op_dup 1
19976                      [(and:SI
19977                         (zero_extract:SI
19978                           (match_dup 2)
19979                           (const_int 8)
19980                           (const_int 8))
19981                         (match_dup 3))
19982                       (const_int 0)]))
19983               (set (zero_extract:SI (match_dup 2)
19984                                     (const_int 8)
19985                                     (const_int 8))
19986                    (and:SI
19987                      (zero_extract:SI
19988                        (match_dup 2)
19989                        (const_int 8)
19990                        (const_int 8))
19991                      (match_dup 3)))])]
19992   "")
19993
19994 ;; Don't do logical operations with memory inputs.
19995 (define_peephole2
19996   [(match_scratch:SI 2 "r")
19997    (parallel [(set (match_operand:SI 0 "register_operand" "")
19998                    (match_operator:SI 3 "arith_or_logical_operator"
19999                      [(match_dup 0)
20000                       (match_operand:SI 1 "memory_operand" "")]))
20001               (clobber (reg:CC FLAGS_REG))])]
20002   "! optimize_size && ! TARGET_READ_MODIFY"
20003   [(set (match_dup 2) (match_dup 1))
20004    (parallel [(set (match_dup 0)
20005                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20006               (clobber (reg:CC FLAGS_REG))])]
20007   "")
20008
20009 (define_peephole2
20010   [(match_scratch:SI 2 "r")
20011    (parallel [(set (match_operand:SI 0 "register_operand" "")
20012                    (match_operator:SI 3 "arith_or_logical_operator"
20013                      [(match_operand:SI 1 "memory_operand" "")
20014                       (match_dup 0)]))
20015               (clobber (reg:CC FLAGS_REG))])]
20016   "! optimize_size && ! TARGET_READ_MODIFY"
20017   [(set (match_dup 2) (match_dup 1))
20018    (parallel [(set (match_dup 0)
20019                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20020               (clobber (reg:CC FLAGS_REG))])]
20021   "")
20022
20023 ; Don't do logical operations with memory outputs
20024 ;
20025 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20026 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20027 ; the same decoder scheduling characteristics as the original.
20028
20029 (define_peephole2
20030   [(match_scratch:SI 2 "r")
20031    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20032                    (match_operator:SI 3 "arith_or_logical_operator"
20033                      [(match_dup 0)
20034                       (match_operand:SI 1 "nonmemory_operand" "")]))
20035               (clobber (reg:CC FLAGS_REG))])]
20036   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20037   [(set (match_dup 2) (match_dup 0))
20038    (parallel [(set (match_dup 2)
20039                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20040               (clobber (reg:CC FLAGS_REG))])
20041    (set (match_dup 0) (match_dup 2))]
20042   "")
20043
20044 (define_peephole2
20045   [(match_scratch:SI 2 "r")
20046    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20047                    (match_operator:SI 3 "arith_or_logical_operator"
20048                      [(match_operand:SI 1 "nonmemory_operand" "")
20049                       (match_dup 0)]))
20050               (clobber (reg:CC FLAGS_REG))])]
20051   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20052   [(set (match_dup 2) (match_dup 0))
20053    (parallel [(set (match_dup 2)
20054                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20055               (clobber (reg:CC FLAGS_REG))])
20056    (set (match_dup 0) (match_dup 2))]
20057   "")
20058
20059 ;; Attempt to always use XOR for zeroing registers.
20060 (define_peephole2
20061   [(set (match_operand 0 "register_operand" "")
20062         (match_operand 1 "const0_operand" ""))]
20063   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20064    && (! TARGET_USE_MOV0 || optimize_size)
20065    && GENERAL_REG_P (operands[0])
20066    && peep2_regno_dead_p (0, FLAGS_REG)"
20067   [(parallel [(set (match_dup 0) (const_int 0))
20068               (clobber (reg:CC FLAGS_REG))])]
20069 {
20070   operands[0] = gen_lowpart (word_mode, operands[0]);
20071 })
20072
20073 (define_peephole2
20074   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20075         (const_int 0))]
20076   "(GET_MODE (operands[0]) == QImode
20077     || GET_MODE (operands[0]) == HImode)
20078    && (! TARGET_USE_MOV0 || optimize_size)
20079    && peep2_regno_dead_p (0, FLAGS_REG)"
20080   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20081               (clobber (reg:CC FLAGS_REG))])])
20082
20083 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20084 (define_peephole2
20085   [(set (match_operand 0 "register_operand" "")
20086         (const_int -1))]
20087   "(GET_MODE (operands[0]) == HImode
20088     || GET_MODE (operands[0]) == SImode
20089     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20090    && (optimize_size || TARGET_PENTIUM)
20091    && peep2_regno_dead_p (0, FLAGS_REG)"
20092   [(parallel [(set (match_dup 0) (const_int -1))
20093               (clobber (reg:CC FLAGS_REG))])]
20094   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20095                               operands[0]);")
20096
20097 ;; Attempt to convert simple leas to adds. These can be created by
20098 ;; move expanders.
20099 (define_peephole2
20100   [(set (match_operand:SI 0 "register_operand" "")
20101         (plus:SI (match_dup 0)
20102                  (match_operand:SI 1 "nonmemory_operand" "")))]
20103   "peep2_regno_dead_p (0, FLAGS_REG)"
20104   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20105               (clobber (reg:CC FLAGS_REG))])]
20106   "")
20107
20108 (define_peephole2
20109   [(set (match_operand:SI 0 "register_operand" "")
20110         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20111                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20112   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20113   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20114               (clobber (reg:CC FLAGS_REG))])]
20115   "operands[2] = gen_lowpart (SImode, operands[2]);")
20116
20117 (define_peephole2
20118   [(set (match_operand:DI 0 "register_operand" "")
20119         (plus:DI (match_dup 0)
20120                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20121   "peep2_regno_dead_p (0, FLAGS_REG)"
20122   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20123               (clobber (reg:CC FLAGS_REG))])]
20124   "")
20125
20126 (define_peephole2
20127   [(set (match_operand:SI 0 "register_operand" "")
20128         (mult:SI (match_dup 0)
20129                  (match_operand:SI 1 "const_int_operand" "")))]
20130   "exact_log2 (INTVAL (operands[1])) >= 0
20131    && peep2_regno_dead_p (0, FLAGS_REG)"
20132   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20133               (clobber (reg:CC FLAGS_REG))])]
20134   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20135
20136 (define_peephole2
20137   [(set (match_operand:DI 0 "register_operand" "")
20138         (mult:DI (match_dup 0)
20139                  (match_operand:DI 1 "const_int_operand" "")))]
20140   "exact_log2 (INTVAL (operands[1])) >= 0
20141    && peep2_regno_dead_p (0, FLAGS_REG)"
20142   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20143               (clobber (reg:CC FLAGS_REG))])]
20144   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20145
20146 (define_peephole2
20147   [(set (match_operand:SI 0 "register_operand" "")
20148         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20149                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20150   "exact_log2 (INTVAL (operands[2])) >= 0
20151    && REGNO (operands[0]) == REGNO (operands[1])
20152    && peep2_regno_dead_p (0, FLAGS_REG)"
20153   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20154               (clobber (reg:CC FLAGS_REG))])]
20155   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20156
20157 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20158 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20159 ;; many CPUs it is also faster, since special hardware to avoid esp
20160 ;; dependencies is present.
20161
20162 ;; While some of these conversions may be done using splitters, we use peepholes
20163 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20164
20165 ;; Convert prologue esp subtractions to push.
20166 ;; We need register to push.  In order to keep verify_flow_info happy we have
20167 ;; two choices
20168 ;; - use scratch and clobber it in order to avoid dependencies
20169 ;; - use already live register
20170 ;; We can't use the second way right now, since there is no reliable way how to
20171 ;; verify that given register is live.  First choice will also most likely in
20172 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20173 ;; call clobbered registers are dead.  We may want to use base pointer as an
20174 ;; alternative when no register is available later.
20175
20176 (define_peephole2
20177   [(match_scratch:SI 0 "r")
20178    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20179               (clobber (reg:CC FLAGS_REG))
20180               (clobber (mem:BLK (scratch)))])]
20181   "optimize_size || !TARGET_SUB_ESP_4"
20182   [(clobber (match_dup 0))
20183    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20184               (clobber (mem:BLK (scratch)))])])
20185
20186 (define_peephole2
20187   [(match_scratch:SI 0 "r")
20188    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20189               (clobber (reg:CC FLAGS_REG))
20190               (clobber (mem:BLK (scratch)))])]
20191   "optimize_size || !TARGET_SUB_ESP_8"
20192   [(clobber (match_dup 0))
20193    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20194    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20195               (clobber (mem:BLK (scratch)))])])
20196
20197 ;; Convert esp subtractions to push.
20198 (define_peephole2
20199   [(match_scratch:SI 0 "r")
20200    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20201               (clobber (reg:CC FLAGS_REG))])]
20202   "optimize_size || !TARGET_SUB_ESP_4"
20203   [(clobber (match_dup 0))
20204    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20205
20206 (define_peephole2
20207   [(match_scratch:SI 0 "r")
20208    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20209               (clobber (reg:CC FLAGS_REG))])]
20210   "optimize_size || !TARGET_SUB_ESP_8"
20211   [(clobber (match_dup 0))
20212    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20213    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20214
20215 ;; Convert epilogue deallocator to pop.
20216 (define_peephole2
20217   [(match_scratch:SI 0 "r")
20218    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20219               (clobber (reg:CC FLAGS_REG))
20220               (clobber (mem:BLK (scratch)))])]
20221   "optimize_size || !TARGET_ADD_ESP_4"
20222   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20223               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20224               (clobber (mem:BLK (scratch)))])]
20225   "")
20226
20227 ;; Two pops case is tricky, since pop causes dependency on destination register.
20228 ;; We use two registers if available.
20229 (define_peephole2
20230   [(match_scratch:SI 0 "r")
20231    (match_scratch:SI 1 "r")
20232    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20233               (clobber (reg:CC FLAGS_REG))
20234               (clobber (mem:BLK (scratch)))])]
20235   "optimize_size || !TARGET_ADD_ESP_8"
20236   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20237               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20238               (clobber (mem:BLK (scratch)))])
20239    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20240               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20241   "")
20242
20243 (define_peephole2
20244   [(match_scratch:SI 0 "r")
20245    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20246               (clobber (reg:CC FLAGS_REG))
20247               (clobber (mem:BLK (scratch)))])]
20248   "optimize_size"
20249   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20250               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20251               (clobber (mem:BLK (scratch)))])
20252    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20253               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20254   "")
20255
20256 ;; Convert esp additions to pop.
20257 (define_peephole2
20258   [(match_scratch:SI 0 "r")
20259    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20260               (clobber (reg:CC FLAGS_REG))])]
20261   ""
20262   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20263               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20264   "")
20265
20266 ;; Two pops case is tricky, since pop causes dependency on destination register.
20267 ;; We use two registers if available.
20268 (define_peephole2
20269   [(match_scratch:SI 0 "r")
20270    (match_scratch:SI 1 "r")
20271    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20272               (clobber (reg:CC FLAGS_REG))])]
20273   ""
20274   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20275               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20276    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20277               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20278   "")
20279
20280 (define_peephole2
20281   [(match_scratch:SI 0 "r")
20282    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20283               (clobber (reg:CC FLAGS_REG))])]
20284   "optimize_size"
20285   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20286               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20287    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20288               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20289   "")
20290 \f
20291 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20292 ;; required and register dies.  Similarly for 128 to plus -128.
20293 (define_peephole2
20294   [(set (match_operand 0 "flags_reg_operand" "")
20295         (match_operator 1 "compare_operator"
20296           [(match_operand 2 "register_operand" "")
20297            (match_operand 3 "const_int_operand" "")]))]
20298   "(INTVAL (operands[3]) == -1
20299     || INTVAL (operands[3]) == 1
20300     || INTVAL (operands[3]) == 128)
20301    && ix86_match_ccmode (insn, CCGCmode)
20302    && peep2_reg_dead_p (1, operands[2])"
20303   [(parallel [(set (match_dup 0)
20304                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20305               (clobber (match_dup 2))])]
20306   "")
20307 \f
20308 (define_peephole2
20309   [(match_scratch:DI 0 "r")
20310    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20311               (clobber (reg:CC FLAGS_REG))
20312               (clobber (mem:BLK (scratch)))])]
20313   "optimize_size || !TARGET_SUB_ESP_4"
20314   [(clobber (match_dup 0))
20315    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20316               (clobber (mem:BLK (scratch)))])])
20317
20318 (define_peephole2
20319   [(match_scratch:DI 0 "r")
20320    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20321               (clobber (reg:CC FLAGS_REG))
20322               (clobber (mem:BLK (scratch)))])]
20323   "optimize_size || !TARGET_SUB_ESP_8"
20324   [(clobber (match_dup 0))
20325    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20326    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20327               (clobber (mem:BLK (scratch)))])])
20328
20329 ;; Convert esp subtractions to push.
20330 (define_peephole2
20331   [(match_scratch:DI 0 "r")
20332    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20333               (clobber (reg:CC FLAGS_REG))])]
20334   "optimize_size || !TARGET_SUB_ESP_4"
20335   [(clobber (match_dup 0))
20336    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20337
20338 (define_peephole2
20339   [(match_scratch:DI 0 "r")
20340    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20341               (clobber (reg:CC FLAGS_REG))])]
20342   "optimize_size || !TARGET_SUB_ESP_8"
20343   [(clobber (match_dup 0))
20344    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20345    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20346
20347 ;; Convert epilogue deallocator to pop.
20348 (define_peephole2
20349   [(match_scratch:DI 0 "r")
20350    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20351               (clobber (reg:CC FLAGS_REG))
20352               (clobber (mem:BLK (scratch)))])]
20353   "optimize_size || !TARGET_ADD_ESP_4"
20354   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20355               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20356               (clobber (mem:BLK (scratch)))])]
20357   "")
20358
20359 ;; Two pops case is tricky, since pop causes dependency on destination register.
20360 ;; We use two registers if available.
20361 (define_peephole2
20362   [(match_scratch:DI 0 "r")
20363    (match_scratch:DI 1 "r")
20364    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20365               (clobber (reg:CC FLAGS_REG))
20366               (clobber (mem:BLK (scratch)))])]
20367   "optimize_size || !TARGET_ADD_ESP_8"
20368   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20369               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20370               (clobber (mem:BLK (scratch)))])
20371    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20372               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20373   "")
20374
20375 (define_peephole2
20376   [(match_scratch:DI 0 "r")
20377    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20378               (clobber (reg:CC FLAGS_REG))
20379               (clobber (mem:BLK (scratch)))])]
20380   "optimize_size"
20381   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20382               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20383               (clobber (mem:BLK (scratch)))])
20384    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20385               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20386   "")
20387
20388 ;; Convert esp additions to pop.
20389 (define_peephole2
20390   [(match_scratch:DI 0 "r")
20391    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20392               (clobber (reg:CC FLAGS_REG))])]
20393   ""
20394   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20395               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20396   "")
20397
20398 ;; Two pops case is tricky, since pop causes dependency on destination register.
20399 ;; We use two registers if available.
20400 (define_peephole2
20401   [(match_scratch:DI 0 "r")
20402    (match_scratch:DI 1 "r")
20403    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20404               (clobber (reg:CC FLAGS_REG))])]
20405   ""
20406   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20407               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20408    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20409               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20410   "")
20411
20412 (define_peephole2
20413   [(match_scratch:DI 0 "r")
20414    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20415               (clobber (reg:CC FLAGS_REG))])]
20416   "optimize_size"
20417   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20418               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20419    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20420               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20421   "")
20422 \f
20423 ;; Convert imul by three, five and nine into lea
20424 (define_peephole2
20425   [(parallel
20426     [(set (match_operand:SI 0 "register_operand" "")
20427           (mult:SI (match_operand:SI 1 "register_operand" "")
20428                    (match_operand:SI 2 "const_int_operand" "")))
20429      (clobber (reg:CC FLAGS_REG))])]
20430   "INTVAL (operands[2]) == 3
20431    || INTVAL (operands[2]) == 5
20432    || INTVAL (operands[2]) == 9"
20433   [(set (match_dup 0)
20434         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20435                  (match_dup 1)))]
20436   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20437
20438 (define_peephole2
20439   [(parallel
20440     [(set (match_operand:SI 0 "register_operand" "")
20441           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20442                    (match_operand:SI 2 "const_int_operand" "")))
20443      (clobber (reg:CC FLAGS_REG))])]
20444   "!optimize_size
20445    && (INTVAL (operands[2]) == 3
20446        || INTVAL (operands[2]) == 5
20447        || INTVAL (operands[2]) == 9)"
20448   [(set (match_dup 0) (match_dup 1))
20449    (set (match_dup 0)
20450         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20451                  (match_dup 0)))]
20452   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20453
20454 (define_peephole2
20455   [(parallel
20456     [(set (match_operand:DI 0 "register_operand" "")
20457           (mult:DI (match_operand:DI 1 "register_operand" "")
20458                    (match_operand:DI 2 "const_int_operand" "")))
20459      (clobber (reg:CC FLAGS_REG))])]
20460   "TARGET_64BIT
20461    && (INTVAL (operands[2]) == 3
20462        || INTVAL (operands[2]) == 5
20463        || INTVAL (operands[2]) == 9)"
20464   [(set (match_dup 0)
20465         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20466                  (match_dup 1)))]
20467   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20468
20469 (define_peephole2
20470   [(parallel
20471     [(set (match_operand:DI 0 "register_operand" "")
20472           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20473                    (match_operand:DI 2 "const_int_operand" "")))
20474      (clobber (reg:CC FLAGS_REG))])]
20475   "TARGET_64BIT
20476    && !optimize_size
20477    && (INTVAL (operands[2]) == 3
20478        || INTVAL (operands[2]) == 5
20479        || INTVAL (operands[2]) == 9)"
20480   [(set (match_dup 0) (match_dup 1))
20481    (set (match_dup 0)
20482         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20483                  (match_dup 0)))]
20484   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20485
20486 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20487 ;; imul $32bit_imm, reg, reg is direct decoded.
20488 (define_peephole2
20489   [(match_scratch:DI 3 "r")
20490    (parallel [(set (match_operand:DI 0 "register_operand" "")
20491                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20492                             (match_operand:DI 2 "immediate_operand" "")))
20493               (clobber (reg:CC FLAGS_REG))])]
20494   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20495    && !satisfies_constraint_K (operands[2])"
20496   [(set (match_dup 3) (match_dup 1))
20497    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20498               (clobber (reg:CC FLAGS_REG))])]
20499 "")
20500
20501 (define_peephole2
20502   [(match_scratch:SI 3 "r")
20503    (parallel [(set (match_operand:SI 0 "register_operand" "")
20504                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20505                             (match_operand:SI 2 "immediate_operand" "")))
20506               (clobber (reg:CC FLAGS_REG))])]
20507   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20508    && !satisfies_constraint_K (operands[2])"
20509   [(set (match_dup 3) (match_dup 1))
20510    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20511               (clobber (reg:CC FLAGS_REG))])]
20512 "")
20513
20514 (define_peephole2
20515   [(match_scratch:SI 3 "r")
20516    (parallel [(set (match_operand:DI 0 "register_operand" "")
20517                    (zero_extend:DI
20518                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20519                               (match_operand:SI 2 "immediate_operand" ""))))
20520               (clobber (reg:CC FLAGS_REG))])]
20521   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20522    && !satisfies_constraint_K (operands[2])"
20523   [(set (match_dup 3) (match_dup 1))
20524    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20525               (clobber (reg:CC FLAGS_REG))])]
20526 "")
20527
20528 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20529 ;; Convert it into imul reg, reg
20530 ;; It would be better to force assembler to encode instruction using long
20531 ;; immediate, but there is apparently no way to do so.
20532 (define_peephole2
20533   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20534                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20535                             (match_operand:DI 2 "const_int_operand" "")))
20536               (clobber (reg:CC FLAGS_REG))])
20537    (match_scratch:DI 3 "r")]
20538   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20539    && satisfies_constraint_K (operands[2])"
20540   [(set (match_dup 3) (match_dup 2))
20541    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20542               (clobber (reg:CC FLAGS_REG))])]
20543 {
20544   if (!rtx_equal_p (operands[0], operands[1]))
20545     emit_move_insn (operands[0], operands[1]);
20546 })
20547
20548 (define_peephole2
20549   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20550                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20551                             (match_operand:SI 2 "const_int_operand" "")))
20552               (clobber (reg:CC FLAGS_REG))])
20553    (match_scratch:SI 3 "r")]
20554   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20555    && satisfies_constraint_K (operands[2])"
20556   [(set (match_dup 3) (match_dup 2))
20557    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20558               (clobber (reg:CC FLAGS_REG))])]
20559 {
20560   if (!rtx_equal_p (operands[0], operands[1]))
20561     emit_move_insn (operands[0], operands[1]);
20562 })
20563
20564 (define_peephole2
20565   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20566                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20567                             (match_operand:HI 2 "immediate_operand" "")))
20568               (clobber (reg:CC FLAGS_REG))])
20569    (match_scratch:HI 3 "r")]
20570   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20571   [(set (match_dup 3) (match_dup 2))
20572    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20573               (clobber (reg:CC FLAGS_REG))])]
20574 {
20575   if (!rtx_equal_p (operands[0], operands[1]))
20576     emit_move_insn (operands[0], operands[1]);
20577 })
20578
20579 ;; After splitting up read-modify operations, array accesses with memory
20580 ;; operands might end up in form:
20581 ;;  sall    $2, %eax
20582 ;;  movl    4(%esp), %edx
20583 ;;  addl    %edx, %eax
20584 ;; instead of pre-splitting:
20585 ;;  sall    $2, %eax
20586 ;;  addl    4(%esp), %eax
20587 ;; Turn it into:
20588 ;;  movl    4(%esp), %edx
20589 ;;  leal    (%edx,%eax,4), %eax
20590
20591 (define_peephole2
20592   [(parallel [(set (match_operand 0 "register_operand" "")
20593                    (ashift (match_operand 1 "register_operand" "")
20594                            (match_operand 2 "const_int_operand" "")))
20595                (clobber (reg:CC FLAGS_REG))])
20596    (set (match_operand 3 "register_operand")
20597         (match_operand 4 "x86_64_general_operand" ""))
20598    (parallel [(set (match_operand 5 "register_operand" "")
20599                    (plus (match_operand 6 "register_operand" "")
20600                          (match_operand 7 "register_operand" "")))
20601                    (clobber (reg:CC FLAGS_REG))])]
20602   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20603    /* Validate MODE for lea.  */
20604    && ((!TARGET_PARTIAL_REG_STALL
20605         && (GET_MODE (operands[0]) == QImode
20606             || GET_MODE (operands[0]) == HImode))
20607        || GET_MODE (operands[0]) == SImode
20608        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20609    /* We reorder load and the shift.  */
20610    && !rtx_equal_p (operands[1], operands[3])
20611    && !reg_overlap_mentioned_p (operands[0], operands[4])
20612    /* Last PLUS must consist of operand 0 and 3.  */
20613    && !rtx_equal_p (operands[0], operands[3])
20614    && (rtx_equal_p (operands[3], operands[6])
20615        || rtx_equal_p (operands[3], operands[7]))
20616    && (rtx_equal_p (operands[0], operands[6])
20617        || rtx_equal_p (operands[0], operands[7]))
20618    /* The intermediate operand 0 must die or be same as output.  */
20619    && (rtx_equal_p (operands[0], operands[5])
20620        || peep2_reg_dead_p (3, operands[0]))"
20621   [(set (match_dup 3) (match_dup 4))
20622    (set (match_dup 0) (match_dup 1))]
20623 {
20624   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20625   int scale = 1 << INTVAL (operands[2]);
20626   rtx index = gen_lowpart (Pmode, operands[1]);
20627   rtx base = gen_lowpart (Pmode, operands[3]);
20628   rtx dest = gen_lowpart (mode, operands[5]);
20629
20630   operands[1] = gen_rtx_PLUS (Pmode, base,
20631                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20632   if (mode != Pmode)
20633     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20634   operands[0] = dest;
20635 })
20636 \f
20637 ;; Call-value patterns last so that the wildcard operand does not
20638 ;; disrupt insn-recog's switch tables.
20639
20640 (define_insn "*call_value_pop_0"
20641   [(set (match_operand 0 "" "")
20642         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20643               (match_operand:SI 2 "" "")))
20644    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20645                             (match_operand:SI 3 "immediate_operand" "")))]
20646   "!TARGET_64BIT"
20647 {
20648   if (SIBLING_CALL_P (insn))
20649     return "jmp\t%P1";
20650   else
20651     return "call\t%P1";
20652 }
20653   [(set_attr "type" "callv")])
20654
20655 (define_insn "*call_value_pop_1"
20656   [(set (match_operand 0 "" "")
20657         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20658               (match_operand:SI 2 "" "")))
20659    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20660                             (match_operand:SI 3 "immediate_operand" "i")))]
20661   "!TARGET_64BIT"
20662 {
20663   if (constant_call_address_operand (operands[1], Pmode))
20664     {
20665       if (SIBLING_CALL_P (insn))
20666         return "jmp\t%P1";
20667       else
20668         return "call\t%P1";
20669     }
20670   if (SIBLING_CALL_P (insn))
20671     return "jmp\t%A1";
20672   else
20673     return "call\t%A1";
20674 }
20675   [(set_attr "type" "callv")])
20676
20677 (define_insn "*call_value_0"
20678   [(set (match_operand 0 "" "")
20679         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20680               (match_operand:SI 2 "" "")))]
20681   "!TARGET_64BIT"
20682 {
20683   if (SIBLING_CALL_P (insn))
20684     return "jmp\t%P1";
20685   else
20686     return "call\t%P1";
20687 }
20688   [(set_attr "type" "callv")])
20689
20690 (define_insn "*call_value_0_rex64"
20691   [(set (match_operand 0 "" "")
20692         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20693               (match_operand:DI 2 "const_int_operand" "")))]
20694   "TARGET_64BIT"
20695 {
20696   if (SIBLING_CALL_P (insn))
20697     return "jmp\t%P1";
20698   else
20699     return "call\t%P1";
20700 }
20701   [(set_attr "type" "callv")])
20702
20703 (define_insn "*call_value_1"
20704   [(set (match_operand 0 "" "")
20705         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20706               (match_operand:SI 2 "" "")))]
20707   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20708 {
20709   if (constant_call_address_operand (operands[1], Pmode))
20710     return "call\t%P1";
20711   return "call\t%A1";
20712 }
20713   [(set_attr "type" "callv")])
20714
20715 (define_insn "*sibcall_value_1"
20716   [(set (match_operand 0 "" "")
20717         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20718               (match_operand:SI 2 "" "")))]
20719   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20720 {
20721   if (constant_call_address_operand (operands[1], Pmode))
20722     return "jmp\t%P1";
20723   return "jmp\t%A1";
20724 }
20725   [(set_attr "type" "callv")])
20726
20727 (define_insn "*call_value_1_rex64"
20728   [(set (match_operand 0 "" "")
20729         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20730               (match_operand:DI 2 "" "")))]
20731   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20732 {
20733   if (constant_call_address_operand (operands[1], Pmode))
20734     return "call\t%P1";
20735   return "call\t%A1";
20736 }
20737   [(set_attr "type" "callv")])
20738
20739 (define_insn "*sibcall_value_1_rex64"
20740   [(set (match_operand 0 "" "")
20741         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20742               (match_operand:DI 2 "" "")))]
20743   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20744   "jmp\t%P1"
20745   [(set_attr "type" "callv")])
20746
20747 (define_insn "*sibcall_value_1_rex64_v"
20748   [(set (match_operand 0 "" "")
20749         (call (mem:QI (reg:DI R11_REG))
20750               (match_operand:DI 1 "" "")))]
20751   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20752   "jmp\t*%%r11"
20753   [(set_attr "type" "callv")])
20754 \f
20755 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20756 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20757 ;; caught for use by garbage collectors and the like.  Using an insn that
20758 ;; maps to SIGILL makes it more likely the program will rightfully die.
20759 ;; Keeping with tradition, "6" is in honor of #UD.
20760 (define_insn "trap"
20761   [(trap_if (const_int 1) (const_int 6))]
20762   ""
20763   { return ASM_SHORT "0x0b0f"; }
20764   [(set_attr "length" "2")])
20765
20766 (define_expand "sse_prologue_save"
20767   [(parallel [(set (match_operand:BLK 0 "" "")
20768                    (unspec:BLK [(reg:DI 21)
20769                                 (reg:DI 22)
20770                                 (reg:DI 23)
20771                                 (reg:DI 24)
20772                                 (reg:DI 25)
20773                                 (reg:DI 26)
20774                                 (reg:DI 27)
20775                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20776               (use (match_operand:DI 1 "register_operand" ""))
20777               (use (match_operand:DI 2 "immediate_operand" ""))
20778               (use (label_ref:DI (match_operand 3 "" "")))])]
20779   "TARGET_64BIT"
20780   "")
20781
20782 (define_insn "*sse_prologue_save_insn"
20783   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20784                           (match_operand:DI 4 "const_int_operand" "n")))
20785         (unspec:BLK [(reg:DI 21)
20786                      (reg:DI 22)
20787                      (reg:DI 23)
20788                      (reg:DI 24)
20789                      (reg:DI 25)
20790                      (reg:DI 26)
20791                      (reg:DI 27)
20792                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20793    (use (match_operand:DI 1 "register_operand" "r"))
20794    (use (match_operand:DI 2 "const_int_operand" "i"))
20795    (use (label_ref:DI (match_operand 3 "" "X")))]
20796   "TARGET_64BIT
20797    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20798    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20799   "*
20800 {
20801   int i;
20802   operands[0] = gen_rtx_MEM (Pmode,
20803                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20804   output_asm_insn (\"jmp\\t%A1\", operands);
20805   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20806     {
20807       operands[4] = adjust_address (operands[0], DImode, i*16);
20808       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20809       PUT_MODE (operands[4], TImode);
20810       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20811         output_asm_insn (\"rex\", operands);
20812       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20813     }
20814   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20815                              CODE_LABEL_NUMBER (operands[3]));
20816   return \"\";
20817 }
20818   "
20819   [(set_attr "type" "other")
20820    (set_attr "length_immediate" "0")
20821    (set_attr "length_address" "0")
20822    (set_attr "length" "135")
20823    (set_attr "memory" "store")
20824    (set_attr "modrm" "0")
20825    (set_attr "mode" "DI")])
20826
20827 (define_expand "prefetch"
20828   [(prefetch (match_operand 0 "address_operand" "")
20829              (match_operand:SI 1 "const_int_operand" "")
20830              (match_operand:SI 2 "const_int_operand" ""))]
20831   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20832 {
20833   int rw = INTVAL (operands[1]);
20834   int locality = INTVAL (operands[2]);
20835
20836   gcc_assert (rw == 0 || rw == 1);
20837   gcc_assert (locality >= 0 && locality <= 3);
20838   gcc_assert (GET_MODE (operands[0]) == Pmode
20839               || GET_MODE (operands[0]) == VOIDmode);
20840
20841   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20842      supported by SSE counterpart or the SSE prefetch is not available
20843      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20844      of locality.  */
20845   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20846     operands[2] = GEN_INT (3);
20847   else
20848     operands[1] = const0_rtx;
20849 })
20850
20851 (define_insn "*prefetch_sse"
20852   [(prefetch (match_operand:SI 0 "address_operand" "p")
20853              (const_int 0)
20854              (match_operand:SI 1 "const_int_operand" ""))]
20855   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20856 {
20857   static const char * const patterns[4] = {
20858    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20859   };
20860
20861   int locality = INTVAL (operands[1]);
20862   gcc_assert (locality >= 0 && locality <= 3);
20863
20864   return patterns[locality];
20865 }
20866   [(set_attr "type" "sse")
20867    (set_attr "memory" "none")])
20868
20869 (define_insn "*prefetch_sse_rex"
20870   [(prefetch (match_operand:DI 0 "address_operand" "p")
20871              (const_int 0)
20872              (match_operand:SI 1 "const_int_operand" ""))]
20873   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20874 {
20875   static const char * const patterns[4] = {
20876    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20877   };
20878
20879   int locality = INTVAL (operands[1]);
20880   gcc_assert (locality >= 0 && locality <= 3);
20881
20882   return patterns[locality];
20883 }
20884   [(set_attr "type" "sse")
20885    (set_attr "memory" "none")])
20886
20887 (define_insn "*prefetch_3dnow"
20888   [(prefetch (match_operand:SI 0 "address_operand" "p")
20889              (match_operand:SI 1 "const_int_operand" "n")
20890              (const_int 3))]
20891   "TARGET_3DNOW && !TARGET_64BIT"
20892 {
20893   if (INTVAL (operands[1]) == 0)
20894     return "prefetch\t%a0";
20895   else
20896     return "prefetchw\t%a0";
20897 }
20898   [(set_attr "type" "mmx")
20899    (set_attr "memory" "none")])
20900
20901 (define_insn "*prefetch_3dnow_rex"
20902   [(prefetch (match_operand:DI 0 "address_operand" "p")
20903              (match_operand:SI 1 "const_int_operand" "n")
20904              (const_int 3))]
20905   "TARGET_3DNOW && TARGET_64BIT"
20906 {
20907   if (INTVAL (operands[1]) == 0)
20908     return "prefetch\t%a0";
20909   else
20910     return "prefetchw\t%a0";
20911 }
20912   [(set_attr "type" "mmx")
20913    (set_attr "memory" "none")])
20914
20915 (define_expand "stack_protect_set"
20916   [(match_operand 0 "memory_operand" "")
20917    (match_operand 1 "memory_operand" "")]
20918   ""
20919 {
20920 #ifdef TARGET_THREAD_SSP_OFFSET
20921   if (TARGET_64BIT)
20922     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20923                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20924   else
20925     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20926                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20927 #else
20928   if (TARGET_64BIT)
20929     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20930   else
20931     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20932 #endif
20933   DONE;
20934 })
20935
20936 (define_insn "stack_protect_set_si"
20937   [(set (match_operand:SI 0 "memory_operand" "=m")
20938         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20939    (set (match_scratch:SI 2 "=&r") (const_int 0))
20940    (clobber (reg:CC FLAGS_REG))]
20941   ""
20942   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20943   [(set_attr "type" "multi")])
20944
20945 (define_insn "stack_protect_set_di"
20946   [(set (match_operand:DI 0 "memory_operand" "=m")
20947         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20948    (set (match_scratch:DI 2 "=&r") (const_int 0))
20949    (clobber (reg:CC FLAGS_REG))]
20950   "TARGET_64BIT"
20951   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20952   [(set_attr "type" "multi")])
20953
20954 (define_insn "stack_tls_protect_set_si"
20955   [(set (match_operand:SI 0 "memory_operand" "=m")
20956         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20957    (set (match_scratch:SI 2 "=&r") (const_int 0))
20958    (clobber (reg:CC FLAGS_REG))]
20959   ""
20960   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20961   [(set_attr "type" "multi")])
20962
20963 (define_insn "stack_tls_protect_set_di"
20964   [(set (match_operand:DI 0 "memory_operand" "=m")
20965         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20966    (set (match_scratch:DI 2 "=&r") (const_int 0))
20967    (clobber (reg:CC FLAGS_REG))]
20968   "TARGET_64BIT"
20969   {
20970      /* The kernel uses a different segment register for performance reasons; a
20971         system call would not have to trash the userspace segment register,
20972         which would be expensive */
20973      if (ix86_cmodel != CM_KERNEL)
20974         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20975      else
20976         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20977   }
20978   [(set_attr "type" "multi")])
20979
20980 (define_expand "stack_protect_test"
20981   [(match_operand 0 "memory_operand" "")
20982    (match_operand 1 "memory_operand" "")
20983    (match_operand 2 "" "")]
20984   ""
20985 {
20986   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20987   ix86_compare_op0 = operands[0];
20988   ix86_compare_op1 = operands[1];
20989   ix86_compare_emitted = flags;
20990
20991 #ifdef TARGET_THREAD_SSP_OFFSET
20992   if (TARGET_64BIT)
20993     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20994                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20995   else
20996     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20997                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20998 #else
20999   if (TARGET_64BIT)
21000     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21001   else
21002     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21003 #endif
21004   emit_jump_insn (gen_beq (operands[2]));
21005   DONE;
21006 })
21007
21008 (define_insn "stack_protect_test_si"
21009   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21010         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21011                      (match_operand:SI 2 "memory_operand" "m")]
21012                     UNSPEC_SP_TEST))
21013    (clobber (match_scratch:SI 3 "=&r"))]
21014   ""
21015   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21016   [(set_attr "type" "multi")])
21017
21018 (define_insn "stack_protect_test_di"
21019   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21020         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21021                      (match_operand:DI 2 "memory_operand" "m")]
21022                     UNSPEC_SP_TEST))
21023    (clobber (match_scratch:DI 3 "=&r"))]
21024   "TARGET_64BIT"
21025   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21026   [(set_attr "type" "multi")])
21027
21028 (define_insn "stack_tls_protect_test_si"
21029   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21030         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21031                      (match_operand:SI 2 "const_int_operand" "i")]
21032                     UNSPEC_SP_TLS_TEST))
21033    (clobber (match_scratch:SI 3 "=r"))]
21034   ""
21035   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21036   [(set_attr "type" "multi")])
21037
21038 (define_insn "stack_tls_protect_test_di"
21039   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21040         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21041                      (match_operand:DI 2 "const_int_operand" "i")]
21042                     UNSPEC_SP_TLS_TEST))
21043    (clobber (match_scratch:DI 3 "=r"))]
21044   "TARGET_64BIT"
21045   {
21046      /* The kernel uses a different segment register for performance reasons; a
21047         system call would not have to trash the userspace segment register,
21048         which would be expensive */
21049      if (ix86_cmodel != CM_KERNEL)
21050         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21051      else
21052         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21053   }
21054   [(set_attr "type" "multi")])
21055
21056 (include "mmx.md")
21057 (include "sse.md")
21058 (include "sync.md")