OSDN Git Service

* config/i386/i386.md (*bswapdi2_rex): Renamed from bswapdi2.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
71
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76    (UNSPEC_TLSDESC              19)
77
78    ; Other random patterns
79    (UNSPEC_SCAS                 20)
80    (UNSPEC_FNSTSW               21)
81    (UNSPEC_SAHF                 22)
82    (UNSPEC_FSTCW                23)
83    (UNSPEC_ADD_CARRY            24)
84    (UNSPEC_FLDCW                25)
85    (UNSPEC_REP                  26)
86    (UNSPEC_EH_RETURN            27)
87    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
88    (UNSPEC_TRUNC_NOOP           29)
89
90    ; For SSE/MMX support:
91    (UNSPEC_FIX_NOTRUNC          30)
92    (UNSPEC_MASKMOV              31)
93    (UNSPEC_MOVMSK               32)
94    (UNSPEC_MOVNT                33)
95    (UNSPEC_MOVU                 34)
96    (UNSPEC_RCP                  35)
97    (UNSPEC_RSQRT                36)
98    (UNSPEC_SFENCE               37)
99    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
100    (UNSPEC_PFRCP                39)
101    (UNSPEC_PFRCPIT1             40)
102    (UNSPEC_PFRCPIT2             41)
103    (UNSPEC_PFRSQRT              42)
104    (UNSPEC_PFRSQIT1             43)
105    (UNSPEC_MFENCE               44)
106    (UNSPEC_LFENCE               45)
107    (UNSPEC_PSADBW               46)
108    (UNSPEC_LDDQU                47)
109
110    ; Generic math support
111    (UNSPEC_COPYSIGN             50)
112    (UNSPEC_IEEE_MIN             51)     ; not commutative
113    (UNSPEC_IEEE_MAX             52)     ; not commutative
114
115    ; x87 Floating point
116    (UNSPEC_SIN                  60)
117    (UNSPEC_COS                  61)
118    (UNSPEC_FPATAN               62)
119    (UNSPEC_FYL2X                63)
120    (UNSPEC_FYL2XP1              64)
121    (UNSPEC_FRNDINT              65)
122    (UNSPEC_FIST                 66)
123    (UNSPEC_F2XM1                67)
124    (UNSPEC_TAN                  68)
125    (UNSPEC_FXAM                 69)
126
127    ; x87 Rounding
128    (UNSPEC_FRNDINT_FLOOR        70)
129    (UNSPEC_FRNDINT_CEIL         71)
130    (UNSPEC_FRNDINT_TRUNC        72)
131    (UNSPEC_FRNDINT_MASK_PM      73)
132    (UNSPEC_FIST_FLOOR           74)
133    (UNSPEC_FIST_CEIL            75)
134
135    ; x87 Double output FP
136    (UNSPEC_SINCOS_COS           80)
137    (UNSPEC_SINCOS_SIN           81)
138    (UNSPEC_XTRACT_FRACT         84)
139    (UNSPEC_XTRACT_EXP           85)
140    (UNSPEC_FSCALE_FRACT         86)
141    (UNSPEC_FSCALE_EXP           87)
142    (UNSPEC_FPREM_F              88)
143    (UNSPEC_FPREM_U              89)
144    (UNSPEC_FPREM1_F             90)
145    (UNSPEC_FPREM1_U             91)
146
147    ; SSP patterns
148    (UNSPEC_SP_SET               100)
149    (UNSPEC_SP_TEST              101)
150    (UNSPEC_SP_TLS_SET           102)
151    (UNSPEC_SP_TLS_TEST          103)
152
153    ; SSSE3
154    (UNSPEC_PSHUFB               120)
155    (UNSPEC_PSIGN                121)
156    (UNSPEC_PALIGNR              122)
157
158    ; For SSE4A support
159    (UNSPEC_EXTRQI               130)
160    (UNSPEC_EXTRQ                131)   
161    (UNSPEC_INSERTQI             132)
162    (UNSPEC_INSERTQ              133)
163   ])
164
165 (define_constants
166   [(UNSPECV_BLOCKAGE            0)
167    (UNSPECV_STACK_PROBE         1)
168    (UNSPECV_EMMS                2)
169    (UNSPECV_LDMXCSR             3)
170    (UNSPECV_STMXCSR             4)
171    (UNSPECV_FEMMS               5)
172    (UNSPECV_CLFLUSH             6)
173    (UNSPECV_ALIGN               7)
174    (UNSPECV_MONITOR             8)
175    (UNSPECV_MWAIT               9)
176    (UNSPECV_CMPXCHG_1           10)
177    (UNSPECV_CMPXCHG_2           11)
178    (UNSPECV_XCHG                12)
179    (UNSPECV_LOCK                13)
180   ])
181
182 ;; Registers by name.
183 (define_constants
184   [(BP_REG                       6)
185    (SP_REG                       7)
186    (FLAGS_REG                   17)
187    (FPSR_REG                    18)
188    (FPCR_REG                    19)
189    (R10_REG                     39)
190    (R11_REG                     40)
191   ])
192
193 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
194 ;; from i386.c.
195
196 ;; In C guard expressions, put expressions which may be compile-time
197 ;; constants first.  This allows for better optimization.  For
198 ;; example, write "TARGET_64BIT && reload_completed", not
199 ;; "reload_completed && TARGET_64BIT".
200
201 \f
202 ;; Processor type.  This attribute must exactly match the processor_type
203 ;; enumeration in i386.h.
204 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
205                     nocona,core2,generic32,generic64,amdfam10"
206   (const (symbol_ref "ix86_tune")))
207
208 ;; A basic instruction type.  Refinements due to arguments to be
209 ;; provided in other attributes.
210 (define_attr "type"
211   "other,multi,
212    alu,alu1,negnot,imov,imovx,lea,
213    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
214    icmp,test,ibr,setcc,icmov,
215    push,pop,call,callv,leave,
216    str,bitmanip,
217    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
218    sselog,sselog1,sseiadd,sseishft,sseimul,
219    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
220    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
221   (const_string "other"))
222
223 ;; Main data type used by the insn
224 (define_attr "mode"
225   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
226   (const_string "unknown"))
227
228 ;; The CPU unit operations uses.
229 (define_attr "unit" "integer,i387,sse,mmx,unknown"
230   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
231            (const_string "i387")
232          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
233                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
234            (const_string "sse")
235          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
236            (const_string "mmx")
237          (eq_attr "type" "other")
238            (const_string "unknown")]
239          (const_string "integer")))
240
241 ;; The (bounding maximum) length of an instruction immediate.
242 (define_attr "length_immediate" ""
243   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
244                           bitmanip")
245            (const_int 0)
246          (eq_attr "unit" "i387,sse,mmx")
247            (const_int 0)
248          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
249                           imul,icmp,push,pop")
250            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
251          (eq_attr "type" "imov,test")
252            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
253          (eq_attr "type" "call")
254            (if_then_else (match_operand 0 "constant_call_address_operand" "")
255              (const_int 4)
256              (const_int 0))
257          (eq_attr "type" "callv")
258            (if_then_else (match_operand 1 "constant_call_address_operand" "")
259              (const_int 4)
260              (const_int 0))
261          ;; We don't know the size before shorten_branches.  Expect
262          ;; the instruction to fit for better scheduling.
263          (eq_attr "type" "ibr")
264            (const_int 1)
265          ]
266          (symbol_ref "/* Update immediate_length and other attributes! */
267                       gcc_unreachable (),1")))
268
269 ;; The (bounding maximum) length of an instruction address.
270 (define_attr "length_address" ""
271   (cond [(eq_attr "type" "str,other,multi,fxch")
272            (const_int 0)
273          (and (eq_attr "type" "call")
274               (match_operand 0 "constant_call_address_operand" ""))
275              (const_int 0)
276          (and (eq_attr "type" "callv")
277               (match_operand 1 "constant_call_address_operand" ""))
278              (const_int 0)
279          ]
280          (symbol_ref "ix86_attr_length_address_default (insn)")))
281
282 ;; Set when length prefix is used.
283 (define_attr "prefix_data16" ""
284   (if_then_else (ior (eq_attr "mode" "HI")
285                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
286     (const_int 1)
287     (const_int 0)))
288
289 ;; Set when string REP prefix is used.
290 (define_attr "prefix_rep" ""
291   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
292     (const_int 1)
293     (const_int 0)))
294
295 ;; Set when 0f opcode prefix is used.
296 (define_attr "prefix_0f" ""
297   (if_then_else
298     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
299          (eq_attr "unit" "sse,mmx"))
300     (const_int 1)
301     (const_int 0)))
302
303 ;; Set when REX opcode prefix is used.
304 (define_attr "prefix_rex" ""
305   (cond [(and (eq_attr "mode" "DI")
306               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
307            (const_int 1)
308          (and (eq_attr "mode" "QI")
309               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
310                   (const_int 0)))
311            (const_int 1)
312          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
313              (const_int 0))
314            (const_int 1)
315         ]
316         (const_int 0)))
317
318 ;; Set when modrm byte is used.
319 (define_attr "modrm" ""
320   (cond [(eq_attr "type" "str,leave")
321            (const_int 0)
322          (eq_attr "unit" "i387")
323            (const_int 0)
324          (and (eq_attr "type" "incdec")
325               (ior (match_operand:SI 1 "register_operand" "")
326                    (match_operand:HI 1 "register_operand" "")))
327            (const_int 0)
328          (and (eq_attr "type" "push")
329               (not (match_operand 1 "memory_operand" "")))
330            (const_int 0)
331          (and (eq_attr "type" "pop")
332               (not (match_operand 0 "memory_operand" "")))
333            (const_int 0)
334          (and (eq_attr "type" "imov")
335               (ior (and (match_operand 0 "register_operand" "")
336                         (match_operand 1 "immediate_operand" ""))
337                    (ior (and (match_operand 0 "ax_reg_operand" "")
338                              (match_operand 1 "memory_displacement_only_operand" ""))
339                         (and (match_operand 0 "memory_displacement_only_operand" "")
340                              (match_operand 1 "ax_reg_operand" "")))))
341            (const_int 0)
342          (and (eq_attr "type" "call")
343               (match_operand 0 "constant_call_address_operand" ""))
344              (const_int 0)
345          (and (eq_attr "type" "callv")
346               (match_operand 1 "constant_call_address_operand" ""))
347              (const_int 0)
348          ]
349          (const_int 1)))
350
351 ;; The (bounding maximum) length of an instruction in bytes.
352 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
353 ;; Later we may want to split them and compute proper length as for
354 ;; other insns.
355 (define_attr "length" ""
356   (cond [(eq_attr "type" "other,multi,fistp,frndint")
357            (const_int 16)
358          (eq_attr "type" "fcmp")
359            (const_int 4)
360          (eq_attr "unit" "i387")
361            (plus (const_int 2)
362                  (plus (attr "prefix_data16")
363                        (attr "length_address")))]
364          (plus (plus (attr "modrm")
365                      (plus (attr "prefix_0f")
366                            (plus (attr "prefix_rex")
367                                  (const_int 1))))
368                (plus (attr "prefix_rep")
369                      (plus (attr "prefix_data16")
370                            (plus (attr "length_immediate")
371                                  (attr "length_address")))))))
372
373 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
374 ;; `store' if there is a simple memory reference therein, or `unknown'
375 ;; if the instruction is complex.
376
377 (define_attr "memory" "none,load,store,both,unknown"
378   (cond [(eq_attr "type" "other,multi,str")
379            (const_string "unknown")
380          (eq_attr "type" "lea,fcmov,fpspc")
381            (const_string "none")
382          (eq_attr "type" "fistp,leave")
383            (const_string "both")
384          (eq_attr "type" "frndint")
385            (const_string "load")
386          (eq_attr "type" "push")
387            (if_then_else (match_operand 1 "memory_operand" "")
388              (const_string "both")
389              (const_string "store"))
390          (eq_attr "type" "pop")
391            (if_then_else (match_operand 0 "memory_operand" "")
392              (const_string "both")
393              (const_string "load"))
394          (eq_attr "type" "setcc")
395            (if_then_else (match_operand 0 "memory_operand" "")
396              (const_string "store")
397              (const_string "none"))
398          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
399            (if_then_else (ior (match_operand 0 "memory_operand" "")
400                               (match_operand 1 "memory_operand" ""))
401              (const_string "load")
402              (const_string "none"))
403          (eq_attr "type" "ibr")
404            (if_then_else (match_operand 0 "memory_operand" "")
405              (const_string "load")
406              (const_string "none"))
407          (eq_attr "type" "call")
408            (if_then_else (match_operand 0 "constant_call_address_operand" "")
409              (const_string "none")
410              (const_string "load"))
411          (eq_attr "type" "callv")
412            (if_then_else (match_operand 1 "constant_call_address_operand" "")
413              (const_string "none")
414              (const_string "load"))
415          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
416               (match_operand 1 "memory_operand" ""))
417            (const_string "both")
418          (and (match_operand 0 "memory_operand" "")
419               (match_operand 1 "memory_operand" ""))
420            (const_string "both")
421          (match_operand 0 "memory_operand" "")
422            (const_string "store")
423          (match_operand 1 "memory_operand" "")
424            (const_string "load")
425          (and (eq_attr "type"
426                  "!alu1,negnot,ishift1,
427                    imov,imovx,icmp,test,bitmanip,
428                    fmov,fcmp,fsgn,
429                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
430                    mmx,mmxmov,mmxcmp,mmxcvt")
431               (match_operand 2 "memory_operand" ""))
432            (const_string "load")
433          (and (eq_attr "type" "icmov")
434               (match_operand 3 "memory_operand" ""))
435            (const_string "load")
436         ]
437         (const_string "none")))
438
439 ;; Indicates if an instruction has both an immediate and a displacement.
440
441 (define_attr "imm_disp" "false,true,unknown"
442   (cond [(eq_attr "type" "other,multi")
443            (const_string "unknown")
444          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
445               (and (match_operand 0 "memory_displacement_operand" "")
446                    (match_operand 1 "immediate_operand" "")))
447            (const_string "true")
448          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
449               (and (match_operand 0 "memory_displacement_operand" "")
450                    (match_operand 2 "immediate_operand" "")))
451            (const_string "true")
452         ]
453         (const_string "false")))
454
455 ;; Indicates if an FP operation has an integer source.
456
457 (define_attr "fp_int_src" "false,true"
458   (const_string "false"))
459
460 ;; Defines rounding mode of an FP operation.
461
462 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
463   (const_string "any"))
464
465 ;; Describe a user's asm statement.
466 (define_asm_attributes
467   [(set_attr "length" "128")
468    (set_attr "type" "multi")])
469
470 ;; All x87 floating point modes
471 (define_mode_macro X87MODEF [SF DF XF])
472
473 ;; x87 SFmode and DFMode floating point modes
474 (define_mode_macro X87MODEF12 [SF DF])
475
476 ;; All integer modes handled by x87 fisttp operator.
477 (define_mode_macro X87MODEI [HI SI DI])
478
479 ;; All integer modes handled by integer x87 operators.
480 (define_mode_macro X87MODEI12 [HI SI])
481
482 ;; All SSE floating point modes
483 (define_mode_macro SSEMODEF [SF DF])
484
485 ;; All integer modes handled by SSE cvtts?2si* operators.
486 (define_mode_macro SSEMODEI24 [SI DI])
487
488 ;; SSE asm suffix for floating point modes
489 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
490
491 \f
492 ;; Scheduling descriptions
493
494 (include "pentium.md")
495 (include "ppro.md")
496 (include "k6.md")
497 (include "athlon.md")
498 (include "geode.md")
499
500 \f
501 ;; Operand and operator predicates and constraints
502
503 (include "predicates.md")
504 (include "constraints.md")
505
506 \f
507 ;; Compare instructions.
508
509 ;; All compare insns have expanders that save the operands away without
510 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
511 ;; after the cmp) will actually emit the cmpM.
512
513 (define_expand "cmpti"
514   [(set (reg:CC FLAGS_REG)
515         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
516                     (match_operand:TI 1 "x86_64_general_operand" "")))]
517   "TARGET_64BIT"
518 {
519   if (MEM_P (operands[0]) && MEM_P (operands[1]))
520     operands[0] = force_reg (TImode, operands[0]);
521   ix86_compare_op0 = operands[0];
522   ix86_compare_op1 = operands[1];
523   DONE;
524 })
525
526 (define_expand "cmpdi"
527   [(set (reg:CC FLAGS_REG)
528         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
529                     (match_operand:DI 1 "x86_64_general_operand" "")))]
530   ""
531 {
532   if (MEM_P (operands[0]) && MEM_P (operands[1]))
533     operands[0] = force_reg (DImode, operands[0]);
534   ix86_compare_op0 = operands[0];
535   ix86_compare_op1 = operands[1];
536   DONE;
537 })
538
539 (define_expand "cmpsi"
540   [(set (reg:CC FLAGS_REG)
541         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
542                     (match_operand:SI 1 "general_operand" "")))]
543   ""
544 {
545   if (MEM_P (operands[0]) && MEM_P (operands[1]))
546     operands[0] = force_reg (SImode, operands[0]);
547   ix86_compare_op0 = operands[0];
548   ix86_compare_op1 = operands[1];
549   DONE;
550 })
551
552 (define_expand "cmphi"
553   [(set (reg:CC FLAGS_REG)
554         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
555                     (match_operand:HI 1 "general_operand" "")))]
556   ""
557 {
558   if (MEM_P (operands[0]) && MEM_P (operands[1]))
559     operands[0] = force_reg (HImode, operands[0]);
560   ix86_compare_op0 = operands[0];
561   ix86_compare_op1 = operands[1];
562   DONE;
563 })
564
565 (define_expand "cmpqi"
566   [(set (reg:CC FLAGS_REG)
567         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
568                     (match_operand:QI 1 "general_operand" "")))]
569   "TARGET_QIMODE_MATH"
570 {
571   if (MEM_P (operands[0]) && MEM_P (operands[1]))
572     operands[0] = force_reg (QImode, operands[0]);
573   ix86_compare_op0 = operands[0];
574   ix86_compare_op1 = operands[1];
575   DONE;
576 })
577
578 (define_insn "cmpdi_ccno_1_rex64"
579   [(set (reg FLAGS_REG)
580         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
581                  (match_operand:DI 1 "const0_operand" "n,n")))]
582   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
583   "@
584    test{q}\t{%0, %0|%0, %0}
585    cmp{q}\t{%1, %0|%0, %1}"
586   [(set_attr "type" "test,icmp")
587    (set_attr "length_immediate" "0,1")
588    (set_attr "mode" "DI")])
589
590 (define_insn "*cmpdi_minus_1_rex64"
591   [(set (reg FLAGS_REG)
592         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
593                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
594                  (const_int 0)))]
595   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
596   "cmp{q}\t{%1, %0|%0, %1}"
597   [(set_attr "type" "icmp")
598    (set_attr "mode" "DI")])
599
600 (define_expand "cmpdi_1_rex64"
601   [(set (reg:CC FLAGS_REG)
602         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
603                     (match_operand:DI 1 "general_operand" "")))]
604   "TARGET_64BIT"
605   "")
606
607 (define_insn "cmpdi_1_insn_rex64"
608   [(set (reg FLAGS_REG)
609         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
610                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
611   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
612   "cmp{q}\t{%1, %0|%0, %1}"
613   [(set_attr "type" "icmp")
614    (set_attr "mode" "DI")])
615
616
617 (define_insn "*cmpsi_ccno_1"
618   [(set (reg FLAGS_REG)
619         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
620                  (match_operand:SI 1 "const0_operand" "n,n")))]
621   "ix86_match_ccmode (insn, CCNOmode)"
622   "@
623    test{l}\t{%0, %0|%0, %0}
624    cmp{l}\t{%1, %0|%0, %1}"
625   [(set_attr "type" "test,icmp")
626    (set_attr "length_immediate" "0,1")
627    (set_attr "mode" "SI")])
628
629 (define_insn "*cmpsi_minus_1"
630   [(set (reg FLAGS_REG)
631         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
632                            (match_operand:SI 1 "general_operand" "ri,mr"))
633                  (const_int 0)))]
634   "ix86_match_ccmode (insn, CCGOCmode)"
635   "cmp{l}\t{%1, %0|%0, %1}"
636   [(set_attr "type" "icmp")
637    (set_attr "mode" "SI")])
638
639 (define_expand "cmpsi_1"
640   [(set (reg:CC FLAGS_REG)
641         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
642                     (match_operand:SI 1 "general_operand" "ri,mr")))]
643   ""
644   "")
645
646 (define_insn "*cmpsi_1_insn"
647   [(set (reg FLAGS_REG)
648         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
649                  (match_operand:SI 1 "general_operand" "ri,mr")))]
650   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
651     && ix86_match_ccmode (insn, CCmode)"
652   "cmp{l}\t{%1, %0|%0, %1}"
653   [(set_attr "type" "icmp")
654    (set_attr "mode" "SI")])
655
656 (define_insn "*cmphi_ccno_1"
657   [(set (reg FLAGS_REG)
658         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
659                  (match_operand:HI 1 "const0_operand" "n,n")))]
660   "ix86_match_ccmode (insn, CCNOmode)"
661   "@
662    test{w}\t{%0, %0|%0, %0}
663    cmp{w}\t{%1, %0|%0, %1}"
664   [(set_attr "type" "test,icmp")
665    (set_attr "length_immediate" "0,1")
666    (set_attr "mode" "HI")])
667
668 (define_insn "*cmphi_minus_1"
669   [(set (reg FLAGS_REG)
670         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
671                            (match_operand:HI 1 "general_operand" "ri,mr"))
672                  (const_int 0)))]
673   "ix86_match_ccmode (insn, CCGOCmode)"
674   "cmp{w}\t{%1, %0|%0, %1}"
675   [(set_attr "type" "icmp")
676    (set_attr "mode" "HI")])
677
678 (define_insn "*cmphi_1"
679   [(set (reg FLAGS_REG)
680         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
681                  (match_operand:HI 1 "general_operand" "ri,mr")))]
682   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
683    && ix86_match_ccmode (insn, CCmode)"
684   "cmp{w}\t{%1, %0|%0, %1}"
685   [(set_attr "type" "icmp")
686    (set_attr "mode" "HI")])
687
688 (define_insn "*cmpqi_ccno_1"
689   [(set (reg FLAGS_REG)
690         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
691                  (match_operand:QI 1 "const0_operand" "n,n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "@
694    test{b}\t{%0, %0|%0, %0}
695    cmp{b}\t{$0, %0|%0, 0}"
696   [(set_attr "type" "test,icmp")
697    (set_attr "length_immediate" "0,1")
698    (set_attr "mode" "QI")])
699
700 (define_insn "*cmpqi_1"
701   [(set (reg FLAGS_REG)
702         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
703                  (match_operand:QI 1 "general_operand" "qi,mq")))]
704   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
705     && ix86_match_ccmode (insn, CCmode)"
706   "cmp{b}\t{%1, %0|%0, %1}"
707   [(set_attr "type" "icmp")
708    (set_attr "mode" "QI")])
709
710 (define_insn "*cmpqi_minus_1"
711   [(set (reg FLAGS_REG)
712         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
713                            (match_operand:QI 1 "general_operand" "qi,mq"))
714                  (const_int 0)))]
715   "ix86_match_ccmode (insn, CCGOCmode)"
716   "cmp{b}\t{%1, %0|%0, %1}"
717   [(set_attr "type" "icmp")
718    (set_attr "mode" "QI")])
719
720 (define_insn "*cmpqi_ext_1"
721   [(set (reg FLAGS_REG)
722         (compare
723           (match_operand:QI 0 "general_operand" "Qm")
724           (subreg:QI
725             (zero_extract:SI
726               (match_operand 1 "ext_register_operand" "Q")
727               (const_int 8)
728               (const_int 8)) 0)))]
729   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
730   "cmp{b}\t{%h1, %0|%0, %h1}"
731   [(set_attr "type" "icmp")
732    (set_attr "mode" "QI")])
733
734 (define_insn "*cmpqi_ext_1_rex64"
735   [(set (reg FLAGS_REG)
736         (compare
737           (match_operand:QI 0 "register_operand" "Q")
738           (subreg:QI
739             (zero_extract:SI
740               (match_operand 1 "ext_register_operand" "Q")
741               (const_int 8)
742               (const_int 8)) 0)))]
743   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
744   "cmp{b}\t{%h1, %0|%0, %h1}"
745   [(set_attr "type" "icmp")
746    (set_attr "mode" "QI")])
747
748 (define_insn "*cmpqi_ext_2"
749   [(set (reg FLAGS_REG)
750         (compare
751           (subreg:QI
752             (zero_extract:SI
753               (match_operand 0 "ext_register_operand" "Q")
754               (const_int 8)
755               (const_int 8)) 0)
756           (match_operand:QI 1 "const0_operand" "n")))]
757   "ix86_match_ccmode (insn, CCNOmode)"
758   "test{b}\t%h0, %h0"
759   [(set_attr "type" "test")
760    (set_attr "length_immediate" "0")
761    (set_attr "mode" "QI")])
762
763 (define_expand "cmpqi_ext_3"
764   [(set (reg:CC FLAGS_REG)
765         (compare:CC
766           (subreg:QI
767             (zero_extract:SI
768               (match_operand 0 "ext_register_operand" "")
769               (const_int 8)
770               (const_int 8)) 0)
771           (match_operand:QI 1 "general_operand" "")))]
772   ""
773   "")
774
775 (define_insn "cmpqi_ext_3_insn"
776   [(set (reg FLAGS_REG)
777         (compare
778           (subreg:QI
779             (zero_extract:SI
780               (match_operand 0 "ext_register_operand" "Q")
781               (const_int 8)
782               (const_int 8)) 0)
783           (match_operand:QI 1 "general_operand" "Qmn")))]
784   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
785   "cmp{b}\t{%1, %h0|%h0, %1}"
786   [(set_attr "type" "icmp")
787    (set_attr "mode" "QI")])
788
789 (define_insn "cmpqi_ext_3_insn_rex64"
790   [(set (reg FLAGS_REG)
791         (compare
792           (subreg:QI
793             (zero_extract:SI
794               (match_operand 0 "ext_register_operand" "Q")
795               (const_int 8)
796               (const_int 8)) 0)
797           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
798   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
799   "cmp{b}\t{%1, %h0|%h0, %1}"
800   [(set_attr "type" "icmp")
801    (set_attr "mode" "QI")])
802
803 (define_insn "*cmpqi_ext_4"
804   [(set (reg FLAGS_REG)
805         (compare
806           (subreg:QI
807             (zero_extract:SI
808               (match_operand 0 "ext_register_operand" "Q")
809               (const_int 8)
810               (const_int 8)) 0)
811           (subreg:QI
812             (zero_extract:SI
813               (match_operand 1 "ext_register_operand" "Q")
814               (const_int 8)
815               (const_int 8)) 0)))]
816   "ix86_match_ccmode (insn, CCmode)"
817   "cmp{b}\t{%h1, %h0|%h0, %h1}"
818   [(set_attr "type" "icmp")
819    (set_attr "mode" "QI")])
820
821 ;; These implement float point compares.
822 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
823 ;; which would allow mix and match FP modes on the compares.  Which is what
824 ;; the old patterns did, but with many more of them.
825
826 (define_expand "cmpxf"
827   [(set (reg:CC FLAGS_REG)
828         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
829                     (match_operand:XF 1 "nonmemory_operand" "")))]
830   "TARGET_80387"
831 {
832   ix86_compare_op0 = operands[0];
833   ix86_compare_op1 = operands[1];
834   DONE;
835 })
836
837 (define_expand "cmpdf"
838   [(set (reg:CC FLAGS_REG)
839         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
840                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
841   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
842 {
843   ix86_compare_op0 = operands[0];
844   ix86_compare_op1 = operands[1];
845   DONE;
846 })
847
848 (define_expand "cmpsf"
849   [(set (reg:CC FLAGS_REG)
850         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
851                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
852   "TARGET_80387 || TARGET_SSE_MATH"
853 {
854   ix86_compare_op0 = operands[0];
855   ix86_compare_op1 = operands[1];
856   DONE;
857 })
858
859 ;; FP compares, step 1:
860 ;; Set the FP condition codes.
861 ;;
862 ;; CCFPmode     compare with exceptions
863 ;; CCFPUmode    compare with no exceptions
864
865 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
866 ;; used to manage the reg stack popping would not be preserved.
867
868 (define_insn "*cmpfp_0"
869   [(set (match_operand:HI 0 "register_operand" "=a")
870         (unspec:HI
871           [(compare:CCFP
872              (match_operand 1 "register_operand" "f")
873              (match_operand 2 "const0_operand" "X"))]
874         UNSPEC_FNSTSW))]
875   "TARGET_80387
876    && FLOAT_MODE_P (GET_MODE (operands[1]))
877    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
878   "* return output_fp_compare (insn, operands, 0, 0);"
879   [(set_attr "type" "multi")
880    (set_attr "unit" "i387")
881    (set (attr "mode")
882      (cond [(match_operand:SF 1 "" "")
883               (const_string "SF")
884             (match_operand:DF 1 "" "")
885               (const_string "DF")
886            ]
887            (const_string "XF")))])
888
889 (define_insn "*cmpfp_sf"
890   [(set (match_operand:HI 0 "register_operand" "=a")
891         (unspec:HI
892           [(compare:CCFP
893              (match_operand:SF 1 "register_operand" "f")
894              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
895           UNSPEC_FNSTSW))]
896   "TARGET_80387"
897   "* return output_fp_compare (insn, operands, 0, 0);"
898   [(set_attr "type" "multi")
899    (set_attr "unit" "i387")
900    (set_attr "mode" "SF")])
901
902 (define_insn "*cmpfp_df"
903   [(set (match_operand:HI 0 "register_operand" "=a")
904         (unspec:HI
905           [(compare:CCFP
906              (match_operand:DF 1 "register_operand" "f")
907              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
908           UNSPEC_FNSTSW))]
909   "TARGET_80387"
910   "* return output_fp_compare (insn, operands, 0, 0);"
911   [(set_attr "type" "multi")
912    (set_attr "unit" "i387")
913    (set_attr "mode" "DF")])
914
915 (define_insn "*cmpfp_xf"
916   [(set (match_operand:HI 0 "register_operand" "=a")
917         (unspec:HI
918           [(compare:CCFP
919              (match_operand:XF 1 "register_operand" "f")
920              (match_operand:XF 2 "register_operand" "f"))]
921           UNSPEC_FNSTSW))]
922   "TARGET_80387"
923   "* return output_fp_compare (insn, operands, 0, 0);"
924   [(set_attr "type" "multi")
925    (set_attr "unit" "i387")
926    (set_attr "mode" "XF")])
927
928 (define_insn "*cmpfp_u"
929   [(set (match_operand:HI 0 "register_operand" "=a")
930         (unspec:HI
931           [(compare:CCFPU
932              (match_operand 1 "register_operand" "f")
933              (match_operand 2 "register_operand" "f"))]
934           UNSPEC_FNSTSW))]
935   "TARGET_80387
936    && FLOAT_MODE_P (GET_MODE (operands[1]))
937    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
938   "* return output_fp_compare (insn, operands, 0, 1);"
939   [(set_attr "type" "multi")
940    (set_attr "unit" "i387")
941    (set (attr "mode")
942      (cond [(match_operand:SF 1 "" "")
943               (const_string "SF")
944             (match_operand:DF 1 "" "")
945               (const_string "DF")
946            ]
947            (const_string "XF")))])
948
949 (define_insn "*cmpfp_<mode>"
950   [(set (match_operand:HI 0 "register_operand" "=a")
951         (unspec:HI
952           [(compare:CCFP
953              (match_operand 1 "register_operand" "f")
954              (match_operator 3 "float_operator"
955                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
956           UNSPEC_FNSTSW))]
957   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
958    && FLOAT_MODE_P (GET_MODE (operands[1]))
959    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
960   "* return output_fp_compare (insn, operands, 0, 0);"
961   [(set_attr "type" "multi")
962    (set_attr "unit" "i387")
963    (set_attr "fp_int_src" "true")
964    (set_attr "mode" "<MODE>")])
965
966 ;; FP compares, step 2
967 ;; Move the fpsw to ax.
968
969 (define_insn "x86_fnstsw_1"
970   [(set (match_operand:HI 0 "register_operand" "=a")
971         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
972   "TARGET_80387"
973   "fnstsw\t%0"
974   [(set_attr "length" "2")
975    (set_attr "mode" "SI")
976    (set_attr "unit" "i387")])
977
978 ;; FP compares, step 3
979 ;; Get ax into flags, general case.
980
981 (define_insn "x86_sahf_1"
982   [(set (reg:CC FLAGS_REG)
983         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
984   "!TARGET_64BIT"
985   "sahf"
986   [(set_attr "length" "1")
987    (set_attr "athlon_decode" "vector")
988    (set_attr "amdfam10_decode" "direct")
989    (set_attr "mode" "SI")])
990
991 ;; Pentium Pro can do steps 1 through 3 in one go.
992 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
993 (define_insn "*cmpfp_i_mixed"
994   [(set (reg:CCFP FLAGS_REG)
995         (compare:CCFP (match_operand 0 "register_operand" "f,x")
996                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
997   "TARGET_MIX_SSE_I387
998    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1000   "* return output_fp_compare (insn, operands, 1, 0);"
1001   [(set_attr "type" "fcmp,ssecomi")
1002    (set (attr "mode")
1003      (if_then_else (match_operand:SF 1 "" "")
1004         (const_string "SF")
1005         (const_string "DF")))
1006    (set_attr "athlon_decode" "vector")
1007    (set_attr "amdfam10_decode" "direct")])
1008
1009 (define_insn "*cmpfp_i_sse"
1010   [(set (reg:CCFP FLAGS_REG)
1011         (compare:CCFP (match_operand 0 "register_operand" "x")
1012                       (match_operand 1 "nonimmediate_operand" "xm")))]
1013   "TARGET_SSE_MATH
1014    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016   "* return output_fp_compare (insn, operands, 1, 0);"
1017   [(set_attr "type" "ssecomi")
1018    (set (attr "mode")
1019      (if_then_else (match_operand:SF 1 "" "")
1020         (const_string "SF")
1021         (const_string "DF")))
1022    (set_attr "athlon_decode" "vector")
1023    (set_attr "amdfam10_decode" "direct")])
1024
1025 (define_insn "*cmpfp_i_i387"
1026   [(set (reg:CCFP FLAGS_REG)
1027         (compare:CCFP (match_operand 0 "register_operand" "f")
1028                       (match_operand 1 "register_operand" "f")))]
1029   "TARGET_80387 && TARGET_CMOVE
1030    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1031    && FLOAT_MODE_P (GET_MODE (operands[0]))
1032    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033   "* return output_fp_compare (insn, operands, 1, 0);"
1034   [(set_attr "type" "fcmp")
1035    (set (attr "mode")
1036      (cond [(match_operand:SF 1 "" "")
1037               (const_string "SF")
1038             (match_operand:DF 1 "" "")
1039               (const_string "DF")
1040            ]
1041            (const_string "XF")))
1042    (set_attr "athlon_decode" "vector")
1043    (set_attr "amdfam10_decode" "direct")])
1044
1045 (define_insn "*cmpfp_iu_mixed"
1046   [(set (reg:CCFPU FLAGS_REG)
1047         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1048                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1049   "TARGET_MIX_SSE_I387
1050    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1051    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1052   "* return output_fp_compare (insn, operands, 1, 1);"
1053   [(set_attr "type" "fcmp,ssecomi")
1054    (set (attr "mode")
1055      (if_then_else (match_operand:SF 1 "" "")
1056         (const_string "SF")
1057         (const_string "DF")))
1058    (set_attr "athlon_decode" "vector")
1059    (set_attr "amdfam10_decode" "direct")])
1060
1061 (define_insn "*cmpfp_iu_sse"
1062   [(set (reg:CCFPU FLAGS_REG)
1063         (compare:CCFPU (match_operand 0 "register_operand" "x")
1064                        (match_operand 1 "nonimmediate_operand" "xm")))]
1065   "TARGET_SSE_MATH
1066    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1067    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1068   "* return output_fp_compare (insn, operands, 1, 1);"
1069   [(set_attr "type" "ssecomi")
1070    (set (attr "mode")
1071      (if_then_else (match_operand:SF 1 "" "")
1072         (const_string "SF")
1073         (const_string "DF")))
1074    (set_attr "athlon_decode" "vector")
1075    (set_attr "amdfam10_decode" "direct")])
1076
1077 (define_insn "*cmpfp_iu_387"
1078   [(set (reg:CCFPU FLAGS_REG)
1079         (compare:CCFPU (match_operand 0 "register_operand" "f")
1080                        (match_operand 1 "register_operand" "f")))]
1081   "TARGET_80387 && TARGET_CMOVE
1082    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1083    && FLOAT_MODE_P (GET_MODE (operands[0]))
1084    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1085   "* return output_fp_compare (insn, operands, 1, 1);"
1086   [(set_attr "type" "fcmp")
1087    (set (attr "mode")
1088      (cond [(match_operand:SF 1 "" "")
1089               (const_string "SF")
1090             (match_operand:DF 1 "" "")
1091               (const_string "DF")
1092            ]
1093            (const_string "XF")))
1094    (set_attr "athlon_decode" "vector")
1095    (set_attr "amdfam10_decode" "direct")])
1096 \f
1097 ;; Move instructions.
1098
1099 ;; General case of fullword move.
1100
1101 (define_expand "movsi"
1102   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1103         (match_operand:SI 1 "general_operand" ""))]
1104   ""
1105   "ix86_expand_move (SImode, operands); DONE;")
1106
1107 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1108 ;; general_operand.
1109 ;;
1110 ;; %%% We don't use a post-inc memory reference because x86 is not a
1111 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1112 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1113 ;; targets without our curiosities, and it is just as easy to represent
1114 ;; this differently.
1115
1116 (define_insn "*pushsi2"
1117   [(set (match_operand:SI 0 "push_operand" "=<")
1118         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1119   "!TARGET_64BIT"
1120   "push{l}\t%1"
1121   [(set_attr "type" "push")
1122    (set_attr "mode" "SI")])
1123
1124 ;; For 64BIT abi we always round up to 8 bytes.
1125 (define_insn "*pushsi2_rex64"
1126   [(set (match_operand:SI 0 "push_operand" "=X")
1127         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1128   "TARGET_64BIT"
1129   "push{q}\t%q1"
1130   [(set_attr "type" "push")
1131    (set_attr "mode" "SI")])
1132
1133 (define_insn "*pushsi2_prologue"
1134   [(set (match_operand:SI 0 "push_operand" "=<")
1135         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1136    (clobber (mem:BLK (scratch)))]
1137   "!TARGET_64BIT"
1138   "push{l}\t%1"
1139   [(set_attr "type" "push")
1140    (set_attr "mode" "SI")])
1141
1142 (define_insn "*popsi1_epilogue"
1143   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1144         (mem:SI (reg:SI SP_REG)))
1145    (set (reg:SI SP_REG)
1146         (plus:SI (reg:SI SP_REG) (const_int 4)))
1147    (clobber (mem:BLK (scratch)))]
1148   "!TARGET_64BIT"
1149   "pop{l}\t%0"
1150   [(set_attr "type" "pop")
1151    (set_attr "mode" "SI")])
1152
1153 (define_insn "popsi1"
1154   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1155         (mem:SI (reg:SI SP_REG)))
1156    (set (reg:SI SP_REG)
1157         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1158   "!TARGET_64BIT"
1159   "pop{l}\t%0"
1160   [(set_attr "type" "pop")
1161    (set_attr "mode" "SI")])
1162
1163 (define_insn "*movsi_xor"
1164   [(set (match_operand:SI 0 "register_operand" "=r")
1165         (match_operand:SI 1 "const0_operand" "i"))
1166    (clobber (reg:CC FLAGS_REG))]
1167   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1168   "xor{l}\t{%0, %0|%0, %0}"
1169   [(set_attr "type" "alu1")
1170    (set_attr "mode" "SI")
1171    (set_attr "length_immediate" "0")])
1172
1173 (define_insn "*movsi_or"
1174   [(set (match_operand:SI 0 "register_operand" "=r")
1175         (match_operand:SI 1 "immediate_operand" "i"))
1176    (clobber (reg:CC FLAGS_REG))]
1177   "reload_completed
1178    && operands[1] == constm1_rtx
1179    && (TARGET_PENTIUM || optimize_size)"
1180 {
1181   operands[1] = constm1_rtx;
1182   return "or{l}\t{%1, %0|%0, %1}";
1183 }
1184   [(set_attr "type" "alu1")
1185    (set_attr "mode" "SI")
1186    (set_attr "length_immediate" "1")])
1187
1188 (define_insn "*movsi_1"
1189   [(set (match_operand:SI 0 "nonimmediate_operand"
1190                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1191         (match_operand:SI 1 "general_operand"
1192                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1193   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1194 {
1195   switch (get_attr_type (insn))
1196     {
1197     case TYPE_SSELOG1:
1198       if (get_attr_mode (insn) == MODE_TI)
1199         return "pxor\t%0, %0";
1200       return "xorps\t%0, %0";
1201
1202     case TYPE_SSEMOV:
1203       switch (get_attr_mode (insn))
1204         {
1205         case MODE_TI:
1206           return "movdqa\t{%1, %0|%0, %1}";
1207         case MODE_V4SF:
1208           return "movaps\t{%1, %0|%0, %1}";
1209         case MODE_SI:
1210           return "movd\t{%1, %0|%0, %1}";
1211         case MODE_SF:
1212           return "movss\t{%1, %0|%0, %1}";
1213         default:
1214           gcc_unreachable ();
1215         }
1216
1217     case TYPE_MMXADD:
1218       return "pxor\t%0, %0";
1219
1220     case TYPE_MMXMOV:
1221       if (get_attr_mode (insn) == MODE_DI)
1222         return "movq\t{%1, %0|%0, %1}";
1223       return "movd\t{%1, %0|%0, %1}";
1224
1225     case TYPE_LEA:
1226       return "lea{l}\t{%1, %0|%0, %1}";
1227
1228     default:
1229       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1230       return "mov{l}\t{%1, %0|%0, %1}";
1231     }
1232 }
1233   [(set (attr "type")
1234      (cond [(eq_attr "alternative" "2")
1235               (const_string "mmxadd")
1236             (eq_attr "alternative" "3,4,5")
1237               (const_string "mmxmov")
1238             (eq_attr "alternative" "6")
1239               (const_string "sselog1")
1240             (eq_attr "alternative" "7,8,9,10,11")
1241               (const_string "ssemov")
1242             (match_operand:DI 1 "pic_32bit_operand" "")
1243               (const_string "lea")
1244            ]
1245            (const_string "imov")))
1246    (set (attr "mode")
1247      (cond [(eq_attr "alternative" "2,3")
1248               (const_string "DI")
1249             (eq_attr "alternative" "6,7")
1250               (if_then_else
1251                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1252                 (const_string "V4SF")
1253                 (const_string "TI"))
1254             (and (eq_attr "alternative" "8,9,10,11")
1255                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1256               (const_string "SF")
1257            ]
1258            (const_string "SI")))])
1259
1260 ;; Stores and loads of ax to arbitrary constant address.
1261 ;; We fake an second form of instruction to force reload to load address
1262 ;; into register when rax is not available
1263 (define_insn "*movabssi_1_rex64"
1264   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1265         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1266   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1267   "@
1268    movabs{l}\t{%1, %P0|%P0, %1}
1269    mov{l}\t{%1, %a0|%a0, %1}"
1270   [(set_attr "type" "imov")
1271    (set_attr "modrm" "0,*")
1272    (set_attr "length_address" "8,0")
1273    (set_attr "length_immediate" "0,*")
1274    (set_attr "memory" "store")
1275    (set_attr "mode" "SI")])
1276
1277 (define_insn "*movabssi_2_rex64"
1278   [(set (match_operand:SI 0 "register_operand" "=a,r")
1279         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1280   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1281   "@
1282    movabs{l}\t{%P1, %0|%0, %P1}
1283    mov{l}\t{%a1, %0|%0, %a1}"
1284   [(set_attr "type" "imov")
1285    (set_attr "modrm" "0,*")
1286    (set_attr "length_address" "8,0")
1287    (set_attr "length_immediate" "0")
1288    (set_attr "memory" "load")
1289    (set_attr "mode" "SI")])
1290
1291 (define_insn "*swapsi"
1292   [(set (match_operand:SI 0 "register_operand" "+r")
1293         (match_operand:SI 1 "register_operand" "+r"))
1294    (set (match_dup 1)
1295         (match_dup 0))]
1296   ""
1297   "xchg{l}\t%1, %0"
1298   [(set_attr "type" "imov")
1299    (set_attr "mode" "SI")
1300    (set_attr "pent_pair" "np")
1301    (set_attr "athlon_decode" "vector")
1302    (set_attr "amdfam10_decode" "double")])   
1303
1304 (define_expand "movhi"
1305   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1306         (match_operand:HI 1 "general_operand" ""))]
1307   ""
1308   "ix86_expand_move (HImode, operands); DONE;")
1309
1310 (define_insn "*pushhi2"
1311   [(set (match_operand:HI 0 "push_operand" "=X")
1312         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1313   "!TARGET_64BIT"
1314   "push{l}\t%k1"
1315   [(set_attr "type" "push")
1316    (set_attr "mode" "SI")])
1317
1318 ;; For 64BIT abi we always round up to 8 bytes.
1319 (define_insn "*pushhi2_rex64"
1320   [(set (match_operand:HI 0 "push_operand" "=X")
1321         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1322   "TARGET_64BIT"
1323   "push{q}\t%q1"
1324   [(set_attr "type" "push")
1325    (set_attr "mode" "DI")])
1326
1327 (define_insn "*movhi_1"
1328   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1329         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1330   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1331 {
1332   switch (get_attr_type (insn))
1333     {
1334     case TYPE_IMOVX:
1335       /* movzwl is faster than movw on p2 due to partial word stalls,
1336          though not as fast as an aligned movl.  */
1337       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1338     default:
1339       if (get_attr_mode (insn) == MODE_SI)
1340         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1341       else
1342         return "mov{w}\t{%1, %0|%0, %1}";
1343     }
1344 }
1345   [(set (attr "type")
1346      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1347               (const_string "imov")
1348             (and (eq_attr "alternative" "0")
1349                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1350                           (const_int 0))
1351                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1352                           (const_int 0))))
1353               (const_string "imov")
1354             (and (eq_attr "alternative" "1,2")
1355                  (match_operand:HI 1 "aligned_operand" ""))
1356               (const_string "imov")
1357             (and (ne (symbol_ref "TARGET_MOVX")
1358                      (const_int 0))
1359                  (eq_attr "alternative" "0,2"))
1360               (const_string "imovx")
1361            ]
1362            (const_string "imov")))
1363     (set (attr "mode")
1364       (cond [(eq_attr "type" "imovx")
1365                (const_string "SI")
1366              (and (eq_attr "alternative" "1,2")
1367                   (match_operand:HI 1 "aligned_operand" ""))
1368                (const_string "SI")
1369              (and (eq_attr "alternative" "0")
1370                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1371                            (const_int 0))
1372                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1373                            (const_int 0))))
1374                (const_string "SI")
1375             ]
1376             (const_string "HI")))])
1377
1378 ;; Stores and loads of ax to arbitrary constant address.
1379 ;; We fake an second form of instruction to force reload to load address
1380 ;; into register when rax is not available
1381 (define_insn "*movabshi_1_rex64"
1382   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1383         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1384   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1385   "@
1386    movabs{w}\t{%1, %P0|%P0, %1}
1387    mov{w}\t{%1, %a0|%a0, %1}"
1388   [(set_attr "type" "imov")
1389    (set_attr "modrm" "0,*")
1390    (set_attr "length_address" "8,0")
1391    (set_attr "length_immediate" "0,*")
1392    (set_attr "memory" "store")
1393    (set_attr "mode" "HI")])
1394
1395 (define_insn "*movabshi_2_rex64"
1396   [(set (match_operand:HI 0 "register_operand" "=a,r")
1397         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1398   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1399   "@
1400    movabs{w}\t{%P1, %0|%0, %P1}
1401    mov{w}\t{%a1, %0|%0, %a1}"
1402   [(set_attr "type" "imov")
1403    (set_attr "modrm" "0,*")
1404    (set_attr "length_address" "8,0")
1405    (set_attr "length_immediate" "0")
1406    (set_attr "memory" "load")
1407    (set_attr "mode" "HI")])
1408
1409 (define_insn "*swaphi_1"
1410   [(set (match_operand:HI 0 "register_operand" "+r")
1411         (match_operand:HI 1 "register_operand" "+r"))
1412    (set (match_dup 1)
1413         (match_dup 0))]
1414   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1415   "xchg{l}\t%k1, %k0"
1416   [(set_attr "type" "imov")
1417    (set_attr "mode" "SI")
1418    (set_attr "pent_pair" "np")
1419    (set_attr "athlon_decode" "vector")
1420    (set_attr "amdfam10_decode" "double")])   
1421
1422 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1423 (define_insn "*swaphi_2"
1424   [(set (match_operand:HI 0 "register_operand" "+r")
1425         (match_operand:HI 1 "register_operand" "+r"))
1426    (set (match_dup 1)
1427         (match_dup 0))]
1428   "TARGET_PARTIAL_REG_STALL"
1429   "xchg{w}\t%1, %0"
1430   [(set_attr "type" "imov")
1431    (set_attr "mode" "HI")
1432    (set_attr "pent_pair" "np")
1433    (set_attr "athlon_decode" "vector")])
1434
1435 (define_expand "movstricthi"
1436   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1437         (match_operand:HI 1 "general_operand" ""))]
1438   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1439 {
1440   /* Don't generate memory->memory moves, go through a register */
1441   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1442     operands[1] = force_reg (HImode, operands[1]);
1443 })
1444
1445 (define_insn "*movstricthi_1"
1446   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1447         (match_operand:HI 1 "general_operand" "rn,m"))]
1448   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1449    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1450   "mov{w}\t{%1, %0|%0, %1}"
1451   [(set_attr "type" "imov")
1452    (set_attr "mode" "HI")])
1453
1454 (define_insn "*movstricthi_xor"
1455   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1456         (match_operand:HI 1 "const0_operand" "i"))
1457    (clobber (reg:CC FLAGS_REG))]
1458   "reload_completed
1459    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1460   "xor{w}\t{%0, %0|%0, %0}"
1461   [(set_attr "type" "alu1")
1462    (set_attr "mode" "HI")
1463    (set_attr "length_immediate" "0")])
1464
1465 (define_expand "movqi"
1466   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1467         (match_operand:QI 1 "general_operand" ""))]
1468   ""
1469   "ix86_expand_move (QImode, operands); DONE;")
1470
1471 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1472 ;; "push a byte".  But actually we use pushl, which has the effect
1473 ;; of rounding the amount pushed up to a word.
1474
1475 (define_insn "*pushqi2"
1476   [(set (match_operand:QI 0 "push_operand" "=X")
1477         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1478   "!TARGET_64BIT"
1479   "push{l}\t%k1"
1480   [(set_attr "type" "push")
1481    (set_attr "mode" "SI")])
1482
1483 ;; For 64BIT abi we always round up to 8 bytes.
1484 (define_insn "*pushqi2_rex64"
1485   [(set (match_operand:QI 0 "push_operand" "=X")
1486         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1487   "TARGET_64BIT"
1488   "push{q}\t%q1"
1489   [(set_attr "type" "push")
1490    (set_attr "mode" "DI")])
1491
1492 ;; Situation is quite tricky about when to choose full sized (SImode) move
1493 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1494 ;; partial register dependency machines (such as AMD Athlon), where QImode
1495 ;; moves issue extra dependency and for partial register stalls machines
1496 ;; that don't use QImode patterns (and QImode move cause stall on the next
1497 ;; instruction).
1498 ;;
1499 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1500 ;; register stall machines with, where we use QImode instructions, since
1501 ;; partial register stall can be caused there.  Then we use movzx.
1502 (define_insn "*movqi_1"
1503   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1504         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1505   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1506 {
1507   switch (get_attr_type (insn))
1508     {
1509     case TYPE_IMOVX:
1510       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1511       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1512     default:
1513       if (get_attr_mode (insn) == MODE_SI)
1514         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1515       else
1516         return "mov{b}\t{%1, %0|%0, %1}";
1517     }
1518 }
1519   [(set (attr "type")
1520      (cond [(and (eq_attr "alternative" "5")
1521                  (not (match_operand:QI 1 "aligned_operand" "")))
1522               (const_string "imovx")
1523             (ne (symbol_ref "optimize_size") (const_int 0))
1524               (const_string "imov")
1525             (and (eq_attr "alternative" "3")
1526                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1527                           (const_int 0))
1528                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1529                           (const_int 0))))
1530               (const_string "imov")
1531             (eq_attr "alternative" "3,5")
1532               (const_string "imovx")
1533             (and (ne (symbol_ref "TARGET_MOVX")
1534                      (const_int 0))
1535                  (eq_attr "alternative" "2"))
1536               (const_string "imovx")
1537            ]
1538            (const_string "imov")))
1539    (set (attr "mode")
1540       (cond [(eq_attr "alternative" "3,4,5")
1541                (const_string "SI")
1542              (eq_attr "alternative" "6")
1543                (const_string "QI")
1544              (eq_attr "type" "imovx")
1545                (const_string "SI")
1546              (and (eq_attr "type" "imov")
1547                   (and (eq_attr "alternative" "0,1")
1548                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1549                                 (const_int 0))
1550                             (and (eq (symbol_ref "optimize_size")
1551                                      (const_int 0))
1552                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1553                                      (const_int 0))))))
1554                (const_string "SI")
1555              ;; Avoid partial register stalls when not using QImode arithmetic
1556              (and (eq_attr "type" "imov")
1557                   (and (eq_attr "alternative" "0,1")
1558                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1559                                 (const_int 0))
1560                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1561                                 (const_int 0)))))
1562                (const_string "SI")
1563            ]
1564            (const_string "QI")))])
1565
1566 (define_expand "reload_outqi"
1567   [(parallel [(match_operand:QI 0 "" "=m")
1568               (match_operand:QI 1 "register_operand" "r")
1569               (match_operand:QI 2 "register_operand" "=&q")])]
1570   ""
1571 {
1572   rtx op0, op1, op2;
1573   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1574
1575   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1576   if (! q_regs_operand (op1, QImode))
1577     {
1578       emit_insn (gen_movqi (op2, op1));
1579       op1 = op2;
1580     }
1581   emit_insn (gen_movqi (op0, op1));
1582   DONE;
1583 })
1584
1585 (define_insn "*swapqi_1"
1586   [(set (match_operand:QI 0 "register_operand" "+r")
1587         (match_operand:QI 1 "register_operand" "+r"))
1588    (set (match_dup 1)
1589         (match_dup 0))]
1590   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1591   "xchg{l}\t%k1, %k0"
1592   [(set_attr "type" "imov")
1593    (set_attr "mode" "SI")
1594    (set_attr "pent_pair" "np")
1595    (set_attr "athlon_decode" "vector")
1596    (set_attr "amdfam10_decode" "vector")])   
1597
1598 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1599 (define_insn "*swapqi_2"
1600   [(set (match_operand:QI 0 "register_operand" "+q")
1601         (match_operand:QI 1 "register_operand" "+q"))
1602    (set (match_dup 1)
1603         (match_dup 0))]
1604   "TARGET_PARTIAL_REG_STALL"
1605   "xchg{b}\t%1, %0"
1606   [(set_attr "type" "imov")
1607    (set_attr "mode" "QI")
1608    (set_attr "pent_pair" "np")
1609    (set_attr "athlon_decode" "vector")])
1610
1611 (define_expand "movstrictqi"
1612   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1613         (match_operand:QI 1 "general_operand" ""))]
1614   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1615 {
1616   /* Don't generate memory->memory moves, go through a register.  */
1617   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1618     operands[1] = force_reg (QImode, operands[1]);
1619 })
1620
1621 (define_insn "*movstrictqi_1"
1622   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1623         (match_operand:QI 1 "general_operand" "*qn,m"))]
1624   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1625    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1626   "mov{b}\t{%1, %0|%0, %1}"
1627   [(set_attr "type" "imov")
1628    (set_attr "mode" "QI")])
1629
1630 (define_insn "*movstrictqi_xor"
1631   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1632         (match_operand:QI 1 "const0_operand" "i"))
1633    (clobber (reg:CC FLAGS_REG))]
1634   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1635   "xor{b}\t{%0, %0|%0, %0}"
1636   [(set_attr "type" "alu1")
1637    (set_attr "mode" "QI")
1638    (set_attr "length_immediate" "0")])
1639
1640 (define_insn "*movsi_extv_1"
1641   [(set (match_operand:SI 0 "register_operand" "=R")
1642         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1643                          (const_int 8)
1644                          (const_int 8)))]
1645   ""
1646   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1647   [(set_attr "type" "imovx")
1648    (set_attr "mode" "SI")])
1649
1650 (define_insn "*movhi_extv_1"
1651   [(set (match_operand:HI 0 "register_operand" "=R")
1652         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1653                          (const_int 8)
1654                          (const_int 8)))]
1655   ""
1656   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1657   [(set_attr "type" "imovx")
1658    (set_attr "mode" "SI")])
1659
1660 (define_insn "*movqi_extv_1"
1661   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1662         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1663                          (const_int 8)
1664                          (const_int 8)))]
1665   "!TARGET_64BIT"
1666 {
1667   switch (get_attr_type (insn))
1668     {
1669     case TYPE_IMOVX:
1670       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1671     default:
1672       return "mov{b}\t{%h1, %0|%0, %h1}";
1673     }
1674 }
1675   [(set (attr "type")
1676      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1677                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1678                              (ne (symbol_ref "TARGET_MOVX")
1679                                  (const_int 0))))
1680         (const_string "imovx")
1681         (const_string "imov")))
1682    (set (attr "mode")
1683      (if_then_else (eq_attr "type" "imovx")
1684         (const_string "SI")
1685         (const_string "QI")))])
1686
1687 (define_insn "*movqi_extv_1_rex64"
1688   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1689         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1690                          (const_int 8)
1691                          (const_int 8)))]
1692   "TARGET_64BIT"
1693 {
1694   switch (get_attr_type (insn))
1695     {
1696     case TYPE_IMOVX:
1697       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1698     default:
1699       return "mov{b}\t{%h1, %0|%0, %h1}";
1700     }
1701 }
1702   [(set (attr "type")
1703      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1704                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1705                              (ne (symbol_ref "TARGET_MOVX")
1706                                  (const_int 0))))
1707         (const_string "imovx")
1708         (const_string "imov")))
1709    (set (attr "mode")
1710      (if_then_else (eq_attr "type" "imovx")
1711         (const_string "SI")
1712         (const_string "QI")))])
1713
1714 ;; Stores and loads of ax to arbitrary constant address.
1715 ;; We fake an second form of instruction to force reload to load address
1716 ;; into register when rax is not available
1717 (define_insn "*movabsqi_1_rex64"
1718   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1719         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1720   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1721   "@
1722    movabs{b}\t{%1, %P0|%P0, %1}
1723    mov{b}\t{%1, %a0|%a0, %1}"
1724   [(set_attr "type" "imov")
1725    (set_attr "modrm" "0,*")
1726    (set_attr "length_address" "8,0")
1727    (set_attr "length_immediate" "0,*")
1728    (set_attr "memory" "store")
1729    (set_attr "mode" "QI")])
1730
1731 (define_insn "*movabsqi_2_rex64"
1732   [(set (match_operand:QI 0 "register_operand" "=a,r")
1733         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1734   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1735   "@
1736    movabs{b}\t{%P1, %0|%0, %P1}
1737    mov{b}\t{%a1, %0|%0, %a1}"
1738   [(set_attr "type" "imov")
1739    (set_attr "modrm" "0,*")
1740    (set_attr "length_address" "8,0")
1741    (set_attr "length_immediate" "0")
1742    (set_attr "memory" "load")
1743    (set_attr "mode" "QI")])
1744
1745 (define_insn "*movdi_extzv_1"
1746   [(set (match_operand:DI 0 "register_operand" "=R")
1747         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1748                          (const_int 8)
1749                          (const_int 8)))]
1750   "TARGET_64BIT"
1751   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1752   [(set_attr "type" "imovx")
1753    (set_attr "mode" "DI")])
1754
1755 (define_insn "*movsi_extzv_1"
1756   [(set (match_operand:SI 0 "register_operand" "=R")
1757         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1758                          (const_int 8)
1759                          (const_int 8)))]
1760   ""
1761   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1762   [(set_attr "type" "imovx")
1763    (set_attr "mode" "SI")])
1764
1765 (define_insn "*movqi_extzv_2"
1766   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1767         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1768                                     (const_int 8)
1769                                     (const_int 8)) 0))]
1770   "!TARGET_64BIT"
1771 {
1772   switch (get_attr_type (insn))
1773     {
1774     case TYPE_IMOVX:
1775       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1776     default:
1777       return "mov{b}\t{%h1, %0|%0, %h1}";
1778     }
1779 }
1780   [(set (attr "type")
1781      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1782                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1783                              (ne (symbol_ref "TARGET_MOVX")
1784                                  (const_int 0))))
1785         (const_string "imovx")
1786         (const_string "imov")))
1787    (set (attr "mode")
1788      (if_then_else (eq_attr "type" "imovx")
1789         (const_string "SI")
1790         (const_string "QI")))])
1791
1792 (define_insn "*movqi_extzv_2_rex64"
1793   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1794         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1795                                     (const_int 8)
1796                                     (const_int 8)) 0))]
1797   "TARGET_64BIT"
1798 {
1799   switch (get_attr_type (insn))
1800     {
1801     case TYPE_IMOVX:
1802       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1803     default:
1804       return "mov{b}\t{%h1, %0|%0, %h1}";
1805     }
1806 }
1807   [(set (attr "type")
1808      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1809                         (ne (symbol_ref "TARGET_MOVX")
1810                             (const_int 0)))
1811         (const_string "imovx")
1812         (const_string "imov")))
1813    (set (attr "mode")
1814      (if_then_else (eq_attr "type" "imovx")
1815         (const_string "SI")
1816         (const_string "QI")))])
1817
1818 (define_insn "movsi_insv_1"
1819   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1820                          (const_int 8)
1821                          (const_int 8))
1822         (match_operand:SI 1 "general_operand" "Qmn"))]
1823   "!TARGET_64BIT"
1824   "mov{b}\t{%b1, %h0|%h0, %b1}"
1825   [(set_attr "type" "imov")
1826    (set_attr "mode" "QI")])
1827
1828 (define_insn "*movsi_insv_1_rex64"
1829   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1830                          (const_int 8)
1831                          (const_int 8))
1832         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1833   "TARGET_64BIT"
1834   "mov{b}\t{%b1, %h0|%h0, %b1}"
1835   [(set_attr "type" "imov")
1836    (set_attr "mode" "QI")])
1837
1838 (define_insn "movdi_insv_1_rex64"
1839   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1840                          (const_int 8)
1841                          (const_int 8))
1842         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1843   "TARGET_64BIT"
1844   "mov{b}\t{%b1, %h0|%h0, %b1}"
1845   [(set_attr "type" "imov")
1846    (set_attr "mode" "QI")])
1847
1848 (define_insn "*movqi_insv_2"
1849   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1850                          (const_int 8)
1851                          (const_int 8))
1852         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1853                      (const_int 8)))]
1854   ""
1855   "mov{b}\t{%h1, %h0|%h0, %h1}"
1856   [(set_attr "type" "imov")
1857    (set_attr "mode" "QI")])
1858
1859 (define_expand "movdi"
1860   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1861         (match_operand:DI 1 "general_operand" ""))]
1862   ""
1863   "ix86_expand_move (DImode, operands); DONE;")
1864
1865 (define_insn "*pushdi"
1866   [(set (match_operand:DI 0 "push_operand" "=<")
1867         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1868   "!TARGET_64BIT"
1869   "#")
1870
1871 (define_insn "*pushdi2_rex64"
1872   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1873         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1874   "TARGET_64BIT"
1875   "@
1876    push{q}\t%1
1877    #"
1878   [(set_attr "type" "push,multi")
1879    (set_attr "mode" "DI")])
1880
1881 ;; Convert impossible pushes of immediate to existing instructions.
1882 ;; First try to get scratch register and go through it.  In case this
1883 ;; fails, push sign extended lower part first and then overwrite
1884 ;; upper part by 32bit move.
1885 (define_peephole2
1886   [(match_scratch:DI 2 "r")
1887    (set (match_operand:DI 0 "push_operand" "")
1888         (match_operand:DI 1 "immediate_operand" ""))]
1889   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1890    && !x86_64_immediate_operand (operands[1], DImode)"
1891   [(set (match_dup 2) (match_dup 1))
1892    (set (match_dup 0) (match_dup 2))]
1893   "")
1894
1895 ;; We need to define this as both peepholer and splitter for case
1896 ;; peephole2 pass is not run.
1897 ;; "&& 1" is needed to keep it from matching the previous pattern.
1898 (define_peephole2
1899   [(set (match_operand:DI 0 "push_operand" "")
1900         (match_operand:DI 1 "immediate_operand" ""))]
1901   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1902    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1903   [(set (match_dup 0) (match_dup 1))
1904    (set (match_dup 2) (match_dup 3))]
1905   "split_di (operands + 1, 1, operands + 2, operands + 3);
1906    operands[1] = gen_lowpart (DImode, operands[2]);
1907    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1908                                                     GEN_INT (4)));
1909   ")
1910
1911 (define_split
1912   [(set (match_operand:DI 0 "push_operand" "")
1913         (match_operand:DI 1 "immediate_operand" ""))]
1914   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1915                     ? flow2_completed : reload_completed)
1916    && !symbolic_operand (operands[1], DImode)
1917    && !x86_64_immediate_operand (operands[1], DImode)"
1918   [(set (match_dup 0) (match_dup 1))
1919    (set (match_dup 2) (match_dup 3))]
1920   "split_di (operands + 1, 1, operands + 2, operands + 3);
1921    operands[1] = gen_lowpart (DImode, operands[2]);
1922    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1923                                                     GEN_INT (4)));
1924   ")
1925
1926 (define_insn "*pushdi2_prologue_rex64"
1927   [(set (match_operand:DI 0 "push_operand" "=<")
1928         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1929    (clobber (mem:BLK (scratch)))]
1930   "TARGET_64BIT"
1931   "push{q}\t%1"
1932   [(set_attr "type" "push")
1933    (set_attr "mode" "DI")])
1934
1935 (define_insn "*popdi1_epilogue_rex64"
1936   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1937         (mem:DI (reg:DI SP_REG)))
1938    (set (reg:DI SP_REG)
1939         (plus:DI (reg:DI SP_REG) (const_int 8)))
1940    (clobber (mem:BLK (scratch)))]
1941   "TARGET_64BIT"
1942   "pop{q}\t%0"
1943   [(set_attr "type" "pop")
1944    (set_attr "mode" "DI")])
1945
1946 (define_insn "popdi1"
1947   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1948         (mem:DI (reg:DI SP_REG)))
1949    (set (reg:DI SP_REG)
1950         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1951   "TARGET_64BIT"
1952   "pop{q}\t%0"
1953   [(set_attr "type" "pop")
1954    (set_attr "mode" "DI")])
1955
1956 (define_insn "*movdi_xor_rex64"
1957   [(set (match_operand:DI 0 "register_operand" "=r")
1958         (match_operand:DI 1 "const0_operand" "i"))
1959    (clobber (reg:CC FLAGS_REG))]
1960   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1961    && reload_completed"
1962   "xor{l}\t{%k0, %k0|%k0, %k0}"
1963   [(set_attr "type" "alu1")
1964    (set_attr "mode" "SI")
1965    (set_attr "length_immediate" "0")])
1966
1967 (define_insn "*movdi_or_rex64"
1968   [(set (match_operand:DI 0 "register_operand" "=r")
1969         (match_operand:DI 1 "const_int_operand" "i"))
1970    (clobber (reg:CC FLAGS_REG))]
1971   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1972    && reload_completed
1973    && operands[1] == constm1_rtx"
1974 {
1975   operands[1] = constm1_rtx;
1976   return "or{q}\t{%1, %0|%0, %1}";
1977 }
1978   [(set_attr "type" "alu1")
1979    (set_attr "mode" "DI")
1980    (set_attr "length_immediate" "1")])
1981
1982 (define_insn "*movdi_2"
1983   [(set (match_operand:DI 0 "nonimmediate_operand"
1984                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
1985         (match_operand:DI 1 "general_operand"
1986                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
1987   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1988   "@
1989    #
1990    #
1991    pxor\t%0, %0
1992    movq\t{%1, %0|%0, %1}
1993    movq\t{%1, %0|%0, %1}
1994    pxor\t%0, %0
1995    movq\t{%1, %0|%0, %1}
1996    movdqa\t{%1, %0|%0, %1}
1997    movq\t{%1, %0|%0, %1}
1998    xorps\t%0, %0
1999    movlps\t{%1, %0|%0, %1}
2000    movaps\t{%1, %0|%0, %1}
2001    movlps\t{%1, %0|%0, %1}"
2002   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2003    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2004
2005 (define_split
2006   [(set (match_operand:DI 0 "push_operand" "")
2007         (match_operand:DI 1 "general_operand" ""))]
2008   "!TARGET_64BIT && reload_completed
2009    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2010   [(const_int 0)]
2011   "ix86_split_long_move (operands); DONE;")
2012
2013 ;; %%% This multiword shite has got to go.
2014 (define_split
2015   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2016         (match_operand:DI 1 "general_operand" ""))]
2017   "!TARGET_64BIT && reload_completed
2018    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2019    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2020   [(const_int 0)]
2021   "ix86_split_long_move (operands); DONE;")
2022
2023 (define_insn "*movdi_1_rex64"
2024   [(set (match_operand:DI 0 "nonimmediate_operand"
2025           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2026         (match_operand:DI 1 "general_operand"
2027           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2028   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2029 {
2030   switch (get_attr_type (insn))
2031     {
2032     case TYPE_SSECVT:
2033       if (SSE_REG_P (operands[0]))
2034         return "movq2dq\t{%1, %0|%0, %1}";
2035       else
2036         return "movdq2q\t{%1, %0|%0, %1}";
2037
2038     case TYPE_SSEMOV:
2039       if (get_attr_mode (insn) == MODE_TI)
2040         return "movdqa\t{%1, %0|%0, %1}";
2041       /* FALLTHRU */
2042
2043     case TYPE_MMXMOV:
2044       /* Moves from and into integer register is done using movd
2045          opcode with REX prefix.  */
2046       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2047         return "movd\t{%1, %0|%0, %1}";
2048       return "movq\t{%1, %0|%0, %1}";
2049
2050     case TYPE_SSELOG1:
2051     case TYPE_MMXADD:
2052       return "pxor\t%0, %0";
2053
2054     case TYPE_MULTI:
2055       return "#";
2056
2057     case TYPE_LEA:
2058       return "lea{q}\t{%a1, %0|%0, %a1}";
2059
2060     default:
2061       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2062       if (get_attr_mode (insn) == MODE_SI)
2063         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2064       else if (which_alternative == 2)
2065         return "movabs{q}\t{%1, %0|%0, %1}";
2066       else
2067         return "mov{q}\t{%1, %0|%0, %1}";
2068     }
2069 }
2070   [(set (attr "type")
2071      (cond [(eq_attr "alternative" "5")
2072               (const_string "mmxadd")
2073             (eq_attr "alternative" "6,7,8,9,10")
2074               (const_string "mmxmov")
2075             (eq_attr "alternative" "11")
2076               (const_string "sselog1")
2077             (eq_attr "alternative" "12,13,14,15,16")
2078               (const_string "ssemov")
2079             (eq_attr "alternative" "17,18")
2080               (const_string "ssecvt")
2081             (eq_attr "alternative" "4")
2082               (const_string "multi")
2083             (match_operand:DI 1 "pic_32bit_operand" "")
2084               (const_string "lea")
2085            ]
2086            (const_string "imov")))
2087    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2088    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2089    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2090
2091 ;; Stores and loads of ax to arbitrary constant address.
2092 ;; We fake an second form of instruction to force reload to load address
2093 ;; into register when rax is not available
2094 (define_insn "*movabsdi_1_rex64"
2095   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2096         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2097   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2098   "@
2099    movabs{q}\t{%1, %P0|%P0, %1}
2100    mov{q}\t{%1, %a0|%a0, %1}"
2101   [(set_attr "type" "imov")
2102    (set_attr "modrm" "0,*")
2103    (set_attr "length_address" "8,0")
2104    (set_attr "length_immediate" "0,*")
2105    (set_attr "memory" "store")
2106    (set_attr "mode" "DI")])
2107
2108 (define_insn "*movabsdi_2_rex64"
2109   [(set (match_operand:DI 0 "register_operand" "=a,r")
2110         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2111   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2112   "@
2113    movabs{q}\t{%P1, %0|%0, %P1}
2114    mov{q}\t{%a1, %0|%0, %a1}"
2115   [(set_attr "type" "imov")
2116    (set_attr "modrm" "0,*")
2117    (set_attr "length_address" "8,0")
2118    (set_attr "length_immediate" "0")
2119    (set_attr "memory" "load")
2120    (set_attr "mode" "DI")])
2121
2122 ;; Convert impossible stores of immediate to existing instructions.
2123 ;; First try to get scratch register and go through it.  In case this
2124 ;; fails, move by 32bit parts.
2125 (define_peephole2
2126   [(match_scratch:DI 2 "r")
2127    (set (match_operand:DI 0 "memory_operand" "")
2128         (match_operand:DI 1 "immediate_operand" ""))]
2129   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130    && !x86_64_immediate_operand (operands[1], DImode)"
2131   [(set (match_dup 2) (match_dup 1))
2132    (set (match_dup 0) (match_dup 2))]
2133   "")
2134
2135 ;; We need to define this as both peepholer and splitter for case
2136 ;; peephole2 pass is not run.
2137 ;; "&& 1" is needed to keep it from matching the previous pattern.
2138 (define_peephole2
2139   [(set (match_operand:DI 0 "memory_operand" "")
2140         (match_operand:DI 1 "immediate_operand" ""))]
2141   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2142    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2143   [(set (match_dup 2) (match_dup 3))
2144    (set (match_dup 4) (match_dup 5))]
2145   "split_di (operands, 2, operands + 2, operands + 4);")
2146
2147 (define_split
2148   [(set (match_operand:DI 0 "memory_operand" "")
2149         (match_operand:DI 1 "immediate_operand" ""))]
2150   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2151                     ? flow2_completed : reload_completed)
2152    && !symbolic_operand (operands[1], DImode)
2153    && !x86_64_immediate_operand (operands[1], DImode)"
2154   [(set (match_dup 2) (match_dup 3))
2155    (set (match_dup 4) (match_dup 5))]
2156   "split_di (operands, 2, operands + 2, operands + 4);")
2157
2158 (define_insn "*swapdi_rex64"
2159   [(set (match_operand:DI 0 "register_operand" "+r")
2160         (match_operand:DI 1 "register_operand" "+r"))
2161    (set (match_dup 1)
2162         (match_dup 0))]
2163   "TARGET_64BIT"
2164   "xchg{q}\t%1, %0"
2165   [(set_attr "type" "imov")
2166    (set_attr "mode" "DI")
2167    (set_attr "pent_pair" "np")
2168    (set_attr "athlon_decode" "vector")
2169    (set_attr "amdfam10_decode" "double")])   
2170
2171 (define_expand "movti"
2172   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2173         (match_operand:TI 1 "nonimmediate_operand" ""))]
2174   "TARGET_SSE || TARGET_64BIT"
2175 {
2176   if (TARGET_64BIT)
2177     ix86_expand_move (TImode, operands);
2178   else
2179     ix86_expand_vector_move (TImode, operands);
2180   DONE;
2181 })
2182
2183 (define_insn "*movti_internal"
2184   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2185         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2186   "TARGET_SSE && !TARGET_64BIT
2187    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2188 {
2189   switch (which_alternative)
2190     {
2191     case 0:
2192       if (get_attr_mode (insn) == MODE_V4SF)
2193         return "xorps\t%0, %0";
2194       else
2195         return "pxor\t%0, %0";
2196     case 1:
2197     case 2:
2198       if (get_attr_mode (insn) == MODE_V4SF)
2199         return "movaps\t{%1, %0|%0, %1}";
2200       else
2201         return "movdqa\t{%1, %0|%0, %1}";
2202     default:
2203       gcc_unreachable ();
2204     }
2205 }
2206   [(set_attr "type" "sselog1,ssemov,ssemov")
2207    (set (attr "mode")
2208         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2209                     (ne (symbol_ref "optimize_size") (const_int 0)))
2210                  (const_string "V4SF")
2211                (and (eq_attr "alternative" "2")
2212                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2213                         (const_int 0)))
2214                  (const_string "V4SF")]
2215               (const_string "TI")))])
2216
2217 (define_insn "*movti_rex64"
2218   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2219         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2220   "TARGET_64BIT
2221    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2222 {
2223   switch (which_alternative)
2224     {
2225     case 0:
2226     case 1:
2227       return "#";
2228     case 2:
2229       if (get_attr_mode (insn) == MODE_V4SF)
2230         return "xorps\t%0, %0";
2231       else
2232         return "pxor\t%0, %0";
2233     case 3:
2234     case 4:
2235       if (get_attr_mode (insn) == MODE_V4SF)
2236         return "movaps\t{%1, %0|%0, %1}";
2237       else
2238         return "movdqa\t{%1, %0|%0, %1}";
2239     default:
2240       gcc_unreachable ();
2241     }
2242 }
2243   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2244    (set (attr "mode")
2245         (cond [(eq_attr "alternative" "2,3")
2246                  (if_then_else
2247                    (ne (symbol_ref "optimize_size")
2248                        (const_int 0))
2249                    (const_string "V4SF")
2250                    (const_string "TI"))
2251                (eq_attr "alternative" "4")
2252                  (if_then_else
2253                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2254                             (const_int 0))
2255                         (ne (symbol_ref "optimize_size")
2256                             (const_int 0)))
2257                    (const_string "V4SF")
2258                    (const_string "TI"))]
2259                (const_string "DI")))])
2260
2261 (define_split
2262   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2263         (match_operand:TI 1 "general_operand" ""))]
2264   "reload_completed && !SSE_REG_P (operands[0])
2265    && !SSE_REG_P (operands[1])"
2266   [(const_int 0)]
2267   "ix86_split_long_move (operands); DONE;")
2268
2269 (define_expand "movsf"
2270   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2271         (match_operand:SF 1 "general_operand" ""))]
2272   ""
2273   "ix86_expand_move (SFmode, operands); DONE;")
2274
2275 (define_insn "*pushsf"
2276   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2277         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2278   "!TARGET_64BIT"
2279 {
2280   /* Anything else should be already split before reg-stack.  */
2281   gcc_assert (which_alternative == 1);
2282   return "push{l}\t%1";
2283 }
2284   [(set_attr "type" "multi,push,multi")
2285    (set_attr "unit" "i387,*,*")
2286    (set_attr "mode" "SF,SI,SF")])
2287
2288 (define_insn "*pushsf_rex64"
2289   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2290         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2291   "TARGET_64BIT"
2292 {
2293   /* Anything else should be already split before reg-stack.  */
2294   gcc_assert (which_alternative == 1);
2295   return "push{q}\t%q1";
2296 }
2297   [(set_attr "type" "multi,push,multi")
2298    (set_attr "unit" "i387,*,*")
2299    (set_attr "mode" "SF,DI,SF")])
2300
2301 (define_split
2302   [(set (match_operand:SF 0 "push_operand" "")
2303         (match_operand:SF 1 "memory_operand" ""))]
2304   "reload_completed
2305    && MEM_P (operands[1])
2306    && constant_pool_reference_p (operands[1])"
2307   [(set (match_dup 0)
2308         (match_dup 1))]
2309   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2310
2311
2312 ;; %%% Kill this when call knows how to work this out.
2313 (define_split
2314   [(set (match_operand:SF 0 "push_operand" "")
2315         (match_operand:SF 1 "any_fp_register_operand" ""))]
2316   "!TARGET_64BIT"
2317   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2318    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2319
2320 (define_split
2321   [(set (match_operand:SF 0 "push_operand" "")
2322         (match_operand:SF 1 "any_fp_register_operand" ""))]
2323   "TARGET_64BIT"
2324   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2325    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2326
2327 (define_insn "*movsf_1"
2328   [(set (match_operand:SF 0 "nonimmediate_operand"
2329           "=f,m,f,r  ,m ,x,x,x ,m,*y,m ,*y,Yi,r ,*Ym,r  ")
2330         (match_operand:SF 1 "general_operand"
2331           "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y,r ,Yi,r  ,*Ym"))]
2332   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2333    && (reload_in_progress || reload_completed
2334        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2335        || (!TARGET_SSE_MATH && optimize_size
2336            && standard_80387_constant_p (operands[1]))
2337        || GET_CODE (operands[1]) != CONST_DOUBLE
2338        || memory_operand (operands[0], SFmode))"
2339 {
2340   switch (which_alternative)
2341     {
2342     case 0:
2343       return output_387_reg_move (insn, operands);
2344
2345     case 1:
2346       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2347         return "fstp%z0\t%y0";
2348       else
2349         return "fst%z0\t%y0";
2350
2351     case 2:
2352       return standard_80387_constant_opcode (operands[1]);
2353
2354     case 3:
2355     case 4:
2356       return "mov{l}\t{%1, %0|%0, %1}";
2357     case 5:
2358       if (get_attr_mode (insn) == MODE_TI)
2359         return "pxor\t%0, %0";
2360       else
2361         return "xorps\t%0, %0";
2362     case 6:
2363       if (get_attr_mode (insn) == MODE_V4SF)
2364         return "movaps\t{%1, %0|%0, %1}";
2365       else
2366         return "movss\t{%1, %0|%0, %1}";
2367     case 7: case 8:
2368       return "movss\t{%1, %0|%0, %1}";
2369
2370     case 9: case 10:
2371     case 12: case 13: case 14: case 15:
2372       return "movd\t{%1, %0|%0, %1}";
2373
2374     case 11:
2375       return "movq\t{%1, %0|%0, %1}";
2376
2377     default:
2378       gcc_unreachable ();
2379     }
2380 }
2381   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2382    (set (attr "mode")
2383         (cond [(eq_attr "alternative" "3,4,9,10")
2384                  (const_string "SI")
2385                (eq_attr "alternative" "5")
2386                  (if_then_else
2387                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2388                                  (const_int 0))
2389                              (ne (symbol_ref "TARGET_SSE2")
2390                                  (const_int 0)))
2391                         (eq (symbol_ref "optimize_size")
2392                             (const_int 0)))
2393                    (const_string "TI")
2394                    (const_string "V4SF"))
2395                /* For architectures resolving dependencies on
2396                   whole SSE registers use APS move to break dependency
2397                   chains, otherwise use short move to avoid extra work.
2398
2399                   Do the same for architectures resolving dependencies on
2400                   the parts.  While in DF mode it is better to always handle
2401                   just register parts, the SF mode is different due to lack
2402                   of instructions to load just part of the register.  It is
2403                   better to maintain the whole registers in single format
2404                   to avoid problems on using packed logical operations.  */
2405                (eq_attr "alternative" "6")
2406                  (if_then_else
2407                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2408                             (const_int 0))
2409                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2410                             (const_int 0)))
2411                    (const_string "V4SF")
2412                    (const_string "SF"))
2413                (eq_attr "alternative" "11")
2414                  (const_string "DI")]
2415                (const_string "SF")))])
2416
2417 (define_insn "*swapsf"
2418   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2419         (match_operand:SF 1 "fp_register_operand" "+f"))
2420    (set (match_dup 1)
2421         (match_dup 0))]
2422   "reload_completed || TARGET_80387"
2423 {
2424   if (STACK_TOP_P (operands[0]))
2425     return "fxch\t%1";
2426   else
2427     return "fxch\t%0";
2428 }
2429   [(set_attr "type" "fxch")
2430    (set_attr "mode" "SF")])
2431
2432 (define_expand "movdf"
2433   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2434         (match_operand:DF 1 "general_operand" ""))]
2435   ""
2436   "ix86_expand_move (DFmode, operands); DONE;")
2437
2438 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2439 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2440 ;; On the average, pushdf using integers can be still shorter.  Allow this
2441 ;; pattern for optimize_size too.
2442
2443 (define_insn "*pushdf_nointeger"
2444   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2445         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2446   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2447 {
2448   /* This insn should be already split before reg-stack.  */
2449   gcc_unreachable ();
2450 }
2451   [(set_attr "type" "multi")
2452    (set_attr "unit" "i387,*,*,*")
2453    (set_attr "mode" "DF,SI,SI,DF")])
2454
2455 (define_insn "*pushdf_integer"
2456   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2457         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2458   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2459 {
2460   /* This insn should be already split before reg-stack.  */
2461   gcc_unreachable ();
2462 }
2463   [(set_attr "type" "multi")
2464    (set_attr "unit" "i387,*,*")
2465    (set_attr "mode" "DF,SI,DF")])
2466
2467 ;; %%% Kill this when call knows how to work this out.
2468 (define_split
2469   [(set (match_operand:DF 0 "push_operand" "")
2470         (match_operand:DF 1 "any_fp_register_operand" ""))]
2471   "!TARGET_64BIT && reload_completed"
2472   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2473    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2474   "")
2475
2476 (define_split
2477   [(set (match_operand:DF 0 "push_operand" "")
2478         (match_operand:DF 1 "any_fp_register_operand" ""))]
2479   "TARGET_64BIT && reload_completed"
2480   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2481    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2482   "")
2483
2484 (define_split
2485   [(set (match_operand:DF 0 "push_operand" "")
2486         (match_operand:DF 1 "general_operand" ""))]
2487   "reload_completed"
2488   [(const_int 0)]
2489   "ix86_split_long_move (operands); DONE;")
2490
2491 ;; Moving is usually shorter when only FP registers are used. This separate
2492 ;; movdf pattern avoids the use of integer registers for FP operations
2493 ;; when optimizing for size.
2494
2495 (define_insn "*movdf_nointeger"
2496   [(set (match_operand:DF 0 "nonimmediate_operand"
2497                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2498         (match_operand:DF 1 "general_operand"
2499                         "fm,f,G,*roF,F*r,C   ,Y2*x,mY2*x,Y2*x"))]
2500   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2501    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2502    && (reload_in_progress || reload_completed
2503        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2504        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2505            && standard_80387_constant_p (operands[1]))
2506        || GET_CODE (operands[1]) != CONST_DOUBLE
2507        || memory_operand (operands[0], DFmode))"
2508 {
2509   switch (which_alternative)
2510     {
2511     case 0:
2512       return output_387_reg_move (insn, operands);
2513
2514     case 1:
2515       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2516         return "fstp%z0\t%y0";
2517       else
2518         return "fst%z0\t%y0";
2519
2520     case 2:
2521       return standard_80387_constant_opcode (operands[1]);
2522
2523     case 3:
2524     case 4:
2525       return "#";
2526     case 5:
2527       switch (get_attr_mode (insn))
2528         {
2529         case MODE_V4SF:
2530           return "xorps\t%0, %0";
2531         case MODE_V2DF:
2532           return "xorpd\t%0, %0";
2533         case MODE_TI:
2534           return "pxor\t%0, %0";
2535         default:
2536           gcc_unreachable ();
2537         }
2538     case 6:
2539     case 7:
2540     case 8:
2541       switch (get_attr_mode (insn))
2542         {
2543         case MODE_V4SF:
2544           return "movaps\t{%1, %0|%0, %1}";
2545         case MODE_V2DF:
2546           return "movapd\t{%1, %0|%0, %1}";
2547         case MODE_TI:
2548           return "movdqa\t{%1, %0|%0, %1}";
2549         case MODE_DI:
2550           return "movq\t{%1, %0|%0, %1}";
2551         case MODE_DF:
2552           return "movsd\t{%1, %0|%0, %1}";
2553         case MODE_V1DF:
2554           return "movlpd\t{%1, %0|%0, %1}";
2555         case MODE_V2SF:
2556           return "movlps\t{%1, %0|%0, %1}";
2557         default:
2558           gcc_unreachable ();
2559         }
2560
2561     default:
2562       gcc_unreachable ();
2563     }
2564 }
2565   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2566    (set (attr "mode")
2567         (cond [(eq_attr "alternative" "0,1,2")
2568                  (const_string "DF")
2569                (eq_attr "alternative" "3,4")
2570                  (const_string "SI")
2571
2572                /* For SSE1, we have many fewer alternatives.  */
2573                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2574                  (cond [(eq_attr "alternative" "5,6")
2575                           (const_string "V4SF")
2576                        ]
2577                    (const_string "V2SF"))
2578
2579                /* xorps is one byte shorter.  */
2580                (eq_attr "alternative" "5")
2581                  (cond [(ne (symbol_ref "optimize_size")
2582                             (const_int 0))
2583                           (const_string "V4SF")
2584                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2585                             (const_int 0))
2586                           (const_string "TI")
2587                        ]
2588                        (const_string "V2DF"))
2589
2590                /* For architectures resolving dependencies on
2591                   whole SSE registers use APD move to break dependency
2592                   chains, otherwise use short move to avoid extra work.
2593
2594                   movaps encodes one byte shorter.  */
2595                (eq_attr "alternative" "6")
2596                  (cond
2597                    [(ne (symbol_ref "optimize_size")
2598                         (const_int 0))
2599                       (const_string "V4SF")
2600                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2601                         (const_int 0))
2602                       (const_string "V2DF")
2603                    ]
2604                    (const_string "DF"))
2605                /* For architectures resolving dependencies on register
2606                   parts we may avoid extra work to zero out upper part
2607                   of register.  */
2608                (eq_attr "alternative" "7")
2609                  (if_then_else
2610                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2611                        (const_int 0))
2612                    (const_string "V1DF")
2613                    (const_string "DF"))
2614               ]
2615               (const_string "DF")))])
2616
2617 (define_insn "*movdf_integer_rex64"
2618   [(set (match_operand:DF 0 "nonimmediate_operand"
2619                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2620         (match_operand:DF 1 "general_operand"
2621                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2622   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2623    && (reload_in_progress || reload_completed
2624        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2625        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2626            && standard_80387_constant_p (operands[1]))
2627        || GET_CODE (operands[1]) != CONST_DOUBLE
2628        || memory_operand (operands[0], DFmode))"
2629 {
2630   switch (which_alternative)
2631     {
2632     case 0:
2633       return output_387_reg_move (insn, operands);
2634
2635     case 1:
2636       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2637         return "fstp%z0\t%y0";
2638       else
2639         return "fst%z0\t%y0";
2640
2641     case 2:
2642       return standard_80387_constant_opcode (operands[1]);
2643
2644     case 3:
2645     case 4:
2646       return "#";
2647
2648     case 5:
2649       switch (get_attr_mode (insn))
2650         {
2651         case MODE_V4SF:
2652           return "xorps\t%0, %0";
2653         case MODE_V2DF:
2654           return "xorpd\t%0, %0";
2655         case MODE_TI:
2656           return "pxor\t%0, %0";
2657         default:
2658           gcc_unreachable ();
2659         }
2660     case 6:
2661     case 7:
2662     case 8:
2663       switch (get_attr_mode (insn))
2664         {
2665         case MODE_V4SF:
2666           return "movaps\t{%1, %0|%0, %1}";
2667         case MODE_V2DF:
2668           return "movapd\t{%1, %0|%0, %1}";
2669         case MODE_TI:
2670           return "movdqa\t{%1, %0|%0, %1}";
2671         case MODE_DI:
2672           return "movq\t{%1, %0|%0, %1}";
2673         case MODE_DF:
2674           return "movsd\t{%1, %0|%0, %1}";
2675         case MODE_V1DF:
2676           return "movlpd\t{%1, %0|%0, %1}";
2677         case MODE_V2SF:
2678           return "movlps\t{%1, %0|%0, %1}";
2679         default:
2680           gcc_unreachable ();
2681         }
2682
2683     case 9:
2684     case 10:
2685       return "movd\t{%1, %0|%0, %1}";
2686
2687     default:
2688       gcc_unreachable();
2689     }
2690 }
2691   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2692    (set (attr "mode")
2693         (cond [(eq_attr "alternative" "0,1,2")
2694                  (const_string "DF")
2695                (eq_attr "alternative" "3,4,9,10")
2696                  (const_string "DI")
2697
2698                /* For SSE1, we have many fewer alternatives.  */
2699                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2700                  (cond [(eq_attr "alternative" "5,6")
2701                           (const_string "V4SF")
2702                        ]
2703                    (const_string "V2SF"))
2704
2705                /* xorps is one byte shorter.  */
2706                (eq_attr "alternative" "5")
2707                  (cond [(ne (symbol_ref "optimize_size")
2708                             (const_int 0))
2709                           (const_string "V4SF")
2710                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2711                             (const_int 0))
2712                           (const_string "TI")
2713                        ]
2714                        (const_string "V2DF"))
2715
2716                /* For architectures resolving dependencies on
2717                   whole SSE registers use APD move to break dependency
2718                   chains, otherwise use short move to avoid extra work.
2719
2720                   movaps encodes one byte shorter.  */
2721                (eq_attr "alternative" "6")
2722                  (cond
2723                    [(ne (symbol_ref "optimize_size")
2724                         (const_int 0))
2725                       (const_string "V4SF")
2726                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2727                         (const_int 0))
2728                       (const_string "V2DF")
2729                    ]
2730                    (const_string "DF"))
2731                /* For architectures resolving dependencies on register
2732                   parts we may avoid extra work to zero out upper part
2733                   of register.  */
2734                (eq_attr "alternative" "7")
2735                  (if_then_else
2736                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2737                        (const_int 0))
2738                    (const_string "V1DF")
2739                    (const_string "DF"))
2740               ]
2741               (const_string "DF")))])
2742
2743 (define_insn "*movdf_integer"
2744   [(set (match_operand:DF 0 "nonimmediate_operand"
2745                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2746         (match_operand:DF 1 "general_operand"
2747                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2748   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2749    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2750    && (reload_in_progress || reload_completed
2751        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2752        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2753            && standard_80387_constant_p (operands[1]))
2754        || GET_CODE (operands[1]) != CONST_DOUBLE
2755        || memory_operand (operands[0], DFmode))"
2756 {
2757   switch (which_alternative)
2758     {
2759     case 0:
2760       return output_387_reg_move (insn, operands);
2761
2762     case 1:
2763       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2764         return "fstp%z0\t%y0";
2765       else
2766         return "fst%z0\t%y0";
2767
2768     case 2:
2769       return standard_80387_constant_opcode (operands[1]);
2770
2771     case 3:
2772     case 4:
2773       return "#";
2774
2775     case 5:
2776       switch (get_attr_mode (insn))
2777         {
2778         case MODE_V4SF:
2779           return "xorps\t%0, %0";
2780         case MODE_V2DF:
2781           return "xorpd\t%0, %0";
2782         case MODE_TI:
2783           return "pxor\t%0, %0";
2784         default:
2785           gcc_unreachable ();
2786         }
2787     case 6:
2788     case 7:
2789     case 8:
2790       switch (get_attr_mode (insn))
2791         {
2792         case MODE_V4SF:
2793           return "movaps\t{%1, %0|%0, %1}";
2794         case MODE_V2DF:
2795           return "movapd\t{%1, %0|%0, %1}";
2796         case MODE_TI:
2797           return "movdqa\t{%1, %0|%0, %1}";
2798         case MODE_DI:
2799           return "movq\t{%1, %0|%0, %1}";
2800         case MODE_DF:
2801           return "movsd\t{%1, %0|%0, %1}";
2802         case MODE_V1DF:
2803           return "movlpd\t{%1, %0|%0, %1}";
2804         case MODE_V2SF:
2805           return "movlps\t{%1, %0|%0, %1}";
2806         default:
2807           gcc_unreachable ();
2808         }
2809
2810     default:
2811       gcc_unreachable();
2812     }
2813 }
2814   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2815    (set (attr "mode")
2816         (cond [(eq_attr "alternative" "0,1,2")
2817                  (const_string "DF")
2818                (eq_attr "alternative" "3,4")
2819                  (const_string "SI")
2820
2821                /* For SSE1, we have many fewer alternatives.  */
2822                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2823                  (cond [(eq_attr "alternative" "5,6")
2824                           (const_string "V4SF")
2825                        ]
2826                    (const_string "V2SF"))
2827
2828                /* xorps is one byte shorter.  */
2829                (eq_attr "alternative" "5")
2830                  (cond [(ne (symbol_ref "optimize_size")
2831                             (const_int 0))
2832                           (const_string "V4SF")
2833                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2834                             (const_int 0))
2835                           (const_string "TI")
2836                        ]
2837                        (const_string "V2DF"))
2838
2839                /* For architectures resolving dependencies on
2840                   whole SSE registers use APD move to break dependency
2841                   chains, otherwise use short move to avoid extra work.
2842
2843                   movaps encodes one byte shorter.  */
2844                (eq_attr "alternative" "6")
2845                  (cond
2846                    [(ne (symbol_ref "optimize_size")
2847                         (const_int 0))
2848                       (const_string "V4SF")
2849                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2850                         (const_int 0))
2851                       (const_string "V2DF")
2852                    ]
2853                    (const_string "DF"))
2854                /* For architectures resolving dependencies on register
2855                   parts we may avoid extra work to zero out upper part
2856                   of register.  */
2857                (eq_attr "alternative" "7")
2858                  (if_then_else
2859                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2860                        (const_int 0))
2861                    (const_string "V1DF")
2862                    (const_string "DF"))
2863               ]
2864               (const_string "DF")))])
2865
2866 (define_split
2867   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2868         (match_operand:DF 1 "general_operand" ""))]
2869   "reload_completed
2870    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2871    && ! (ANY_FP_REG_P (operands[0]) ||
2872          (GET_CODE (operands[0]) == SUBREG
2873           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2874    && ! (ANY_FP_REG_P (operands[1]) ||
2875          (GET_CODE (operands[1]) == SUBREG
2876           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2877   [(const_int 0)]
2878   "ix86_split_long_move (operands); DONE;")
2879
2880 (define_insn "*swapdf"
2881   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2882         (match_operand:DF 1 "fp_register_operand" "+f"))
2883    (set (match_dup 1)
2884         (match_dup 0))]
2885   "reload_completed || TARGET_80387"
2886 {
2887   if (STACK_TOP_P (operands[0]))
2888     return "fxch\t%1";
2889   else
2890     return "fxch\t%0";
2891 }
2892   [(set_attr "type" "fxch")
2893    (set_attr "mode" "DF")])
2894
2895 (define_expand "movxf"
2896   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2897         (match_operand:XF 1 "general_operand" ""))]
2898   ""
2899   "ix86_expand_move (XFmode, operands); DONE;")
2900
2901 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2902 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2903 ;; Pushing using integer instructions is longer except for constants
2904 ;; and direct memory references.
2905 ;; (assuming that any given constant is pushed only once, but this ought to be
2906 ;;  handled elsewhere).
2907
2908 (define_insn "*pushxf_nointeger"
2909   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2910         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2911   "optimize_size"
2912 {
2913   /* This insn should be already split before reg-stack.  */
2914   gcc_unreachable ();
2915 }
2916   [(set_attr "type" "multi")
2917    (set_attr "unit" "i387,*,*")
2918    (set_attr "mode" "XF,SI,SI")])
2919
2920 (define_insn "*pushxf_integer"
2921   [(set (match_operand:XF 0 "push_operand" "=<,<")
2922         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2923   "!optimize_size"
2924 {
2925   /* This insn should be already split before reg-stack.  */
2926   gcc_unreachable ();
2927 }
2928   [(set_attr "type" "multi")
2929    (set_attr "unit" "i387,*")
2930    (set_attr "mode" "XF,SI")])
2931
2932 (define_split
2933   [(set (match_operand 0 "push_operand" "")
2934         (match_operand 1 "general_operand" ""))]
2935   "reload_completed
2936    && (GET_MODE (operands[0]) == XFmode
2937        || GET_MODE (operands[0]) == DFmode)
2938    && !ANY_FP_REG_P (operands[1])"
2939   [(const_int 0)]
2940   "ix86_split_long_move (operands); DONE;")
2941
2942 (define_split
2943   [(set (match_operand:XF 0 "push_operand" "")
2944         (match_operand:XF 1 "any_fp_register_operand" ""))]
2945   "!TARGET_64BIT"
2946   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2947    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2948   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2949
2950 (define_split
2951   [(set (match_operand:XF 0 "push_operand" "")
2952         (match_operand:XF 1 "any_fp_register_operand" ""))]
2953   "TARGET_64BIT"
2954   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2955    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2956   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2957
2958 ;; Do not use integer registers when optimizing for size
2959 (define_insn "*movxf_nointeger"
2960   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2961         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2962   "optimize_size
2963    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2964    && (reload_in_progress || reload_completed
2965        || (optimize_size && standard_80387_constant_p (operands[1]))
2966        || GET_CODE (operands[1]) != CONST_DOUBLE
2967        || memory_operand (operands[0], XFmode))"
2968 {
2969   switch (which_alternative)
2970     {
2971     case 0:
2972       return output_387_reg_move (insn, operands);
2973
2974     case 1:
2975       /* There is no non-popping store to memory for XFmode.  So if
2976          we need one, follow the store with a load.  */
2977       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2978         return "fstp%z0\t%y0\;fld%z0\t%y0";
2979       else
2980         return "fstp%z0\t%y0";
2981
2982     case 2:
2983       return standard_80387_constant_opcode (operands[1]);
2984
2985     case 3: case 4:
2986       return "#";
2987     default:
2988       gcc_unreachable ();
2989     }
2990 }
2991   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2992    (set_attr "mode" "XF,XF,XF,SI,SI")])
2993
2994 (define_insn "*movxf_integer"
2995   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2996         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2997   "!optimize_size
2998    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2999    && (reload_in_progress || reload_completed
3000        || (optimize_size && standard_80387_constant_p (operands[1]))
3001        || GET_CODE (operands[1]) != CONST_DOUBLE
3002        || memory_operand (operands[0], XFmode))"
3003 {
3004   switch (which_alternative)
3005     {
3006     case 0:
3007       return output_387_reg_move (insn, operands);
3008
3009     case 1:
3010       /* There is no non-popping store to memory for XFmode.  So if
3011          we need one, follow the store with a load.  */
3012       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3013         return "fstp%z0\t%y0\;fld%z0\t%y0";
3014       else
3015         return "fstp%z0\t%y0";
3016
3017     case 2:
3018       return standard_80387_constant_opcode (operands[1]);
3019
3020     case 3: case 4:
3021       return "#";
3022
3023     default:
3024       gcc_unreachable ();
3025     }
3026 }
3027   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3028    (set_attr "mode" "XF,XF,XF,SI,SI")])
3029
3030 (define_split
3031   [(set (match_operand 0 "nonimmediate_operand" "")
3032         (match_operand 1 "general_operand" ""))]
3033   "reload_completed
3034    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3035    && GET_MODE (operands[0]) == XFmode
3036    && ! (ANY_FP_REG_P (operands[0]) ||
3037          (GET_CODE (operands[0]) == SUBREG
3038           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3039    && ! (ANY_FP_REG_P (operands[1]) ||
3040          (GET_CODE (operands[1]) == SUBREG
3041           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3042   [(const_int 0)]
3043   "ix86_split_long_move (operands); DONE;")
3044
3045 (define_split
3046   [(set (match_operand 0 "register_operand" "")
3047         (match_operand 1 "memory_operand" ""))]
3048   "reload_completed
3049    && MEM_P (operands[1])
3050    && (GET_MODE (operands[0]) == XFmode
3051        || GET_MODE (operands[0]) == SFmode
3052        || GET_MODE (operands[0]) == DFmode)
3053    && constant_pool_reference_p (operands[1])"
3054   [(set (match_dup 0) (match_dup 1))]
3055 {
3056   rtx c = avoid_constant_pool_reference (operands[1]);
3057   rtx r = operands[0];
3058
3059   if (GET_CODE (r) == SUBREG)
3060     r = SUBREG_REG (r);
3061
3062   if (SSE_REG_P (r))
3063     {
3064       if (!standard_sse_constant_p (c))
3065         FAIL;
3066     }
3067   else if (FP_REG_P (r))
3068     {
3069       if (!standard_80387_constant_p (c))
3070         FAIL;
3071     }
3072   else if (MMX_REG_P (r))
3073     FAIL;
3074
3075   operands[1] = c;
3076 })
3077
3078 (define_split
3079   [(set (match_operand 0 "register_operand" "")
3080         (float_extend (match_operand 1 "memory_operand" "")))]
3081   "reload_completed
3082    && MEM_P (operands[1])
3083    && (GET_MODE (operands[0]) == XFmode
3084        || GET_MODE (operands[0]) == SFmode
3085        || GET_MODE (operands[0]) == DFmode)
3086    && constant_pool_reference_p (operands[1])"
3087   [(set (match_dup 0) (match_dup 1))]
3088 {
3089   rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
3090   rtx r = operands[0];
3091
3092   if (GET_CODE (r) == SUBREG)
3093     r = SUBREG_REG (r);
3094
3095   if (SSE_REG_P (r))
3096     {
3097       if (!standard_sse_constant_p (c))
3098         FAIL;
3099     }
3100   else if (FP_REG_P (r))
3101     {
3102       if (!standard_80387_constant_p (c))
3103         FAIL;
3104     }
3105   else if (MMX_REG_P (r))
3106     FAIL;
3107
3108   operands[1] = c;
3109 })
3110
3111 (define_insn "swapxf"
3112   [(set (match_operand:XF 0 "register_operand" "+f")
3113         (match_operand:XF 1 "register_operand" "+f"))
3114    (set (match_dup 1)
3115         (match_dup 0))]
3116   "TARGET_80387"
3117 {
3118   if (STACK_TOP_P (operands[0]))
3119     return "fxch\t%1";
3120   else
3121     return "fxch\t%0";
3122 }
3123   [(set_attr "type" "fxch")
3124    (set_attr "mode" "XF")])
3125
3126 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3127 (define_split
3128   [(set (match_operand:X87MODEF 0 "register_operand" "")
3129         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3130   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3131    && (standard_80387_constant_p (operands[1]) == 8
3132        || standard_80387_constant_p (operands[1]) == 9)"
3133   [(set (match_dup 0)(match_dup 1))
3134    (set (match_dup 0)
3135         (neg:X87MODEF (match_dup 0)))]
3136 {
3137   REAL_VALUE_TYPE r;
3138
3139   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3140   if (real_isnegzero (&r))
3141     operands[1] = CONST0_RTX (<MODE>mode);
3142   else
3143     operands[1] = CONST1_RTX (<MODE>mode);
3144 })
3145
3146 (define_expand "movtf"
3147   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3148         (match_operand:TF 1 "nonimmediate_operand" ""))]
3149   "TARGET_64BIT"
3150 {
3151   ix86_expand_move (TFmode, operands);
3152   DONE;
3153 })
3154
3155 (define_insn "*movtf_internal"
3156   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3157         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3158   "TARGET_64BIT
3159    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3160 {
3161   switch (which_alternative)
3162     {
3163     case 0:
3164     case 1:
3165       return "#";
3166     case 2:
3167       if (get_attr_mode (insn) == MODE_V4SF)
3168         return "xorps\t%0, %0";
3169       else
3170         return "pxor\t%0, %0";
3171     case 3:
3172     case 4:
3173       if (get_attr_mode (insn) == MODE_V4SF)
3174         return "movaps\t{%1, %0|%0, %1}";
3175       else
3176         return "movdqa\t{%1, %0|%0, %1}";
3177     default:
3178       gcc_unreachable ();
3179     }
3180 }
3181   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3182    (set (attr "mode")
3183         (cond [(eq_attr "alternative" "2,3")
3184                  (if_then_else
3185                    (ne (symbol_ref "optimize_size")
3186                        (const_int 0))
3187                    (const_string "V4SF")
3188                    (const_string "TI"))
3189                (eq_attr "alternative" "4")
3190                  (if_then_else
3191                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3192                             (const_int 0))
3193                         (ne (symbol_ref "optimize_size")
3194                             (const_int 0)))
3195                    (const_string "V4SF")
3196                    (const_string "TI"))]
3197                (const_string "DI")))])
3198
3199 (define_split
3200   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3201         (match_operand:TF 1 "general_operand" ""))]
3202   "reload_completed && !SSE_REG_P (operands[0])
3203    && !SSE_REG_P (operands[1])"
3204   [(const_int 0)]
3205   "ix86_split_long_move (operands); DONE;")
3206 \f
3207 ;; Zero extension instructions
3208
3209 (define_expand "zero_extendhisi2"
3210   [(set (match_operand:SI 0 "register_operand" "")
3211      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3212   ""
3213 {
3214   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3215     {
3216       operands[1] = force_reg (HImode, operands[1]);
3217       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3218       DONE;
3219     }
3220 })
3221
3222 (define_insn "zero_extendhisi2_and"
3223   [(set (match_operand:SI 0 "register_operand" "=r")
3224      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3225    (clobber (reg:CC FLAGS_REG))]
3226   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3227   "#"
3228   [(set_attr "type" "alu1")
3229    (set_attr "mode" "SI")])
3230
3231 (define_split
3232   [(set (match_operand:SI 0 "register_operand" "")
3233         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3234    (clobber (reg:CC FLAGS_REG))]
3235   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3236   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3237               (clobber (reg:CC FLAGS_REG))])]
3238   "")
3239
3240 (define_insn "*zero_extendhisi2_movzwl"
3241   [(set (match_operand:SI 0 "register_operand" "=r")
3242      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3243   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3244   "movz{wl|x}\t{%1, %0|%0, %1}"
3245   [(set_attr "type" "imovx")
3246    (set_attr "mode" "SI")])
3247
3248 (define_expand "zero_extendqihi2"
3249   [(parallel
3250     [(set (match_operand:HI 0 "register_operand" "")
3251        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3252      (clobber (reg:CC FLAGS_REG))])]
3253   ""
3254   "")
3255
3256 (define_insn "*zero_extendqihi2_and"
3257   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3258      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3259    (clobber (reg:CC FLAGS_REG))]
3260   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3261   "#"
3262   [(set_attr "type" "alu1")
3263    (set_attr "mode" "HI")])
3264
3265 (define_insn "*zero_extendqihi2_movzbw_and"
3266   [(set (match_operand:HI 0 "register_operand" "=r,r")
3267      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3268    (clobber (reg:CC FLAGS_REG))]
3269   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3270   "#"
3271   [(set_attr "type" "imovx,alu1")
3272    (set_attr "mode" "HI")])
3273
3274 ; zero extend to SImode here to avoid partial register stalls
3275 (define_insn "*zero_extendqihi2_movzbl"
3276   [(set (match_operand:HI 0 "register_operand" "=r")
3277      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3279   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3280   [(set_attr "type" "imovx")
3281    (set_attr "mode" "SI")])
3282
3283 ;; For the movzbw case strip only the clobber
3284 (define_split
3285   [(set (match_operand:HI 0 "register_operand" "")
3286         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3287    (clobber (reg:CC FLAGS_REG))]
3288   "reload_completed
3289    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3290    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3291   [(set (match_operand:HI 0 "register_operand" "")
3292         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3293
3294 ;; When source and destination does not overlap, clear destination
3295 ;; first and then do the movb
3296 (define_split
3297   [(set (match_operand:HI 0 "register_operand" "")
3298         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3299    (clobber (reg:CC FLAGS_REG))]
3300   "reload_completed
3301    && ANY_QI_REG_P (operands[0])
3302    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3303    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3304   [(set (match_dup 0) (const_int 0))
3305    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3306   "operands[2] = gen_lowpart (QImode, operands[0]);")
3307
3308 ;; Rest is handled by single and.
3309 (define_split
3310   [(set (match_operand:HI 0 "register_operand" "")
3311         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3312    (clobber (reg:CC FLAGS_REG))]
3313   "reload_completed
3314    && true_regnum (operands[0]) == true_regnum (operands[1])"
3315   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3316               (clobber (reg:CC FLAGS_REG))])]
3317   "")
3318
3319 (define_expand "zero_extendqisi2"
3320   [(parallel
3321     [(set (match_operand:SI 0 "register_operand" "")
3322        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3323      (clobber (reg:CC FLAGS_REG))])]
3324   ""
3325   "")
3326
3327 (define_insn "*zero_extendqisi2_and"
3328   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3329      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3330    (clobber (reg:CC FLAGS_REG))]
3331   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3332   "#"
3333   [(set_attr "type" "alu1")
3334    (set_attr "mode" "SI")])
3335
3336 (define_insn "*zero_extendqisi2_movzbw_and"
3337   [(set (match_operand:SI 0 "register_operand" "=r,r")
3338      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3339    (clobber (reg:CC FLAGS_REG))]
3340   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3341   "#"
3342   [(set_attr "type" "imovx,alu1")
3343    (set_attr "mode" "SI")])
3344
3345 (define_insn "*zero_extendqisi2_movzbw"
3346   [(set (match_operand:SI 0 "register_operand" "=r")
3347      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3348   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3349   "movz{bl|x}\t{%1, %0|%0, %1}"
3350   [(set_attr "type" "imovx")
3351    (set_attr "mode" "SI")])
3352
3353 ;; For the movzbl case strip only the clobber
3354 (define_split
3355   [(set (match_operand:SI 0 "register_operand" "")
3356         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3357    (clobber (reg:CC FLAGS_REG))]
3358   "reload_completed
3359    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3360    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3361   [(set (match_dup 0)
3362         (zero_extend:SI (match_dup 1)))])
3363
3364 ;; When source and destination does not overlap, clear destination
3365 ;; first and then do the movb
3366 (define_split
3367   [(set (match_operand:SI 0 "register_operand" "")
3368         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3369    (clobber (reg:CC FLAGS_REG))]
3370   "reload_completed
3371    && ANY_QI_REG_P (operands[0])
3372    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3373    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3374    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3375   [(set (match_dup 0) (const_int 0))
3376    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3377   "operands[2] = gen_lowpart (QImode, operands[0]);")
3378
3379 ;; Rest is handled by single and.
3380 (define_split
3381   [(set (match_operand:SI 0 "register_operand" "")
3382         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3383    (clobber (reg:CC FLAGS_REG))]
3384   "reload_completed
3385    && true_regnum (operands[0]) == true_regnum (operands[1])"
3386   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3387               (clobber (reg:CC FLAGS_REG))])]
3388   "")
3389
3390 ;; %%% Kill me once multi-word ops are sane.
3391 (define_expand "zero_extendsidi2"
3392   [(set (match_operand:DI 0 "register_operand" "=r")
3393      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3394   ""
3395 {
3396   if (!TARGET_64BIT)
3397     {
3398       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3399       DONE;
3400     }
3401 })
3402
3403 (define_insn "zero_extendsidi2_32"
3404   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,*y,?*Yi,*Y2")
3405         (zero_extend:DI
3406          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m ,r   ,m")))
3407    (clobber (reg:CC FLAGS_REG))]
3408   "!TARGET_64BIT"
3409   "@
3410    #
3411    #
3412    #
3413    movd\t{%1, %0|%0, %1}
3414    movd\t{%1, %0|%0, %1}
3415    movd\t{%1, %0|%0, %1}
3416    movd\t{%1, %0|%0, %1}"
3417   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3418    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3419
3420 (define_insn "zero_extendsidi2_rex64"
3421   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,*y,?*Yi,*Y2")
3422      (zero_extend:DI
3423        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m ,r   ,m")))]
3424   "TARGET_64BIT"
3425   "@
3426    mov\t{%k1, %k0|%k0, %k1}
3427    #
3428    movd\t{%1, %0|%0, %1}
3429    movd\t{%1, %0|%0, %1}
3430    movd\t{%1, %0|%0, %1}
3431    movd\t{%1, %0|%0, %1}"
3432   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3433    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3434
3435 (define_split
3436   [(set (match_operand:DI 0 "memory_operand" "")
3437      (zero_extend:DI (match_dup 0)))]
3438   "TARGET_64BIT"
3439   [(set (match_dup 4) (const_int 0))]
3440   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3441
3442 (define_split
3443   [(set (match_operand:DI 0 "register_operand" "")
3444         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3445    (clobber (reg:CC FLAGS_REG))]
3446   "!TARGET_64BIT && reload_completed
3447    && true_regnum (operands[0]) == true_regnum (operands[1])"
3448   [(set (match_dup 4) (const_int 0))]
3449   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3450
3451 (define_split
3452   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3453         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3454    (clobber (reg:CC FLAGS_REG))]
3455   "!TARGET_64BIT && reload_completed
3456    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3457   [(set (match_dup 3) (match_dup 1))
3458    (set (match_dup 4) (const_int 0))]
3459   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3460
3461 (define_insn "zero_extendhidi2"
3462   [(set (match_operand:DI 0 "register_operand" "=r")
3463      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3464   "TARGET_64BIT"
3465   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3466   [(set_attr "type" "imovx")
3467    (set_attr "mode" "DI")])
3468
3469 (define_insn "zero_extendqidi2"
3470   [(set (match_operand:DI 0 "register_operand" "=r")
3471      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3472   "TARGET_64BIT"
3473   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3474   [(set_attr "type" "imovx")
3475    (set_attr "mode" "DI")])
3476 \f
3477 ;; Sign extension instructions
3478
3479 (define_expand "extendsidi2"
3480   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3481                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3482               (clobber (reg:CC FLAGS_REG))
3483               (clobber (match_scratch:SI 2 ""))])]
3484   ""
3485 {
3486   if (TARGET_64BIT)
3487     {
3488       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3489       DONE;
3490     }
3491 })
3492
3493 (define_insn "*extendsidi2_1"
3494   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3495         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3496    (clobber (reg:CC FLAGS_REG))
3497    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3498   "!TARGET_64BIT"
3499   "#")
3500
3501 (define_insn "extendsidi2_rex64"
3502   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3503         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3504   "TARGET_64BIT"
3505   "@
3506    {cltq|cdqe}
3507    movs{lq|x}\t{%1,%0|%0, %1}"
3508   [(set_attr "type" "imovx")
3509    (set_attr "mode" "DI")
3510    (set_attr "prefix_0f" "0")
3511    (set_attr "modrm" "0,1")])
3512
3513 (define_insn "extendhidi2"
3514   [(set (match_operand:DI 0 "register_operand" "=r")
3515         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3516   "TARGET_64BIT"
3517   "movs{wq|x}\t{%1,%0|%0, %1}"
3518   [(set_attr "type" "imovx")
3519    (set_attr "mode" "DI")])
3520
3521 (define_insn "extendqidi2"
3522   [(set (match_operand:DI 0 "register_operand" "=r")
3523         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3524   "TARGET_64BIT"
3525   "movs{bq|x}\t{%1,%0|%0, %1}"
3526    [(set_attr "type" "imovx")
3527     (set_attr "mode" "DI")])
3528
3529 ;; Extend to memory case when source register does die.
3530 (define_split
3531   [(set (match_operand:DI 0 "memory_operand" "")
3532         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3533    (clobber (reg:CC FLAGS_REG))
3534    (clobber (match_operand:SI 2 "register_operand" ""))]
3535   "(reload_completed
3536     && dead_or_set_p (insn, operands[1])
3537     && !reg_mentioned_p (operands[1], operands[0]))"
3538   [(set (match_dup 3) (match_dup 1))
3539    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3540               (clobber (reg:CC FLAGS_REG))])
3541    (set (match_dup 4) (match_dup 1))]
3542   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3543
3544 ;; Extend to memory case when source register does not die.
3545 (define_split
3546   [(set (match_operand:DI 0 "memory_operand" "")
3547         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3548    (clobber (reg:CC FLAGS_REG))
3549    (clobber (match_operand:SI 2 "register_operand" ""))]
3550   "reload_completed"
3551   [(const_int 0)]
3552 {
3553   split_di (&operands[0], 1, &operands[3], &operands[4]);
3554
3555   emit_move_insn (operands[3], operands[1]);
3556
3557   /* Generate a cltd if possible and doing so it profitable.  */
3558   if (true_regnum (operands[1]) == 0
3559       && true_regnum (operands[2]) == 1
3560       && (optimize_size || TARGET_USE_CLTD))
3561     {
3562       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3563     }
3564   else
3565     {
3566       emit_move_insn (operands[2], operands[1]);
3567       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3568     }
3569   emit_move_insn (operands[4], operands[2]);
3570   DONE;
3571 })
3572
3573 ;; Extend to register case.  Optimize case where source and destination
3574 ;; registers match and cases where we can use cltd.
3575 (define_split
3576   [(set (match_operand:DI 0 "register_operand" "")
3577         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3578    (clobber (reg:CC FLAGS_REG))
3579    (clobber (match_scratch:SI 2 ""))]
3580   "reload_completed"
3581   [(const_int 0)]
3582 {
3583   split_di (&operands[0], 1, &operands[3], &operands[4]);
3584
3585   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3586     emit_move_insn (operands[3], operands[1]);
3587
3588   /* Generate a cltd if possible and doing so it profitable.  */
3589   if (true_regnum (operands[3]) == 0
3590       && (optimize_size || TARGET_USE_CLTD))
3591     {
3592       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3593       DONE;
3594     }
3595
3596   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3597     emit_move_insn (operands[4], operands[1]);
3598
3599   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3600   DONE;
3601 })
3602
3603 (define_insn "extendhisi2"
3604   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3605         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3606   ""
3607 {
3608   switch (get_attr_prefix_0f (insn))
3609     {
3610     case 0:
3611       return "{cwtl|cwde}";
3612     default:
3613       return "movs{wl|x}\t{%1,%0|%0, %1}";
3614     }
3615 }
3616   [(set_attr "type" "imovx")
3617    (set_attr "mode" "SI")
3618    (set (attr "prefix_0f")
3619      ;; movsx is short decodable while cwtl is vector decoded.
3620      (if_then_else (and (eq_attr "cpu" "!k6")
3621                         (eq_attr "alternative" "0"))
3622         (const_string "0")
3623         (const_string "1")))
3624    (set (attr "modrm")
3625      (if_then_else (eq_attr "prefix_0f" "0")
3626         (const_string "0")
3627         (const_string "1")))])
3628
3629 (define_insn "*extendhisi2_zext"
3630   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3631         (zero_extend:DI
3632           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3633   "TARGET_64BIT"
3634 {
3635   switch (get_attr_prefix_0f (insn))
3636     {
3637     case 0:
3638       return "{cwtl|cwde}";
3639     default:
3640       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3641     }
3642 }
3643   [(set_attr "type" "imovx")
3644    (set_attr "mode" "SI")
3645    (set (attr "prefix_0f")
3646      ;; movsx is short decodable while cwtl is vector decoded.
3647      (if_then_else (and (eq_attr "cpu" "!k6")
3648                         (eq_attr "alternative" "0"))
3649         (const_string "0")
3650         (const_string "1")))
3651    (set (attr "modrm")
3652      (if_then_else (eq_attr "prefix_0f" "0")
3653         (const_string "0")
3654         (const_string "1")))])
3655
3656 (define_insn "extendqihi2"
3657   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3658         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3659   ""
3660 {
3661   switch (get_attr_prefix_0f (insn))
3662     {
3663     case 0:
3664       return "{cbtw|cbw}";
3665     default:
3666       return "movs{bw|x}\t{%1,%0|%0, %1}";
3667     }
3668 }
3669   [(set_attr "type" "imovx")
3670    (set_attr "mode" "HI")
3671    (set (attr "prefix_0f")
3672      ;; movsx is short decodable while cwtl is vector decoded.
3673      (if_then_else (and (eq_attr "cpu" "!k6")
3674                         (eq_attr "alternative" "0"))
3675         (const_string "0")
3676         (const_string "1")))
3677    (set (attr "modrm")
3678      (if_then_else (eq_attr "prefix_0f" "0")
3679         (const_string "0")
3680         (const_string "1")))])
3681
3682 (define_insn "extendqisi2"
3683   [(set (match_operand:SI 0 "register_operand" "=r")
3684         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3685   ""
3686   "movs{bl|x}\t{%1,%0|%0, %1}"
3687    [(set_attr "type" "imovx")
3688     (set_attr "mode" "SI")])
3689
3690 (define_insn "*extendqisi2_zext"
3691   [(set (match_operand:DI 0 "register_operand" "=r")
3692         (zero_extend:DI
3693           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3694   "TARGET_64BIT"
3695   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3696    [(set_attr "type" "imovx")
3697     (set_attr "mode" "SI")])
3698 \f
3699 ;; Conversions between float and double.
3700
3701 ;; These are all no-ops in the model used for the 80387.  So just
3702 ;; emit moves.
3703
3704 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3705 (define_insn "*dummy_extendsfdf2"
3706   [(set (match_operand:DF 0 "push_operand" "=<")
3707         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3708   "0"
3709   "#")
3710
3711 (define_split
3712   [(set (match_operand:DF 0 "push_operand" "")
3713         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3714   "!TARGET_64BIT"
3715   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3716    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3717
3718 (define_split
3719   [(set (match_operand:DF 0 "push_operand" "")
3720         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3721   "TARGET_64BIT"
3722   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3723    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3724
3725 (define_insn "*dummy_extendsfxf2"
3726   [(set (match_operand:XF 0 "push_operand" "=<")
3727         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3728   "0"
3729   "#")
3730
3731 (define_split
3732   [(set (match_operand:XF 0 "push_operand" "")
3733         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3734   ""
3735   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3736    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3737   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3738
3739 (define_split
3740   [(set (match_operand:XF 0 "push_operand" "")
3741         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3742   "TARGET_64BIT"
3743   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3744    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3745   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3746
3747 (define_split
3748   [(set (match_operand:XF 0 "push_operand" "")
3749         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3750   ""
3751   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3752    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3753   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3754
3755 (define_split
3756   [(set (match_operand:XF 0 "push_operand" "")
3757         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3758   "TARGET_64BIT"
3759   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3760    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3761   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3762
3763 (define_expand "extendsfdf2"
3764   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3765         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3766   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3767 {
3768   /* ??? Needed for compress_float_constant since all fp constants
3769      are LEGITIMATE_CONSTANT_P.  */
3770   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3771     {
3772       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3773           && standard_80387_constant_p (operands[1]) > 0)
3774         {
3775           operands[1] = simplify_const_unary_operation
3776             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3777           emit_move_insn_1 (operands[0], operands[1]);
3778           DONE;
3779         }
3780       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3781     }
3782 })
3783
3784 (define_insn "*extendsfdf2_mixed"
3785   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3786         (float_extend:DF
3787           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3788   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3789 {
3790   switch (which_alternative)
3791     {
3792     case 0:
3793       return output_387_reg_move (insn, operands);
3794
3795     case 1:
3796       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3797         return "fstp%z0\t%y0";
3798       else
3799         return "fst%z0\t%y0";
3800
3801     case 2:
3802       return "cvtss2sd\t{%1, %0|%0, %1}";
3803
3804     default:
3805       gcc_unreachable ();
3806     }
3807 }
3808   [(set_attr "type" "fmov,fmov,ssecvt")
3809    (set_attr "mode" "SF,XF,DF")])
3810
3811 (define_insn "*extendsfdf2_sse"
3812   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3813         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3814   "TARGET_SSE2 && TARGET_SSE_MATH"
3815   "cvtss2sd\t{%1, %0|%0, %1}"
3816   [(set_attr "type" "ssecvt")
3817    (set_attr "mode" "DF")])
3818
3819 (define_insn "*extendsfdf2_i387"
3820   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3821         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3822   "TARGET_80387"
3823 {
3824   switch (which_alternative)
3825     {
3826     case 0:
3827       return output_387_reg_move (insn, operands);
3828
3829     case 1:
3830       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3831         return "fstp%z0\t%y0";
3832       else
3833         return "fst%z0\t%y0";
3834
3835     default:
3836       gcc_unreachable ();
3837     }
3838 }
3839   [(set_attr "type" "fmov")
3840    (set_attr "mode" "SF,XF")])
3841
3842 (define_expand "extendsfxf2"
3843   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3844         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3845   "TARGET_80387"
3846 {
3847   /* ??? Needed for compress_float_constant since all fp constants
3848      are LEGITIMATE_CONSTANT_P.  */
3849   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3850     {
3851       if (standard_80387_constant_p (operands[1]) > 0)
3852         {
3853           operands[1] = simplify_const_unary_operation
3854             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3855           emit_move_insn_1 (operands[0], operands[1]);
3856           DONE;
3857         }
3858       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3859     }
3860 })
3861
3862 (define_insn "*extendsfxf2_i387"
3863   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3864         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3865   "TARGET_80387"
3866 {
3867   switch (which_alternative)
3868     {
3869     case 0:
3870       return output_387_reg_move (insn, operands);
3871
3872     case 1:
3873       /* There is no non-popping store to memory for XFmode.  So if
3874          we need one, follow the store with a load.  */
3875       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3876         return "fstp%z0\t%y0";
3877       else
3878         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3879
3880     default:
3881       gcc_unreachable ();
3882     }
3883 }
3884   [(set_attr "type" "fmov")
3885    (set_attr "mode" "SF,XF")])
3886
3887 (define_expand "extenddfxf2"
3888   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3889         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3890   "TARGET_80387"
3891 {
3892   /* ??? Needed for compress_float_constant since all fp constants
3893      are LEGITIMATE_CONSTANT_P.  */
3894   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3895     {
3896       if (standard_80387_constant_p (operands[1]) > 0)
3897         {
3898           operands[1] = simplify_const_unary_operation
3899             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3900           emit_move_insn_1 (operands[0], operands[1]);
3901           DONE;
3902         }
3903       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3904     }
3905 })
3906
3907 (define_insn "*extenddfxf2_i387"
3908   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3909         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3910   "TARGET_80387"
3911 {
3912   switch (which_alternative)
3913     {
3914     case 0:
3915       return output_387_reg_move (insn, operands);
3916
3917     case 1:
3918       /* There is no non-popping store to memory for XFmode.  So if
3919          we need one, follow the store with a load.  */
3920       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3921         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3922       else
3923         return "fstp%z0\t%y0";
3924
3925     default:
3926       gcc_unreachable ();
3927     }
3928 }
3929   [(set_attr "type" "fmov")
3930    (set_attr "mode" "DF,XF")])
3931
3932 ;; %%% This seems bad bad news.
3933 ;; This cannot output into an f-reg because there is no way to be sure
3934 ;; of truncating in that case.  Otherwise this is just like a simple move
3935 ;; insn.  So we pretend we can output to a reg in order to get better
3936 ;; register preferencing, but we really use a stack slot.
3937
3938 ;; Conversion from DFmode to SFmode.
3939
3940 (define_expand "truncdfsf2"
3941   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3942         (float_truncate:SF
3943           (match_operand:DF 1 "nonimmediate_operand" "")))]
3944   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3945 {
3946   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3947     ;
3948   else if (flag_unsafe_math_optimizations)
3949     ;
3950   else
3951     {
3952       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3953       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3954       DONE;
3955     }
3956 })
3957
3958 (define_expand "truncdfsf2_with_temp"
3959   [(parallel [(set (match_operand:SF 0 "" "")
3960                    (float_truncate:SF (match_operand:DF 1 "" "")))
3961               (clobber (match_operand:SF 2 "" ""))])]
3962   "")
3963
3964 (define_insn "*truncdfsf_fast_mixed"
3965   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
3966         (float_truncate:SF
3967           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3968   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3969 {
3970   switch (which_alternative)
3971     {
3972     case 0:
3973       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3974         return "fstp%z0\t%y0";
3975       else
3976         return "fst%z0\t%y0";
3977     case 1:
3978       return output_387_reg_move (insn, operands);
3979     case 2:
3980       return "cvtsd2ss\t{%1, %0|%0, %1}";
3981     default:
3982       gcc_unreachable ();
3983     }
3984 }
3985   [(set_attr "type" "fmov,fmov,ssecvt")
3986    (set_attr "mode" "SF")])
3987
3988 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3989 ;; because nothing we do here is unsafe.
3990 (define_insn "*truncdfsf_fast_sse"
3991   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
3992         (float_truncate:SF
3993           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3994   "TARGET_SSE2 && TARGET_SSE_MATH"
3995   "cvtsd2ss\t{%1, %0|%0, %1}"
3996   [(set_attr "type" "ssecvt")
3997    (set_attr "mode" "SF")])
3998
3999 (define_insn "*truncdfsf_fast_i387"
4000   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4001         (float_truncate:SF
4002           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4003   "TARGET_80387 && flag_unsafe_math_optimizations"
4004   "* return output_387_reg_move (insn, operands);"
4005   [(set_attr "type" "fmov")
4006    (set_attr "mode" "SF")])
4007
4008 (define_insn "*truncdfsf_mixed"
4009   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4010         (float_truncate:SF
4011           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4012    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4013   "TARGET_MIX_SSE_I387"
4014 {
4015   switch (which_alternative)
4016     {
4017     case 0:
4018       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4019         return "fstp%z0\t%y0";
4020       else
4021         return "fst%z0\t%y0";
4022     case 1:
4023       return "#";
4024     case 2:
4025       return "cvtsd2ss\t{%1, %0|%0, %1}";
4026     default:
4027       gcc_unreachable ();
4028     }
4029 }
4030   [(set_attr "type" "fmov,multi,ssecvt")
4031    (set_attr "unit" "*,i387,*")
4032    (set_attr "mode" "SF")])
4033
4034 (define_insn "*truncdfsf_i387"
4035   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4036         (float_truncate:SF
4037           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4038    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4039   "TARGET_80387"
4040 {
4041   switch (which_alternative)
4042     {
4043     case 0:
4044       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4045         return "fstp%z0\t%y0";
4046       else
4047         return "fst%z0\t%y0";
4048     case 1:
4049       return "#";
4050     default:
4051       gcc_unreachable ();
4052     }
4053 }
4054   [(set_attr "type" "fmov,multi")
4055    (set_attr "unit" "*,i387")
4056    (set_attr "mode" "SF")])
4057
4058 (define_insn "*truncdfsf2_i387_1"
4059   [(set (match_operand:SF 0 "memory_operand" "=m")
4060         (float_truncate:SF
4061           (match_operand:DF 1 "register_operand" "f")))]
4062   "TARGET_80387
4063    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4064    && !TARGET_MIX_SSE_I387"
4065 {
4066   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4067     return "fstp%z0\t%y0";
4068   else
4069     return "fst%z0\t%y0";
4070 }
4071   [(set_attr "type" "fmov")
4072    (set_attr "mode" "SF")])
4073
4074 (define_split
4075   [(set (match_operand:SF 0 "register_operand" "")
4076         (float_truncate:SF
4077          (match_operand:DF 1 "fp_register_operand" "")))
4078    (clobber (match_operand 2 "" ""))]
4079   "reload_completed"
4080   [(set (match_dup 2) (match_dup 1))
4081    (set (match_dup 0) (match_dup 2))]
4082 {
4083   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4084 })
4085
4086 ;; Conversion from XFmode to SFmode.
4087
4088 (define_expand "truncxfsf2"
4089   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4090                    (float_truncate:SF
4091                     (match_operand:XF 1 "register_operand" "")))
4092               (clobber (match_dup 2))])]
4093   "TARGET_80387"
4094 {
4095   if (flag_unsafe_math_optimizations)
4096     {
4097       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
4098       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
4099       if (reg != operands[0])
4100         emit_move_insn (operands[0], reg);
4101       DONE;
4102     }
4103   else
4104     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
4105 })
4106
4107 (define_insn "*truncxfsf2_mixed"
4108   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
4109         (float_truncate:SF
4110          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4111    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4112   "TARGET_80387"
4113 {
4114   gcc_assert (!which_alternative);
4115   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4116     return "fstp%z0\t%y0";
4117   else
4118     return "fst%z0\t%y0";
4119 }
4120   [(set_attr "type" "fmov,multi,multi,multi")
4121    (set_attr "unit" "*,i387,i387,i387")
4122    (set_attr "mode" "SF")])
4123
4124 (define_insn "truncxfsf2_i387_noop"
4125   [(set (match_operand:SF 0 "register_operand" "=f")
4126         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
4127   "TARGET_80387 && flag_unsafe_math_optimizations"
4128   "* return output_387_reg_move (insn, operands);"
4129   [(set_attr "type" "fmov")
4130    (set_attr "mode" "SF")])
4131
4132 (define_insn "*truncxfsf2_i387"
4133   [(set (match_operand:SF 0 "memory_operand" "=m")
4134         (float_truncate:SF
4135          (match_operand:XF 1 "register_operand" "f")))]
4136   "TARGET_80387"
4137 {
4138   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4139     return "fstp%z0\t%y0";
4140   else
4141     return "fst%z0\t%y0";
4142 }
4143   [(set_attr "type" "fmov")
4144    (set_attr "mode" "SF")])
4145
4146 (define_split
4147   [(set (match_operand:SF 0 "register_operand" "")
4148         (float_truncate:SF
4149          (match_operand:XF 1 "register_operand" "")))
4150    (clobber (match_operand:SF 2 "memory_operand" ""))]
4151   "TARGET_80387 && reload_completed"
4152   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4153    (set (match_dup 0) (match_dup 2))]
4154   "")
4155
4156 (define_split
4157   [(set (match_operand:SF 0 "memory_operand" "")
4158         (float_truncate:SF
4159          (match_operand:XF 1 "register_operand" "")))
4160    (clobber (match_operand:SF 2 "memory_operand" ""))]
4161   "TARGET_80387"
4162   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4163   "")
4164
4165 ;; Conversion from XFmode to DFmode.
4166
4167 (define_expand "truncxfdf2"
4168   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4169                    (float_truncate:DF
4170                     (match_operand:XF 1 "register_operand" "")))
4171               (clobber (match_dup 2))])]
4172   "TARGET_80387"
4173 {
4174   if (flag_unsafe_math_optimizations)
4175     {
4176       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4177       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4178       if (reg != operands[0])
4179         emit_move_insn (operands[0], reg);
4180       DONE;
4181     }
4182   else
4183     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4184 })
4185
4186 (define_insn "*truncxfdf2_mixed"
4187   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y2*x")
4188         (float_truncate:DF
4189          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4190    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4191   "TARGET_80387"
4192 {
4193   gcc_assert (!which_alternative);
4194   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4195     return "fstp%z0\t%y0";
4196   else
4197     return "fst%z0\t%y0";
4198 }
4199   [(set_attr "type" "fmov,multi,multi,multi")
4200    (set_attr "unit" "*,i387,i387,i387")
4201    (set_attr "mode" "DF")])
4202
4203 (define_insn "truncxfdf2_i387_noop"
4204   [(set (match_operand:DF 0 "register_operand" "=f")
4205         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4206   "TARGET_80387 && flag_unsafe_math_optimizations"
4207   "* return output_387_reg_move (insn, operands);"
4208   [(set_attr "type" "fmov")
4209    (set_attr "mode" "DF")])
4210
4211 (define_insn "*truncxfdf2_i387"
4212   [(set (match_operand:DF 0 "memory_operand" "=m")
4213         (float_truncate:DF
4214           (match_operand:XF 1 "register_operand" "f")))]
4215   "TARGET_80387"
4216 {
4217   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4218     return "fstp%z0\t%y0";
4219   else
4220     return "fst%z0\t%y0";
4221 }
4222   [(set_attr "type" "fmov")
4223    (set_attr "mode" "DF")])
4224
4225 (define_split
4226   [(set (match_operand:DF 0 "register_operand" "")
4227         (float_truncate:DF
4228          (match_operand:XF 1 "register_operand" "")))
4229    (clobber (match_operand:DF 2 "memory_operand" ""))]
4230   "TARGET_80387 && reload_completed"
4231   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4232    (set (match_dup 0) (match_dup 2))]
4233   "")
4234
4235 (define_split
4236   [(set (match_operand:DF 0 "memory_operand" "")
4237         (float_truncate:DF
4238          (match_operand:XF 1 "register_operand" "")))
4239    (clobber (match_operand:DF 2 "memory_operand" ""))]
4240   "TARGET_80387"
4241   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4242   "")
4243 \f
4244 ;; Signed conversion to DImode.
4245
4246 (define_expand "fix_truncxfdi2"
4247   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4249               (clobber (reg:CC FLAGS_REG))])]
4250   "TARGET_80387"
4251 {
4252   if (TARGET_FISTTP)
4253    {
4254      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4255      DONE;
4256    }
4257 })
4258
4259 (define_expand "fix_trunc<mode>di2"
4260   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4261                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4262               (clobber (reg:CC FLAGS_REG))])]
4263   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4264 {
4265   if (TARGET_FISTTP
4266       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4267    {
4268      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4269      DONE;
4270    }
4271   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4272    {
4273      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4274      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4275      if (out != operands[0])
4276         emit_move_insn (operands[0], out);
4277      DONE;
4278    }
4279 })
4280
4281 ;; Signed conversion to SImode.
4282
4283 (define_expand "fix_truncxfsi2"
4284   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4285                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4286               (clobber (reg:CC FLAGS_REG))])]
4287   "TARGET_80387"
4288 {
4289   if (TARGET_FISTTP)
4290    {
4291      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4292      DONE;
4293    }
4294 })
4295
4296 (define_expand "fix_trunc<mode>si2"
4297   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4298                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4299               (clobber (reg:CC FLAGS_REG))])]
4300   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4301 {
4302   if (TARGET_FISTTP
4303       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4304    {
4305      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4306      DONE;
4307    }
4308   if (SSE_FLOAT_MODE_P (<MODE>mode))
4309    {
4310      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4311      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4312      if (out != operands[0])
4313         emit_move_insn (operands[0], out);
4314      DONE;
4315    }
4316 })
4317
4318 ;; Signed conversion to HImode.
4319
4320 (define_expand "fix_trunc<mode>hi2"
4321   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4322                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4323               (clobber (reg:CC FLAGS_REG))])]
4324   "TARGET_80387
4325    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4326 {
4327   if (TARGET_FISTTP)
4328    {
4329      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4330      DONE;
4331    }
4332 })
4333
4334 ;; Unsigned conversion to SImode.
4335
4336 (define_expand "fixuns_trunc<mode>si2"
4337   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4338                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))]
4339   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4340    && TARGET_KEEPS_VECTOR_ALIGNED_STACK && !optimize_size"
4341 {
4342   ix86_expand_convert_uns_si_sse (operands[0], operands[1]);
4343   DONE;
4344 })
4345
4346 ;; Unsigned conversion to HImode.
4347 ;; Without these patterns, we'll try the unsigned SI conversion which
4348 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4349
4350 (define_expand "fixuns_truncsfhi2"
4351   [(set (match_dup 2)
4352         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))
4353    (set (match_operand:HI 0 "nonimmediate_operand" "")
4354         (subreg:HI (match_dup 2) 0))]
4355   "TARGET_SSE_MATH"
4356   "operands[2] = gen_reg_rtx (SImode);")
4357
4358 (define_expand "fixuns_truncdfhi2"
4359   [(set (match_dup 2)
4360         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))
4361    (set (match_operand:HI 0 "nonimmediate_operand" "")
4362         (subreg:HI (match_dup 2) 0))]
4363   "TARGET_SSE_MATH"
4364   "operands[2] = gen_reg_rtx (SImode);")
4365
4366 ;; When SSE is available, it is always faster to use it!
4367 (define_insn "fix_truncsfdi_sse"
4368   [(set (match_operand:DI 0 "register_operand" "=r,r")
4369         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4370   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4371   "cvttss2si{q}\t{%1, %0|%0, %1}"
4372   [(set_attr "type" "sseicvt")
4373    (set_attr "mode" "SF")
4374    (set_attr "athlon_decode" "double,vector")
4375    (set_attr "amdfam10_decode" "double,double")])
4376
4377 (define_insn "fix_truncdfdi_sse"
4378   [(set (match_operand:DI 0 "register_operand" "=r,r")
4379         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4380   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4381   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4382   [(set_attr "type" "sseicvt")
4383    (set_attr "mode" "DF")
4384    (set_attr "athlon_decode" "double,vector")
4385    (set_attr "amdfam10_decode" "double,double")])
4386
4387 (define_insn "fix_truncsfsi_sse"
4388   [(set (match_operand:SI 0 "register_operand" "=r,r")
4389         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4390   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4391   "cvttss2si\t{%1, %0|%0, %1}"
4392   [(set_attr "type" "sseicvt")
4393    (set_attr "mode" "DF")
4394    (set_attr "athlon_decode" "double,vector")
4395    (set_attr "amdfam10_decode" "double,double")])
4396
4397 (define_insn "fix_truncdfsi_sse"
4398   [(set (match_operand:SI 0 "register_operand" "=r,r")
4399         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4400   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4401   "cvttsd2si\t{%1, %0|%0, %1}"
4402   [(set_attr "type" "sseicvt")
4403    (set_attr "mode" "DF")
4404    (set_attr "athlon_decode" "double,vector")
4405    (set_attr "amdfam10_decode" "double,double")])
4406
4407 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4408 (define_peephole2
4409   [(set (match_operand:DF 0 "register_operand" "")
4410         (match_operand:DF 1 "memory_operand" ""))
4411    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4412         (fix:SSEMODEI24 (match_dup 0)))]
4413   "!TARGET_K8
4414    && peep2_reg_dead_p (2, operands[0])"
4415   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4416   "")
4417
4418 (define_peephole2
4419   [(set (match_operand:SF 0 "register_operand" "")
4420         (match_operand:SF 1 "memory_operand" ""))
4421    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4422         (fix:SSEMODEI24 (match_dup 0)))]
4423   "!TARGET_K8
4424    && peep2_reg_dead_p (2, operands[0])"
4425   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4426   "")
4427
4428 ;; Avoid vector decoded forms of the instruction.
4429 (define_peephole2
4430   [(match_scratch:DF 2 "Y")
4431    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4432         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4433   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4434   [(set (match_dup 2) (match_dup 1))
4435    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4436   "")
4437
4438 (define_peephole2
4439   [(match_scratch:SF 2 "x")
4440    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4441         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4442   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4443   [(set (match_dup 2) (match_dup 1))
4444    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4445   "")
4446
4447 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4448   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4449         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4450   "TARGET_FISTTP
4451    && FLOAT_MODE_P (GET_MODE (operands[1]))
4452    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4453          && (TARGET_64BIT || <MODE>mode != DImode))
4454         && TARGET_SSE_MATH)
4455    && !(reload_completed || reload_in_progress)"
4456   "#"
4457   "&& 1"
4458   [(const_int 0)]
4459 {
4460   if (memory_operand (operands[0], VOIDmode))
4461     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4462   else
4463     {
4464       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4465       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4466                                                             operands[1],
4467                                                             operands[2]));
4468     }
4469   DONE;
4470 }
4471   [(set_attr "type" "fisttp")
4472    (set_attr "mode" "<MODE>")])
4473
4474 (define_insn "fix_trunc<mode>_i387_fisttp"
4475   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4476         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4477    (clobber (match_scratch:XF 2 "=&1f"))]
4478   "TARGET_FISTTP
4479    && FLOAT_MODE_P (GET_MODE (operands[1]))
4480    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4481          && (TARGET_64BIT || <MODE>mode != DImode))
4482         && TARGET_SSE_MATH)"
4483   "* return output_fix_trunc (insn, operands, 1);"
4484   [(set_attr "type" "fisttp")
4485    (set_attr "mode" "<MODE>")])
4486
4487 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4488   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4489         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4490    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4491    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4492   "TARGET_FISTTP
4493    && FLOAT_MODE_P (GET_MODE (operands[1]))
4494    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4495         && (TARGET_64BIT || <MODE>mode != DImode))
4496         && TARGET_SSE_MATH)"
4497   "#"
4498   [(set_attr "type" "fisttp")
4499    (set_attr "mode" "<MODE>")])
4500
4501 (define_split
4502   [(set (match_operand:X87MODEI 0 "register_operand" "")
4503         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4504    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4505    (clobber (match_scratch 3 ""))]
4506   "reload_completed"
4507   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4508               (clobber (match_dup 3))])
4509    (set (match_dup 0) (match_dup 2))]
4510   "")
4511
4512 (define_split
4513   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4514         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4515    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4516    (clobber (match_scratch 3 ""))]
4517   "reload_completed"
4518   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4519               (clobber (match_dup 3))])]
4520   "")
4521
4522 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4523 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4524 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4525 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4526 ;; function in i386.c.
4527 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4528   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4529         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4530    (clobber (reg:CC FLAGS_REG))]
4531   "TARGET_80387 && !TARGET_FISTTP
4532    && FLOAT_MODE_P (GET_MODE (operands[1]))
4533    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4534          && (TARGET_64BIT || <MODE>mode != DImode))
4535    && !(reload_completed || reload_in_progress)"
4536   "#"
4537   "&& 1"
4538   [(const_int 0)]
4539 {
4540   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4541
4542   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4543   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4544   if (memory_operand (operands[0], VOIDmode))
4545     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4546                                          operands[2], operands[3]));
4547   else
4548     {
4549       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4550       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4551                                                      operands[2], operands[3],
4552                                                      operands[4]));
4553     }
4554   DONE;
4555 }
4556   [(set_attr "type" "fistp")
4557    (set_attr "i387_cw" "trunc")
4558    (set_attr "mode" "<MODE>")])
4559
4560 (define_insn "fix_truncdi_i387"
4561   [(set (match_operand:DI 0 "memory_operand" "=m")
4562         (fix:DI (match_operand 1 "register_operand" "f")))
4563    (use (match_operand:HI 2 "memory_operand" "m"))
4564    (use (match_operand:HI 3 "memory_operand" "m"))
4565    (clobber (match_scratch:XF 4 "=&1f"))]
4566   "TARGET_80387 && !TARGET_FISTTP
4567    && FLOAT_MODE_P (GET_MODE (operands[1]))
4568    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4569   "* return output_fix_trunc (insn, operands, 0);"
4570   [(set_attr "type" "fistp")
4571    (set_attr "i387_cw" "trunc")
4572    (set_attr "mode" "DI")])
4573
4574 (define_insn "fix_truncdi_i387_with_temp"
4575   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4576         (fix:DI (match_operand 1 "register_operand" "f,f")))
4577    (use (match_operand:HI 2 "memory_operand" "m,m"))
4578    (use (match_operand:HI 3 "memory_operand" "m,m"))
4579    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4580    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4581   "TARGET_80387 && !TARGET_FISTTP
4582    && FLOAT_MODE_P (GET_MODE (operands[1]))
4583    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4584   "#"
4585   [(set_attr "type" "fistp")
4586    (set_attr "i387_cw" "trunc")
4587    (set_attr "mode" "DI")])
4588
4589 (define_split
4590   [(set (match_operand:DI 0 "register_operand" "")
4591         (fix:DI (match_operand 1 "register_operand" "")))
4592    (use (match_operand:HI 2 "memory_operand" ""))
4593    (use (match_operand:HI 3 "memory_operand" ""))
4594    (clobber (match_operand:DI 4 "memory_operand" ""))
4595    (clobber (match_scratch 5 ""))]
4596   "reload_completed"
4597   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4598               (use (match_dup 2))
4599               (use (match_dup 3))
4600               (clobber (match_dup 5))])
4601    (set (match_dup 0) (match_dup 4))]
4602   "")
4603
4604 (define_split
4605   [(set (match_operand:DI 0 "memory_operand" "")
4606         (fix:DI (match_operand 1 "register_operand" "")))
4607    (use (match_operand:HI 2 "memory_operand" ""))
4608    (use (match_operand:HI 3 "memory_operand" ""))
4609    (clobber (match_operand:DI 4 "memory_operand" ""))
4610    (clobber (match_scratch 5 ""))]
4611   "reload_completed"
4612   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4613               (use (match_dup 2))
4614               (use (match_dup 3))
4615               (clobber (match_dup 5))])]
4616   "")
4617
4618 (define_insn "fix_trunc<mode>_i387"
4619   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4620         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4621    (use (match_operand:HI 2 "memory_operand" "m"))
4622    (use (match_operand:HI 3 "memory_operand" "m"))]
4623   "TARGET_80387 && !TARGET_FISTTP
4624    && FLOAT_MODE_P (GET_MODE (operands[1]))
4625    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4626   "* return output_fix_trunc (insn, operands, 0);"
4627   [(set_attr "type" "fistp")
4628    (set_attr "i387_cw" "trunc")
4629    (set_attr "mode" "<MODE>")])
4630
4631 (define_insn "fix_trunc<mode>_i387_with_temp"
4632   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4633         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4634    (use (match_operand:HI 2 "memory_operand" "m,m"))
4635    (use (match_operand:HI 3 "memory_operand" "m,m"))
4636    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4637   "TARGET_80387 && !TARGET_FISTTP
4638    && FLOAT_MODE_P (GET_MODE (operands[1]))
4639    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4640   "#"
4641   [(set_attr "type" "fistp")
4642    (set_attr "i387_cw" "trunc")
4643    (set_attr "mode" "<MODE>")])
4644
4645 (define_split
4646   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4647         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4648    (use (match_operand:HI 2 "memory_operand" ""))
4649    (use (match_operand:HI 3 "memory_operand" ""))
4650    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4651   "reload_completed"
4652   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4653               (use (match_dup 2))
4654               (use (match_dup 3))])
4655    (set (match_dup 0) (match_dup 4))]
4656   "")
4657
4658 (define_split
4659   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4660         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4661    (use (match_operand:HI 2 "memory_operand" ""))
4662    (use (match_operand:HI 3 "memory_operand" ""))
4663    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4664   "reload_completed"
4665   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4666               (use (match_dup 2))
4667               (use (match_dup 3))])]
4668   "")
4669
4670 (define_insn "x86_fnstcw_1"
4671   [(set (match_operand:HI 0 "memory_operand" "=m")
4672         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4673   "TARGET_80387"
4674   "fnstcw\t%0"
4675   [(set_attr "length" "2")
4676    (set_attr "mode" "HI")
4677    (set_attr "unit" "i387")])
4678
4679 (define_insn "x86_fldcw_1"
4680   [(set (reg:HI FPCR_REG)
4681         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4682   "TARGET_80387"
4683   "fldcw\t%0"
4684   [(set_attr "length" "2")
4685    (set_attr "mode" "HI")
4686    (set_attr "unit" "i387")
4687    (set_attr "athlon_decode" "vector")
4688    (set_attr "amdfam10_decode" "vector")])   
4689 \f
4690 ;; Conversion between fixed point and floating point.
4691
4692 ;; Even though we only accept memory inputs, the backend _really_
4693 ;; wants to be able to do this between registers.
4694
4695 (define_expand "floathisf2"
4696   [(set (match_operand:SF 0 "register_operand" "")
4697         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4698   "TARGET_80387 || TARGET_SSE_MATH"
4699 {
4700   if (TARGET_SSE_MATH)
4701     {
4702       emit_insn (gen_floatsisf2 (operands[0],
4703                                  convert_to_mode (SImode, operands[1], 0)));
4704       DONE;
4705     }
4706 })
4707
4708 (define_insn "*floathisf2_i387"
4709   [(set (match_operand:SF 0 "register_operand" "=f,f")
4710         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4711   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4712   "@
4713    fild%z1\t%1
4714    #"
4715   [(set_attr "type" "fmov,multi")
4716    (set_attr "mode" "SF")
4717    (set_attr "unit" "*,i387")
4718    (set_attr "fp_int_src" "true")])
4719
4720 (define_expand "floatsisf2"
4721   [(set (match_operand:SF 0 "register_operand" "")
4722         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4723   "TARGET_80387 || TARGET_SSE_MATH"
4724   "")
4725
4726 (define_insn "*floatsisf2_mixed"
4727   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4728         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4729   "TARGET_MIX_SSE_I387"
4730   "@
4731    fild%z1\t%1
4732    #
4733    cvtsi2ss\t{%1, %0|%0, %1}
4734    cvtsi2ss\t{%1, %0|%0, %1}"
4735   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4736    (set_attr "mode" "SF")
4737    (set_attr "unit" "*,i387,*,*")
4738    (set_attr "athlon_decode" "*,*,vector,double")
4739    (set_attr "amdfam10_decode" "*,*,vector,double")
4740    (set_attr "fp_int_src" "true")])
4741
4742 (define_insn "*floatsisf2_sse"
4743   [(set (match_operand:SF 0 "register_operand" "=x,x")
4744         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4745   "TARGET_SSE_MATH"
4746   "cvtsi2ss\t{%1, %0|%0, %1}"
4747   [(set_attr "type" "sseicvt")
4748    (set_attr "mode" "SF")
4749    (set_attr "athlon_decode" "vector,double")
4750    (set_attr "amdfam10_decode" "vector,double")
4751    (set_attr "fp_int_src" "true")])
4752
4753 (define_insn "*floatsisf2_i387"
4754   [(set (match_operand:SF 0 "register_operand" "=f,f")
4755         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4756   "TARGET_80387"
4757   "@
4758    fild%z1\t%1
4759    #"
4760   [(set_attr "type" "fmov,multi")
4761    (set_attr "mode" "SF")
4762    (set_attr "unit" "*,i387")
4763    (set_attr "fp_int_src" "true")])
4764
4765 (define_expand "floatdisf2"
4766   [(set (match_operand:SF 0 "register_operand" "")
4767         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4768   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4769   "")
4770
4771 (define_insn "*floatdisf2_mixed"
4772   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4773         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4774   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4775   "@
4776    fild%z1\t%1
4777    #
4778    cvtsi2ss{q}\t{%1, %0|%0, %1}
4779    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4780   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4781    (set_attr "mode" "SF")
4782    (set_attr "unit" "*,i387,*,*")
4783    (set_attr "athlon_decode" "*,*,vector,double")
4784    (set_attr "amdfam10_decode" "*,*,vector,double")
4785    (set_attr "fp_int_src" "true")])
4786
4787 (define_insn "*floatdisf2_sse"
4788   [(set (match_operand:SF 0 "register_operand" "=x,x")
4789         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4790   "TARGET_64BIT && TARGET_SSE_MATH"
4791   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4792   [(set_attr "type" "sseicvt")
4793    (set_attr "mode" "SF")
4794    (set_attr "athlon_decode" "vector,double")
4795    (set_attr "amdfam10_decode" "vector,double")
4796    (set_attr "fp_int_src" "true")])
4797
4798 (define_insn "*floatdisf2_i387"
4799   [(set (match_operand:SF 0 "register_operand" "=f,f")
4800         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4801   "TARGET_80387"
4802   "@
4803    fild%z1\t%1
4804    #"
4805   [(set_attr "type" "fmov,multi")
4806    (set_attr "mode" "SF")
4807    (set_attr "unit" "*,i387")
4808    (set_attr "fp_int_src" "true")])
4809
4810 (define_expand "floathidf2"
4811   [(set (match_operand:DF 0 "register_operand" "")
4812         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4813   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4814 {
4815   if (TARGET_SSE2 && TARGET_SSE_MATH)
4816     {
4817       emit_insn (gen_floatsidf2 (operands[0],
4818                                  convert_to_mode (SImode, operands[1], 0)));
4819       DONE;
4820     }
4821 })
4822
4823 (define_insn "*floathidf2_i387"
4824   [(set (match_operand:DF 0 "register_operand" "=f,f")
4825         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4826   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4827   "@
4828    fild%z1\t%1
4829    #"
4830   [(set_attr "type" "fmov,multi")
4831    (set_attr "mode" "DF")
4832    (set_attr "unit" "*,i387")
4833    (set_attr "fp_int_src" "true")])
4834
4835 (define_expand "floatsidf2"
4836   [(set (match_operand:DF 0 "register_operand" "")
4837         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4838   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4839   "")
4840
4841 (define_insn "*floatsidf2_mixed"
4842   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4843         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4844   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4845   "@
4846    fild%z1\t%1
4847    #
4848    cvtsi2sd\t{%1, %0|%0, %1}
4849    cvtsi2sd\t{%1, %0|%0, %1}"
4850   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4851    (set_attr "mode" "DF")
4852    (set_attr "unit" "*,i387,*,*")
4853    (set_attr "athlon_decode" "*,*,double,direct")
4854    (set_attr "amdfam10_decode" "*,*,vector,double")
4855    (set_attr "fp_int_src" "true")])
4856
4857 (define_insn "*floatsidf2_sse"
4858   [(set (match_operand:DF 0 "register_operand" "=x,x")
4859         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4860   "TARGET_SSE2 && TARGET_SSE_MATH"
4861   "cvtsi2sd\t{%1, %0|%0, %1}"
4862   [(set_attr "type" "sseicvt")
4863    (set_attr "mode" "DF")
4864    (set_attr "athlon_decode" "double,direct")
4865    (set_attr "amdfam10_decode" "vector,double")
4866    (set_attr "fp_int_src" "true")])
4867
4868 (define_insn "*floatsidf2_i387"
4869   [(set (match_operand:DF 0 "register_operand" "=f,f")
4870         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4871   "TARGET_80387"
4872   "@
4873    fild%z1\t%1
4874    #"
4875   [(set_attr "type" "fmov,multi")
4876    (set_attr "mode" "DF")
4877    (set_attr "unit" "*,i387")
4878    (set_attr "fp_int_src" "true")])
4879
4880 (define_expand "floatdidf2"
4881   [(set (match_operand:DF 0 "register_operand" "")
4882         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4883   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4884 {
4885   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4886     {
4887       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4888       DONE;
4889     }
4890 })
4891
4892 (define_insn "*floatdidf2_mixed"
4893   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4894         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4895   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4896   "@
4897    fild%z1\t%1
4898    #
4899    cvtsi2sd{q}\t{%1, %0|%0, %1}
4900    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4901   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4902    (set_attr "mode" "DF")
4903    (set_attr "unit" "*,i387,*,*")
4904    (set_attr "athlon_decode" "*,*,double,direct")
4905    (set_attr "amdfam10_decode" "*,*,vector,double")
4906    (set_attr "fp_int_src" "true")])
4907
4908 (define_insn "*floatdidf2_sse"
4909   [(set (match_operand:DF 0 "register_operand" "=x,x")
4910         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4911   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4912   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4913   [(set_attr "type" "sseicvt")
4914    (set_attr "mode" "DF")
4915    (set_attr "athlon_decode" "double,direct")
4916    (set_attr "amdfam10_decode" "vector,double")
4917    (set_attr "fp_int_src" "true")])
4918
4919 (define_insn "*floatdidf2_i387"
4920   [(set (match_operand:DF 0 "register_operand" "=f,f")
4921         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4922   "TARGET_80387"
4923   "@
4924    fild%z1\t%1
4925    #"
4926   [(set_attr "type" "fmov,multi")
4927    (set_attr "mode" "DF")
4928    (set_attr "unit" "*,i387")
4929    (set_attr "fp_int_src" "true")])
4930
4931 (define_insn "floathixf2"
4932   [(set (match_operand:XF 0 "register_operand" "=f,f")
4933         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4934   "TARGET_80387"
4935   "@
4936    fild%z1\t%1
4937    #"
4938   [(set_attr "type" "fmov,multi")
4939    (set_attr "mode" "XF")
4940    (set_attr "unit" "*,i387")
4941    (set_attr "fp_int_src" "true")])
4942
4943 (define_insn "floatsixf2"
4944   [(set (match_operand:XF 0 "register_operand" "=f,f")
4945         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4946   "TARGET_80387"
4947   "@
4948    fild%z1\t%1
4949    #"
4950   [(set_attr "type" "fmov,multi")
4951    (set_attr "mode" "XF")
4952    (set_attr "unit" "*,i387")
4953    (set_attr "fp_int_src" "true")])
4954
4955 (define_insn "floatdixf2"
4956   [(set (match_operand:XF 0 "register_operand" "=f,f")
4957         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4958   "TARGET_80387"
4959   "@
4960    fild%z1\t%1
4961    #"
4962   [(set_attr "type" "fmov,multi")
4963    (set_attr "mode" "XF")
4964    (set_attr "unit" "*,i387")
4965    (set_attr "fp_int_src" "true")])
4966
4967 ;; %%% Kill these when reload knows how to do it.
4968 (define_split
4969   [(set (match_operand 0 "fp_register_operand" "")
4970         (float (match_operand 1 "register_operand" "")))]
4971   "reload_completed
4972    && TARGET_80387
4973    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4974   [(const_int 0)]
4975 {
4976   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4977   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4978   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4979   ix86_free_from_memory (GET_MODE (operands[1]));
4980   DONE;
4981 })
4982
4983 (define_expand "floatunssisf2"
4984   [(use (match_operand:SF 0 "register_operand" ""))
4985    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4986   "!TARGET_64BIT"
4987 {
4988   if (TARGET_SSE_MATH && TARGET_SSE2)
4989     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
4990   else
4991     x86_emit_floatuns (operands);
4992   DONE;
4993 })
4994
4995 (define_expand "floatunssidf2"
4996   [(use (match_operand:DF 0 "register_operand" ""))
4997    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4998   "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
4999   "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5000
5001 (define_expand "floatunsdisf2"
5002   [(use (match_operand:SF 0 "register_operand" ""))
5003    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5004   "TARGET_64BIT && TARGET_SSE_MATH"
5005   "x86_emit_floatuns (operands); DONE;")
5006
5007 (define_expand "floatunsdidf2"
5008   [(use (match_operand:DF 0 "register_operand" ""))
5009    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5010   "TARGET_SSE_MATH && TARGET_SSE2
5011    && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5012 {
5013   if (TARGET_64BIT)
5014     x86_emit_floatuns (operands);
5015   else
5016     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5017   DONE;
5018 })
5019 \f
5020 ;; SSE extract/set expanders
5021
5022 \f
5023 ;; Add instructions
5024
5025 ;; %%% splits for addditi3
5026
5027 (define_expand "addti3"
5028   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5029         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5030                  (match_operand:TI 2 "x86_64_general_operand" "")))
5031    (clobber (reg:CC FLAGS_REG))]
5032   "TARGET_64BIT"
5033   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5034
5035 (define_insn "*addti3_1"
5036   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5037         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5038                  (match_operand:TI 2 "general_operand" "roiF,riF")))
5039    (clobber (reg:CC FLAGS_REG))]
5040   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5041   "#")
5042
5043 (define_split
5044   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5045         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5046                  (match_operand:TI 2 "general_operand" "")))
5047    (clobber (reg:CC FLAGS_REG))]
5048   "TARGET_64BIT && reload_completed"
5049   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5050                                           UNSPEC_ADD_CARRY))
5051               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5052    (parallel [(set (match_dup 3)
5053                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5054                                      (match_dup 4))
5055                             (match_dup 5)))
5056               (clobber (reg:CC FLAGS_REG))])]
5057   "split_ti (operands+0, 1, operands+0, operands+3);
5058    split_ti (operands+1, 1, operands+1, operands+4);
5059    split_ti (operands+2, 1, operands+2, operands+5);")
5060
5061 ;; %%% splits for addsidi3
5062 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5063 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5064 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5065
5066 (define_expand "adddi3"
5067   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5068         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5069                  (match_operand:DI 2 "x86_64_general_operand" "")))
5070    (clobber (reg:CC FLAGS_REG))]
5071   ""
5072   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5073
5074 (define_insn "*adddi3_1"
5075   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5076         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5077                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5078    (clobber (reg:CC FLAGS_REG))]
5079   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5080   "#")
5081
5082 (define_split
5083   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5084         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5085                  (match_operand:DI 2 "general_operand" "")))
5086    (clobber (reg:CC FLAGS_REG))]
5087   "!TARGET_64BIT && reload_completed"
5088   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5089                                           UNSPEC_ADD_CARRY))
5090               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5091    (parallel [(set (match_dup 3)
5092                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5093                                      (match_dup 4))
5094                             (match_dup 5)))
5095               (clobber (reg:CC FLAGS_REG))])]
5096   "split_di (operands+0, 1, operands+0, operands+3);
5097    split_di (operands+1, 1, operands+1, operands+4);
5098    split_di (operands+2, 1, operands+2, operands+5);")
5099
5100 (define_insn "adddi3_carry_rex64"
5101   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5102           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5103                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5104                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5105    (clobber (reg:CC FLAGS_REG))]
5106   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5107   "adc{q}\t{%2, %0|%0, %2}"
5108   [(set_attr "type" "alu")
5109    (set_attr "pent_pair" "pu")
5110    (set_attr "mode" "DI")])
5111
5112 (define_insn "*adddi3_cc_rex64"
5113   [(set (reg:CC FLAGS_REG)
5114         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5115                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5116                    UNSPEC_ADD_CARRY))
5117    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5118         (plus:DI (match_dup 1) (match_dup 2)))]
5119   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5120   "add{q}\t{%2, %0|%0, %2}"
5121   [(set_attr "type" "alu")
5122    (set_attr "mode" "DI")])
5123
5124 (define_insn "addqi3_carry"
5125   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5126           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5127                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5128                    (match_operand:QI 2 "general_operand" "qi,qm")))
5129    (clobber (reg:CC FLAGS_REG))]
5130   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5131   "adc{b}\t{%2, %0|%0, %2}"
5132   [(set_attr "type" "alu")
5133    (set_attr "pent_pair" "pu")
5134    (set_attr "mode" "QI")])
5135
5136 (define_insn "addhi3_carry"
5137   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5138           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5139                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5140                    (match_operand:HI 2 "general_operand" "ri,rm")))
5141    (clobber (reg:CC FLAGS_REG))]
5142   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5143   "adc{w}\t{%2, %0|%0, %2}"
5144   [(set_attr "type" "alu")
5145    (set_attr "pent_pair" "pu")
5146    (set_attr "mode" "HI")])
5147
5148 (define_insn "addsi3_carry"
5149   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5150           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5151                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5152                    (match_operand:SI 2 "general_operand" "ri,rm")))
5153    (clobber (reg:CC FLAGS_REG))]
5154   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5155   "adc{l}\t{%2, %0|%0, %2}"
5156   [(set_attr "type" "alu")
5157    (set_attr "pent_pair" "pu")
5158    (set_attr "mode" "SI")])
5159
5160 (define_insn "*addsi3_carry_zext"
5161   [(set (match_operand:DI 0 "register_operand" "=r")
5162           (zero_extend:DI
5163             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5164                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5165                      (match_operand:SI 2 "general_operand" "rim"))))
5166    (clobber (reg:CC FLAGS_REG))]
5167   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5168   "adc{l}\t{%2, %k0|%k0, %2}"
5169   [(set_attr "type" "alu")
5170    (set_attr "pent_pair" "pu")
5171    (set_attr "mode" "SI")])
5172
5173 (define_insn "*addsi3_cc"
5174   [(set (reg:CC FLAGS_REG)
5175         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5176                     (match_operand:SI 2 "general_operand" "ri,rm")]
5177                    UNSPEC_ADD_CARRY))
5178    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5179         (plus:SI (match_dup 1) (match_dup 2)))]
5180   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5181   "add{l}\t{%2, %0|%0, %2}"
5182   [(set_attr "type" "alu")
5183    (set_attr "mode" "SI")])
5184
5185 (define_insn "addqi3_cc"
5186   [(set (reg:CC FLAGS_REG)
5187         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5188                     (match_operand:QI 2 "general_operand" "qi,qm")]
5189                    UNSPEC_ADD_CARRY))
5190    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5191         (plus:QI (match_dup 1) (match_dup 2)))]
5192   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5193   "add{b}\t{%2, %0|%0, %2}"
5194   [(set_attr "type" "alu")
5195    (set_attr "mode" "QI")])
5196
5197 (define_expand "addsi3"
5198   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5199                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5200                             (match_operand:SI 2 "general_operand" "")))
5201               (clobber (reg:CC FLAGS_REG))])]
5202   ""
5203   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5204
5205 (define_insn "*lea_1"
5206   [(set (match_operand:SI 0 "register_operand" "=r")
5207         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5208   "!TARGET_64BIT"
5209   "lea{l}\t{%a1, %0|%0, %a1}"
5210   [(set_attr "type" "lea")
5211    (set_attr "mode" "SI")])
5212
5213 (define_insn "*lea_1_rex64"
5214   [(set (match_operand:SI 0 "register_operand" "=r")
5215         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5216   "TARGET_64BIT"
5217   "lea{l}\t{%a1, %0|%0, %a1}"
5218   [(set_attr "type" "lea")
5219    (set_attr "mode" "SI")])
5220
5221 (define_insn "*lea_1_zext"
5222   [(set (match_operand:DI 0 "register_operand" "=r")
5223         (zero_extend:DI
5224          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5225   "TARGET_64BIT"
5226   "lea{l}\t{%a1, %k0|%k0, %a1}"
5227   [(set_attr "type" "lea")
5228    (set_attr "mode" "SI")])
5229
5230 (define_insn "*lea_2_rex64"
5231   [(set (match_operand:DI 0 "register_operand" "=r")
5232         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5233   "TARGET_64BIT"
5234   "lea{q}\t{%a1, %0|%0, %a1}"
5235   [(set_attr "type" "lea")
5236    (set_attr "mode" "DI")])
5237
5238 ;; The lea patterns for non-Pmodes needs to be matched by several
5239 ;; insns converted to real lea by splitters.
5240
5241 (define_insn_and_split "*lea_general_1"
5242   [(set (match_operand 0 "register_operand" "=r")
5243         (plus (plus (match_operand 1 "index_register_operand" "l")
5244                     (match_operand 2 "register_operand" "r"))
5245               (match_operand 3 "immediate_operand" "i")))]
5246   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5247     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5248    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5249    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5250    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5251    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5252        || GET_MODE (operands[3]) == VOIDmode)"
5253   "#"
5254   "&& reload_completed"
5255   [(const_int 0)]
5256 {
5257   rtx pat;
5258   operands[0] = gen_lowpart (SImode, operands[0]);
5259   operands[1] = gen_lowpart (Pmode, operands[1]);
5260   operands[2] = gen_lowpart (Pmode, operands[2]);
5261   operands[3] = gen_lowpart (Pmode, operands[3]);
5262   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5263                       operands[3]);
5264   if (Pmode != SImode)
5265     pat = gen_rtx_SUBREG (SImode, pat, 0);
5266   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5267   DONE;
5268 }
5269   [(set_attr "type" "lea")
5270    (set_attr "mode" "SI")])
5271
5272 (define_insn_and_split "*lea_general_1_zext"
5273   [(set (match_operand:DI 0 "register_operand" "=r")
5274         (zero_extend:DI
5275           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5276                             (match_operand:SI 2 "register_operand" "r"))
5277                    (match_operand:SI 3 "immediate_operand" "i"))))]
5278   "TARGET_64BIT"
5279   "#"
5280   "&& reload_completed"
5281   [(set (match_dup 0)
5282         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5283                                                      (match_dup 2))
5284                                             (match_dup 3)) 0)))]
5285 {
5286   operands[1] = gen_lowpart (Pmode, operands[1]);
5287   operands[2] = gen_lowpart (Pmode, operands[2]);
5288   operands[3] = gen_lowpart (Pmode, operands[3]);
5289 }
5290   [(set_attr "type" "lea")
5291    (set_attr "mode" "SI")])
5292
5293 (define_insn_and_split "*lea_general_2"
5294   [(set (match_operand 0 "register_operand" "=r")
5295         (plus (mult (match_operand 1 "index_register_operand" "l")
5296                     (match_operand 2 "const248_operand" "i"))
5297               (match_operand 3 "nonmemory_operand" "ri")))]
5298   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5299     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5300    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5301    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5302    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5303        || GET_MODE (operands[3]) == VOIDmode)"
5304   "#"
5305   "&& reload_completed"
5306   [(const_int 0)]
5307 {
5308   rtx pat;
5309   operands[0] = gen_lowpart (SImode, operands[0]);
5310   operands[1] = gen_lowpart (Pmode, operands[1]);
5311   operands[3] = gen_lowpart (Pmode, operands[3]);
5312   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5313                       operands[3]);
5314   if (Pmode != SImode)
5315     pat = gen_rtx_SUBREG (SImode, pat, 0);
5316   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5317   DONE;
5318 }
5319   [(set_attr "type" "lea")
5320    (set_attr "mode" "SI")])
5321
5322 (define_insn_and_split "*lea_general_2_zext"
5323   [(set (match_operand:DI 0 "register_operand" "=r")
5324         (zero_extend:DI
5325           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5326                             (match_operand:SI 2 "const248_operand" "n"))
5327                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5328   "TARGET_64BIT"
5329   "#"
5330   "&& reload_completed"
5331   [(set (match_dup 0)
5332         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5333                                                      (match_dup 2))
5334                                             (match_dup 3)) 0)))]
5335 {
5336   operands[1] = gen_lowpart (Pmode, operands[1]);
5337   operands[3] = gen_lowpart (Pmode, operands[3]);
5338 }
5339   [(set_attr "type" "lea")
5340    (set_attr "mode" "SI")])
5341
5342 (define_insn_and_split "*lea_general_3"
5343   [(set (match_operand 0 "register_operand" "=r")
5344         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5345                           (match_operand 2 "const248_operand" "i"))
5346                     (match_operand 3 "register_operand" "r"))
5347               (match_operand 4 "immediate_operand" "i")))]
5348   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5349     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5350    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5351    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5352    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5353   "#"
5354   "&& reload_completed"
5355   [(const_int 0)]
5356 {
5357   rtx pat;
5358   operands[0] = gen_lowpart (SImode, operands[0]);
5359   operands[1] = gen_lowpart (Pmode, operands[1]);
5360   operands[3] = gen_lowpart (Pmode, operands[3]);
5361   operands[4] = gen_lowpart (Pmode, operands[4]);
5362   pat = gen_rtx_PLUS (Pmode,
5363                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5364                                                          operands[2]),
5365                                     operands[3]),
5366                       operands[4]);
5367   if (Pmode != SImode)
5368     pat = gen_rtx_SUBREG (SImode, pat, 0);
5369   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5370   DONE;
5371 }
5372   [(set_attr "type" "lea")
5373    (set_attr "mode" "SI")])
5374
5375 (define_insn_and_split "*lea_general_3_zext"
5376   [(set (match_operand:DI 0 "register_operand" "=r")
5377         (zero_extend:DI
5378           (plus:SI (plus:SI (mult:SI
5379                               (match_operand:SI 1 "index_register_operand" "l")
5380                               (match_operand:SI 2 "const248_operand" "n"))
5381                             (match_operand:SI 3 "register_operand" "r"))
5382                    (match_operand:SI 4 "immediate_operand" "i"))))]
5383   "TARGET_64BIT"
5384   "#"
5385   "&& reload_completed"
5386   [(set (match_dup 0)
5387         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5388                                                               (match_dup 2))
5389                                                      (match_dup 3))
5390                                             (match_dup 4)) 0)))]
5391 {
5392   operands[1] = gen_lowpart (Pmode, operands[1]);
5393   operands[3] = gen_lowpart (Pmode, operands[3]);
5394   operands[4] = gen_lowpart (Pmode, operands[4]);
5395 }
5396   [(set_attr "type" "lea")
5397    (set_attr "mode" "SI")])
5398
5399 (define_insn "*adddi_1_rex64"
5400   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5401         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5402                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5403    (clobber (reg:CC FLAGS_REG))]
5404   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5405 {
5406   switch (get_attr_type (insn))
5407     {
5408     case TYPE_LEA:
5409       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5410       return "lea{q}\t{%a2, %0|%0, %a2}";
5411
5412     case TYPE_INCDEC:
5413       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5414       if (operands[2] == const1_rtx)
5415         return "inc{q}\t%0";
5416       else
5417         {
5418           gcc_assert (operands[2] == constm1_rtx);
5419           return "dec{q}\t%0";
5420         }
5421
5422     default:
5423       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5424
5425       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5426          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5427       if (CONST_INT_P (operands[2])
5428           /* Avoid overflows.  */
5429           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5430           && (INTVAL (operands[2]) == 128
5431               || (INTVAL (operands[2]) < 0
5432                   && INTVAL (operands[2]) != -128)))
5433         {
5434           operands[2] = GEN_INT (-INTVAL (operands[2]));
5435           return "sub{q}\t{%2, %0|%0, %2}";
5436         }
5437       return "add{q}\t{%2, %0|%0, %2}";
5438     }
5439 }
5440   [(set (attr "type")
5441      (cond [(eq_attr "alternative" "2")
5442               (const_string "lea")
5443             ; Current assemblers are broken and do not allow @GOTOFF in
5444             ; ought but a memory context.
5445             (match_operand:DI 2 "pic_symbolic_operand" "")
5446               (const_string "lea")
5447             (match_operand:DI 2 "incdec_operand" "")
5448               (const_string "incdec")
5449            ]
5450            (const_string "alu")))
5451    (set_attr "mode" "DI")])
5452
5453 ;; Convert lea to the lea pattern to avoid flags dependency.
5454 (define_split
5455   [(set (match_operand:DI 0 "register_operand" "")
5456         (plus:DI (match_operand:DI 1 "register_operand" "")
5457                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5458    (clobber (reg:CC FLAGS_REG))]
5459   "TARGET_64BIT && reload_completed
5460    && true_regnum (operands[0]) != true_regnum (operands[1])"
5461   [(set (match_dup 0)
5462         (plus:DI (match_dup 1)
5463                  (match_dup 2)))]
5464   "")
5465
5466 (define_insn "*adddi_2_rex64"
5467   [(set (reg FLAGS_REG)
5468         (compare
5469           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5470                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5471           (const_int 0)))
5472    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5473         (plus:DI (match_dup 1) (match_dup 2)))]
5474   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5475    && ix86_binary_operator_ok (PLUS, DImode, operands)
5476    /* Current assemblers are broken and do not allow @GOTOFF in
5477       ought but a memory context.  */
5478    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5479 {
5480   switch (get_attr_type (insn))
5481     {
5482     case TYPE_INCDEC:
5483       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5484       if (operands[2] == const1_rtx)
5485         return "inc{q}\t%0";
5486       else
5487         {
5488           gcc_assert (operands[2] == constm1_rtx);
5489           return "dec{q}\t%0";
5490         }
5491
5492     default:
5493       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5494       /* ???? We ought to handle there the 32bit case too
5495          - do we need new constraint?  */
5496       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5497          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5498       if (CONST_INT_P (operands[2])
5499           /* Avoid overflows.  */
5500           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5501           && (INTVAL (operands[2]) == 128
5502               || (INTVAL (operands[2]) < 0
5503                   && INTVAL (operands[2]) != -128)))
5504         {
5505           operands[2] = GEN_INT (-INTVAL (operands[2]));
5506           return "sub{q}\t{%2, %0|%0, %2}";
5507         }
5508       return "add{q}\t{%2, %0|%0, %2}";
5509     }
5510 }
5511   [(set (attr "type")
5512      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5513         (const_string "incdec")
5514         (const_string "alu")))
5515    (set_attr "mode" "DI")])
5516
5517 (define_insn "*adddi_3_rex64"
5518   [(set (reg FLAGS_REG)
5519         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5520                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5521    (clobber (match_scratch:DI 0 "=r"))]
5522   "TARGET_64BIT
5523    && ix86_match_ccmode (insn, CCZmode)
5524    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5525    /* Current assemblers are broken and do not allow @GOTOFF in
5526       ought but a memory context.  */
5527    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5528 {
5529   switch (get_attr_type (insn))
5530     {
5531     case TYPE_INCDEC:
5532       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5533       if (operands[2] == const1_rtx)
5534         return "inc{q}\t%0";
5535       else
5536         {
5537           gcc_assert (operands[2] == constm1_rtx);
5538           return "dec{q}\t%0";
5539         }
5540
5541     default:
5542       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5543       /* ???? We ought to handle there the 32bit case too
5544          - do we need new constraint?  */
5545       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5546          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5547       if (CONST_INT_P (operands[2])
5548           /* Avoid overflows.  */
5549           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5550           && (INTVAL (operands[2]) == 128
5551               || (INTVAL (operands[2]) < 0
5552                   && INTVAL (operands[2]) != -128)))
5553         {
5554           operands[2] = GEN_INT (-INTVAL (operands[2]));
5555           return "sub{q}\t{%2, %0|%0, %2}";
5556         }
5557       return "add{q}\t{%2, %0|%0, %2}";
5558     }
5559 }
5560   [(set (attr "type")
5561      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5562         (const_string "incdec")
5563         (const_string "alu")))
5564    (set_attr "mode" "DI")])
5565
5566 ; For comparisons against 1, -1 and 128, we may generate better code
5567 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5568 ; is matched then.  We can't accept general immediate, because for
5569 ; case of overflows,  the result is messed up.
5570 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5571 ; when negated.
5572 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5573 ; only for comparisons not depending on it.
5574 (define_insn "*adddi_4_rex64"
5575   [(set (reg FLAGS_REG)
5576         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5577                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5578    (clobber (match_scratch:DI 0 "=rm"))]
5579   "TARGET_64BIT
5580    &&  ix86_match_ccmode (insn, CCGCmode)"
5581 {
5582   switch (get_attr_type (insn))
5583     {
5584     case TYPE_INCDEC:
5585       if (operands[2] == constm1_rtx)
5586         return "inc{q}\t%0";
5587       else
5588         {
5589           gcc_assert (operands[2] == const1_rtx);
5590           return "dec{q}\t%0";
5591         }
5592
5593     default:
5594       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5595       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5596          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5597       if ((INTVAL (operands[2]) == -128
5598            || (INTVAL (operands[2]) > 0
5599                && INTVAL (operands[2]) != 128))
5600           /* Avoid overflows.  */
5601           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5602         return "sub{q}\t{%2, %0|%0, %2}";
5603       operands[2] = GEN_INT (-INTVAL (operands[2]));
5604       return "add{q}\t{%2, %0|%0, %2}";
5605     }
5606 }
5607   [(set (attr "type")
5608      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5609         (const_string "incdec")
5610         (const_string "alu")))
5611    (set_attr "mode" "DI")])
5612
5613 (define_insn "*adddi_5_rex64"
5614   [(set (reg FLAGS_REG)
5615         (compare
5616           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5617                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5618           (const_int 0)))
5619    (clobber (match_scratch:DI 0 "=r"))]
5620   "TARGET_64BIT
5621    && ix86_match_ccmode (insn, CCGOCmode)
5622    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5623    /* Current assemblers are broken and do not allow @GOTOFF in
5624       ought but a memory context.  */
5625    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5626 {
5627   switch (get_attr_type (insn))
5628     {
5629     case TYPE_INCDEC:
5630       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5631       if (operands[2] == const1_rtx)
5632         return "inc{q}\t%0";
5633       else
5634         {
5635           gcc_assert (operands[2] == constm1_rtx);
5636           return "dec{q}\t%0";
5637         }
5638
5639     default:
5640       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5641       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5642          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5643       if (CONST_INT_P (operands[2])
5644           /* Avoid overflows.  */
5645           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5646           && (INTVAL (operands[2]) == 128
5647               || (INTVAL (operands[2]) < 0
5648                   && INTVAL (operands[2]) != -128)))
5649         {
5650           operands[2] = GEN_INT (-INTVAL (operands[2]));
5651           return "sub{q}\t{%2, %0|%0, %2}";
5652         }
5653       return "add{q}\t{%2, %0|%0, %2}";
5654     }
5655 }
5656   [(set (attr "type")
5657      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5658         (const_string "incdec")
5659         (const_string "alu")))
5660    (set_attr "mode" "DI")])
5661
5662
5663 (define_insn "*addsi_1"
5664   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5665         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5666                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5667    (clobber (reg:CC FLAGS_REG))]
5668   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5669 {
5670   switch (get_attr_type (insn))
5671     {
5672     case TYPE_LEA:
5673       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5674       return "lea{l}\t{%a2, %0|%0, %a2}";
5675
5676     case TYPE_INCDEC:
5677       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5678       if (operands[2] == const1_rtx)
5679         return "inc{l}\t%0";
5680       else
5681         {
5682           gcc_assert (operands[2] == constm1_rtx);
5683           return "dec{l}\t%0";
5684         }
5685
5686     default:
5687       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5688
5689       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5690          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5691       if (CONST_INT_P (operands[2])
5692           && (INTVAL (operands[2]) == 128
5693               || (INTVAL (operands[2]) < 0
5694                   && INTVAL (operands[2]) != -128)))
5695         {
5696           operands[2] = GEN_INT (-INTVAL (operands[2]));
5697           return "sub{l}\t{%2, %0|%0, %2}";
5698         }
5699       return "add{l}\t{%2, %0|%0, %2}";
5700     }
5701 }
5702   [(set (attr "type")
5703      (cond [(eq_attr "alternative" "2")
5704               (const_string "lea")
5705             ; Current assemblers are broken and do not allow @GOTOFF in
5706             ; ought but a memory context.
5707             (match_operand:SI 2 "pic_symbolic_operand" "")
5708               (const_string "lea")
5709             (match_operand:SI 2 "incdec_operand" "")
5710               (const_string "incdec")
5711            ]
5712            (const_string "alu")))
5713    (set_attr "mode" "SI")])
5714
5715 ;; Convert lea to the lea pattern to avoid flags dependency.
5716 (define_split
5717   [(set (match_operand 0 "register_operand" "")
5718         (plus (match_operand 1 "register_operand" "")
5719               (match_operand 2 "nonmemory_operand" "")))
5720    (clobber (reg:CC FLAGS_REG))]
5721   "reload_completed
5722    && true_regnum (operands[0]) != true_regnum (operands[1])"
5723   [(const_int 0)]
5724 {
5725   rtx pat;
5726   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5727      may confuse gen_lowpart.  */
5728   if (GET_MODE (operands[0]) != Pmode)
5729     {
5730       operands[1] = gen_lowpart (Pmode, operands[1]);
5731       operands[2] = gen_lowpart (Pmode, operands[2]);
5732     }
5733   operands[0] = gen_lowpart (SImode, operands[0]);
5734   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5735   if (Pmode != SImode)
5736     pat = gen_rtx_SUBREG (SImode, pat, 0);
5737   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5738   DONE;
5739 })
5740
5741 ;; It may seem that nonimmediate operand is proper one for operand 1.
5742 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5743 ;; we take care in ix86_binary_operator_ok to not allow two memory
5744 ;; operands so proper swapping will be done in reload.  This allow
5745 ;; patterns constructed from addsi_1 to match.
5746 (define_insn "addsi_1_zext"
5747   [(set (match_operand:DI 0 "register_operand" "=r,r")
5748         (zero_extend:DI
5749           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5750                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5751    (clobber (reg:CC FLAGS_REG))]
5752   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5753 {
5754   switch (get_attr_type (insn))
5755     {
5756     case TYPE_LEA:
5757       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5758       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5759
5760     case TYPE_INCDEC:
5761       if (operands[2] == const1_rtx)
5762         return "inc{l}\t%k0";
5763       else
5764         {
5765           gcc_assert (operands[2] == constm1_rtx);
5766           return "dec{l}\t%k0";
5767         }
5768
5769     default:
5770       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5771          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5772       if (CONST_INT_P (operands[2])
5773           && (INTVAL (operands[2]) == 128
5774               || (INTVAL (operands[2]) < 0
5775                   && INTVAL (operands[2]) != -128)))
5776         {
5777           operands[2] = GEN_INT (-INTVAL (operands[2]));
5778           return "sub{l}\t{%2, %k0|%k0, %2}";
5779         }
5780       return "add{l}\t{%2, %k0|%k0, %2}";
5781     }
5782 }
5783   [(set (attr "type")
5784      (cond [(eq_attr "alternative" "1")
5785               (const_string "lea")
5786             ; Current assemblers are broken and do not allow @GOTOFF in
5787             ; ought but a memory context.
5788             (match_operand:SI 2 "pic_symbolic_operand" "")
5789               (const_string "lea")
5790             (match_operand:SI 2 "incdec_operand" "")
5791               (const_string "incdec")
5792            ]
5793            (const_string "alu")))
5794    (set_attr "mode" "SI")])
5795
5796 ;; Convert lea to the lea pattern to avoid flags dependency.
5797 (define_split
5798   [(set (match_operand:DI 0 "register_operand" "")
5799         (zero_extend:DI
5800           (plus:SI (match_operand:SI 1 "register_operand" "")
5801                    (match_operand:SI 2 "nonmemory_operand" ""))))
5802    (clobber (reg:CC FLAGS_REG))]
5803   "TARGET_64BIT && reload_completed
5804    && true_regnum (operands[0]) != true_regnum (operands[1])"
5805   [(set (match_dup 0)
5806         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5807 {
5808   operands[1] = gen_lowpart (Pmode, operands[1]);
5809   operands[2] = gen_lowpart (Pmode, operands[2]);
5810 })
5811
5812 (define_insn "*addsi_2"
5813   [(set (reg FLAGS_REG)
5814         (compare
5815           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5816                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5817           (const_int 0)))
5818    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5819         (plus:SI (match_dup 1) (match_dup 2)))]
5820   "ix86_match_ccmode (insn, CCGOCmode)
5821    && ix86_binary_operator_ok (PLUS, SImode, operands)
5822    /* Current assemblers are broken and do not allow @GOTOFF in
5823       ought but a memory context.  */
5824    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5825 {
5826   switch (get_attr_type (insn))
5827     {
5828     case TYPE_INCDEC:
5829       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5830       if (operands[2] == const1_rtx)
5831         return "inc{l}\t%0";
5832       else
5833         {
5834           gcc_assert (operands[2] == constm1_rtx);
5835           return "dec{l}\t%0";
5836         }
5837
5838     default:
5839       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5840       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5841          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5842       if (CONST_INT_P (operands[2])
5843           && (INTVAL (operands[2]) == 128
5844               || (INTVAL (operands[2]) < 0
5845                   && INTVAL (operands[2]) != -128)))
5846         {
5847           operands[2] = GEN_INT (-INTVAL (operands[2]));
5848           return "sub{l}\t{%2, %0|%0, %2}";
5849         }
5850       return "add{l}\t{%2, %0|%0, %2}";
5851     }
5852 }
5853   [(set (attr "type")
5854      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5855         (const_string "incdec")
5856         (const_string "alu")))
5857    (set_attr "mode" "SI")])
5858
5859 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5860 (define_insn "*addsi_2_zext"
5861   [(set (reg FLAGS_REG)
5862         (compare
5863           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5864                    (match_operand:SI 2 "general_operand" "rmni"))
5865           (const_int 0)))
5866    (set (match_operand:DI 0 "register_operand" "=r")
5867         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5868   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5869    && ix86_binary_operator_ok (PLUS, SImode, operands)
5870    /* Current assemblers are broken and do not allow @GOTOFF in
5871       ought but a memory context.  */
5872    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5873 {
5874   switch (get_attr_type (insn))
5875     {
5876     case TYPE_INCDEC:
5877       if (operands[2] == const1_rtx)
5878         return "inc{l}\t%k0";
5879       else
5880         {
5881           gcc_assert (operands[2] == constm1_rtx);
5882           return "dec{l}\t%k0";
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 (CONST_INT_P (operands[2])
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{l}\t{%2, %k0|%k0, %2}";
5895         }
5896       return "add{l}\t{%2, %k0|%k0, %2}";
5897     }
5898 }
5899   [(set (attr "type")
5900      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5901         (const_string "incdec")
5902         (const_string "alu")))
5903    (set_attr "mode" "SI")])
5904
5905 (define_insn "*addsi_3"
5906   [(set (reg FLAGS_REG)
5907         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5908                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5909    (clobber (match_scratch:SI 0 "=r"))]
5910   "ix86_match_ccmode (insn, CCZmode)
5911    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5912    /* Current assemblers are broken and do not allow @GOTOFF in
5913       ought but a memory context.  */
5914    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5915 {
5916   switch (get_attr_type (insn))
5917     {
5918     case TYPE_INCDEC:
5919       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5920       if (operands[2] == const1_rtx)
5921         return "inc{l}\t%0";
5922       else
5923         {
5924           gcc_assert (operands[2] == constm1_rtx);
5925           return "dec{l}\t%0";
5926         }
5927
5928     default:
5929       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5930       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5931          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5932       if (CONST_INT_P (operands[2])
5933           && (INTVAL (operands[2]) == 128
5934               || (INTVAL (operands[2]) < 0
5935                   && INTVAL (operands[2]) != -128)))
5936         {
5937           operands[2] = GEN_INT (-INTVAL (operands[2]));
5938           return "sub{l}\t{%2, %0|%0, %2}";
5939         }
5940       return "add{l}\t{%2, %0|%0, %2}";
5941     }
5942 }
5943   [(set (attr "type")
5944      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5945         (const_string "incdec")
5946         (const_string "alu")))
5947    (set_attr "mode" "SI")])
5948
5949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5950 (define_insn "*addsi_3_zext"
5951   [(set (reg FLAGS_REG)
5952         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5953                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5954    (set (match_operand:DI 0 "register_operand" "=r")
5955         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5956   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5957    && ix86_binary_operator_ok (PLUS, SImode, operands)
5958    /* Current assemblers are broken and do not allow @GOTOFF in
5959       ought but a memory context.  */
5960    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5961 {
5962   switch (get_attr_type (insn))
5963     {
5964     case TYPE_INCDEC:
5965       if (operands[2] == const1_rtx)
5966         return "inc{l}\t%k0";
5967       else
5968         {
5969           gcc_assert (operands[2] == constm1_rtx);
5970           return "dec{l}\t%k0";
5971         }
5972
5973     default:
5974       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5975          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5976       if (CONST_INT_P (operands[2])
5977           && (INTVAL (operands[2]) == 128
5978               || (INTVAL (operands[2]) < 0
5979                   && INTVAL (operands[2]) != -128)))
5980         {
5981           operands[2] = GEN_INT (-INTVAL (operands[2]));
5982           return "sub{l}\t{%2, %k0|%k0, %2}";
5983         }
5984       return "add{l}\t{%2, %k0|%k0, %2}";
5985     }
5986 }
5987   [(set (attr "type")
5988      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5989         (const_string "incdec")
5990         (const_string "alu")))
5991    (set_attr "mode" "SI")])
5992
5993 ; For comparisons against 1, -1 and 128, we may generate better code
5994 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5995 ; is matched then.  We can't accept general immediate, because for
5996 ; case of overflows,  the result is messed up.
5997 ; This pattern also don't hold of 0x80000000, since the value overflows
5998 ; when negated.
5999 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6000 ; only for comparisons not depending on it.
6001 (define_insn "*addsi_4"
6002   [(set (reg FLAGS_REG)
6003         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6004                  (match_operand:SI 2 "const_int_operand" "n")))
6005    (clobber (match_scratch:SI 0 "=rm"))]
6006   "ix86_match_ccmode (insn, CCGCmode)
6007    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6008 {
6009   switch (get_attr_type (insn))
6010     {
6011     case TYPE_INCDEC:
6012       if (operands[2] == constm1_rtx)
6013         return "inc{l}\t%0";
6014       else
6015         {
6016           gcc_assert (operands[2] == const1_rtx);
6017           return "dec{l}\t%0";
6018         }
6019
6020     default:
6021       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6022       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6023          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6024       if ((INTVAL (operands[2]) == -128
6025            || (INTVAL (operands[2]) > 0
6026                && INTVAL (operands[2]) != 128)))
6027         return "sub{l}\t{%2, %0|%0, %2}";
6028       operands[2] = GEN_INT (-INTVAL (operands[2]));
6029       return "add{l}\t{%2, %0|%0, %2}";
6030     }
6031 }
6032   [(set (attr "type")
6033      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6034         (const_string "incdec")
6035         (const_string "alu")))
6036    (set_attr "mode" "SI")])
6037
6038 (define_insn "*addsi_5"
6039   [(set (reg FLAGS_REG)
6040         (compare
6041           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6042                    (match_operand:SI 2 "general_operand" "rmni"))
6043           (const_int 0)))
6044    (clobber (match_scratch:SI 0 "=r"))]
6045   "ix86_match_ccmode (insn, CCGOCmode)
6046    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6047    /* Current assemblers are broken and do not allow @GOTOFF in
6048       ought but a memory context.  */
6049    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6050 {
6051   switch (get_attr_type (insn))
6052     {
6053     case TYPE_INCDEC:
6054       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6055       if (operands[2] == const1_rtx)
6056         return "inc{l}\t%0";
6057       else
6058         {
6059           gcc_assert (operands[2] == constm1_rtx);
6060           return "dec{l}\t%0";
6061         }
6062
6063     default:
6064       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6065       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6066          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6067       if (CONST_INT_P (operands[2])
6068           && (INTVAL (operands[2]) == 128
6069               || (INTVAL (operands[2]) < 0
6070                   && INTVAL (operands[2]) != -128)))
6071         {
6072           operands[2] = GEN_INT (-INTVAL (operands[2]));
6073           return "sub{l}\t{%2, %0|%0, %2}";
6074         }
6075       return "add{l}\t{%2, %0|%0, %2}";
6076     }
6077 }
6078   [(set (attr "type")
6079      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6080         (const_string "incdec")
6081         (const_string "alu")))
6082    (set_attr "mode" "SI")])
6083
6084 (define_expand "addhi3"
6085   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6086                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6087                             (match_operand:HI 2 "general_operand" "")))
6088               (clobber (reg:CC FLAGS_REG))])]
6089   "TARGET_HIMODE_MATH"
6090   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6091
6092 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6093 ;; type optimizations enabled by define-splits.  This is not important
6094 ;; for PII, and in fact harmful because of partial register stalls.
6095
6096 (define_insn "*addhi_1_lea"
6097   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6098         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6099                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6100    (clobber (reg:CC FLAGS_REG))]
6101   "!TARGET_PARTIAL_REG_STALL
6102    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6103 {
6104   switch (get_attr_type (insn))
6105     {
6106     case TYPE_LEA:
6107       return "#";
6108     case TYPE_INCDEC:
6109       if (operands[2] == const1_rtx)
6110         return "inc{w}\t%0";
6111       else
6112         {
6113           gcc_assert (operands[2] == constm1_rtx);
6114           return "dec{w}\t%0";
6115         }
6116
6117     default:
6118       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6119          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6120       if (CONST_INT_P (operands[2])
6121           && (INTVAL (operands[2]) == 128
6122               || (INTVAL (operands[2]) < 0
6123                   && INTVAL (operands[2]) != -128)))
6124         {
6125           operands[2] = GEN_INT (-INTVAL (operands[2]));
6126           return "sub{w}\t{%2, %0|%0, %2}";
6127         }
6128       return "add{w}\t{%2, %0|%0, %2}";
6129     }
6130 }
6131   [(set (attr "type")
6132      (if_then_else (eq_attr "alternative" "2")
6133         (const_string "lea")
6134         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6135            (const_string "incdec")
6136            (const_string "alu"))))
6137    (set_attr "mode" "HI,HI,SI")])
6138
6139 (define_insn "*addhi_1"
6140   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6141         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6142                  (match_operand:HI 2 "general_operand" "ri,rm")))
6143    (clobber (reg:CC FLAGS_REG))]
6144   "TARGET_PARTIAL_REG_STALL
6145    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6146 {
6147   switch (get_attr_type (insn))
6148     {
6149     case TYPE_INCDEC:
6150       if (operands[2] == const1_rtx)
6151         return "inc{w}\t%0";
6152       else
6153         {
6154           gcc_assert (operands[2] == constm1_rtx);
6155           return "dec{w}\t%0";
6156         }
6157
6158     default:
6159       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6160          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6161       if (CONST_INT_P (operands[2])
6162           && (INTVAL (operands[2]) == 128
6163               || (INTVAL (operands[2]) < 0
6164                   && INTVAL (operands[2]) != -128)))
6165         {
6166           operands[2] = GEN_INT (-INTVAL (operands[2]));
6167           return "sub{w}\t{%2, %0|%0, %2}";
6168         }
6169       return "add{w}\t{%2, %0|%0, %2}";
6170     }
6171 }
6172   [(set (attr "type")
6173      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6174         (const_string "incdec")
6175         (const_string "alu")))
6176    (set_attr "mode" "HI")])
6177
6178 (define_insn "*addhi_2"
6179   [(set (reg FLAGS_REG)
6180         (compare
6181           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6182                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6183           (const_int 0)))
6184    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6185         (plus:HI (match_dup 1) (match_dup 2)))]
6186   "ix86_match_ccmode (insn, CCGOCmode)
6187    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6188 {
6189   switch (get_attr_type (insn))
6190     {
6191     case TYPE_INCDEC:
6192       if (operands[2] == const1_rtx)
6193         return "inc{w}\t%0";
6194       else
6195         {
6196           gcc_assert (operands[2] == constm1_rtx);
6197           return "dec{w}\t%0";
6198         }
6199
6200     default:
6201       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6202          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6203       if (CONST_INT_P (operands[2])
6204           && (INTVAL (operands[2]) == 128
6205               || (INTVAL (operands[2]) < 0
6206                   && INTVAL (operands[2]) != -128)))
6207         {
6208           operands[2] = GEN_INT (-INTVAL (operands[2]));
6209           return "sub{w}\t{%2, %0|%0, %2}";
6210         }
6211       return "add{w}\t{%2, %0|%0, %2}";
6212     }
6213 }
6214   [(set (attr "type")
6215      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6216         (const_string "incdec")
6217         (const_string "alu")))
6218    (set_attr "mode" "HI")])
6219
6220 (define_insn "*addhi_3"
6221   [(set (reg FLAGS_REG)
6222         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6223                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6224    (clobber (match_scratch:HI 0 "=r"))]
6225   "ix86_match_ccmode (insn, CCZmode)
6226    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6227 {
6228   switch (get_attr_type (insn))
6229     {
6230     case TYPE_INCDEC:
6231       if (operands[2] == const1_rtx)
6232         return "inc{w}\t%0";
6233       else
6234         {
6235           gcc_assert (operands[2] == constm1_rtx);
6236           return "dec{w}\t%0";
6237         }
6238
6239     default:
6240       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6241          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6242       if (CONST_INT_P (operands[2])
6243           && (INTVAL (operands[2]) == 128
6244               || (INTVAL (operands[2]) < 0
6245                   && INTVAL (operands[2]) != -128)))
6246         {
6247           operands[2] = GEN_INT (-INTVAL (operands[2]));
6248           return "sub{w}\t{%2, %0|%0, %2}";
6249         }
6250       return "add{w}\t{%2, %0|%0, %2}";
6251     }
6252 }
6253   [(set (attr "type")
6254      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6255         (const_string "incdec")
6256         (const_string "alu")))
6257    (set_attr "mode" "HI")])
6258
6259 ; See comments above addsi_4 for details.
6260 (define_insn "*addhi_4"
6261   [(set (reg FLAGS_REG)
6262         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6263                  (match_operand:HI 2 "const_int_operand" "n")))
6264    (clobber (match_scratch:HI 0 "=rm"))]
6265   "ix86_match_ccmode (insn, CCGCmode)
6266    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6267 {
6268   switch (get_attr_type (insn))
6269     {
6270     case TYPE_INCDEC:
6271       if (operands[2] == constm1_rtx)
6272         return "inc{w}\t%0";
6273       else
6274         {
6275           gcc_assert (operands[2] == const1_rtx);
6276           return "dec{w}\t%0";
6277         }
6278
6279     default:
6280       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6281       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6282          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6283       if ((INTVAL (operands[2]) == -128
6284            || (INTVAL (operands[2]) > 0
6285                && INTVAL (operands[2]) != 128)))
6286         return "sub{w}\t{%2, %0|%0, %2}";
6287       operands[2] = GEN_INT (-INTVAL (operands[2]));
6288       return "add{w}\t{%2, %0|%0, %2}";
6289     }
6290 }
6291   [(set (attr "type")
6292      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6293         (const_string "incdec")
6294         (const_string "alu")))
6295    (set_attr "mode" "SI")])
6296
6297
6298 (define_insn "*addhi_5"
6299   [(set (reg FLAGS_REG)
6300         (compare
6301           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6302                    (match_operand:HI 2 "general_operand" "rmni"))
6303           (const_int 0)))
6304    (clobber (match_scratch:HI 0 "=r"))]
6305   "ix86_match_ccmode (insn, CCGOCmode)
6306    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6307 {
6308   switch (get_attr_type (insn))
6309     {
6310     case TYPE_INCDEC:
6311       if (operands[2] == const1_rtx)
6312         return "inc{w}\t%0";
6313       else
6314         {
6315           gcc_assert (operands[2] == constm1_rtx);
6316           return "dec{w}\t%0";
6317         }
6318
6319     default:
6320       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6321          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6322       if (CONST_INT_P (operands[2])
6323           && (INTVAL (operands[2]) == 128
6324               || (INTVAL (operands[2]) < 0
6325                   && INTVAL (operands[2]) != -128)))
6326         {
6327           operands[2] = GEN_INT (-INTVAL (operands[2]));
6328           return "sub{w}\t{%2, %0|%0, %2}";
6329         }
6330       return "add{w}\t{%2, %0|%0, %2}";
6331     }
6332 }
6333   [(set (attr "type")
6334      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6335         (const_string "incdec")
6336         (const_string "alu")))
6337    (set_attr "mode" "HI")])
6338
6339 (define_expand "addqi3"
6340   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6341                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6342                             (match_operand:QI 2 "general_operand" "")))
6343               (clobber (reg:CC FLAGS_REG))])]
6344   "TARGET_QIMODE_MATH"
6345   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6346
6347 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6348 (define_insn "*addqi_1_lea"
6349   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6350         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6351                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6352    (clobber (reg:CC FLAGS_REG))]
6353   "!TARGET_PARTIAL_REG_STALL
6354    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6355 {
6356   int widen = (which_alternative == 2);
6357   switch (get_attr_type (insn))
6358     {
6359     case TYPE_LEA:
6360       return "#";
6361     case TYPE_INCDEC:
6362       if (operands[2] == const1_rtx)
6363         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6364       else
6365         {
6366           gcc_assert (operands[2] == constm1_rtx);
6367           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6368         }
6369
6370     default:
6371       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6372          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6373       if (CONST_INT_P (operands[2])
6374           && (INTVAL (operands[2]) == 128
6375               || (INTVAL (operands[2]) < 0
6376                   && INTVAL (operands[2]) != -128)))
6377         {
6378           operands[2] = GEN_INT (-INTVAL (operands[2]));
6379           if (widen)
6380             return "sub{l}\t{%2, %k0|%k0, %2}";
6381           else
6382             return "sub{b}\t{%2, %0|%0, %2}";
6383         }
6384       if (widen)
6385         return "add{l}\t{%k2, %k0|%k0, %k2}";
6386       else
6387         return "add{b}\t{%2, %0|%0, %2}";
6388     }
6389 }
6390   [(set (attr "type")
6391      (if_then_else (eq_attr "alternative" "3")
6392         (const_string "lea")
6393         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6394            (const_string "incdec")
6395            (const_string "alu"))))
6396    (set_attr "mode" "QI,QI,SI,SI")])
6397
6398 (define_insn "*addqi_1"
6399   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6400         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6401                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6402    (clobber (reg:CC FLAGS_REG))]
6403   "TARGET_PARTIAL_REG_STALL
6404    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6405 {
6406   int widen = (which_alternative == 2);
6407   switch (get_attr_type (insn))
6408     {
6409     case TYPE_INCDEC:
6410       if (operands[2] == const1_rtx)
6411         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6412       else
6413         {
6414           gcc_assert (operands[2] == constm1_rtx);
6415           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6416         }
6417
6418     default:
6419       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6420          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6421       if (CONST_INT_P (operands[2])
6422           && (INTVAL (operands[2]) == 128
6423               || (INTVAL (operands[2]) < 0
6424                   && INTVAL (operands[2]) != -128)))
6425         {
6426           operands[2] = GEN_INT (-INTVAL (operands[2]));
6427           if (widen)
6428             return "sub{l}\t{%2, %k0|%k0, %2}";
6429           else
6430             return "sub{b}\t{%2, %0|%0, %2}";
6431         }
6432       if (widen)
6433         return "add{l}\t{%k2, %k0|%k0, %k2}";
6434       else
6435         return "add{b}\t{%2, %0|%0, %2}";
6436     }
6437 }
6438   [(set (attr "type")
6439      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6440         (const_string "incdec")
6441         (const_string "alu")))
6442    (set_attr "mode" "QI,QI,SI")])
6443
6444 (define_insn "*addqi_1_slp"
6445   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6446         (plus:QI (match_dup 0)
6447                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6448    (clobber (reg:CC FLAGS_REG))]
6449   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6450    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6451 {
6452   switch (get_attr_type (insn))
6453     {
6454     case TYPE_INCDEC:
6455       if (operands[1] == const1_rtx)
6456         return "inc{b}\t%0";
6457       else
6458         {
6459           gcc_assert (operands[1] == constm1_rtx);
6460           return "dec{b}\t%0";
6461         }
6462
6463     default:
6464       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6465       if (CONST_INT_P (operands[1])
6466           && INTVAL (operands[1]) < 0)
6467         {
6468           operands[1] = GEN_INT (-INTVAL (operands[1]));
6469           return "sub{b}\t{%1, %0|%0, %1}";
6470         }
6471       return "add{b}\t{%1, %0|%0, %1}";
6472     }
6473 }
6474   [(set (attr "type")
6475      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6476         (const_string "incdec")
6477         (const_string "alu1")))
6478    (set (attr "memory")
6479      (if_then_else (match_operand 1 "memory_operand" "")
6480         (const_string "load")
6481         (const_string "none")))
6482    (set_attr "mode" "QI")])
6483
6484 (define_insn "*addqi_2"
6485   [(set (reg FLAGS_REG)
6486         (compare
6487           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6488                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6489           (const_int 0)))
6490    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6491         (plus:QI (match_dup 1) (match_dup 2)))]
6492   "ix86_match_ccmode (insn, CCGOCmode)
6493    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6494 {
6495   switch (get_attr_type (insn))
6496     {
6497     case TYPE_INCDEC:
6498       if (operands[2] == const1_rtx)
6499         return "inc{b}\t%0";
6500       else
6501         {
6502           gcc_assert (operands[2] == constm1_rtx
6503                       || (CONST_INT_P (operands[2])
6504                           && INTVAL (operands[2]) == 255));
6505           return "dec{b}\t%0";
6506         }
6507
6508     default:
6509       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6510       if (CONST_INT_P (operands[2])
6511           && INTVAL (operands[2]) < 0)
6512         {
6513           operands[2] = GEN_INT (-INTVAL (operands[2]));
6514           return "sub{b}\t{%2, %0|%0, %2}";
6515         }
6516       return "add{b}\t{%2, %0|%0, %2}";
6517     }
6518 }
6519   [(set (attr "type")
6520      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6521         (const_string "incdec")
6522         (const_string "alu")))
6523    (set_attr "mode" "QI")])
6524
6525 (define_insn "*addqi_3"
6526   [(set (reg FLAGS_REG)
6527         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6528                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6529    (clobber (match_scratch:QI 0 "=q"))]
6530   "ix86_match_ccmode (insn, CCZmode)
6531    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6532 {
6533   switch (get_attr_type (insn))
6534     {
6535     case TYPE_INCDEC:
6536       if (operands[2] == const1_rtx)
6537         return "inc{b}\t%0";
6538       else
6539         {
6540           gcc_assert (operands[2] == constm1_rtx
6541                       || (CONST_INT_P (operands[2])
6542                           && INTVAL (operands[2]) == 255));
6543           return "dec{b}\t%0";
6544         }
6545
6546     default:
6547       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6548       if (CONST_INT_P (operands[2])
6549           && INTVAL (operands[2]) < 0)
6550         {
6551           operands[2] = GEN_INT (-INTVAL (operands[2]));
6552           return "sub{b}\t{%2, %0|%0, %2}";
6553         }
6554       return "add{b}\t{%2, %0|%0, %2}";
6555     }
6556 }
6557   [(set (attr "type")
6558      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6559         (const_string "incdec")
6560         (const_string "alu")))
6561    (set_attr "mode" "QI")])
6562
6563 ; See comments above addsi_4 for details.
6564 (define_insn "*addqi_4"
6565   [(set (reg FLAGS_REG)
6566         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6567                  (match_operand:QI 2 "const_int_operand" "n")))
6568    (clobber (match_scratch:QI 0 "=qm"))]
6569   "ix86_match_ccmode (insn, CCGCmode)
6570    && (INTVAL (operands[2]) & 0xff) != 0x80"
6571 {
6572   switch (get_attr_type (insn))
6573     {
6574     case TYPE_INCDEC:
6575       if (operands[2] == constm1_rtx
6576           || (CONST_INT_P (operands[2])
6577               && INTVAL (operands[2]) == 255))
6578         return "inc{b}\t%0";
6579       else
6580         {
6581           gcc_assert (operands[2] == const1_rtx);
6582           return "dec{b}\t%0";
6583         }
6584
6585     default:
6586       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6587       if (INTVAL (operands[2]) < 0)
6588         {
6589           operands[2] = GEN_INT (-INTVAL (operands[2]));
6590           return "add{b}\t{%2, %0|%0, %2}";
6591         }
6592       return "sub{b}\t{%2, %0|%0, %2}";
6593     }
6594 }
6595   [(set (attr "type")
6596      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6597         (const_string "incdec")
6598         (const_string "alu")))
6599    (set_attr "mode" "QI")])
6600
6601
6602 (define_insn "*addqi_5"
6603   [(set (reg FLAGS_REG)
6604         (compare
6605           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6606                    (match_operand:QI 2 "general_operand" "qmni"))
6607           (const_int 0)))
6608    (clobber (match_scratch:QI 0 "=q"))]
6609   "ix86_match_ccmode (insn, CCGOCmode)
6610    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6611 {
6612   switch (get_attr_type (insn))
6613     {
6614     case TYPE_INCDEC:
6615       if (operands[2] == const1_rtx)
6616         return "inc{b}\t%0";
6617       else
6618         {
6619           gcc_assert (operands[2] == constm1_rtx
6620                       || (CONST_INT_P (operands[2])
6621                           && INTVAL (operands[2]) == 255));
6622           return "dec{b}\t%0";
6623         }
6624
6625     default:
6626       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6627       if (CONST_INT_P (operands[2])
6628           && INTVAL (operands[2]) < 0)
6629         {
6630           operands[2] = GEN_INT (-INTVAL (operands[2]));
6631           return "sub{b}\t{%2, %0|%0, %2}";
6632         }
6633       return "add{b}\t{%2, %0|%0, %2}";
6634     }
6635 }
6636   [(set (attr "type")
6637      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6638         (const_string "incdec")
6639         (const_string "alu")))
6640    (set_attr "mode" "QI")])
6641
6642
6643 (define_insn "addqi_ext_1"
6644   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6645                          (const_int 8)
6646                          (const_int 8))
6647         (plus:SI
6648           (zero_extract:SI
6649             (match_operand 1 "ext_register_operand" "0")
6650             (const_int 8)
6651             (const_int 8))
6652           (match_operand:QI 2 "general_operand" "Qmn")))
6653    (clobber (reg:CC FLAGS_REG))]
6654   "!TARGET_64BIT"
6655 {
6656   switch (get_attr_type (insn))
6657     {
6658     case TYPE_INCDEC:
6659       if (operands[2] == const1_rtx)
6660         return "inc{b}\t%h0";
6661       else
6662         {
6663           gcc_assert (operands[2] == constm1_rtx
6664                       || (CONST_INT_P (operands[2])
6665                           && INTVAL (operands[2]) == 255));
6666           return "dec{b}\t%h0";
6667         }
6668
6669     default:
6670       return "add{b}\t{%2, %h0|%h0, %2}";
6671     }
6672 }
6673   [(set (attr "type")
6674      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6675         (const_string "incdec")
6676         (const_string "alu")))
6677    (set_attr "mode" "QI")])
6678
6679 (define_insn "*addqi_ext_1_rex64"
6680   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6681                          (const_int 8)
6682                          (const_int 8))
6683         (plus:SI
6684           (zero_extract:SI
6685             (match_operand 1 "ext_register_operand" "0")
6686             (const_int 8)
6687             (const_int 8))
6688           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6689    (clobber (reg:CC FLAGS_REG))]
6690   "TARGET_64BIT"
6691 {
6692   switch (get_attr_type (insn))
6693     {
6694     case TYPE_INCDEC:
6695       if (operands[2] == const1_rtx)
6696         return "inc{b}\t%h0";
6697       else
6698         {
6699           gcc_assert (operands[2] == constm1_rtx
6700                       || (CONST_INT_P (operands[2])
6701                           && INTVAL (operands[2]) == 255));
6702           return "dec{b}\t%h0";
6703         }
6704
6705     default:
6706       return "add{b}\t{%2, %h0|%h0, %2}";
6707     }
6708 }
6709   [(set (attr "type")
6710      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6711         (const_string "incdec")
6712         (const_string "alu")))
6713    (set_attr "mode" "QI")])
6714
6715 (define_insn "*addqi_ext_2"
6716   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6717                          (const_int 8)
6718                          (const_int 8))
6719         (plus:SI
6720           (zero_extract:SI
6721             (match_operand 1 "ext_register_operand" "%0")
6722             (const_int 8)
6723             (const_int 8))
6724           (zero_extract:SI
6725             (match_operand 2 "ext_register_operand" "Q")
6726             (const_int 8)
6727             (const_int 8))))
6728    (clobber (reg:CC FLAGS_REG))]
6729   ""
6730   "add{b}\t{%h2, %h0|%h0, %h2}"
6731   [(set_attr "type" "alu")
6732    (set_attr "mode" "QI")])
6733
6734 ;; The patterns that match these are at the end of this file.
6735
6736 (define_expand "addxf3"
6737   [(set (match_operand:XF 0 "register_operand" "")
6738         (plus:XF (match_operand:XF 1 "register_operand" "")
6739                  (match_operand:XF 2 "register_operand" "")))]
6740   "TARGET_80387"
6741   "")
6742
6743 (define_expand "adddf3"
6744   [(set (match_operand:DF 0 "register_operand" "")
6745         (plus:DF (match_operand:DF 1 "register_operand" "")
6746                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6747   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6748   "")
6749
6750 (define_expand "addsf3"
6751   [(set (match_operand:SF 0 "register_operand" "")
6752         (plus:SF (match_operand:SF 1 "register_operand" "")
6753                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6754   "TARGET_80387 || TARGET_SSE_MATH"
6755   "")
6756 \f
6757 ;; Subtract instructions
6758
6759 ;; %%% splits for subditi3
6760
6761 (define_expand "subti3"
6762   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6763                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6764                              (match_operand:TI 2 "x86_64_general_operand" "")))
6765               (clobber (reg:CC FLAGS_REG))])]
6766   "TARGET_64BIT"
6767   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6768
6769 (define_insn "*subti3_1"
6770   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6771         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6772                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6773    (clobber (reg:CC FLAGS_REG))]
6774   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6775   "#")
6776
6777 (define_split
6778   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6779         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6780                   (match_operand:TI 2 "general_operand" "")))
6781    (clobber (reg:CC FLAGS_REG))]
6782   "TARGET_64BIT && reload_completed"
6783   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6784               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6785    (parallel [(set (match_dup 3)
6786                    (minus:DI (match_dup 4)
6787                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6788                                       (match_dup 5))))
6789               (clobber (reg:CC FLAGS_REG))])]
6790   "split_ti (operands+0, 1, operands+0, operands+3);
6791    split_ti (operands+1, 1, operands+1, operands+4);
6792    split_ti (operands+2, 1, operands+2, operands+5);")
6793
6794 ;; %%% splits for subsidi3
6795
6796 (define_expand "subdi3"
6797   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6798                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6799                              (match_operand:DI 2 "x86_64_general_operand" "")))
6800               (clobber (reg:CC FLAGS_REG))])]
6801   ""
6802   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6803
6804 (define_insn "*subdi3_1"
6805   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6806         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6807                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6808    (clobber (reg:CC FLAGS_REG))]
6809   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6810   "#")
6811
6812 (define_split
6813   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6814         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6815                   (match_operand:DI 2 "general_operand" "")))
6816    (clobber (reg:CC FLAGS_REG))]
6817   "!TARGET_64BIT && reload_completed"
6818   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6819               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6820    (parallel [(set (match_dup 3)
6821                    (minus:SI (match_dup 4)
6822                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6823                                       (match_dup 5))))
6824               (clobber (reg:CC FLAGS_REG))])]
6825   "split_di (operands+0, 1, operands+0, operands+3);
6826    split_di (operands+1, 1, operands+1, operands+4);
6827    split_di (operands+2, 1, operands+2, operands+5);")
6828
6829 (define_insn "subdi3_carry_rex64"
6830   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6831           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6832             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6833                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6834    (clobber (reg:CC FLAGS_REG))]
6835   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6836   "sbb{q}\t{%2, %0|%0, %2}"
6837   [(set_attr "type" "alu")
6838    (set_attr "pent_pair" "pu")
6839    (set_attr "mode" "DI")])
6840
6841 (define_insn "*subdi_1_rex64"
6842   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6843         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6844                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6845    (clobber (reg:CC FLAGS_REG))]
6846   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6847   "sub{q}\t{%2, %0|%0, %2}"
6848   [(set_attr "type" "alu")
6849    (set_attr "mode" "DI")])
6850
6851 (define_insn "*subdi_2_rex64"
6852   [(set (reg FLAGS_REG)
6853         (compare
6854           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6855                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6856           (const_int 0)))
6857    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6858         (minus:DI (match_dup 1) (match_dup 2)))]
6859   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6860    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6861   "sub{q}\t{%2, %0|%0, %2}"
6862   [(set_attr "type" "alu")
6863    (set_attr "mode" "DI")])
6864
6865 (define_insn "*subdi_3_rex63"
6866   [(set (reg FLAGS_REG)
6867         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6868                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6869    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6870         (minus:DI (match_dup 1) (match_dup 2)))]
6871   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6872    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6873   "sub{q}\t{%2, %0|%0, %2}"
6874   [(set_attr "type" "alu")
6875    (set_attr "mode" "DI")])
6876
6877 (define_insn "subqi3_carry"
6878   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6879           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6880             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6881                (match_operand:QI 2 "general_operand" "qi,qm"))))
6882    (clobber (reg:CC FLAGS_REG))]
6883   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6884   "sbb{b}\t{%2, %0|%0, %2}"
6885   [(set_attr "type" "alu")
6886    (set_attr "pent_pair" "pu")
6887    (set_attr "mode" "QI")])
6888
6889 (define_insn "subhi3_carry"
6890   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6891           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6892             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6893                (match_operand:HI 2 "general_operand" "ri,rm"))))
6894    (clobber (reg:CC FLAGS_REG))]
6895   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6896   "sbb{w}\t{%2, %0|%0, %2}"
6897   [(set_attr "type" "alu")
6898    (set_attr "pent_pair" "pu")
6899    (set_attr "mode" "HI")])
6900
6901 (define_insn "subsi3_carry"
6902   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6903           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6904             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6905                (match_operand:SI 2 "general_operand" "ri,rm"))))
6906    (clobber (reg:CC FLAGS_REG))]
6907   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6908   "sbb{l}\t{%2, %0|%0, %2}"
6909   [(set_attr "type" "alu")
6910    (set_attr "pent_pair" "pu")
6911    (set_attr "mode" "SI")])
6912
6913 (define_insn "subsi3_carry_zext"
6914   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6915           (zero_extend:DI
6916             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6917               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6918                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6919    (clobber (reg:CC FLAGS_REG))]
6920   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6921   "sbb{l}\t{%2, %k0|%k0, %2}"
6922   [(set_attr "type" "alu")
6923    (set_attr "pent_pair" "pu")
6924    (set_attr "mode" "SI")])
6925
6926 (define_expand "subsi3"
6927   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6928                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6929                              (match_operand:SI 2 "general_operand" "")))
6930               (clobber (reg:CC FLAGS_REG))])]
6931   ""
6932   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6933
6934 (define_insn "*subsi_1"
6935   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6936         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6937                   (match_operand:SI 2 "general_operand" "ri,rm")))
6938    (clobber (reg:CC FLAGS_REG))]
6939   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6940   "sub{l}\t{%2, %0|%0, %2}"
6941   [(set_attr "type" "alu")
6942    (set_attr "mode" "SI")])
6943
6944 (define_insn "*subsi_1_zext"
6945   [(set (match_operand:DI 0 "register_operand" "=r")
6946         (zero_extend:DI
6947           (minus:SI (match_operand:SI 1 "register_operand" "0")
6948                     (match_operand:SI 2 "general_operand" "rim"))))
6949    (clobber (reg:CC FLAGS_REG))]
6950   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6951   "sub{l}\t{%2, %k0|%k0, %2}"
6952   [(set_attr "type" "alu")
6953    (set_attr "mode" "SI")])
6954
6955 (define_insn "*subsi_2"
6956   [(set (reg FLAGS_REG)
6957         (compare
6958           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6959                     (match_operand:SI 2 "general_operand" "ri,rm"))
6960           (const_int 0)))
6961    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6962         (minus:SI (match_dup 1) (match_dup 2)))]
6963   "ix86_match_ccmode (insn, CCGOCmode)
6964    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6965   "sub{l}\t{%2, %0|%0, %2}"
6966   [(set_attr "type" "alu")
6967    (set_attr "mode" "SI")])
6968
6969 (define_insn "*subsi_2_zext"
6970   [(set (reg FLAGS_REG)
6971         (compare
6972           (minus:SI (match_operand:SI 1 "register_operand" "0")
6973                     (match_operand:SI 2 "general_operand" "rim"))
6974           (const_int 0)))
6975    (set (match_operand:DI 0 "register_operand" "=r")
6976         (zero_extend:DI
6977           (minus:SI (match_dup 1)
6978                     (match_dup 2))))]
6979   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6980    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6981   "sub{l}\t{%2, %k0|%k0, %2}"
6982   [(set_attr "type" "alu")
6983    (set_attr "mode" "SI")])
6984
6985 (define_insn "*subsi_3"
6986   [(set (reg FLAGS_REG)
6987         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6988                  (match_operand:SI 2 "general_operand" "ri,rm")))
6989    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6990         (minus:SI (match_dup 1) (match_dup 2)))]
6991   "ix86_match_ccmode (insn, CCmode)
6992    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6993   "sub{l}\t{%2, %0|%0, %2}"
6994   [(set_attr "type" "alu")
6995    (set_attr "mode" "SI")])
6996
6997 (define_insn "*subsi_3_zext"
6998   [(set (reg FLAGS_REG)
6999         (compare (match_operand:SI 1 "register_operand" "0")
7000                  (match_operand:SI 2 "general_operand" "rim")))
7001    (set (match_operand:DI 0 "register_operand" "=r")
7002         (zero_extend:DI
7003           (minus:SI (match_dup 1)
7004                     (match_dup 2))))]
7005   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7006    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7007   "sub{l}\t{%2, %1|%1, %2}"
7008   [(set_attr "type" "alu")
7009    (set_attr "mode" "DI")])
7010
7011 (define_expand "subhi3"
7012   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7013                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7014                              (match_operand:HI 2 "general_operand" "")))
7015               (clobber (reg:CC FLAGS_REG))])]
7016   "TARGET_HIMODE_MATH"
7017   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7018
7019 (define_insn "*subhi_1"
7020   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7021         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7022                   (match_operand:HI 2 "general_operand" "ri,rm")))
7023    (clobber (reg:CC FLAGS_REG))]
7024   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7025   "sub{w}\t{%2, %0|%0, %2}"
7026   [(set_attr "type" "alu")
7027    (set_attr "mode" "HI")])
7028
7029 (define_insn "*subhi_2"
7030   [(set (reg FLAGS_REG)
7031         (compare
7032           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7033                     (match_operand:HI 2 "general_operand" "ri,rm"))
7034           (const_int 0)))
7035    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7036         (minus:HI (match_dup 1) (match_dup 2)))]
7037   "ix86_match_ccmode (insn, CCGOCmode)
7038    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7039   "sub{w}\t{%2, %0|%0, %2}"
7040   [(set_attr "type" "alu")
7041    (set_attr "mode" "HI")])
7042
7043 (define_insn "*subhi_3"
7044   [(set (reg FLAGS_REG)
7045         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7046                  (match_operand:HI 2 "general_operand" "ri,rm")))
7047    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7048         (minus:HI (match_dup 1) (match_dup 2)))]
7049   "ix86_match_ccmode (insn, CCmode)
7050    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7051   "sub{w}\t{%2, %0|%0, %2}"
7052   [(set_attr "type" "alu")
7053    (set_attr "mode" "HI")])
7054
7055 (define_expand "subqi3"
7056   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7057                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7058                              (match_operand:QI 2 "general_operand" "")))
7059               (clobber (reg:CC FLAGS_REG))])]
7060   "TARGET_QIMODE_MATH"
7061   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7062
7063 (define_insn "*subqi_1"
7064   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7065         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7066                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7067    (clobber (reg:CC FLAGS_REG))]
7068   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7069   "sub{b}\t{%2, %0|%0, %2}"
7070   [(set_attr "type" "alu")
7071    (set_attr "mode" "QI")])
7072
7073 (define_insn "*subqi_1_slp"
7074   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7075         (minus:QI (match_dup 0)
7076                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7077    (clobber (reg:CC FLAGS_REG))]
7078   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7079    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7080   "sub{b}\t{%1, %0|%0, %1}"
7081   [(set_attr "type" "alu1")
7082    (set_attr "mode" "QI")])
7083
7084 (define_insn "*subqi_2"
7085   [(set (reg FLAGS_REG)
7086         (compare
7087           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7088                     (match_operand:QI 2 "general_operand" "qi,qm"))
7089           (const_int 0)))
7090    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7091         (minus:HI (match_dup 1) (match_dup 2)))]
7092   "ix86_match_ccmode (insn, CCGOCmode)
7093    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7094   "sub{b}\t{%2, %0|%0, %2}"
7095   [(set_attr "type" "alu")
7096    (set_attr "mode" "QI")])
7097
7098 (define_insn "*subqi_3"
7099   [(set (reg FLAGS_REG)
7100         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7101                  (match_operand:QI 2 "general_operand" "qi,qm")))
7102    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7103         (minus:HI (match_dup 1) (match_dup 2)))]
7104   "ix86_match_ccmode (insn, CCmode)
7105    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7106   "sub{b}\t{%2, %0|%0, %2}"
7107   [(set_attr "type" "alu")
7108    (set_attr "mode" "QI")])
7109
7110 ;; The patterns that match these are at the end of this file.
7111
7112 (define_expand "subxf3"
7113   [(set (match_operand:XF 0 "register_operand" "")
7114         (minus:XF (match_operand:XF 1 "register_operand" "")
7115                   (match_operand:XF 2 "register_operand" "")))]
7116   "TARGET_80387"
7117   "")
7118
7119 (define_expand "subdf3"
7120   [(set (match_operand:DF 0 "register_operand" "")
7121         (minus:DF (match_operand:DF 1 "register_operand" "")
7122                   (match_operand:DF 2 "nonimmediate_operand" "")))]
7123   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7124   "")
7125
7126 (define_expand "subsf3"
7127   [(set (match_operand:SF 0 "register_operand" "")
7128         (minus:SF (match_operand:SF 1 "register_operand" "")
7129                   (match_operand:SF 2 "nonimmediate_operand" "")))]
7130   "TARGET_80387 || TARGET_SSE_MATH"
7131   "")
7132 \f
7133 ;; Multiply instructions
7134
7135 (define_expand "muldi3"
7136   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7137                    (mult:DI (match_operand:DI 1 "register_operand" "")
7138                             (match_operand:DI 2 "x86_64_general_operand" "")))
7139               (clobber (reg:CC FLAGS_REG))])]
7140   "TARGET_64BIT"
7141   "")
7142
7143 ;; On AMDFAM10 
7144 ;; IMUL reg64, reg64, imm8      Direct
7145 ;; IMUL reg64, mem64, imm8      VectorPath
7146 ;; IMUL reg64, reg64, imm32     Direct
7147 ;; IMUL reg64, mem64, imm32     VectorPath 
7148 ;; IMUL reg64, reg64            Direct
7149 ;; IMUL reg64, mem64            Direct
7150
7151 (define_insn "*muldi3_1_rex64"
7152   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7153         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7154                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7155    (clobber (reg:CC FLAGS_REG))]
7156   "TARGET_64BIT
7157    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7158   "@
7159    imul{q}\t{%2, %1, %0|%0, %1, %2}
7160    imul{q}\t{%2, %1, %0|%0, %1, %2}
7161    imul{q}\t{%2, %0|%0, %2}"
7162   [(set_attr "type" "imul")
7163    (set_attr "prefix_0f" "0,0,1")
7164    (set (attr "athlon_decode")
7165         (cond [(eq_attr "cpu" "athlon")
7166                   (const_string "vector")
7167                (eq_attr "alternative" "1")
7168                   (const_string "vector")
7169                (and (eq_attr "alternative" "2")
7170                     (match_operand 1 "memory_operand" ""))
7171                   (const_string "vector")]
7172               (const_string "direct")))
7173    (set (attr "amdfam10_decode")
7174         (cond [(and (eq_attr "alternative" "0,1")
7175                     (match_operand 1 "memory_operand" ""))
7176                   (const_string "vector")]
7177               (const_string "direct")))       
7178    (set_attr "mode" "DI")])
7179
7180 (define_expand "mulsi3"
7181   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7182                    (mult:SI (match_operand:SI 1 "register_operand" "")
7183                             (match_operand:SI 2 "general_operand" "")))
7184               (clobber (reg:CC FLAGS_REG))])]
7185   ""
7186   "")
7187
7188 ;; On AMDFAM10 
7189 ;; IMUL reg32, reg32, imm8      Direct
7190 ;; IMUL reg32, mem32, imm8      VectorPath
7191 ;; IMUL reg32, reg32, imm32     Direct
7192 ;; IMUL reg32, mem32, imm32     VectorPath
7193 ;; IMUL reg32, reg32            Direct
7194 ;; IMUL reg32, mem32            Direct
7195
7196 (define_insn "*mulsi3_1"
7197   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7198         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7199                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7200    (clobber (reg:CC FLAGS_REG))]
7201   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7202   "@
7203    imul{l}\t{%2, %1, %0|%0, %1, %2}
7204    imul{l}\t{%2, %1, %0|%0, %1, %2}
7205    imul{l}\t{%2, %0|%0, %2}"
7206   [(set_attr "type" "imul")
7207    (set_attr "prefix_0f" "0,0,1")
7208    (set (attr "athlon_decode")
7209         (cond [(eq_attr "cpu" "athlon")
7210                   (const_string "vector")
7211                (eq_attr "alternative" "1")
7212                   (const_string "vector")
7213                (and (eq_attr "alternative" "2")
7214                     (match_operand 1 "memory_operand" ""))
7215                   (const_string "vector")]
7216               (const_string "direct")))
7217    (set (attr "amdfam10_decode")
7218         (cond [(and (eq_attr "alternative" "0,1")
7219                     (match_operand 1 "memory_operand" ""))
7220                   (const_string "vector")]
7221               (const_string "direct")))       
7222    (set_attr "mode" "SI")])
7223
7224 (define_insn "*mulsi3_1_zext"
7225   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7226         (zero_extend:DI
7227           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7228                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7229    (clobber (reg:CC FLAGS_REG))]
7230   "TARGET_64BIT
7231    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7232   "@
7233    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7234    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7235    imul{l}\t{%2, %k0|%k0, %2}"
7236   [(set_attr "type" "imul")
7237    (set_attr "prefix_0f" "0,0,1")
7238    (set (attr "athlon_decode")
7239         (cond [(eq_attr "cpu" "athlon")
7240                   (const_string "vector")
7241                (eq_attr "alternative" "1")
7242                   (const_string "vector")
7243                (and (eq_attr "alternative" "2")
7244                     (match_operand 1 "memory_operand" ""))
7245                   (const_string "vector")]
7246               (const_string "direct")))
7247    (set (attr "amdfam10_decode")
7248         (cond [(and (eq_attr "alternative" "0,1")
7249                     (match_operand 1 "memory_operand" ""))
7250                   (const_string "vector")]
7251               (const_string "direct")))       
7252    (set_attr "mode" "SI")])
7253
7254 (define_expand "mulhi3"
7255   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7256                    (mult:HI (match_operand:HI 1 "register_operand" "")
7257                             (match_operand:HI 2 "general_operand" "")))
7258               (clobber (reg:CC FLAGS_REG))])]
7259   "TARGET_HIMODE_MATH"
7260   "")
7261
7262 ;; On AMDFAM10
7263 ;; IMUL reg16, reg16, imm8      VectorPath
7264 ;; IMUL reg16, mem16, imm8      VectorPath
7265 ;; IMUL reg16, reg16, imm16     VectorPath
7266 ;; IMUL reg16, mem16, imm16     VectorPath
7267 ;; IMUL reg16, reg16            Direct
7268 ;; IMUL reg16, mem16            Direct
7269 (define_insn "*mulhi3_1"
7270   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7271         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7272                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7273    (clobber (reg:CC FLAGS_REG))]
7274   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7275   "@
7276    imul{w}\t{%2, %1, %0|%0, %1, %2}
7277    imul{w}\t{%2, %1, %0|%0, %1, %2}
7278    imul{w}\t{%2, %0|%0, %2}"
7279   [(set_attr "type" "imul")
7280    (set_attr "prefix_0f" "0,0,1")
7281    (set (attr "athlon_decode")
7282         (cond [(eq_attr "cpu" "athlon")
7283                   (const_string "vector")
7284                (eq_attr "alternative" "1,2")
7285                   (const_string "vector")]
7286               (const_string "direct")))
7287    (set (attr "amdfam10_decode")
7288         (cond [(eq_attr "alternative" "0,1")
7289                   (const_string "vector")]
7290               (const_string "direct")))
7291    (set_attr "mode" "HI")])
7292
7293 (define_expand "mulqi3"
7294   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7295                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7296                             (match_operand:QI 2 "register_operand" "")))
7297               (clobber (reg:CC FLAGS_REG))])]
7298   "TARGET_QIMODE_MATH"
7299   "")
7300
7301 ;;On AMDFAM10
7302 ;; MUL reg8     Direct
7303 ;; MUL mem8     Direct
7304
7305 (define_insn "*mulqi3_1"
7306   [(set (match_operand:QI 0 "register_operand" "=a")
7307         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7308                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7309    (clobber (reg:CC FLAGS_REG))]
7310   "TARGET_QIMODE_MATH
7311    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7312   "mul{b}\t%2"
7313   [(set_attr "type" "imul")
7314    (set_attr "length_immediate" "0")
7315    (set (attr "athlon_decode")
7316      (if_then_else (eq_attr "cpu" "athlon")
7317         (const_string "vector")
7318         (const_string "direct")))
7319    (set_attr "amdfam10_decode" "direct")        
7320    (set_attr "mode" "QI")])
7321
7322 (define_expand "umulqihi3"
7323   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7324                    (mult:HI (zero_extend:HI
7325                               (match_operand:QI 1 "nonimmediate_operand" ""))
7326                             (zero_extend:HI
7327                               (match_operand:QI 2 "register_operand" ""))))
7328               (clobber (reg:CC FLAGS_REG))])]
7329   "TARGET_QIMODE_MATH"
7330   "")
7331
7332 (define_insn "*umulqihi3_1"
7333   [(set (match_operand:HI 0 "register_operand" "=a")
7334         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7335                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7336    (clobber (reg:CC FLAGS_REG))]
7337   "TARGET_QIMODE_MATH
7338    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7339   "mul{b}\t%2"
7340   [(set_attr "type" "imul")
7341    (set_attr "length_immediate" "0")
7342    (set (attr "athlon_decode")
7343      (if_then_else (eq_attr "cpu" "athlon")
7344         (const_string "vector")
7345         (const_string "direct")))
7346    (set_attr "amdfam10_decode" "direct")        
7347    (set_attr "mode" "QI")])
7348
7349 (define_expand "mulqihi3"
7350   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7351                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7352                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7353               (clobber (reg:CC FLAGS_REG))])]
7354   "TARGET_QIMODE_MATH"
7355   "")
7356
7357 (define_insn "*mulqihi3_insn"
7358   [(set (match_operand:HI 0 "register_operand" "=a")
7359         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7360                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7361    (clobber (reg:CC FLAGS_REG))]
7362   "TARGET_QIMODE_MATH
7363    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7364   "imul{b}\t%2"
7365   [(set_attr "type" "imul")
7366    (set_attr "length_immediate" "0")
7367    (set (attr "athlon_decode")
7368      (if_then_else (eq_attr "cpu" "athlon")
7369         (const_string "vector")
7370         (const_string "direct")))
7371    (set_attr "amdfam10_decode" "direct")        
7372    (set_attr "mode" "QI")])
7373
7374 (define_expand "umulditi3"
7375   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7376                    (mult:TI (zero_extend:TI
7377                               (match_operand:DI 1 "nonimmediate_operand" ""))
7378                             (zero_extend:TI
7379                               (match_operand:DI 2 "register_operand" ""))))
7380               (clobber (reg:CC FLAGS_REG))])]
7381   "TARGET_64BIT"
7382   "")
7383
7384 (define_insn "*umulditi3_insn"
7385   [(set (match_operand:TI 0 "register_operand" "=A")
7386         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7387                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7388    (clobber (reg:CC FLAGS_REG))]
7389   "TARGET_64BIT
7390    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7391   "mul{q}\t%2"
7392   [(set_attr "type" "imul")
7393    (set_attr "length_immediate" "0")
7394    (set (attr "athlon_decode")
7395      (if_then_else (eq_attr "cpu" "athlon")
7396         (const_string "vector")
7397         (const_string "double")))
7398    (set_attr "amdfam10_decode" "double")        
7399    (set_attr "mode" "DI")])
7400
7401 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7402 (define_expand "umulsidi3"
7403   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7404                    (mult:DI (zero_extend:DI
7405                               (match_operand:SI 1 "nonimmediate_operand" ""))
7406                             (zero_extend:DI
7407                               (match_operand:SI 2 "register_operand" ""))))
7408               (clobber (reg:CC FLAGS_REG))])]
7409   "!TARGET_64BIT"
7410   "")
7411
7412 (define_insn "*umulsidi3_insn"
7413   [(set (match_operand:DI 0 "register_operand" "=A")
7414         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7415                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7416    (clobber (reg:CC FLAGS_REG))]
7417   "!TARGET_64BIT
7418    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7419   "mul{l}\t%2"
7420   [(set_attr "type" "imul")
7421    (set_attr "length_immediate" "0")
7422    (set (attr "athlon_decode")
7423      (if_then_else (eq_attr "cpu" "athlon")
7424         (const_string "vector")
7425         (const_string "double")))
7426    (set_attr "amdfam10_decode" "double")        
7427    (set_attr "mode" "SI")])
7428
7429 (define_expand "mulditi3"
7430   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7431                    (mult:TI (sign_extend:TI
7432                               (match_operand:DI 1 "nonimmediate_operand" ""))
7433                             (sign_extend:TI
7434                               (match_operand:DI 2 "register_operand" ""))))
7435               (clobber (reg:CC FLAGS_REG))])]
7436   "TARGET_64BIT"
7437   "")
7438
7439 (define_insn "*mulditi3_insn"
7440   [(set (match_operand:TI 0 "register_operand" "=A")
7441         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7442                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7443    (clobber (reg:CC FLAGS_REG))]
7444   "TARGET_64BIT
7445    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7446   "imul{q}\t%2"
7447   [(set_attr "type" "imul")
7448    (set_attr "length_immediate" "0")
7449    (set (attr "athlon_decode")
7450      (if_then_else (eq_attr "cpu" "athlon")
7451         (const_string "vector")
7452         (const_string "double")))
7453    (set_attr "amdfam10_decode" "double")
7454    (set_attr "mode" "DI")])
7455
7456 (define_expand "mulsidi3"
7457   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7458                    (mult:DI (sign_extend:DI
7459                               (match_operand:SI 1 "nonimmediate_operand" ""))
7460                             (sign_extend:DI
7461                               (match_operand:SI 2 "register_operand" ""))))
7462               (clobber (reg:CC FLAGS_REG))])]
7463   "!TARGET_64BIT"
7464   "")
7465
7466 (define_insn "*mulsidi3_insn"
7467   [(set (match_operand:DI 0 "register_operand" "=A")
7468         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7469                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7470    (clobber (reg:CC FLAGS_REG))]
7471   "!TARGET_64BIT
7472    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7473   "imul{l}\t%2"
7474   [(set_attr "type" "imul")
7475    (set_attr "length_immediate" "0")
7476    (set (attr "athlon_decode")
7477      (if_then_else (eq_attr "cpu" "athlon")
7478         (const_string "vector")
7479         (const_string "double")))
7480    (set_attr "amdfam10_decode" "double")        
7481    (set_attr "mode" "SI")])
7482
7483 (define_expand "umuldi3_highpart"
7484   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7485                    (truncate:DI
7486                      (lshiftrt:TI
7487                        (mult:TI (zero_extend:TI
7488                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7489                                 (zero_extend:TI
7490                                   (match_operand:DI 2 "register_operand" "")))
7491                        (const_int 64))))
7492               (clobber (match_scratch:DI 3 ""))
7493               (clobber (reg:CC FLAGS_REG))])]
7494   "TARGET_64BIT"
7495   "")
7496
7497 (define_insn "*umuldi3_highpart_rex64"
7498   [(set (match_operand:DI 0 "register_operand" "=d")
7499         (truncate:DI
7500           (lshiftrt:TI
7501             (mult:TI (zero_extend:TI
7502                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7503                      (zero_extend:TI
7504                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7505             (const_int 64))))
7506    (clobber (match_scratch:DI 3 "=1"))
7507    (clobber (reg:CC FLAGS_REG))]
7508   "TARGET_64BIT
7509    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7510   "mul{q}\t%2"
7511   [(set_attr "type" "imul")
7512    (set_attr "length_immediate" "0")
7513    (set (attr "athlon_decode")
7514      (if_then_else (eq_attr "cpu" "athlon")
7515         (const_string "vector")
7516         (const_string "double")))
7517    (set_attr "amdfam10_decode" "double")        
7518    (set_attr "mode" "DI")])
7519
7520 (define_expand "umulsi3_highpart"
7521   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7522                    (truncate:SI
7523                      (lshiftrt:DI
7524                        (mult:DI (zero_extend:DI
7525                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7526                                 (zero_extend:DI
7527                                   (match_operand:SI 2 "register_operand" "")))
7528                        (const_int 32))))
7529               (clobber (match_scratch:SI 3 ""))
7530               (clobber (reg:CC FLAGS_REG))])]
7531   ""
7532   "")
7533
7534 (define_insn "*umulsi3_highpart_insn"
7535   [(set (match_operand:SI 0 "register_operand" "=d")
7536         (truncate:SI
7537           (lshiftrt:DI
7538             (mult:DI (zero_extend:DI
7539                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7540                      (zero_extend:DI
7541                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7542             (const_int 32))))
7543    (clobber (match_scratch:SI 3 "=1"))
7544    (clobber (reg:CC FLAGS_REG))]
7545   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7546   "mul{l}\t%2"
7547   [(set_attr "type" "imul")
7548    (set_attr "length_immediate" "0")
7549    (set (attr "athlon_decode")
7550      (if_then_else (eq_attr "cpu" "athlon")
7551         (const_string "vector")
7552         (const_string "double")))
7553    (set_attr "amdfam10_decode" "double")
7554    (set_attr "mode" "SI")])
7555
7556 (define_insn "*umulsi3_highpart_zext"
7557   [(set (match_operand:DI 0 "register_operand" "=d")
7558         (zero_extend:DI (truncate:SI
7559           (lshiftrt:DI
7560             (mult:DI (zero_extend:DI
7561                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7562                      (zero_extend:DI
7563                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7564             (const_int 32)))))
7565    (clobber (match_scratch:SI 3 "=1"))
7566    (clobber (reg:CC FLAGS_REG))]
7567   "TARGET_64BIT
7568    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7569   "mul{l}\t%2"
7570   [(set_attr "type" "imul")
7571    (set_attr "length_immediate" "0")
7572    (set (attr "athlon_decode")
7573      (if_then_else (eq_attr "cpu" "athlon")
7574         (const_string "vector")
7575         (const_string "double")))
7576    (set_attr "amdfam10_decode" "double")
7577    (set_attr "mode" "SI")])
7578
7579 (define_expand "smuldi3_highpart"
7580   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7581                    (truncate:DI
7582                      (lshiftrt:TI
7583                        (mult:TI (sign_extend:TI
7584                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7585                                 (sign_extend:TI
7586                                   (match_operand:DI 2 "register_operand" "")))
7587                        (const_int 64))))
7588               (clobber (match_scratch:DI 3 ""))
7589               (clobber (reg:CC FLAGS_REG))])]
7590   "TARGET_64BIT"
7591   "")
7592
7593 (define_insn "*smuldi3_highpart_rex64"
7594   [(set (match_operand:DI 0 "register_operand" "=d")
7595         (truncate:DI
7596           (lshiftrt:TI
7597             (mult:TI (sign_extend:TI
7598                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7599                      (sign_extend:TI
7600                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7601             (const_int 64))))
7602    (clobber (match_scratch:DI 3 "=1"))
7603    (clobber (reg:CC FLAGS_REG))]
7604   "TARGET_64BIT
7605    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7606   "imul{q}\t%2"
7607   [(set_attr "type" "imul")
7608    (set (attr "athlon_decode")
7609      (if_then_else (eq_attr "cpu" "athlon")
7610         (const_string "vector")
7611         (const_string "double")))
7612    (set_attr "amdfam10_decode" "double")
7613    (set_attr "mode" "DI")])
7614
7615 (define_expand "smulsi3_highpart"
7616   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7617                    (truncate:SI
7618                      (lshiftrt:DI
7619                        (mult:DI (sign_extend:DI
7620                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7621                                 (sign_extend:DI
7622                                   (match_operand:SI 2 "register_operand" "")))
7623                        (const_int 32))))
7624               (clobber (match_scratch:SI 3 ""))
7625               (clobber (reg:CC FLAGS_REG))])]
7626   ""
7627   "")
7628
7629 (define_insn "*smulsi3_highpart_insn"
7630   [(set (match_operand:SI 0 "register_operand" "=d")
7631         (truncate:SI
7632           (lshiftrt:DI
7633             (mult:DI (sign_extend:DI
7634                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7635                      (sign_extend:DI
7636                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7637             (const_int 32))))
7638    (clobber (match_scratch:SI 3 "=1"))
7639    (clobber (reg:CC FLAGS_REG))]
7640   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7641   "imul{l}\t%2"
7642   [(set_attr "type" "imul")
7643    (set (attr "athlon_decode")
7644      (if_then_else (eq_attr "cpu" "athlon")
7645         (const_string "vector")
7646         (const_string "double")))
7647    (set_attr "amdfam10_decode" "double")
7648    (set_attr "mode" "SI")])
7649
7650 (define_insn "*smulsi3_highpart_zext"
7651   [(set (match_operand:DI 0 "register_operand" "=d")
7652         (zero_extend:DI (truncate:SI
7653           (lshiftrt:DI
7654             (mult:DI (sign_extend:DI
7655                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7656                      (sign_extend:DI
7657                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7658             (const_int 32)))))
7659    (clobber (match_scratch:SI 3 "=1"))
7660    (clobber (reg:CC FLAGS_REG))]
7661   "TARGET_64BIT
7662    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7663   "imul{l}\t%2"
7664   [(set_attr "type" "imul")
7665    (set (attr "athlon_decode")
7666      (if_then_else (eq_attr "cpu" "athlon")
7667         (const_string "vector")
7668         (const_string "double")))
7669    (set_attr "amdfam10_decode" "double")
7670    (set_attr "mode" "SI")])
7671
7672 ;; The patterns that match these are at the end of this file.
7673
7674 (define_expand "mulxf3"
7675   [(set (match_operand:XF 0 "register_operand" "")
7676         (mult:XF (match_operand:XF 1 "register_operand" "")
7677                  (match_operand:XF 2 "register_operand" "")))]
7678   "TARGET_80387"
7679   "")
7680
7681 (define_expand "muldf3"
7682   [(set (match_operand:DF 0 "register_operand" "")
7683         (mult:DF (match_operand:DF 1 "register_operand" "")
7684                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7685   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7686   "")
7687
7688 (define_expand "mulsf3"
7689   [(set (match_operand:SF 0 "register_operand" "")
7690         (mult:SF (match_operand:SF 1 "register_operand" "")
7691                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7692   "TARGET_80387 || TARGET_SSE_MATH"
7693   "")
7694 \f
7695 ;; Divide instructions
7696
7697 (define_insn "divqi3"
7698   [(set (match_operand:QI 0 "register_operand" "=a")
7699         (div:QI (match_operand:HI 1 "register_operand" "0")
7700                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7701    (clobber (reg:CC FLAGS_REG))]
7702   "TARGET_QIMODE_MATH"
7703   "idiv{b}\t%2"
7704   [(set_attr "type" "idiv")
7705    (set_attr "mode" "QI")])
7706
7707 (define_insn "udivqi3"
7708   [(set (match_operand:QI 0 "register_operand" "=a")
7709         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7710                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7711    (clobber (reg:CC FLAGS_REG))]
7712   "TARGET_QIMODE_MATH"
7713   "div{b}\t%2"
7714   [(set_attr "type" "idiv")
7715    (set_attr "mode" "QI")])
7716
7717 ;; The patterns that match these are at the end of this file.
7718
7719 (define_expand "divxf3"
7720   [(set (match_operand:XF 0 "register_operand" "")
7721         (div:XF (match_operand:XF 1 "register_operand" "")
7722                 (match_operand:XF 2 "register_operand" "")))]
7723   "TARGET_80387"
7724   "")
7725
7726 (define_expand "divdf3"
7727   [(set (match_operand:DF 0 "register_operand" "")
7728         (div:DF (match_operand:DF 1 "register_operand" "")
7729                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7730    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7731    "")
7732
7733 (define_expand "divsf3"
7734   [(set (match_operand:SF 0 "register_operand" "")
7735         (div:SF (match_operand:SF 1 "register_operand" "")
7736                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7737   "TARGET_80387 || TARGET_SSE_MATH"
7738   "")
7739 \f
7740 ;; Remainder instructions.
7741
7742 (define_expand "divmoddi4"
7743   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7744                    (div:DI (match_operand:DI 1 "register_operand" "")
7745                            (match_operand:DI 2 "nonimmediate_operand" "")))
7746               (set (match_operand:DI 3 "register_operand" "")
7747                    (mod:DI (match_dup 1) (match_dup 2)))
7748               (clobber (reg:CC FLAGS_REG))])]
7749   "TARGET_64BIT"
7750   "")
7751
7752 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7753 ;; Penalize eax case slightly because it results in worse scheduling
7754 ;; of code.
7755 (define_insn "*divmoddi4_nocltd_rex64"
7756   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7757         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7758                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7759    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7760         (mod:DI (match_dup 2) (match_dup 3)))
7761    (clobber (reg:CC FLAGS_REG))]
7762   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7763   "#"
7764   [(set_attr "type" "multi")])
7765
7766 (define_insn "*divmoddi4_cltd_rex64"
7767   [(set (match_operand:DI 0 "register_operand" "=a")
7768         (div:DI (match_operand:DI 2 "register_operand" "a")
7769                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7770    (set (match_operand:DI 1 "register_operand" "=&d")
7771         (mod:DI (match_dup 2) (match_dup 3)))
7772    (clobber (reg:CC FLAGS_REG))]
7773   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7774   "#"
7775   [(set_attr "type" "multi")])
7776
7777 (define_insn "*divmoddi_noext_rex64"
7778   [(set (match_operand:DI 0 "register_operand" "=a")
7779         (div:DI (match_operand:DI 1 "register_operand" "0")
7780                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7781    (set (match_operand:DI 3 "register_operand" "=d")
7782         (mod:DI (match_dup 1) (match_dup 2)))
7783    (use (match_operand:DI 4 "register_operand" "3"))
7784    (clobber (reg:CC FLAGS_REG))]
7785   "TARGET_64BIT"
7786   "idiv{q}\t%2"
7787   [(set_attr "type" "idiv")
7788    (set_attr "mode" "DI")])
7789
7790 (define_split
7791   [(set (match_operand:DI 0 "register_operand" "")
7792         (div:DI (match_operand:DI 1 "register_operand" "")
7793                 (match_operand:DI 2 "nonimmediate_operand" "")))
7794    (set (match_operand:DI 3 "register_operand" "")
7795         (mod:DI (match_dup 1) (match_dup 2)))
7796    (clobber (reg:CC FLAGS_REG))]
7797   "TARGET_64BIT && reload_completed"
7798   [(parallel [(set (match_dup 3)
7799                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7800               (clobber (reg:CC FLAGS_REG))])
7801    (parallel [(set (match_dup 0)
7802                    (div:DI (reg:DI 0) (match_dup 2)))
7803               (set (match_dup 3)
7804                    (mod:DI (reg:DI 0) (match_dup 2)))
7805               (use (match_dup 3))
7806               (clobber (reg:CC FLAGS_REG))])]
7807 {
7808   /* Avoid use of cltd in favor of a mov+shift.  */
7809   if (!TARGET_USE_CLTD && !optimize_size)
7810     {
7811       if (true_regnum (operands[1]))
7812         emit_move_insn (operands[0], operands[1]);
7813       else
7814         emit_move_insn (operands[3], operands[1]);
7815       operands[4] = operands[3];
7816     }
7817   else
7818     {
7819       gcc_assert (!true_regnum (operands[1]));
7820       operands[4] = operands[1];
7821     }
7822 })
7823
7824
7825 (define_expand "divmodsi4"
7826   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7827                    (div:SI (match_operand:SI 1 "register_operand" "")
7828                            (match_operand:SI 2 "nonimmediate_operand" "")))
7829               (set (match_operand:SI 3 "register_operand" "")
7830                    (mod:SI (match_dup 1) (match_dup 2)))
7831               (clobber (reg:CC FLAGS_REG))])]
7832   ""
7833   "")
7834
7835 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7836 ;; Penalize eax case slightly because it results in worse scheduling
7837 ;; of code.
7838 (define_insn "*divmodsi4_nocltd"
7839   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7840         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7841                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7842    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7843         (mod:SI (match_dup 2) (match_dup 3)))
7844    (clobber (reg:CC FLAGS_REG))]
7845   "!optimize_size && !TARGET_USE_CLTD"
7846   "#"
7847   [(set_attr "type" "multi")])
7848
7849 (define_insn "*divmodsi4_cltd"
7850   [(set (match_operand:SI 0 "register_operand" "=a")
7851         (div:SI (match_operand:SI 2 "register_operand" "a")
7852                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7853    (set (match_operand:SI 1 "register_operand" "=&d")
7854         (mod:SI (match_dup 2) (match_dup 3)))
7855    (clobber (reg:CC FLAGS_REG))]
7856   "optimize_size || TARGET_USE_CLTD"
7857   "#"
7858   [(set_attr "type" "multi")])
7859
7860 (define_insn "*divmodsi_noext"
7861   [(set (match_operand:SI 0 "register_operand" "=a")
7862         (div:SI (match_operand:SI 1 "register_operand" "0")
7863                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7864    (set (match_operand:SI 3 "register_operand" "=d")
7865         (mod:SI (match_dup 1) (match_dup 2)))
7866    (use (match_operand:SI 4 "register_operand" "3"))
7867    (clobber (reg:CC FLAGS_REG))]
7868   ""
7869   "idiv{l}\t%2"
7870   [(set_attr "type" "idiv")
7871    (set_attr "mode" "SI")])
7872
7873 (define_split
7874   [(set (match_operand:SI 0 "register_operand" "")
7875         (div:SI (match_operand:SI 1 "register_operand" "")
7876                 (match_operand:SI 2 "nonimmediate_operand" "")))
7877    (set (match_operand:SI 3 "register_operand" "")
7878         (mod:SI (match_dup 1) (match_dup 2)))
7879    (clobber (reg:CC FLAGS_REG))]
7880   "reload_completed"
7881   [(parallel [(set (match_dup 3)
7882                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7883               (clobber (reg:CC FLAGS_REG))])
7884    (parallel [(set (match_dup 0)
7885                    (div:SI (reg:SI 0) (match_dup 2)))
7886               (set (match_dup 3)
7887                    (mod:SI (reg:SI 0) (match_dup 2)))
7888               (use (match_dup 3))
7889               (clobber (reg:CC FLAGS_REG))])]
7890 {
7891   /* Avoid use of cltd in favor of a mov+shift.  */
7892   if (!TARGET_USE_CLTD && !optimize_size)
7893     {
7894       if (true_regnum (operands[1]))
7895         emit_move_insn (operands[0], operands[1]);
7896       else
7897         emit_move_insn (operands[3], operands[1]);
7898       operands[4] = operands[3];
7899     }
7900   else
7901     {
7902       gcc_assert (!true_regnum (operands[1]));
7903       operands[4] = operands[1];
7904     }
7905 })
7906 ;; %%% Split me.
7907 (define_insn "divmodhi4"
7908   [(set (match_operand:HI 0 "register_operand" "=a")
7909         (div:HI (match_operand:HI 1 "register_operand" "0")
7910                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7911    (set (match_operand:HI 3 "register_operand" "=&d")
7912         (mod:HI (match_dup 1) (match_dup 2)))
7913    (clobber (reg:CC FLAGS_REG))]
7914   "TARGET_HIMODE_MATH"
7915   "cwtd\;idiv{w}\t%2"
7916   [(set_attr "type" "multi")
7917    (set_attr "length_immediate" "0")
7918    (set_attr "mode" "SI")])
7919
7920 (define_insn "udivmoddi4"
7921   [(set (match_operand:DI 0 "register_operand" "=a")
7922         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7923                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7924    (set (match_operand:DI 3 "register_operand" "=&d")
7925         (umod:DI (match_dup 1) (match_dup 2)))
7926    (clobber (reg:CC FLAGS_REG))]
7927   "TARGET_64BIT"
7928   "xor{q}\t%3, %3\;div{q}\t%2"
7929   [(set_attr "type" "multi")
7930    (set_attr "length_immediate" "0")
7931    (set_attr "mode" "DI")])
7932
7933 (define_insn "*udivmoddi4_noext"
7934   [(set (match_operand:DI 0 "register_operand" "=a")
7935         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7936                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7937    (set (match_operand:DI 3 "register_operand" "=d")
7938         (umod:DI (match_dup 1) (match_dup 2)))
7939    (use (match_dup 3))
7940    (clobber (reg:CC FLAGS_REG))]
7941   "TARGET_64BIT"
7942   "div{q}\t%2"
7943   [(set_attr "type" "idiv")
7944    (set_attr "mode" "DI")])
7945
7946 (define_split
7947   [(set (match_operand:DI 0 "register_operand" "")
7948         (udiv:DI (match_operand:DI 1 "register_operand" "")
7949                  (match_operand:DI 2 "nonimmediate_operand" "")))
7950    (set (match_operand:DI 3 "register_operand" "")
7951         (umod:DI (match_dup 1) (match_dup 2)))
7952    (clobber (reg:CC FLAGS_REG))]
7953   "TARGET_64BIT && reload_completed"
7954   [(set (match_dup 3) (const_int 0))
7955    (parallel [(set (match_dup 0)
7956                    (udiv:DI (match_dup 1) (match_dup 2)))
7957               (set (match_dup 3)
7958                    (umod:DI (match_dup 1) (match_dup 2)))
7959               (use (match_dup 3))
7960               (clobber (reg:CC FLAGS_REG))])]
7961   "")
7962
7963 (define_insn "udivmodsi4"
7964   [(set (match_operand:SI 0 "register_operand" "=a")
7965         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7966                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7967    (set (match_operand:SI 3 "register_operand" "=&d")
7968         (umod:SI (match_dup 1) (match_dup 2)))
7969    (clobber (reg:CC FLAGS_REG))]
7970   ""
7971   "xor{l}\t%3, %3\;div{l}\t%2"
7972   [(set_attr "type" "multi")
7973    (set_attr "length_immediate" "0")
7974    (set_attr "mode" "SI")])
7975
7976 (define_insn "*udivmodsi4_noext"
7977   [(set (match_operand:SI 0 "register_operand" "=a")
7978         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7979                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7980    (set (match_operand:SI 3 "register_operand" "=d")
7981         (umod:SI (match_dup 1) (match_dup 2)))
7982    (use (match_dup 3))
7983    (clobber (reg:CC FLAGS_REG))]
7984   ""
7985   "div{l}\t%2"
7986   [(set_attr "type" "idiv")
7987    (set_attr "mode" "SI")])
7988
7989 (define_split
7990   [(set (match_operand:SI 0 "register_operand" "")
7991         (udiv:SI (match_operand:SI 1 "register_operand" "")
7992                  (match_operand:SI 2 "nonimmediate_operand" "")))
7993    (set (match_operand:SI 3 "register_operand" "")
7994         (umod:SI (match_dup 1) (match_dup 2)))
7995    (clobber (reg:CC FLAGS_REG))]
7996   "reload_completed"
7997   [(set (match_dup 3) (const_int 0))
7998    (parallel [(set (match_dup 0)
7999                    (udiv:SI (match_dup 1) (match_dup 2)))
8000               (set (match_dup 3)
8001                    (umod:SI (match_dup 1) (match_dup 2)))
8002               (use (match_dup 3))
8003               (clobber (reg:CC FLAGS_REG))])]
8004   "")
8005
8006 (define_expand "udivmodhi4"
8007   [(set (match_dup 4) (const_int 0))
8008    (parallel [(set (match_operand:HI 0 "register_operand" "")
8009                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8010                             (match_operand:HI 2 "nonimmediate_operand" "")))
8011               (set (match_operand:HI 3 "register_operand" "")
8012                    (umod:HI (match_dup 1) (match_dup 2)))
8013               (use (match_dup 4))
8014               (clobber (reg:CC FLAGS_REG))])]
8015   "TARGET_HIMODE_MATH"
8016   "operands[4] = gen_reg_rtx (HImode);")
8017
8018 (define_insn "*udivmodhi_noext"
8019   [(set (match_operand:HI 0 "register_operand" "=a")
8020         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8021                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8022    (set (match_operand:HI 3 "register_operand" "=d")
8023         (umod:HI (match_dup 1) (match_dup 2)))
8024    (use (match_operand:HI 4 "register_operand" "3"))
8025    (clobber (reg:CC FLAGS_REG))]
8026   ""
8027   "div{w}\t%2"
8028   [(set_attr "type" "idiv")
8029    (set_attr "mode" "HI")])
8030
8031 ;; We cannot use div/idiv for double division, because it causes
8032 ;; "division by zero" on the overflow and that's not what we expect
8033 ;; from truncate.  Because true (non truncating) double division is
8034 ;; never generated, we can't create this insn anyway.
8035 ;
8036 ;(define_insn ""
8037 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8038 ;       (truncate:SI
8039 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8040 ;                  (zero_extend:DI
8041 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8042 ;   (set (match_operand:SI 3 "register_operand" "=d")
8043 ;       (truncate:SI
8044 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8045 ;   (clobber (reg:CC FLAGS_REG))]
8046 ;  ""
8047 ;  "div{l}\t{%2, %0|%0, %2}"
8048 ;  [(set_attr "type" "idiv")])
8049 \f
8050 ;;- Logical AND instructions
8051
8052 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8053 ;; Note that this excludes ah.
8054
8055 (define_insn "*testdi_1_rex64"
8056   [(set (reg FLAGS_REG)
8057         (compare
8058           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8059                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8060           (const_int 0)))]
8061   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8062    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8063   "@
8064    test{l}\t{%k1, %k0|%k0, %k1}
8065    test{l}\t{%k1, %k0|%k0, %k1}
8066    test{q}\t{%1, %0|%0, %1}
8067    test{q}\t{%1, %0|%0, %1}
8068    test{q}\t{%1, %0|%0, %1}"
8069   [(set_attr "type" "test")
8070    (set_attr "modrm" "0,1,0,1,1")
8071    (set_attr "mode" "SI,SI,DI,DI,DI")
8072    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8073
8074 (define_insn "testsi_1"
8075   [(set (reg FLAGS_REG)
8076         (compare
8077           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8078                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8079           (const_int 0)))]
8080   "ix86_match_ccmode (insn, CCNOmode)
8081    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8082   "test{l}\t{%1, %0|%0, %1}"
8083   [(set_attr "type" "test")
8084    (set_attr "modrm" "0,1,1")
8085    (set_attr "mode" "SI")
8086    (set_attr "pent_pair" "uv,np,uv")])
8087
8088 (define_expand "testsi_ccno_1"
8089   [(set (reg:CCNO FLAGS_REG)
8090         (compare:CCNO
8091           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8092                   (match_operand:SI 1 "nonmemory_operand" ""))
8093           (const_int 0)))]
8094   ""
8095   "")
8096
8097 (define_insn "*testhi_1"
8098   [(set (reg FLAGS_REG)
8099         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8100                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8101                  (const_int 0)))]
8102   "ix86_match_ccmode (insn, CCNOmode)
8103    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8104   "test{w}\t{%1, %0|%0, %1}"
8105   [(set_attr "type" "test")
8106    (set_attr "modrm" "0,1,1")
8107    (set_attr "mode" "HI")
8108    (set_attr "pent_pair" "uv,np,uv")])
8109
8110 (define_expand "testqi_ccz_1"
8111   [(set (reg:CCZ FLAGS_REG)
8112         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8113                              (match_operand:QI 1 "nonmemory_operand" ""))
8114                  (const_int 0)))]
8115   ""
8116   "")
8117
8118 (define_insn "*testqi_1_maybe_si"
8119   [(set (reg FLAGS_REG)
8120         (compare
8121           (and:QI
8122             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8123             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8124           (const_int 0)))]
8125    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8126     && ix86_match_ccmode (insn,
8127                          CONST_INT_P (operands[1])
8128                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8129 {
8130   if (which_alternative == 3)
8131     {
8132       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8133         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8134       return "test{l}\t{%1, %k0|%k0, %1}";
8135     }
8136   return "test{b}\t{%1, %0|%0, %1}";
8137 }
8138   [(set_attr "type" "test")
8139    (set_attr "modrm" "0,1,1,1")
8140    (set_attr "mode" "QI,QI,QI,SI")
8141    (set_attr "pent_pair" "uv,np,uv,np")])
8142
8143 (define_insn "*testqi_1"
8144   [(set (reg FLAGS_REG)
8145         (compare
8146           (and:QI
8147             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8148             (match_operand:QI 1 "general_operand" "n,n,qn"))
8149           (const_int 0)))]
8150   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8151    && ix86_match_ccmode (insn, CCNOmode)"
8152   "test{b}\t{%1, %0|%0, %1}"
8153   [(set_attr "type" "test")
8154    (set_attr "modrm" "0,1,1")
8155    (set_attr "mode" "QI")
8156    (set_attr "pent_pair" "uv,np,uv")])
8157
8158 (define_expand "testqi_ext_ccno_0"
8159   [(set (reg:CCNO FLAGS_REG)
8160         (compare:CCNO
8161           (and:SI
8162             (zero_extract:SI
8163               (match_operand 0 "ext_register_operand" "")
8164               (const_int 8)
8165               (const_int 8))
8166             (match_operand 1 "const_int_operand" ""))
8167           (const_int 0)))]
8168   ""
8169   "")
8170
8171 (define_insn "*testqi_ext_0"
8172   [(set (reg FLAGS_REG)
8173         (compare
8174           (and:SI
8175             (zero_extract:SI
8176               (match_operand 0 "ext_register_operand" "Q")
8177               (const_int 8)
8178               (const_int 8))
8179             (match_operand 1 "const_int_operand" "n"))
8180           (const_int 0)))]
8181   "ix86_match_ccmode (insn, CCNOmode)"
8182   "test{b}\t{%1, %h0|%h0, %1}"
8183   [(set_attr "type" "test")
8184    (set_attr "mode" "QI")
8185    (set_attr "length_immediate" "1")
8186    (set_attr "pent_pair" "np")])
8187
8188 (define_insn "*testqi_ext_1"
8189   [(set (reg FLAGS_REG)
8190         (compare
8191           (and:SI
8192             (zero_extract:SI
8193               (match_operand 0 "ext_register_operand" "Q")
8194               (const_int 8)
8195               (const_int 8))
8196             (zero_extend:SI
8197               (match_operand:QI 1 "general_operand" "Qm")))
8198           (const_int 0)))]
8199   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8200    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8201   "test{b}\t{%1, %h0|%h0, %1}"
8202   [(set_attr "type" "test")
8203    (set_attr "mode" "QI")])
8204
8205 (define_insn "*testqi_ext_1_rex64"
8206   [(set (reg FLAGS_REG)
8207         (compare
8208           (and:SI
8209             (zero_extract:SI
8210               (match_operand 0 "ext_register_operand" "Q")
8211               (const_int 8)
8212               (const_int 8))
8213             (zero_extend:SI
8214               (match_operand:QI 1 "register_operand" "Q")))
8215           (const_int 0)))]
8216   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8217   "test{b}\t{%1, %h0|%h0, %1}"
8218   [(set_attr "type" "test")
8219    (set_attr "mode" "QI")])
8220
8221 (define_insn "*testqi_ext_2"
8222   [(set (reg FLAGS_REG)
8223         (compare
8224           (and:SI
8225             (zero_extract:SI
8226               (match_operand 0 "ext_register_operand" "Q")
8227               (const_int 8)
8228               (const_int 8))
8229             (zero_extract:SI
8230               (match_operand 1 "ext_register_operand" "Q")
8231               (const_int 8)
8232               (const_int 8)))
8233           (const_int 0)))]
8234   "ix86_match_ccmode (insn, CCNOmode)"
8235   "test{b}\t{%h1, %h0|%h0, %h1}"
8236   [(set_attr "type" "test")
8237    (set_attr "mode" "QI")])
8238
8239 ;; Combine likes to form bit extractions for some tests.  Humor it.
8240 (define_insn "*testqi_ext_3"
8241   [(set (reg FLAGS_REG)
8242         (compare (zero_extract:SI
8243                    (match_operand 0 "nonimmediate_operand" "rm")
8244                    (match_operand:SI 1 "const_int_operand" "")
8245                    (match_operand:SI 2 "const_int_operand" ""))
8246                  (const_int 0)))]
8247   "ix86_match_ccmode (insn, CCNOmode)
8248    && INTVAL (operands[1]) > 0
8249    && INTVAL (operands[2]) >= 0
8250    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8251    && (GET_MODE (operands[0]) == SImode
8252        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8253        || GET_MODE (operands[0]) == HImode
8254        || GET_MODE (operands[0]) == QImode)"
8255   "#")
8256
8257 (define_insn "*testqi_ext_3_rex64"
8258   [(set (reg FLAGS_REG)
8259         (compare (zero_extract:DI
8260                    (match_operand 0 "nonimmediate_operand" "rm")
8261                    (match_operand:DI 1 "const_int_operand" "")
8262                    (match_operand:DI 2 "const_int_operand" ""))
8263                  (const_int 0)))]
8264   "TARGET_64BIT
8265    && ix86_match_ccmode (insn, CCNOmode)
8266    && INTVAL (operands[1]) > 0
8267    && INTVAL (operands[2]) >= 0
8268    /* Ensure that resulting mask is zero or sign extended operand.  */
8269    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8270        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8271            && INTVAL (operands[1]) > 32))
8272    && (GET_MODE (operands[0]) == SImode
8273        || GET_MODE (operands[0]) == DImode
8274        || GET_MODE (operands[0]) == HImode
8275        || GET_MODE (operands[0]) == QImode)"
8276   "#")
8277
8278 (define_split
8279   [(set (match_operand 0 "flags_reg_operand" "")
8280         (match_operator 1 "compare_operator"
8281           [(zero_extract
8282              (match_operand 2 "nonimmediate_operand" "")
8283              (match_operand 3 "const_int_operand" "")
8284              (match_operand 4 "const_int_operand" ""))
8285            (const_int 0)]))]
8286   "ix86_match_ccmode (insn, CCNOmode)"
8287   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8288 {
8289   rtx val = operands[2];
8290   HOST_WIDE_INT len = INTVAL (operands[3]);
8291   HOST_WIDE_INT pos = INTVAL (operands[4]);
8292   HOST_WIDE_INT mask;
8293   enum machine_mode mode, submode;
8294
8295   mode = GET_MODE (val);
8296   if (MEM_P (val))
8297     {
8298       /* ??? Combine likes to put non-volatile mem extractions in QImode
8299          no matter the size of the test.  So find a mode that works.  */
8300       if (! MEM_VOLATILE_P (val))
8301         {
8302           mode = smallest_mode_for_size (pos + len, MODE_INT);
8303           val = adjust_address (val, mode, 0);
8304         }
8305     }
8306   else if (GET_CODE (val) == SUBREG
8307            && (submode = GET_MODE (SUBREG_REG (val)),
8308                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8309            && pos + len <= GET_MODE_BITSIZE (submode))
8310     {
8311       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8312       mode = submode;
8313       val = SUBREG_REG (val);
8314     }
8315   else if (mode == HImode && pos + len <= 8)
8316     {
8317       /* Small HImode tests can be converted to QImode.  */
8318       mode = QImode;
8319       val = gen_lowpart (QImode, val);
8320     }
8321
8322   if (len == HOST_BITS_PER_WIDE_INT)
8323     mask = -1;
8324   else
8325     mask = ((HOST_WIDE_INT)1 << len) - 1;
8326   mask <<= pos;
8327
8328   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8329 })
8330
8331 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8332 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8333 ;; this is relatively important trick.
8334 ;; Do the conversion only post-reload to avoid limiting of the register class
8335 ;; to QI regs.
8336 (define_split
8337   [(set (match_operand 0 "flags_reg_operand" "")
8338         (match_operator 1 "compare_operator"
8339           [(and (match_operand 2 "register_operand" "")
8340                 (match_operand 3 "const_int_operand" ""))
8341            (const_int 0)]))]
8342    "reload_completed
8343     && QI_REG_P (operands[2])
8344     && GET_MODE (operands[2]) != QImode
8345     && ((ix86_match_ccmode (insn, CCZmode)
8346          && !(INTVAL (operands[3]) & ~(255 << 8)))
8347         || (ix86_match_ccmode (insn, CCNOmode)
8348             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8349   [(set (match_dup 0)
8350         (match_op_dup 1
8351           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8352                    (match_dup 3))
8353            (const_int 0)]))]
8354   "operands[2] = gen_lowpart (SImode, operands[2]);
8355    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8356
8357 (define_split
8358   [(set (match_operand 0 "flags_reg_operand" "")
8359         (match_operator 1 "compare_operator"
8360           [(and (match_operand 2 "nonimmediate_operand" "")
8361                 (match_operand 3 "const_int_operand" ""))
8362            (const_int 0)]))]
8363    "reload_completed
8364     && GET_MODE (operands[2]) != QImode
8365     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8366     && ((ix86_match_ccmode (insn, CCZmode)
8367          && !(INTVAL (operands[3]) & ~255))
8368         || (ix86_match_ccmode (insn, CCNOmode)
8369             && !(INTVAL (operands[3]) & ~127)))"
8370   [(set (match_dup 0)
8371         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8372                          (const_int 0)]))]
8373   "operands[2] = gen_lowpart (QImode, operands[2]);
8374    operands[3] = gen_lowpart (QImode, operands[3]);")
8375
8376
8377 ;; %%% This used to optimize known byte-wide and operations to memory,
8378 ;; and sometimes to QImode registers.  If this is considered useful,
8379 ;; it should be done with splitters.
8380
8381 (define_expand "anddi3"
8382   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8383         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8384                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8385    (clobber (reg:CC FLAGS_REG))]
8386   "TARGET_64BIT"
8387   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8388
8389 (define_insn "*anddi_1_rex64"
8390   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8391         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8392                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8393    (clobber (reg:CC FLAGS_REG))]
8394   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8395 {
8396   switch (get_attr_type (insn))
8397     {
8398     case TYPE_IMOVX:
8399       {
8400         enum machine_mode mode;
8401
8402         gcc_assert (CONST_INT_P (operands[2]));
8403         if (INTVAL (operands[2]) == 0xff)
8404           mode = QImode;
8405         else
8406           {
8407             gcc_assert (INTVAL (operands[2]) == 0xffff);
8408             mode = HImode;
8409           }
8410
8411         operands[1] = gen_lowpart (mode, operands[1]);
8412         if (mode == QImode)
8413           return "movz{bq|x}\t{%1,%0|%0, %1}";
8414         else
8415           return "movz{wq|x}\t{%1,%0|%0, %1}";
8416       }
8417
8418     default:
8419       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8420       if (get_attr_mode (insn) == MODE_SI)
8421         return "and{l}\t{%k2, %k0|%k0, %k2}";
8422       else
8423         return "and{q}\t{%2, %0|%0, %2}";
8424     }
8425 }
8426   [(set_attr "type" "alu,alu,alu,imovx")
8427    (set_attr "length_immediate" "*,*,*,0")
8428    (set_attr "mode" "SI,DI,DI,DI")])
8429
8430 (define_insn "*anddi_2"
8431   [(set (reg FLAGS_REG)
8432         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8433                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8434                  (const_int 0)))
8435    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8436         (and:DI (match_dup 1) (match_dup 2)))]
8437   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8438    && ix86_binary_operator_ok (AND, DImode, operands)"
8439   "@
8440    and{l}\t{%k2, %k0|%k0, %k2}
8441    and{q}\t{%2, %0|%0, %2}
8442    and{q}\t{%2, %0|%0, %2}"
8443   [(set_attr "type" "alu")
8444    (set_attr "mode" "SI,DI,DI")])
8445
8446 (define_expand "andsi3"
8447   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8448         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8449                 (match_operand:SI 2 "general_operand" "")))
8450    (clobber (reg:CC FLAGS_REG))]
8451   ""
8452   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8453
8454 (define_insn "*andsi_1"
8455   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8456         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8457                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8458    (clobber (reg:CC FLAGS_REG))]
8459   "ix86_binary_operator_ok (AND, SImode, operands)"
8460 {
8461   switch (get_attr_type (insn))
8462     {
8463     case TYPE_IMOVX:
8464       {
8465         enum machine_mode mode;
8466
8467         gcc_assert (CONST_INT_P (operands[2]));
8468         if (INTVAL (operands[2]) == 0xff)
8469           mode = QImode;
8470         else
8471           {
8472             gcc_assert (INTVAL (operands[2]) == 0xffff);
8473             mode = HImode;
8474           }
8475
8476         operands[1] = gen_lowpart (mode, operands[1]);
8477         if (mode == QImode)
8478           return "movz{bl|x}\t{%1,%0|%0, %1}";
8479         else
8480           return "movz{wl|x}\t{%1,%0|%0, %1}";
8481       }
8482
8483     default:
8484       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8485       return "and{l}\t{%2, %0|%0, %2}";
8486     }
8487 }
8488   [(set_attr "type" "alu,alu,imovx")
8489    (set_attr "length_immediate" "*,*,0")
8490    (set_attr "mode" "SI")])
8491
8492 (define_split
8493   [(set (match_operand 0 "register_operand" "")
8494         (and (match_dup 0)
8495              (const_int -65536)))
8496    (clobber (reg:CC FLAGS_REG))]
8497   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8498   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8499   "operands[1] = gen_lowpart (HImode, operands[0]);")
8500
8501 (define_split
8502   [(set (match_operand 0 "ext_register_operand" "")
8503         (and (match_dup 0)
8504              (const_int -256)))
8505    (clobber (reg:CC FLAGS_REG))]
8506   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8507   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8508   "operands[1] = gen_lowpart (QImode, operands[0]);")
8509
8510 (define_split
8511   [(set (match_operand 0 "ext_register_operand" "")
8512         (and (match_dup 0)
8513              (const_int -65281)))
8514    (clobber (reg:CC FLAGS_REG))]
8515   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8516   [(parallel [(set (zero_extract:SI (match_dup 0)
8517                                     (const_int 8)
8518                                     (const_int 8))
8519                    (xor:SI
8520                      (zero_extract:SI (match_dup 0)
8521                                       (const_int 8)
8522                                       (const_int 8))
8523                      (zero_extract:SI (match_dup 0)
8524                                       (const_int 8)
8525                                       (const_int 8))))
8526               (clobber (reg:CC FLAGS_REG))])]
8527   "operands[0] = gen_lowpart (SImode, operands[0]);")
8528
8529 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8530 (define_insn "*andsi_1_zext"
8531   [(set (match_operand:DI 0 "register_operand" "=r")
8532         (zero_extend:DI
8533           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8534                   (match_operand:SI 2 "general_operand" "rim"))))
8535    (clobber (reg:CC FLAGS_REG))]
8536   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8537   "and{l}\t{%2, %k0|%k0, %2}"
8538   [(set_attr "type" "alu")
8539    (set_attr "mode" "SI")])
8540
8541 (define_insn "*andsi_2"
8542   [(set (reg FLAGS_REG)
8543         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8544                          (match_operand:SI 2 "general_operand" "rim,ri"))
8545                  (const_int 0)))
8546    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8547         (and:SI (match_dup 1) (match_dup 2)))]
8548   "ix86_match_ccmode (insn, CCNOmode)
8549    && ix86_binary_operator_ok (AND, SImode, operands)"
8550   "and{l}\t{%2, %0|%0, %2}"
8551   [(set_attr "type" "alu")
8552    (set_attr "mode" "SI")])
8553
8554 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8555 (define_insn "*andsi_2_zext"
8556   [(set (reg FLAGS_REG)
8557         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8558                          (match_operand:SI 2 "general_operand" "rim"))
8559                  (const_int 0)))
8560    (set (match_operand:DI 0 "register_operand" "=r")
8561         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8562   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8563    && ix86_binary_operator_ok (AND, SImode, operands)"
8564   "and{l}\t{%2, %k0|%k0, %2}"
8565   [(set_attr "type" "alu")
8566    (set_attr "mode" "SI")])
8567
8568 (define_expand "andhi3"
8569   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8570         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8571                 (match_operand:HI 2 "general_operand" "")))
8572    (clobber (reg:CC FLAGS_REG))]
8573   "TARGET_HIMODE_MATH"
8574   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8575
8576 (define_insn "*andhi_1"
8577   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8578         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8579                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8580    (clobber (reg:CC FLAGS_REG))]
8581   "ix86_binary_operator_ok (AND, HImode, operands)"
8582 {
8583   switch (get_attr_type (insn))
8584     {
8585     case TYPE_IMOVX:
8586       gcc_assert (CONST_INT_P (operands[2]));
8587       gcc_assert (INTVAL (operands[2]) == 0xff);
8588       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8589
8590     default:
8591       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8592
8593       return "and{w}\t{%2, %0|%0, %2}";
8594     }
8595 }
8596   [(set_attr "type" "alu,alu,imovx")
8597    (set_attr "length_immediate" "*,*,0")
8598    (set_attr "mode" "HI,HI,SI")])
8599
8600 (define_insn "*andhi_2"
8601   [(set (reg FLAGS_REG)
8602         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8603                          (match_operand:HI 2 "general_operand" "rim,ri"))
8604                  (const_int 0)))
8605    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8606         (and:HI (match_dup 1) (match_dup 2)))]
8607   "ix86_match_ccmode (insn, CCNOmode)
8608    && ix86_binary_operator_ok (AND, HImode, operands)"
8609   "and{w}\t{%2, %0|%0, %2}"
8610   [(set_attr "type" "alu")
8611    (set_attr "mode" "HI")])
8612
8613 (define_expand "andqi3"
8614   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8615         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8616                 (match_operand:QI 2 "general_operand" "")))
8617    (clobber (reg:CC FLAGS_REG))]
8618   "TARGET_QIMODE_MATH"
8619   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8620
8621 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8622 (define_insn "*andqi_1"
8623   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8624         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8625                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8626    (clobber (reg:CC FLAGS_REG))]
8627   "ix86_binary_operator_ok (AND, QImode, operands)"
8628   "@
8629    and{b}\t{%2, %0|%0, %2}
8630    and{b}\t{%2, %0|%0, %2}
8631    and{l}\t{%k2, %k0|%k0, %k2}"
8632   [(set_attr "type" "alu")
8633    (set_attr "mode" "QI,QI,SI")])
8634
8635 (define_insn "*andqi_1_slp"
8636   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8637         (and:QI (match_dup 0)
8638                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8639    (clobber (reg:CC FLAGS_REG))]
8640   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8641    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8642   "and{b}\t{%1, %0|%0, %1}"
8643   [(set_attr "type" "alu1")
8644    (set_attr "mode" "QI")])
8645
8646 (define_insn "*andqi_2_maybe_si"
8647   [(set (reg FLAGS_REG)
8648         (compare (and:QI
8649                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8650                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8651                  (const_int 0)))
8652    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8653         (and:QI (match_dup 1) (match_dup 2)))]
8654   "ix86_binary_operator_ok (AND, QImode, operands)
8655    && ix86_match_ccmode (insn,
8656                          CONST_INT_P (operands[2])
8657                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8658 {
8659   if (which_alternative == 2)
8660     {
8661       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8662         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8663       return "and{l}\t{%2, %k0|%k0, %2}";
8664     }
8665   return "and{b}\t{%2, %0|%0, %2}";
8666 }
8667   [(set_attr "type" "alu")
8668    (set_attr "mode" "QI,QI,SI")])
8669
8670 (define_insn "*andqi_2"
8671   [(set (reg FLAGS_REG)
8672         (compare (and:QI
8673                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8674                    (match_operand:QI 2 "general_operand" "qim,qi"))
8675                  (const_int 0)))
8676    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8677         (and:QI (match_dup 1) (match_dup 2)))]
8678   "ix86_match_ccmode (insn, CCNOmode)
8679    && ix86_binary_operator_ok (AND, QImode, operands)"
8680   "and{b}\t{%2, %0|%0, %2}"
8681   [(set_attr "type" "alu")
8682    (set_attr "mode" "QI")])
8683
8684 (define_insn "*andqi_2_slp"
8685   [(set (reg FLAGS_REG)
8686         (compare (and:QI
8687                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8688                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8689                  (const_int 0)))
8690    (set (strict_low_part (match_dup 0))
8691         (and:QI (match_dup 0) (match_dup 1)))]
8692   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8693    && ix86_match_ccmode (insn, CCNOmode)
8694    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8695   "and{b}\t{%1, %0|%0, %1}"
8696   [(set_attr "type" "alu1")
8697    (set_attr "mode" "QI")])
8698
8699 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8700 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8701 ;; for a QImode operand, which of course failed.
8702
8703 (define_insn "andqi_ext_0"
8704   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8705                          (const_int 8)
8706                          (const_int 8))
8707         (and:SI
8708           (zero_extract:SI
8709             (match_operand 1 "ext_register_operand" "0")
8710             (const_int 8)
8711             (const_int 8))
8712           (match_operand 2 "const_int_operand" "n")))
8713    (clobber (reg:CC FLAGS_REG))]
8714   ""
8715   "and{b}\t{%2, %h0|%h0, %2}"
8716   [(set_attr "type" "alu")
8717    (set_attr "length_immediate" "1")
8718    (set_attr "mode" "QI")])
8719
8720 ;; Generated by peephole translating test to and.  This shows up
8721 ;; often in fp comparisons.
8722
8723 (define_insn "*andqi_ext_0_cc"
8724   [(set (reg FLAGS_REG)
8725         (compare
8726           (and:SI
8727             (zero_extract:SI
8728               (match_operand 1 "ext_register_operand" "0")
8729               (const_int 8)
8730               (const_int 8))
8731             (match_operand 2 "const_int_operand" "n"))
8732           (const_int 0)))
8733    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8734                          (const_int 8)
8735                          (const_int 8))
8736         (and:SI
8737           (zero_extract:SI
8738             (match_dup 1)
8739             (const_int 8)
8740             (const_int 8))
8741           (match_dup 2)))]
8742   "ix86_match_ccmode (insn, CCNOmode)"
8743   "and{b}\t{%2, %h0|%h0, %2}"
8744   [(set_attr "type" "alu")
8745    (set_attr "length_immediate" "1")
8746    (set_attr "mode" "QI")])
8747
8748 (define_insn "*andqi_ext_1"
8749   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8750                          (const_int 8)
8751                          (const_int 8))
8752         (and:SI
8753           (zero_extract:SI
8754             (match_operand 1 "ext_register_operand" "0")
8755             (const_int 8)
8756             (const_int 8))
8757           (zero_extend:SI
8758             (match_operand:QI 2 "general_operand" "Qm"))))
8759    (clobber (reg:CC FLAGS_REG))]
8760   "!TARGET_64BIT"
8761   "and{b}\t{%2, %h0|%h0, %2}"
8762   [(set_attr "type" "alu")
8763    (set_attr "length_immediate" "0")
8764    (set_attr "mode" "QI")])
8765
8766 (define_insn "*andqi_ext_1_rex64"
8767   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8768                          (const_int 8)
8769                          (const_int 8))
8770         (and:SI
8771           (zero_extract:SI
8772             (match_operand 1 "ext_register_operand" "0")
8773             (const_int 8)
8774             (const_int 8))
8775           (zero_extend:SI
8776             (match_operand 2 "ext_register_operand" "Q"))))
8777    (clobber (reg:CC FLAGS_REG))]
8778   "TARGET_64BIT"
8779   "and{b}\t{%2, %h0|%h0, %2}"
8780   [(set_attr "type" "alu")
8781    (set_attr "length_immediate" "0")
8782    (set_attr "mode" "QI")])
8783
8784 (define_insn "*andqi_ext_2"
8785   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8786                          (const_int 8)
8787                          (const_int 8))
8788         (and:SI
8789           (zero_extract:SI
8790             (match_operand 1 "ext_register_operand" "%0")
8791             (const_int 8)
8792             (const_int 8))
8793           (zero_extract:SI
8794             (match_operand 2 "ext_register_operand" "Q")
8795             (const_int 8)
8796             (const_int 8))))
8797    (clobber (reg:CC FLAGS_REG))]
8798   ""
8799   "and{b}\t{%h2, %h0|%h0, %h2}"
8800   [(set_attr "type" "alu")
8801    (set_attr "length_immediate" "0")
8802    (set_attr "mode" "QI")])
8803
8804 ;; Convert wide AND instructions with immediate operand to shorter QImode
8805 ;; equivalents when possible.
8806 ;; Don't do the splitting with memory operands, since it introduces risk
8807 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8808 ;; for size, but that can (should?) be handled by generic code instead.
8809 (define_split
8810   [(set (match_operand 0 "register_operand" "")
8811         (and (match_operand 1 "register_operand" "")
8812              (match_operand 2 "const_int_operand" "")))
8813    (clobber (reg:CC FLAGS_REG))]
8814    "reload_completed
8815     && QI_REG_P (operands[0])
8816     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8817     && !(~INTVAL (operands[2]) & ~(255 << 8))
8818     && GET_MODE (operands[0]) != QImode"
8819   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8820                    (and:SI (zero_extract:SI (match_dup 1)
8821                                             (const_int 8) (const_int 8))
8822                            (match_dup 2)))
8823               (clobber (reg:CC FLAGS_REG))])]
8824   "operands[0] = gen_lowpart (SImode, operands[0]);
8825    operands[1] = gen_lowpart (SImode, operands[1]);
8826    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8827
8828 ;; Since AND can be encoded with sign extended immediate, this is only
8829 ;; profitable when 7th bit is not set.
8830 (define_split
8831   [(set (match_operand 0 "register_operand" "")
8832         (and (match_operand 1 "general_operand" "")
8833              (match_operand 2 "const_int_operand" "")))
8834    (clobber (reg:CC FLAGS_REG))]
8835    "reload_completed
8836     && ANY_QI_REG_P (operands[0])
8837     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8838     && !(~INTVAL (operands[2]) & ~255)
8839     && !(INTVAL (operands[2]) & 128)
8840     && GET_MODE (operands[0]) != QImode"
8841   [(parallel [(set (strict_low_part (match_dup 0))
8842                    (and:QI (match_dup 1)
8843                            (match_dup 2)))
8844               (clobber (reg:CC FLAGS_REG))])]
8845   "operands[0] = gen_lowpart (QImode, operands[0]);
8846    operands[1] = gen_lowpart (QImode, operands[1]);
8847    operands[2] = gen_lowpart (QImode, operands[2]);")
8848 \f
8849 ;; Logical inclusive OR instructions
8850
8851 ;; %%% This used to optimize known byte-wide and operations to memory.
8852 ;; If this is considered useful, it should be done with splitters.
8853
8854 (define_expand "iordi3"
8855   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8856         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8857                 (match_operand:DI 2 "x86_64_general_operand" "")))
8858    (clobber (reg:CC FLAGS_REG))]
8859   "TARGET_64BIT"
8860   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8861
8862 (define_insn "*iordi_1_rex64"
8863   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8864         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8865                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8866    (clobber (reg:CC FLAGS_REG))]
8867   "TARGET_64BIT
8868    && ix86_binary_operator_ok (IOR, DImode, operands)"
8869   "or{q}\t{%2, %0|%0, %2}"
8870   [(set_attr "type" "alu")
8871    (set_attr "mode" "DI")])
8872
8873 (define_insn "*iordi_2_rex64"
8874   [(set (reg FLAGS_REG)
8875         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8876                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8877                  (const_int 0)))
8878    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8879         (ior:DI (match_dup 1) (match_dup 2)))]
8880   "TARGET_64BIT
8881    && ix86_match_ccmode (insn, CCNOmode)
8882    && ix86_binary_operator_ok (IOR, DImode, operands)"
8883   "or{q}\t{%2, %0|%0, %2}"
8884   [(set_attr "type" "alu")
8885    (set_attr "mode" "DI")])
8886
8887 (define_insn "*iordi_3_rex64"
8888   [(set (reg FLAGS_REG)
8889         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8890                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8891                  (const_int 0)))
8892    (clobber (match_scratch:DI 0 "=r"))]
8893   "TARGET_64BIT
8894    && ix86_match_ccmode (insn, CCNOmode)
8895    && ix86_binary_operator_ok (IOR, DImode, operands)"
8896   "or{q}\t{%2, %0|%0, %2}"
8897   [(set_attr "type" "alu")
8898    (set_attr "mode" "DI")])
8899
8900
8901 (define_expand "iorsi3"
8902   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8903         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8904                 (match_operand:SI 2 "general_operand" "")))
8905    (clobber (reg:CC FLAGS_REG))]
8906   ""
8907   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8908
8909 (define_insn "*iorsi_1"
8910   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8911         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8912                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8913    (clobber (reg:CC FLAGS_REG))]
8914   "ix86_binary_operator_ok (IOR, SImode, operands)"
8915   "or{l}\t{%2, %0|%0, %2}"
8916   [(set_attr "type" "alu")
8917    (set_attr "mode" "SI")])
8918
8919 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8920 (define_insn "*iorsi_1_zext"
8921   [(set (match_operand:DI 0 "register_operand" "=rm")
8922         (zero_extend:DI
8923           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8924                   (match_operand:SI 2 "general_operand" "rim"))))
8925    (clobber (reg:CC FLAGS_REG))]
8926   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8927   "or{l}\t{%2, %k0|%k0, %2}"
8928   [(set_attr "type" "alu")
8929    (set_attr "mode" "SI")])
8930
8931 (define_insn "*iorsi_1_zext_imm"
8932   [(set (match_operand:DI 0 "register_operand" "=rm")
8933         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8934                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8935    (clobber (reg:CC FLAGS_REG))]
8936   "TARGET_64BIT"
8937   "or{l}\t{%2, %k0|%k0, %2}"
8938   [(set_attr "type" "alu")
8939    (set_attr "mode" "SI")])
8940
8941 (define_insn "*iorsi_2"
8942   [(set (reg FLAGS_REG)
8943         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8944                          (match_operand:SI 2 "general_operand" "rim,ri"))
8945                  (const_int 0)))
8946    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8947         (ior:SI (match_dup 1) (match_dup 2)))]
8948   "ix86_match_ccmode (insn, CCNOmode)
8949    && ix86_binary_operator_ok (IOR, SImode, operands)"
8950   "or{l}\t{%2, %0|%0, %2}"
8951   [(set_attr "type" "alu")
8952    (set_attr "mode" "SI")])
8953
8954 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8955 ;; ??? Special case for immediate operand is missing - it is tricky.
8956 (define_insn "*iorsi_2_zext"
8957   [(set (reg FLAGS_REG)
8958         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8959                          (match_operand:SI 2 "general_operand" "rim"))
8960                  (const_int 0)))
8961    (set (match_operand:DI 0 "register_operand" "=r")
8962         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8963   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8964    && ix86_binary_operator_ok (IOR, SImode, operands)"
8965   "or{l}\t{%2, %k0|%k0, %2}"
8966   [(set_attr "type" "alu")
8967    (set_attr "mode" "SI")])
8968
8969 (define_insn "*iorsi_2_zext_imm"
8970   [(set (reg FLAGS_REG)
8971         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8972                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8973                  (const_int 0)))
8974    (set (match_operand:DI 0 "register_operand" "=r")
8975         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8976   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8977    && ix86_binary_operator_ok (IOR, SImode, operands)"
8978   "or{l}\t{%2, %k0|%k0, %2}"
8979   [(set_attr "type" "alu")
8980    (set_attr "mode" "SI")])
8981
8982 (define_insn "*iorsi_3"
8983   [(set (reg FLAGS_REG)
8984         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8985                          (match_operand:SI 2 "general_operand" "rim"))
8986                  (const_int 0)))
8987    (clobber (match_scratch:SI 0 "=r"))]
8988   "ix86_match_ccmode (insn, CCNOmode)
8989    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8990   "or{l}\t{%2, %0|%0, %2}"
8991   [(set_attr "type" "alu")
8992    (set_attr "mode" "SI")])
8993
8994 (define_expand "iorhi3"
8995   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8996         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8997                 (match_operand:HI 2 "general_operand" "")))
8998    (clobber (reg:CC FLAGS_REG))]
8999   "TARGET_HIMODE_MATH"
9000   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9001
9002 (define_insn "*iorhi_1"
9003   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9004         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9005                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9006    (clobber (reg:CC FLAGS_REG))]
9007   "ix86_binary_operator_ok (IOR, HImode, operands)"
9008   "or{w}\t{%2, %0|%0, %2}"
9009   [(set_attr "type" "alu")
9010    (set_attr "mode" "HI")])
9011
9012 (define_insn "*iorhi_2"
9013   [(set (reg FLAGS_REG)
9014         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9015                          (match_operand:HI 2 "general_operand" "rim,ri"))
9016                  (const_int 0)))
9017    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9018         (ior:HI (match_dup 1) (match_dup 2)))]
9019   "ix86_match_ccmode (insn, CCNOmode)
9020    && ix86_binary_operator_ok (IOR, HImode, operands)"
9021   "or{w}\t{%2, %0|%0, %2}"
9022   [(set_attr "type" "alu")
9023    (set_attr "mode" "HI")])
9024
9025 (define_insn "*iorhi_3"
9026   [(set (reg FLAGS_REG)
9027         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9028                          (match_operand:HI 2 "general_operand" "rim"))
9029                  (const_int 0)))
9030    (clobber (match_scratch:HI 0 "=r"))]
9031   "ix86_match_ccmode (insn, CCNOmode)
9032    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9033   "or{w}\t{%2, %0|%0, %2}"
9034   [(set_attr "type" "alu")
9035    (set_attr "mode" "HI")])
9036
9037 (define_expand "iorqi3"
9038   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9039         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9040                 (match_operand:QI 2 "general_operand" "")))
9041    (clobber (reg:CC FLAGS_REG))]
9042   "TARGET_QIMODE_MATH"
9043   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9044
9045 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9046 (define_insn "*iorqi_1"
9047   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9048         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9049                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9050    (clobber (reg:CC FLAGS_REG))]
9051   "ix86_binary_operator_ok (IOR, QImode, operands)"
9052   "@
9053    or{b}\t{%2, %0|%0, %2}
9054    or{b}\t{%2, %0|%0, %2}
9055    or{l}\t{%k2, %k0|%k0, %k2}"
9056   [(set_attr "type" "alu")
9057    (set_attr "mode" "QI,QI,SI")])
9058
9059 (define_insn "*iorqi_1_slp"
9060   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9061         (ior:QI (match_dup 0)
9062                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9063    (clobber (reg:CC FLAGS_REG))]
9064   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9065    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9066   "or{b}\t{%1, %0|%0, %1}"
9067   [(set_attr "type" "alu1")
9068    (set_attr "mode" "QI")])
9069
9070 (define_insn "*iorqi_2"
9071   [(set (reg FLAGS_REG)
9072         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9073                          (match_operand:QI 2 "general_operand" "qim,qi"))
9074                  (const_int 0)))
9075    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9076         (ior:QI (match_dup 1) (match_dup 2)))]
9077   "ix86_match_ccmode (insn, CCNOmode)
9078    && ix86_binary_operator_ok (IOR, QImode, operands)"
9079   "or{b}\t{%2, %0|%0, %2}"
9080   [(set_attr "type" "alu")
9081    (set_attr "mode" "QI")])
9082
9083 (define_insn "*iorqi_2_slp"
9084   [(set (reg FLAGS_REG)
9085         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9086                          (match_operand:QI 1 "general_operand" "qim,qi"))
9087                  (const_int 0)))
9088    (set (strict_low_part (match_dup 0))
9089         (ior:QI (match_dup 0) (match_dup 1)))]
9090   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9091    && ix86_match_ccmode (insn, CCNOmode)
9092    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9093   "or{b}\t{%1, %0|%0, %1}"
9094   [(set_attr "type" "alu1")
9095    (set_attr "mode" "QI")])
9096
9097 (define_insn "*iorqi_3"
9098   [(set (reg FLAGS_REG)
9099         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9100                          (match_operand:QI 2 "general_operand" "qim"))
9101                  (const_int 0)))
9102    (clobber (match_scratch:QI 0 "=q"))]
9103   "ix86_match_ccmode (insn, CCNOmode)
9104    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9105   "or{b}\t{%2, %0|%0, %2}"
9106   [(set_attr "type" "alu")
9107    (set_attr "mode" "QI")])
9108
9109 (define_insn "iorqi_ext_0"
9110   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9111                          (const_int 8)
9112                          (const_int 8))
9113         (ior:SI
9114           (zero_extract:SI
9115             (match_operand 1 "ext_register_operand" "0")
9116             (const_int 8)
9117             (const_int 8))
9118           (match_operand 2 "const_int_operand" "n")))
9119    (clobber (reg:CC FLAGS_REG))]
9120   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9121   "or{b}\t{%2, %h0|%h0, %2}"
9122   [(set_attr "type" "alu")
9123    (set_attr "length_immediate" "1")
9124    (set_attr "mode" "QI")])
9125
9126 (define_insn "*iorqi_ext_1"
9127   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9128                          (const_int 8)
9129                          (const_int 8))
9130         (ior:SI
9131           (zero_extract:SI
9132             (match_operand 1 "ext_register_operand" "0")
9133             (const_int 8)
9134             (const_int 8))
9135           (zero_extend:SI
9136             (match_operand:QI 2 "general_operand" "Qm"))))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "!TARGET_64BIT
9139    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9140   "or{b}\t{%2, %h0|%h0, %2}"
9141   [(set_attr "type" "alu")
9142    (set_attr "length_immediate" "0")
9143    (set_attr "mode" "QI")])
9144
9145 (define_insn "*iorqi_ext_1_rex64"
9146   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9147                          (const_int 8)
9148                          (const_int 8))
9149         (ior:SI
9150           (zero_extract:SI
9151             (match_operand 1 "ext_register_operand" "0")
9152             (const_int 8)
9153             (const_int 8))
9154           (zero_extend:SI
9155             (match_operand 2 "ext_register_operand" "Q"))))
9156    (clobber (reg:CC FLAGS_REG))]
9157   "TARGET_64BIT
9158    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9159   "or{b}\t{%2, %h0|%h0, %2}"
9160   [(set_attr "type" "alu")
9161    (set_attr "length_immediate" "0")
9162    (set_attr "mode" "QI")])
9163
9164 (define_insn "*iorqi_ext_2"
9165   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9166                          (const_int 8)
9167                          (const_int 8))
9168         (ior:SI
9169           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9170                            (const_int 8)
9171                            (const_int 8))
9172           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9173                            (const_int 8)
9174                            (const_int 8))))
9175    (clobber (reg:CC FLAGS_REG))]
9176   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9177   "ior{b}\t{%h2, %h0|%h0, %h2}"
9178   [(set_attr "type" "alu")
9179    (set_attr "length_immediate" "0")
9180    (set_attr "mode" "QI")])
9181
9182 (define_split
9183   [(set (match_operand 0 "register_operand" "")
9184         (ior (match_operand 1 "register_operand" "")
9185              (match_operand 2 "const_int_operand" "")))
9186    (clobber (reg:CC FLAGS_REG))]
9187    "reload_completed
9188     && QI_REG_P (operands[0])
9189     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9190     && !(INTVAL (operands[2]) & ~(255 << 8))
9191     && GET_MODE (operands[0]) != QImode"
9192   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9193                    (ior:SI (zero_extract:SI (match_dup 1)
9194                                             (const_int 8) (const_int 8))
9195                            (match_dup 2)))
9196               (clobber (reg:CC FLAGS_REG))])]
9197   "operands[0] = gen_lowpart (SImode, operands[0]);
9198    operands[1] = gen_lowpart (SImode, operands[1]);
9199    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9200
9201 ;; Since OR can be encoded with sign extended immediate, this is only
9202 ;; profitable when 7th bit is set.
9203 (define_split
9204   [(set (match_operand 0 "register_operand" "")
9205         (ior (match_operand 1 "general_operand" "")
9206              (match_operand 2 "const_int_operand" "")))
9207    (clobber (reg:CC FLAGS_REG))]
9208    "reload_completed
9209     && ANY_QI_REG_P (operands[0])
9210     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9211     && !(INTVAL (operands[2]) & ~255)
9212     && (INTVAL (operands[2]) & 128)
9213     && GET_MODE (operands[0]) != QImode"
9214   [(parallel [(set (strict_low_part (match_dup 0))
9215                    (ior:QI (match_dup 1)
9216                            (match_dup 2)))
9217               (clobber (reg:CC FLAGS_REG))])]
9218   "operands[0] = gen_lowpart (QImode, operands[0]);
9219    operands[1] = gen_lowpart (QImode, operands[1]);
9220    operands[2] = gen_lowpart (QImode, operands[2]);")
9221 \f
9222 ;; Logical XOR instructions
9223
9224 ;; %%% This used to optimize known byte-wide and operations to memory.
9225 ;; If this is considered useful, it should be done with splitters.
9226
9227 (define_expand "xordi3"
9228   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9229         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9230                 (match_operand:DI 2 "x86_64_general_operand" "")))
9231    (clobber (reg:CC FLAGS_REG))]
9232   "TARGET_64BIT"
9233   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9234
9235 (define_insn "*xordi_1_rex64"
9236   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9237         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9238                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9239    (clobber (reg:CC FLAGS_REG))]
9240   "TARGET_64BIT
9241    && ix86_binary_operator_ok (XOR, DImode, operands)"
9242   "@
9243    xor{q}\t{%2, %0|%0, %2}
9244    xor{q}\t{%2, %0|%0, %2}"
9245   [(set_attr "type" "alu")
9246    (set_attr "mode" "DI,DI")])
9247
9248 (define_insn "*xordi_2_rex64"
9249   [(set (reg FLAGS_REG)
9250         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9251                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9252                  (const_int 0)))
9253    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9254         (xor:DI (match_dup 1) (match_dup 2)))]
9255   "TARGET_64BIT
9256    && ix86_match_ccmode (insn, CCNOmode)
9257    && ix86_binary_operator_ok (XOR, DImode, operands)"
9258   "@
9259    xor{q}\t{%2, %0|%0, %2}
9260    xor{q}\t{%2, %0|%0, %2}"
9261   [(set_attr "type" "alu")
9262    (set_attr "mode" "DI,DI")])
9263
9264 (define_insn "*xordi_3_rex64"
9265   [(set (reg FLAGS_REG)
9266         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9267                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9268                  (const_int 0)))
9269    (clobber (match_scratch:DI 0 "=r"))]
9270   "TARGET_64BIT
9271    && ix86_match_ccmode (insn, CCNOmode)
9272    && ix86_binary_operator_ok (XOR, DImode, operands)"
9273   "xor{q}\t{%2, %0|%0, %2}"
9274   [(set_attr "type" "alu")
9275    (set_attr "mode" "DI")])
9276
9277 (define_expand "xorsi3"
9278   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9279         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9280                 (match_operand:SI 2 "general_operand" "")))
9281    (clobber (reg:CC FLAGS_REG))]
9282   ""
9283   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9284
9285 (define_insn "*xorsi_1"
9286   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9287         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9288                 (match_operand:SI 2 "general_operand" "ri,rm")))
9289    (clobber (reg:CC FLAGS_REG))]
9290   "ix86_binary_operator_ok (XOR, SImode, operands)"
9291   "xor{l}\t{%2, %0|%0, %2}"
9292   [(set_attr "type" "alu")
9293    (set_attr "mode" "SI")])
9294
9295 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9296 ;; Add speccase for immediates
9297 (define_insn "*xorsi_1_zext"
9298   [(set (match_operand:DI 0 "register_operand" "=r")
9299         (zero_extend:DI
9300           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9301                   (match_operand:SI 2 "general_operand" "rim"))))
9302    (clobber (reg:CC FLAGS_REG))]
9303   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9304   "xor{l}\t{%2, %k0|%k0, %2}"
9305   [(set_attr "type" "alu")
9306    (set_attr "mode" "SI")])
9307
9308 (define_insn "*xorsi_1_zext_imm"
9309   [(set (match_operand:DI 0 "register_operand" "=r")
9310         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9311                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9312    (clobber (reg:CC FLAGS_REG))]
9313   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9314   "xor{l}\t{%2, %k0|%k0, %2}"
9315   [(set_attr "type" "alu")
9316    (set_attr "mode" "SI")])
9317
9318 (define_insn "*xorsi_2"
9319   [(set (reg FLAGS_REG)
9320         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9321                          (match_operand:SI 2 "general_operand" "rim,ri"))
9322                  (const_int 0)))
9323    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9324         (xor:SI (match_dup 1) (match_dup 2)))]
9325   "ix86_match_ccmode (insn, CCNOmode)
9326    && ix86_binary_operator_ok (XOR, SImode, operands)"
9327   "xor{l}\t{%2, %0|%0, %2}"
9328   [(set_attr "type" "alu")
9329    (set_attr "mode" "SI")])
9330
9331 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9332 ;; ??? Special case for immediate operand is missing - it is tricky.
9333 (define_insn "*xorsi_2_zext"
9334   [(set (reg FLAGS_REG)
9335         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9336                          (match_operand:SI 2 "general_operand" "rim"))
9337                  (const_int 0)))
9338    (set (match_operand:DI 0 "register_operand" "=r")
9339         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9340   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9341    && ix86_binary_operator_ok (XOR, SImode, operands)"
9342   "xor{l}\t{%2, %k0|%k0, %2}"
9343   [(set_attr "type" "alu")
9344    (set_attr "mode" "SI")])
9345
9346 (define_insn "*xorsi_2_zext_imm"
9347   [(set (reg FLAGS_REG)
9348         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9349                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9350                  (const_int 0)))
9351    (set (match_operand:DI 0 "register_operand" "=r")
9352         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9353   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9354    && ix86_binary_operator_ok (XOR, SImode, operands)"
9355   "xor{l}\t{%2, %k0|%k0, %2}"
9356   [(set_attr "type" "alu")
9357    (set_attr "mode" "SI")])
9358
9359 (define_insn "*xorsi_3"
9360   [(set (reg FLAGS_REG)
9361         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9362                          (match_operand:SI 2 "general_operand" "rim"))
9363                  (const_int 0)))
9364    (clobber (match_scratch:SI 0 "=r"))]
9365   "ix86_match_ccmode (insn, CCNOmode)
9366    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9367   "xor{l}\t{%2, %0|%0, %2}"
9368   [(set_attr "type" "alu")
9369    (set_attr "mode" "SI")])
9370
9371 (define_expand "xorhi3"
9372   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9373         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9374                 (match_operand:HI 2 "general_operand" "")))
9375    (clobber (reg:CC FLAGS_REG))]
9376   "TARGET_HIMODE_MATH"
9377   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9378
9379 (define_insn "*xorhi_1"
9380   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9381         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9382                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9383    (clobber (reg:CC FLAGS_REG))]
9384   "ix86_binary_operator_ok (XOR, HImode, operands)"
9385   "xor{w}\t{%2, %0|%0, %2}"
9386   [(set_attr "type" "alu")
9387    (set_attr "mode" "HI")])
9388
9389 (define_insn "*xorhi_2"
9390   [(set (reg FLAGS_REG)
9391         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9392                          (match_operand:HI 2 "general_operand" "rim,ri"))
9393                  (const_int 0)))
9394    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9395         (xor:HI (match_dup 1) (match_dup 2)))]
9396   "ix86_match_ccmode (insn, CCNOmode)
9397    && ix86_binary_operator_ok (XOR, HImode, operands)"
9398   "xor{w}\t{%2, %0|%0, %2}"
9399   [(set_attr "type" "alu")
9400    (set_attr "mode" "HI")])
9401
9402 (define_insn "*xorhi_3"
9403   [(set (reg FLAGS_REG)
9404         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9405                          (match_operand:HI 2 "general_operand" "rim"))
9406                  (const_int 0)))
9407    (clobber (match_scratch:HI 0 "=r"))]
9408   "ix86_match_ccmode (insn, CCNOmode)
9409    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9410   "xor{w}\t{%2, %0|%0, %2}"
9411   [(set_attr "type" "alu")
9412    (set_attr "mode" "HI")])
9413
9414 (define_expand "xorqi3"
9415   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9416         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9417                 (match_operand:QI 2 "general_operand" "")))
9418    (clobber (reg:CC FLAGS_REG))]
9419   "TARGET_QIMODE_MATH"
9420   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9421
9422 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9423 (define_insn "*xorqi_1"
9424   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9425         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9426                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9427    (clobber (reg:CC FLAGS_REG))]
9428   "ix86_binary_operator_ok (XOR, QImode, operands)"
9429   "@
9430    xor{b}\t{%2, %0|%0, %2}
9431    xor{b}\t{%2, %0|%0, %2}
9432    xor{l}\t{%k2, %k0|%k0, %k2}"
9433   [(set_attr "type" "alu")
9434    (set_attr "mode" "QI,QI,SI")])
9435
9436 (define_insn "*xorqi_1_slp"
9437   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9438         (xor:QI (match_dup 0)
9439                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9440    (clobber (reg:CC FLAGS_REG))]
9441   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9442    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9443   "xor{b}\t{%1, %0|%0, %1}"
9444   [(set_attr "type" "alu1")
9445    (set_attr "mode" "QI")])
9446
9447 (define_insn "xorqi_ext_0"
9448   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9449                          (const_int 8)
9450                          (const_int 8))
9451         (xor:SI
9452           (zero_extract:SI
9453             (match_operand 1 "ext_register_operand" "0")
9454             (const_int 8)
9455             (const_int 8))
9456           (match_operand 2 "const_int_operand" "n")))
9457    (clobber (reg:CC FLAGS_REG))]
9458   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9459   "xor{b}\t{%2, %h0|%h0, %2}"
9460   [(set_attr "type" "alu")
9461    (set_attr "length_immediate" "1")
9462    (set_attr "mode" "QI")])
9463
9464 (define_insn "*xorqi_ext_1"
9465   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9466                          (const_int 8)
9467                          (const_int 8))
9468         (xor:SI
9469           (zero_extract:SI
9470             (match_operand 1 "ext_register_operand" "0")
9471             (const_int 8)
9472             (const_int 8))
9473           (zero_extend:SI
9474             (match_operand:QI 2 "general_operand" "Qm"))))
9475    (clobber (reg:CC FLAGS_REG))]
9476   "!TARGET_64BIT
9477    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9478   "xor{b}\t{%2, %h0|%h0, %2}"
9479   [(set_attr "type" "alu")
9480    (set_attr "length_immediate" "0")
9481    (set_attr "mode" "QI")])
9482
9483 (define_insn "*xorqi_ext_1_rex64"
9484   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9485                          (const_int 8)
9486                          (const_int 8))
9487         (xor:SI
9488           (zero_extract:SI
9489             (match_operand 1 "ext_register_operand" "0")
9490             (const_int 8)
9491             (const_int 8))
9492           (zero_extend:SI
9493             (match_operand 2 "ext_register_operand" "Q"))))
9494    (clobber (reg:CC FLAGS_REG))]
9495   "TARGET_64BIT
9496    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9497   "xor{b}\t{%2, %h0|%h0, %2}"
9498   [(set_attr "type" "alu")
9499    (set_attr "length_immediate" "0")
9500    (set_attr "mode" "QI")])
9501
9502 (define_insn "*xorqi_ext_2"
9503   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9504                          (const_int 8)
9505                          (const_int 8))
9506         (xor:SI
9507           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9508                            (const_int 8)
9509                            (const_int 8))
9510           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9511                            (const_int 8)
9512                            (const_int 8))))
9513    (clobber (reg:CC FLAGS_REG))]
9514   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9515   "xor{b}\t{%h2, %h0|%h0, %h2}"
9516   [(set_attr "type" "alu")
9517    (set_attr "length_immediate" "0")
9518    (set_attr "mode" "QI")])
9519
9520 (define_insn "*xorqi_cc_1"
9521   [(set (reg FLAGS_REG)
9522         (compare
9523           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9524                   (match_operand:QI 2 "general_operand" "qim,qi"))
9525           (const_int 0)))
9526    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9527         (xor:QI (match_dup 1) (match_dup 2)))]
9528   "ix86_match_ccmode (insn, CCNOmode)
9529    && ix86_binary_operator_ok (XOR, QImode, operands)"
9530   "xor{b}\t{%2, %0|%0, %2}"
9531   [(set_attr "type" "alu")
9532    (set_attr "mode" "QI")])
9533
9534 (define_insn "*xorqi_2_slp"
9535   [(set (reg FLAGS_REG)
9536         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9537                          (match_operand:QI 1 "general_operand" "qim,qi"))
9538                  (const_int 0)))
9539    (set (strict_low_part (match_dup 0))
9540         (xor:QI (match_dup 0) (match_dup 1)))]
9541   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9542    && ix86_match_ccmode (insn, CCNOmode)
9543    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9544   "xor{b}\t{%1, %0|%0, %1}"
9545   [(set_attr "type" "alu1")
9546    (set_attr "mode" "QI")])
9547
9548 (define_insn "*xorqi_cc_2"
9549   [(set (reg FLAGS_REG)
9550         (compare
9551           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9552                   (match_operand:QI 2 "general_operand" "qim"))
9553           (const_int 0)))
9554    (clobber (match_scratch:QI 0 "=q"))]
9555   "ix86_match_ccmode (insn, CCNOmode)
9556    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9557   "xor{b}\t{%2, %0|%0, %2}"
9558   [(set_attr "type" "alu")
9559    (set_attr "mode" "QI")])
9560
9561 (define_insn "*xorqi_cc_ext_1"
9562   [(set (reg FLAGS_REG)
9563         (compare
9564           (xor:SI
9565             (zero_extract:SI
9566               (match_operand 1 "ext_register_operand" "0")
9567               (const_int 8)
9568               (const_int 8))
9569             (match_operand:QI 2 "general_operand" "qmn"))
9570           (const_int 0)))
9571    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9572                          (const_int 8)
9573                          (const_int 8))
9574         (xor:SI
9575           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9576           (match_dup 2)))]
9577   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9578   "xor{b}\t{%2, %h0|%h0, %2}"
9579   [(set_attr "type" "alu")
9580    (set_attr "mode" "QI")])
9581
9582 (define_insn "*xorqi_cc_ext_1_rex64"
9583   [(set (reg FLAGS_REG)
9584         (compare
9585           (xor:SI
9586             (zero_extract:SI
9587               (match_operand 1 "ext_register_operand" "0")
9588               (const_int 8)
9589               (const_int 8))
9590             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9591           (const_int 0)))
9592    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9593                          (const_int 8)
9594                          (const_int 8))
9595         (xor:SI
9596           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9597           (match_dup 2)))]
9598   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9599   "xor{b}\t{%2, %h0|%h0, %2}"
9600   [(set_attr "type" "alu")
9601    (set_attr "mode" "QI")])
9602
9603 (define_expand "xorqi_cc_ext_1"
9604   [(parallel [
9605      (set (reg:CCNO FLAGS_REG)
9606           (compare:CCNO
9607             (xor:SI
9608               (zero_extract:SI
9609                 (match_operand 1 "ext_register_operand" "")
9610                 (const_int 8)
9611                 (const_int 8))
9612               (match_operand:QI 2 "general_operand" ""))
9613             (const_int 0)))
9614      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9615                            (const_int 8)
9616                            (const_int 8))
9617           (xor:SI
9618             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9619             (match_dup 2)))])]
9620   ""
9621   "")
9622
9623 (define_split
9624   [(set (match_operand 0 "register_operand" "")
9625         (xor (match_operand 1 "register_operand" "")
9626              (match_operand 2 "const_int_operand" "")))
9627    (clobber (reg:CC FLAGS_REG))]
9628    "reload_completed
9629     && QI_REG_P (operands[0])
9630     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9631     && !(INTVAL (operands[2]) & ~(255 << 8))
9632     && GET_MODE (operands[0]) != QImode"
9633   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9634                    (xor:SI (zero_extract:SI (match_dup 1)
9635                                             (const_int 8) (const_int 8))
9636                            (match_dup 2)))
9637               (clobber (reg:CC FLAGS_REG))])]
9638   "operands[0] = gen_lowpart (SImode, operands[0]);
9639    operands[1] = gen_lowpart (SImode, operands[1]);
9640    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9641
9642 ;; Since XOR can be encoded with sign extended immediate, this is only
9643 ;; profitable when 7th bit is set.
9644 (define_split
9645   [(set (match_operand 0 "register_operand" "")
9646         (xor (match_operand 1 "general_operand" "")
9647              (match_operand 2 "const_int_operand" "")))
9648    (clobber (reg:CC FLAGS_REG))]
9649    "reload_completed
9650     && ANY_QI_REG_P (operands[0])
9651     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9652     && !(INTVAL (operands[2]) & ~255)
9653     && (INTVAL (operands[2]) & 128)
9654     && GET_MODE (operands[0]) != QImode"
9655   [(parallel [(set (strict_low_part (match_dup 0))
9656                    (xor:QI (match_dup 1)
9657                            (match_dup 2)))
9658               (clobber (reg:CC FLAGS_REG))])]
9659   "operands[0] = gen_lowpart (QImode, operands[0]);
9660    operands[1] = gen_lowpart (QImode, operands[1]);
9661    operands[2] = gen_lowpart (QImode, operands[2]);")
9662 \f
9663 ;; Negation instructions
9664
9665 (define_expand "negti2"
9666   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9667                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9668               (clobber (reg:CC FLAGS_REG))])]
9669   "TARGET_64BIT"
9670   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9671
9672 (define_insn "*negti2_1"
9673   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9674         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9675    (clobber (reg:CC FLAGS_REG))]
9676   "TARGET_64BIT
9677    && ix86_unary_operator_ok (NEG, TImode, operands)"
9678   "#")
9679
9680 (define_split
9681   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9682         (neg:TI (match_operand:TI 1 "general_operand" "")))
9683    (clobber (reg:CC FLAGS_REG))]
9684   "TARGET_64BIT && reload_completed"
9685   [(parallel
9686     [(set (reg:CCZ FLAGS_REG)
9687           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9688      (set (match_dup 0) (neg:DI (match_dup 2)))])
9689    (parallel
9690     [(set (match_dup 1)
9691           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9692                             (match_dup 3))
9693                    (const_int 0)))
9694      (clobber (reg:CC FLAGS_REG))])
9695    (parallel
9696     [(set (match_dup 1)
9697           (neg:DI (match_dup 1)))
9698      (clobber (reg:CC FLAGS_REG))])]
9699   "split_ti (operands+1, 1, operands+2, operands+3);
9700    split_ti (operands+0, 1, operands+0, operands+1);")
9701
9702 (define_expand "negdi2"
9703   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9704                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9705               (clobber (reg:CC FLAGS_REG))])]
9706   ""
9707   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9708
9709 (define_insn "*negdi2_1"
9710   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9711         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9712    (clobber (reg:CC FLAGS_REG))]
9713   "!TARGET_64BIT
9714    && ix86_unary_operator_ok (NEG, DImode, operands)"
9715   "#")
9716
9717 (define_split
9718   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9719         (neg:DI (match_operand:DI 1 "general_operand" "")))
9720    (clobber (reg:CC FLAGS_REG))]
9721   "!TARGET_64BIT && reload_completed"
9722   [(parallel
9723     [(set (reg:CCZ FLAGS_REG)
9724           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9725      (set (match_dup 0) (neg:SI (match_dup 2)))])
9726    (parallel
9727     [(set (match_dup 1)
9728           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9729                             (match_dup 3))
9730                    (const_int 0)))
9731      (clobber (reg:CC FLAGS_REG))])
9732    (parallel
9733     [(set (match_dup 1)
9734           (neg:SI (match_dup 1)))
9735      (clobber (reg:CC FLAGS_REG))])]
9736   "split_di (operands+1, 1, operands+2, operands+3);
9737    split_di (operands+0, 1, operands+0, operands+1);")
9738
9739 (define_insn "*negdi2_1_rex64"
9740   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9741         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9742    (clobber (reg:CC FLAGS_REG))]
9743   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9744   "neg{q}\t%0"
9745   [(set_attr "type" "negnot")
9746    (set_attr "mode" "DI")])
9747
9748 ;; The problem with neg is that it does not perform (compare x 0),
9749 ;; it really performs (compare 0 x), which leaves us with the zero
9750 ;; flag being the only useful item.
9751
9752 (define_insn "*negdi2_cmpz_rex64"
9753   [(set (reg:CCZ FLAGS_REG)
9754         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9755                      (const_int 0)))
9756    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9757         (neg:DI (match_dup 1)))]
9758   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9759   "neg{q}\t%0"
9760   [(set_attr "type" "negnot")
9761    (set_attr "mode" "DI")])
9762
9763
9764 (define_expand "negsi2"
9765   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9766                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9767               (clobber (reg:CC FLAGS_REG))])]
9768   ""
9769   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9770
9771 (define_insn "*negsi2_1"
9772   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9773         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9774    (clobber (reg:CC FLAGS_REG))]
9775   "ix86_unary_operator_ok (NEG, SImode, operands)"
9776   "neg{l}\t%0"
9777   [(set_attr "type" "negnot")
9778    (set_attr "mode" "SI")])
9779
9780 ;; Combine is quite creative about this pattern.
9781 (define_insn "*negsi2_1_zext"
9782   [(set (match_operand:DI 0 "register_operand" "=r")
9783         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9784                                         (const_int 32)))
9785                      (const_int 32)))
9786    (clobber (reg:CC FLAGS_REG))]
9787   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9788   "neg{l}\t%k0"
9789   [(set_attr "type" "negnot")
9790    (set_attr "mode" "SI")])
9791
9792 ;; The problem with neg is that it does not perform (compare x 0),
9793 ;; it really performs (compare 0 x), which leaves us with the zero
9794 ;; flag being the only useful item.
9795
9796 (define_insn "*negsi2_cmpz"
9797   [(set (reg:CCZ FLAGS_REG)
9798         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9799                      (const_int 0)))
9800    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9801         (neg:SI (match_dup 1)))]
9802   "ix86_unary_operator_ok (NEG, SImode, operands)"
9803   "neg{l}\t%0"
9804   [(set_attr "type" "negnot")
9805    (set_attr "mode" "SI")])
9806
9807 (define_insn "*negsi2_cmpz_zext"
9808   [(set (reg:CCZ FLAGS_REG)
9809         (compare:CCZ (lshiftrt:DI
9810                        (neg:DI (ashift:DI
9811                                  (match_operand:DI 1 "register_operand" "0")
9812                                  (const_int 32)))
9813                        (const_int 32))
9814                      (const_int 0)))
9815    (set (match_operand:DI 0 "register_operand" "=r")
9816         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9817                                         (const_int 32)))
9818                      (const_int 32)))]
9819   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9820   "neg{l}\t%k0"
9821   [(set_attr "type" "negnot")
9822    (set_attr "mode" "SI")])
9823
9824 (define_expand "neghi2"
9825   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9826                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9827               (clobber (reg:CC FLAGS_REG))])]
9828   "TARGET_HIMODE_MATH"
9829   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9830
9831 (define_insn "*neghi2_1"
9832   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9833         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9834    (clobber (reg:CC FLAGS_REG))]
9835   "ix86_unary_operator_ok (NEG, HImode, operands)"
9836   "neg{w}\t%0"
9837   [(set_attr "type" "negnot")
9838    (set_attr "mode" "HI")])
9839
9840 (define_insn "*neghi2_cmpz"
9841   [(set (reg:CCZ FLAGS_REG)
9842         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9843                      (const_int 0)))
9844    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9845         (neg:HI (match_dup 1)))]
9846   "ix86_unary_operator_ok (NEG, HImode, operands)"
9847   "neg{w}\t%0"
9848   [(set_attr "type" "negnot")
9849    (set_attr "mode" "HI")])
9850
9851 (define_expand "negqi2"
9852   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9853                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9854               (clobber (reg:CC FLAGS_REG))])]
9855   "TARGET_QIMODE_MATH"
9856   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9857
9858 (define_insn "*negqi2_1"
9859   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9860         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9861    (clobber (reg:CC FLAGS_REG))]
9862   "ix86_unary_operator_ok (NEG, QImode, operands)"
9863   "neg{b}\t%0"
9864   [(set_attr "type" "negnot")
9865    (set_attr "mode" "QI")])
9866
9867 (define_insn "*negqi2_cmpz"
9868   [(set (reg:CCZ FLAGS_REG)
9869         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9870                      (const_int 0)))
9871    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9872         (neg:QI (match_dup 1)))]
9873   "ix86_unary_operator_ok (NEG, QImode, operands)"
9874   "neg{b}\t%0"
9875   [(set_attr "type" "negnot")
9876    (set_attr "mode" "QI")])
9877
9878 ;; Changing of sign for FP values is doable using integer unit too.
9879
9880 (define_expand "negsf2"
9881   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9882         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9883   "TARGET_80387 || TARGET_SSE_MATH"
9884   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9885
9886 (define_expand "abssf2"
9887   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9888         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9889   "TARGET_80387 || TARGET_SSE_MATH"
9890   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9891
9892 (define_insn "*absnegsf2_mixed"
9893   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9894         (match_operator:SF 3 "absneg_operator"
9895           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9896    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9897    (clobber (reg:CC FLAGS_REG))]
9898   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9899    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9900   "#")
9901
9902 (define_insn "*absnegsf2_sse"
9903   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9904         (match_operator:SF 3 "absneg_operator"
9905           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9906    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9907    (clobber (reg:CC FLAGS_REG))]
9908   "TARGET_SSE_MATH
9909    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9910   "#")
9911
9912 (define_insn "*absnegsf2_i387"
9913   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9914         (match_operator:SF 3 "absneg_operator"
9915           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9916    (use (match_operand 2 "" ""))
9917    (clobber (reg:CC FLAGS_REG))]
9918   "TARGET_80387 && !TARGET_SSE_MATH
9919    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9920   "#")
9921
9922 (define_expand "copysignsf3"
9923   [(match_operand:SF 0 "register_operand" "")
9924    (match_operand:SF 1 "nonmemory_operand" "")
9925    (match_operand:SF 2 "register_operand" "")]
9926   "TARGET_SSE_MATH"
9927 {
9928   ix86_expand_copysign (operands);
9929   DONE;
9930 })
9931
9932 (define_insn_and_split "copysignsf3_const"
9933   [(set (match_operand:SF 0 "register_operand"          "=x")
9934         (unspec:SF
9935           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9936            (match_operand:SF 2 "register_operand"       "0")
9937            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9938           UNSPEC_COPYSIGN))]
9939   "TARGET_SSE_MATH"
9940   "#"
9941   "&& reload_completed"
9942   [(const_int 0)]
9943 {
9944   ix86_split_copysign_const (operands);
9945   DONE;
9946 })
9947
9948 (define_insn "copysignsf3_var"
9949   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9950         (unspec:SF
9951           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9952            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9953            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9954            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9955           UNSPEC_COPYSIGN))
9956    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9957   "TARGET_SSE_MATH"
9958   "#")
9959
9960 (define_split
9961   [(set (match_operand:SF 0 "register_operand" "")
9962         (unspec:SF
9963           [(match_operand:SF 2 "register_operand" "")
9964            (match_operand:SF 3 "register_operand" "")
9965            (match_operand:V4SF 4 "" "")
9966            (match_operand:V4SF 5 "" "")]
9967           UNSPEC_COPYSIGN))
9968    (clobber (match_scratch:V4SF 1 ""))]
9969   "TARGET_SSE_MATH && reload_completed"
9970   [(const_int 0)]
9971 {
9972   ix86_split_copysign_var (operands);
9973   DONE;
9974 })
9975
9976 (define_expand "negdf2"
9977   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9978         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9979   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9980   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9981
9982 (define_expand "absdf2"
9983   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9984         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9985   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9986   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9987
9988 (define_insn "*absnegdf2_mixed"
9989   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
9990         (match_operator:DF 3 "absneg_operator"
9991           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9992    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
9993    (clobber (reg:CC FLAGS_REG))]
9994   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9995    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9996   "#")
9997
9998 (define_insn "*absnegdf2_sse"
9999   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
10000         (match_operator:DF 3 "absneg_operator"
10001           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10002    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
10003    (clobber (reg:CC FLAGS_REG))]
10004   "TARGET_SSE2 && TARGET_SSE_MATH
10005    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10006   "#")
10007
10008 (define_insn "*absnegdf2_i387"
10009   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10010         (match_operator:DF 3 "absneg_operator"
10011           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10012    (use (match_operand 2 "" ""))
10013    (clobber (reg:CC FLAGS_REG))]
10014   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10015    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10016   "#")
10017
10018 (define_expand "copysigndf3"
10019   [(match_operand:DF 0 "register_operand" "")
10020    (match_operand:DF 1 "nonmemory_operand" "")
10021    (match_operand:DF 2 "register_operand" "")]
10022   "TARGET_SSE2 && TARGET_SSE_MATH"
10023 {
10024   ix86_expand_copysign (operands);
10025   DONE;
10026 })
10027
10028 (define_insn_and_split "copysigndf3_const"
10029   [(set (match_operand:DF 0 "register_operand"          "=x")
10030         (unspec:DF
10031           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
10032            (match_operand:DF 2 "register_operand"       "0")
10033            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
10034           UNSPEC_COPYSIGN))]
10035   "TARGET_SSE2 && TARGET_SSE_MATH"
10036   "#"
10037   "&& reload_completed"
10038   [(const_int 0)]
10039 {
10040   ix86_split_copysign_const (operands);
10041   DONE;
10042 })
10043
10044 (define_insn "copysigndf3_var"
10045   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
10046         (unspec:DF
10047           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
10048            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
10049            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
10050            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
10051           UNSPEC_COPYSIGN))
10052    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
10053   "TARGET_SSE2 && TARGET_SSE_MATH"
10054   "#")
10055
10056 (define_split
10057   [(set (match_operand:DF 0 "register_operand" "")
10058         (unspec:DF
10059           [(match_operand:DF 2 "register_operand" "")
10060            (match_operand:DF 3 "register_operand" "")
10061            (match_operand:V2DF 4 "" "")
10062            (match_operand:V2DF 5 "" "")]
10063           UNSPEC_COPYSIGN))
10064    (clobber (match_scratch:V2DF 1 ""))]
10065   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10066   [(const_int 0)]
10067 {
10068   ix86_split_copysign_var (operands);
10069   DONE;
10070 })
10071
10072 (define_expand "negxf2"
10073   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10074         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10075   "TARGET_80387"
10076   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10077
10078 (define_expand "absxf2"
10079   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10080         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10081   "TARGET_80387"
10082   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10083
10084 (define_insn "*absnegxf2_i387"
10085   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10086         (match_operator:XF 3 "absneg_operator"
10087           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10088    (use (match_operand 2 "" ""))
10089    (clobber (reg:CC FLAGS_REG))]
10090   "TARGET_80387
10091    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10092   "#")
10093
10094 ;; Splitters for fp abs and neg.
10095
10096 (define_split
10097   [(set (match_operand 0 "fp_register_operand" "")
10098         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10099    (use (match_operand 2 "" ""))
10100    (clobber (reg:CC FLAGS_REG))]
10101   "reload_completed"
10102   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10103
10104 (define_split
10105   [(set (match_operand 0 "register_operand" "")
10106         (match_operator 3 "absneg_operator"
10107           [(match_operand 1 "register_operand" "")]))
10108    (use (match_operand 2 "nonimmediate_operand" ""))
10109    (clobber (reg:CC FLAGS_REG))]
10110   "reload_completed && SSE_REG_P (operands[0])"
10111   [(set (match_dup 0) (match_dup 3))]
10112 {
10113   enum machine_mode mode = GET_MODE (operands[0]);
10114   enum machine_mode vmode = GET_MODE (operands[2]);
10115   rtx tmp;
10116
10117   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10118   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10119   if (operands_match_p (operands[0], operands[2]))
10120     {
10121       tmp = operands[1];
10122       operands[1] = operands[2];
10123       operands[2] = tmp;
10124     }
10125   if (GET_CODE (operands[3]) == ABS)
10126     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10127   else
10128     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10129   operands[3] = tmp;
10130 })
10131
10132 (define_split
10133   [(set (match_operand:SF 0 "register_operand" "")
10134         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10135    (use (match_operand:V4SF 2 "" ""))
10136    (clobber (reg:CC FLAGS_REG))]
10137   "reload_completed"
10138   [(parallel [(set (match_dup 0) (match_dup 1))
10139               (clobber (reg:CC FLAGS_REG))])]
10140 {
10141   rtx tmp;
10142   operands[0] = gen_lowpart (SImode, operands[0]);
10143   if (GET_CODE (operands[1]) == ABS)
10144     {
10145       tmp = gen_int_mode (0x7fffffff, SImode);
10146       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10147     }
10148   else
10149     {
10150       tmp = gen_int_mode (0x80000000, SImode);
10151       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10152     }
10153   operands[1] = tmp;
10154 })
10155
10156 (define_split
10157   [(set (match_operand:DF 0 "register_operand" "")
10158         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10159    (use (match_operand 2 "" ""))
10160    (clobber (reg:CC FLAGS_REG))]
10161   "reload_completed"
10162   [(parallel [(set (match_dup 0) (match_dup 1))
10163               (clobber (reg:CC FLAGS_REG))])]
10164 {
10165   rtx tmp;
10166   if (TARGET_64BIT)
10167     {
10168       tmp = gen_lowpart (DImode, operands[0]);
10169       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10170       operands[0] = tmp;
10171
10172       if (GET_CODE (operands[1]) == ABS)
10173         tmp = const0_rtx;
10174       else
10175         tmp = gen_rtx_NOT (DImode, tmp);
10176     }
10177   else
10178     {
10179       operands[0] = gen_highpart (SImode, operands[0]);
10180       if (GET_CODE (operands[1]) == ABS)
10181         {
10182           tmp = gen_int_mode (0x7fffffff, SImode);
10183           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10184         }
10185       else
10186         {
10187           tmp = gen_int_mode (0x80000000, SImode);
10188           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10189         }
10190     }
10191   operands[1] = tmp;
10192 })
10193
10194 (define_split
10195   [(set (match_operand:XF 0 "register_operand" "")
10196         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10197    (use (match_operand 2 "" ""))
10198    (clobber (reg:CC FLAGS_REG))]
10199   "reload_completed"
10200   [(parallel [(set (match_dup 0) (match_dup 1))
10201               (clobber (reg:CC FLAGS_REG))])]
10202 {
10203   rtx tmp;
10204   operands[0] = gen_rtx_REG (SImode,
10205                              true_regnum (operands[0])
10206                              + (TARGET_64BIT ? 1 : 2));
10207   if (GET_CODE (operands[1]) == ABS)
10208     {
10209       tmp = GEN_INT (0x7fff);
10210       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10211     }
10212   else
10213     {
10214       tmp = GEN_INT (0x8000);
10215       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10216     }
10217   operands[1] = tmp;
10218 })
10219
10220 (define_split
10221   [(set (match_operand 0 "memory_operand" "")
10222         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10223    (use (match_operand 2 "" ""))
10224    (clobber (reg:CC FLAGS_REG))]
10225   "reload_completed"
10226   [(parallel [(set (match_dup 0) (match_dup 1))
10227               (clobber (reg:CC FLAGS_REG))])]
10228 {
10229   enum machine_mode mode = GET_MODE (operands[0]);
10230   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10231   rtx tmp;
10232
10233   operands[0] = adjust_address (operands[0], QImode, size - 1);
10234   if (GET_CODE (operands[1]) == ABS)
10235     {
10236       tmp = gen_int_mode (0x7f, QImode);
10237       tmp = gen_rtx_AND (QImode, operands[0], tmp);
10238     }
10239   else
10240     {
10241       tmp = gen_int_mode (0x80, QImode);
10242       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10243     }
10244   operands[1] = tmp;
10245 })
10246
10247 ;; Conditionalize these after reload. If they match before reload, we
10248 ;; lose the clobber and ability to use integer instructions.
10249
10250 (define_insn "*negsf2_1"
10251   [(set (match_operand:SF 0 "register_operand" "=f")
10252         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10253   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10254   "fchs"
10255   [(set_attr "type" "fsgn")
10256    (set_attr "mode" "SF")])
10257
10258 (define_insn "*negdf2_1"
10259   [(set (match_operand:DF 0 "register_operand" "=f")
10260         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10261   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10262   "fchs"
10263   [(set_attr "type" "fsgn")
10264    (set_attr "mode" "DF")])
10265
10266 (define_insn "*negxf2_1"
10267   [(set (match_operand:XF 0 "register_operand" "=f")
10268         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10269   "TARGET_80387"
10270   "fchs"
10271   [(set_attr "type" "fsgn")
10272    (set_attr "mode" "XF")])
10273
10274 (define_insn "*abssf2_1"
10275   [(set (match_operand:SF 0 "register_operand" "=f")
10276         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10277   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10278   "fabs"
10279   [(set_attr "type" "fsgn")
10280    (set_attr "mode" "SF")])
10281
10282 (define_insn "*absdf2_1"
10283   [(set (match_operand:DF 0 "register_operand" "=f")
10284         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10285   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10286   "fabs"
10287   [(set_attr "type" "fsgn")
10288    (set_attr "mode" "DF")])
10289
10290 (define_insn "*absxf2_1"
10291   [(set (match_operand:XF 0 "register_operand" "=f")
10292         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10293   "TARGET_80387"
10294   "fabs"
10295   [(set_attr "type" "fsgn")
10296    (set_attr "mode" "DF")])
10297
10298 (define_insn "*negextendsfdf2"
10299   [(set (match_operand:DF 0 "register_operand" "=f")
10300         (neg:DF (float_extend:DF
10301                   (match_operand:SF 1 "register_operand" "0"))))]
10302   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10303   "fchs"
10304   [(set_attr "type" "fsgn")
10305    (set_attr "mode" "DF")])
10306
10307 (define_insn "*negextenddfxf2"
10308   [(set (match_operand:XF 0 "register_operand" "=f")
10309         (neg:XF (float_extend:XF
10310                   (match_operand:DF 1 "register_operand" "0"))))]
10311   "TARGET_80387"
10312   "fchs"
10313   [(set_attr "type" "fsgn")
10314    (set_attr "mode" "XF")])
10315
10316 (define_insn "*negextendsfxf2"
10317   [(set (match_operand:XF 0 "register_operand" "=f")
10318         (neg:XF (float_extend:XF
10319                   (match_operand:SF 1 "register_operand" "0"))))]
10320   "TARGET_80387"
10321   "fchs"
10322   [(set_attr "type" "fsgn")
10323    (set_attr "mode" "XF")])
10324
10325 (define_insn "*absextendsfdf2"
10326   [(set (match_operand:DF 0 "register_operand" "=f")
10327         (abs:DF (float_extend:DF
10328                   (match_operand:SF 1 "register_operand" "0"))))]
10329   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10330   "fabs"
10331   [(set_attr "type" "fsgn")
10332    (set_attr "mode" "DF")])
10333
10334 (define_insn "*absextenddfxf2"
10335   [(set (match_operand:XF 0 "register_operand" "=f")
10336         (abs:XF (float_extend:XF
10337           (match_operand:DF 1 "register_operand" "0"))))]
10338   "TARGET_80387"
10339   "fabs"
10340   [(set_attr "type" "fsgn")
10341    (set_attr "mode" "XF")])
10342
10343 (define_insn "*absextendsfxf2"
10344   [(set (match_operand:XF 0 "register_operand" "=f")
10345         (abs:XF (float_extend:XF
10346           (match_operand:SF 1 "register_operand" "0"))))]
10347   "TARGET_80387"
10348   "fabs"
10349   [(set_attr "type" "fsgn")
10350    (set_attr "mode" "XF")])
10351 \f
10352 ;; One complement instructions
10353
10354 (define_expand "one_cmpldi2"
10355   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10356         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10357   "TARGET_64BIT"
10358   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10359
10360 (define_insn "*one_cmpldi2_1_rex64"
10361   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10362         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10363   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10364   "not{q}\t%0"
10365   [(set_attr "type" "negnot")
10366    (set_attr "mode" "DI")])
10367
10368 (define_insn "*one_cmpldi2_2_rex64"
10369   [(set (reg FLAGS_REG)
10370         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10371                  (const_int 0)))
10372    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10373         (not:DI (match_dup 1)))]
10374   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10375    && ix86_unary_operator_ok (NOT, DImode, operands)"
10376   "#"
10377   [(set_attr "type" "alu1")
10378    (set_attr "mode" "DI")])
10379
10380 (define_split
10381   [(set (match_operand 0 "flags_reg_operand" "")
10382         (match_operator 2 "compare_operator"
10383           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10384            (const_int 0)]))
10385    (set (match_operand:DI 1 "nonimmediate_operand" "")
10386         (not:DI (match_dup 3)))]
10387   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10388   [(parallel [(set (match_dup 0)
10389                    (match_op_dup 2
10390                      [(xor:DI (match_dup 3) (const_int -1))
10391                       (const_int 0)]))
10392               (set (match_dup 1)
10393                    (xor:DI (match_dup 3) (const_int -1)))])]
10394   "")
10395
10396 (define_expand "one_cmplsi2"
10397   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10398         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10399   ""
10400   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10401
10402 (define_insn "*one_cmplsi2_1"
10403   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10404         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10405   "ix86_unary_operator_ok (NOT, SImode, operands)"
10406   "not{l}\t%0"
10407   [(set_attr "type" "negnot")
10408    (set_attr "mode" "SI")])
10409
10410 ;; ??? Currently never generated - xor is used instead.
10411 (define_insn "*one_cmplsi2_1_zext"
10412   [(set (match_operand:DI 0 "register_operand" "=r")
10413         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10414   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10415   "not{l}\t%k0"
10416   [(set_attr "type" "negnot")
10417    (set_attr "mode" "SI")])
10418
10419 (define_insn "*one_cmplsi2_2"
10420   [(set (reg FLAGS_REG)
10421         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10422                  (const_int 0)))
10423    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10424         (not:SI (match_dup 1)))]
10425   "ix86_match_ccmode (insn, CCNOmode)
10426    && ix86_unary_operator_ok (NOT, SImode, operands)"
10427   "#"
10428   [(set_attr "type" "alu1")
10429    (set_attr "mode" "SI")])
10430
10431 (define_split
10432   [(set (match_operand 0 "flags_reg_operand" "")
10433         (match_operator 2 "compare_operator"
10434           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10435            (const_int 0)]))
10436    (set (match_operand:SI 1 "nonimmediate_operand" "")
10437         (not:SI (match_dup 3)))]
10438   "ix86_match_ccmode (insn, CCNOmode)"
10439   [(parallel [(set (match_dup 0)
10440                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10441                                     (const_int 0)]))
10442               (set (match_dup 1)
10443                    (xor:SI (match_dup 3) (const_int -1)))])]
10444   "")
10445
10446 ;; ??? Currently never generated - xor is used instead.
10447 (define_insn "*one_cmplsi2_2_zext"
10448   [(set (reg FLAGS_REG)
10449         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10450                  (const_int 0)))
10451    (set (match_operand:DI 0 "register_operand" "=r")
10452         (zero_extend:DI (not:SI (match_dup 1))))]
10453   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10454    && ix86_unary_operator_ok (NOT, SImode, operands)"
10455   "#"
10456   [(set_attr "type" "alu1")
10457    (set_attr "mode" "SI")])
10458
10459 (define_split
10460   [(set (match_operand 0 "flags_reg_operand" "")
10461         (match_operator 2 "compare_operator"
10462           [(not:SI (match_operand:SI 3 "register_operand" ""))
10463            (const_int 0)]))
10464    (set (match_operand:DI 1 "register_operand" "")
10465         (zero_extend:DI (not:SI (match_dup 3))))]
10466   "ix86_match_ccmode (insn, CCNOmode)"
10467   [(parallel [(set (match_dup 0)
10468                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10469                                     (const_int 0)]))
10470               (set (match_dup 1)
10471                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10472   "")
10473
10474 (define_expand "one_cmplhi2"
10475   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10476         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10477   "TARGET_HIMODE_MATH"
10478   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10479
10480 (define_insn "*one_cmplhi2_1"
10481   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10482         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10483   "ix86_unary_operator_ok (NOT, HImode, operands)"
10484   "not{w}\t%0"
10485   [(set_attr "type" "negnot")
10486    (set_attr "mode" "HI")])
10487
10488 (define_insn "*one_cmplhi2_2"
10489   [(set (reg FLAGS_REG)
10490         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10491                  (const_int 0)))
10492    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10493         (not:HI (match_dup 1)))]
10494   "ix86_match_ccmode (insn, CCNOmode)
10495    && ix86_unary_operator_ok (NEG, HImode, operands)"
10496   "#"
10497   [(set_attr "type" "alu1")
10498    (set_attr "mode" "HI")])
10499
10500 (define_split
10501   [(set (match_operand 0 "flags_reg_operand" "")
10502         (match_operator 2 "compare_operator"
10503           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10504            (const_int 0)]))
10505    (set (match_operand:HI 1 "nonimmediate_operand" "")
10506         (not:HI (match_dup 3)))]
10507   "ix86_match_ccmode (insn, CCNOmode)"
10508   [(parallel [(set (match_dup 0)
10509                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10510                                     (const_int 0)]))
10511               (set (match_dup 1)
10512                    (xor:HI (match_dup 3) (const_int -1)))])]
10513   "")
10514
10515 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10516 (define_expand "one_cmplqi2"
10517   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10518         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10519   "TARGET_QIMODE_MATH"
10520   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10521
10522 (define_insn "*one_cmplqi2_1"
10523   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10524         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10525   "ix86_unary_operator_ok (NOT, QImode, operands)"
10526   "@
10527    not{b}\t%0
10528    not{l}\t%k0"
10529   [(set_attr "type" "negnot")
10530    (set_attr "mode" "QI,SI")])
10531
10532 (define_insn "*one_cmplqi2_2"
10533   [(set (reg FLAGS_REG)
10534         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10535                  (const_int 0)))
10536    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10537         (not:QI (match_dup 1)))]
10538   "ix86_match_ccmode (insn, CCNOmode)
10539    && ix86_unary_operator_ok (NOT, QImode, operands)"
10540   "#"
10541   [(set_attr "type" "alu1")
10542    (set_attr "mode" "QI")])
10543
10544 (define_split
10545   [(set (match_operand 0 "flags_reg_operand" "")
10546         (match_operator 2 "compare_operator"
10547           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10548            (const_int 0)]))
10549    (set (match_operand:QI 1 "nonimmediate_operand" "")
10550         (not:QI (match_dup 3)))]
10551   "ix86_match_ccmode (insn, CCNOmode)"
10552   [(parallel [(set (match_dup 0)
10553                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10554                                     (const_int 0)]))
10555               (set (match_dup 1)
10556                    (xor:QI (match_dup 3) (const_int -1)))])]
10557   "")
10558 \f
10559 ;; Arithmetic shift instructions
10560
10561 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10562 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10563 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10564 ;; from the assembler input.
10565 ;;
10566 ;; This instruction shifts the target reg/mem as usual, but instead of
10567 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10568 ;; is a left shift double, bits are taken from the high order bits of
10569 ;; reg, else if the insn is a shift right double, bits are taken from the
10570 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10571 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10572 ;;
10573 ;; Since sh[lr]d does not change the `reg' operand, that is done
10574 ;; separately, making all shifts emit pairs of shift double and normal
10575 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10576 ;; support a 63 bit shift, each shift where the count is in a reg expands
10577 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10578 ;;
10579 ;; If the shift count is a constant, we need never emit more than one
10580 ;; shift pair, instead using moves and sign extension for counts greater
10581 ;; than 31.
10582
10583 (define_expand "ashlti3"
10584   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10585                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10586                               (match_operand:QI 2 "nonmemory_operand" "")))
10587               (clobber (reg:CC FLAGS_REG))])]
10588   "TARGET_64BIT"
10589 {
10590   if (! immediate_operand (operands[2], QImode))
10591     {
10592       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10593       DONE;
10594     }
10595   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10596   DONE;
10597 })
10598
10599 (define_insn "ashlti3_1"
10600   [(set (match_operand:TI 0 "register_operand" "=r")
10601         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10602                    (match_operand:QI 2 "register_operand" "c")))
10603    (clobber (match_scratch:DI 3 "=&r"))
10604    (clobber (reg:CC FLAGS_REG))]
10605   "TARGET_64BIT"
10606   "#"
10607   [(set_attr "type" "multi")])
10608
10609 (define_insn "*ashlti3_2"
10610   [(set (match_operand:TI 0 "register_operand" "=r")
10611         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10612                    (match_operand:QI 2 "immediate_operand" "O")))
10613    (clobber (reg:CC FLAGS_REG))]
10614   "TARGET_64BIT"
10615   "#"
10616   [(set_attr "type" "multi")])
10617
10618 (define_split
10619   [(set (match_operand:TI 0 "register_operand" "")
10620         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10621                    (match_operand:QI 2 "register_operand" "")))
10622    (clobber (match_scratch:DI 3 ""))
10623    (clobber (reg:CC FLAGS_REG))]
10624   "TARGET_64BIT && reload_completed"
10625   [(const_int 0)]
10626   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10627
10628 (define_split
10629   [(set (match_operand:TI 0 "register_operand" "")
10630         (ashift:TI (match_operand:TI 1 "register_operand" "")
10631                    (match_operand:QI 2 "immediate_operand" "")))
10632    (clobber (reg:CC FLAGS_REG))]
10633   "TARGET_64BIT && reload_completed"
10634   [(const_int 0)]
10635   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10636
10637 (define_insn "x86_64_shld"
10638   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10639         (ior:DI (ashift:DI (match_dup 0)
10640                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10641                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10642                   (minus:QI (const_int 64) (match_dup 2)))))
10643    (clobber (reg:CC FLAGS_REG))]
10644   "TARGET_64BIT"
10645   "@
10646    shld{q}\t{%2, %1, %0|%0, %1, %2}
10647    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10648   [(set_attr "type" "ishift")
10649    (set_attr "prefix_0f" "1")
10650    (set_attr "mode" "DI")
10651    (set_attr "athlon_decode" "vector")
10652    (set_attr "amdfam10_decode" "vector")])   
10653
10654 (define_expand "x86_64_shift_adj"
10655   [(set (reg:CCZ FLAGS_REG)
10656         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10657                              (const_int 64))
10658                      (const_int 0)))
10659    (set (match_operand:DI 0 "register_operand" "")
10660         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10661                          (match_operand:DI 1 "register_operand" "")
10662                          (match_dup 0)))
10663    (set (match_dup 1)
10664         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10665                          (match_operand:DI 3 "register_operand" "r")
10666                          (match_dup 1)))]
10667   "TARGET_64BIT"
10668   "")
10669
10670 (define_expand "ashldi3"
10671   [(set (match_operand:DI 0 "shiftdi_operand" "")
10672         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10673                    (match_operand:QI 2 "nonmemory_operand" "")))]
10674   ""
10675   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10676
10677 (define_insn "*ashldi3_1_rex64"
10678   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10679         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10680                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10681    (clobber (reg:CC FLAGS_REG))]
10682   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10683 {
10684   switch (get_attr_type (insn))
10685     {
10686     case TYPE_ALU:
10687       gcc_assert (operands[2] == const1_rtx);
10688       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10689       return "add{q}\t{%0, %0|%0, %0}";
10690
10691     case TYPE_LEA:
10692       gcc_assert (CONST_INT_P (operands[2]));
10693       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10694       operands[1] = gen_rtx_MULT (DImode, operands[1],
10695                                   GEN_INT (1 << INTVAL (operands[2])));
10696       return "lea{q}\t{%a1, %0|%0, %a1}";
10697
10698     default:
10699       if (REG_P (operands[2]))
10700         return "sal{q}\t{%b2, %0|%0, %b2}";
10701       else if (operands[2] == const1_rtx
10702                && (TARGET_SHIFT1 || optimize_size))
10703         return "sal{q}\t%0";
10704       else
10705         return "sal{q}\t{%2, %0|%0, %2}";
10706     }
10707 }
10708   [(set (attr "type")
10709      (cond [(eq_attr "alternative" "1")
10710               (const_string "lea")
10711             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10712                           (const_int 0))
10713                       (match_operand 0 "register_operand" ""))
10714                  (match_operand 2 "const1_operand" ""))
10715               (const_string "alu")
10716            ]
10717            (const_string "ishift")))
10718    (set_attr "mode" "DI")])
10719
10720 ;; Convert lea to the lea pattern to avoid flags dependency.
10721 (define_split
10722   [(set (match_operand:DI 0 "register_operand" "")
10723         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10724                    (match_operand:QI 2 "immediate_operand" "")))
10725    (clobber (reg:CC FLAGS_REG))]
10726   "TARGET_64BIT && reload_completed
10727    && true_regnum (operands[0]) != true_regnum (operands[1])"
10728   [(set (match_dup 0)
10729         (mult:DI (match_dup 1)
10730                  (match_dup 2)))]
10731   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10732
10733 ;; This pattern can't accept a variable shift count, since shifts by
10734 ;; zero don't affect the flags.  We assume that shifts by constant
10735 ;; zero are optimized away.
10736 (define_insn "*ashldi3_cmp_rex64"
10737   [(set (reg FLAGS_REG)
10738         (compare
10739           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10740                      (match_operand:QI 2 "immediate_operand" "e"))
10741           (const_int 0)))
10742    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10743         (ashift:DI (match_dup 1) (match_dup 2)))]
10744   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10745    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10746    && (optimize_size
10747        || !TARGET_PARTIAL_FLAG_REG_STALL
10748        || (operands[2] == const1_rtx
10749            && (TARGET_SHIFT1
10750                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10751 {
10752   switch (get_attr_type (insn))
10753     {
10754     case TYPE_ALU:
10755       gcc_assert (operands[2] == const1_rtx);
10756       return "add{q}\t{%0, %0|%0, %0}";
10757
10758     default:
10759       if (REG_P (operands[2]))
10760         return "sal{q}\t{%b2, %0|%0, %b2}";
10761       else if (operands[2] == const1_rtx
10762                && (TARGET_SHIFT1 || optimize_size))
10763         return "sal{q}\t%0";
10764       else
10765         return "sal{q}\t{%2, %0|%0, %2}";
10766     }
10767 }
10768   [(set (attr "type")
10769      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10770                           (const_int 0))
10771                       (match_operand 0 "register_operand" ""))
10772                  (match_operand 2 "const1_operand" ""))
10773               (const_string "alu")
10774            ]
10775            (const_string "ishift")))
10776    (set_attr "mode" "DI")])
10777
10778 (define_insn "*ashldi3_cconly_rex64"
10779   [(set (reg FLAGS_REG)
10780         (compare
10781           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10782                      (match_operand:QI 2 "immediate_operand" "e"))
10783           (const_int 0)))
10784    (clobber (match_scratch:DI 0 "=r"))]
10785   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10786    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10787    && (optimize_size
10788        || !TARGET_PARTIAL_FLAG_REG_STALL
10789        || (operands[2] == const1_rtx
10790            && (TARGET_SHIFT1
10791                || TARGET_DOUBLE_WITH_ADD)))"
10792 {
10793   switch (get_attr_type (insn))
10794     {
10795     case TYPE_ALU:
10796       gcc_assert (operands[2] == const1_rtx);
10797       return "add{q}\t{%0, %0|%0, %0}";
10798
10799     default:
10800       if (REG_P (operands[2]))
10801         return "sal{q}\t{%b2, %0|%0, %b2}";
10802       else if (operands[2] == const1_rtx
10803                && (TARGET_SHIFT1 || optimize_size))
10804         return "sal{q}\t%0";
10805       else
10806         return "sal{q}\t{%2, %0|%0, %2}";
10807     }
10808 }
10809   [(set (attr "type")
10810      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10811                           (const_int 0))
10812                       (match_operand 0 "register_operand" ""))
10813                  (match_operand 2 "const1_operand" ""))
10814               (const_string "alu")
10815            ]
10816            (const_string "ishift")))
10817    (set_attr "mode" "DI")])
10818
10819 (define_insn "*ashldi3_1"
10820   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10821         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10822                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10823    (clobber (reg:CC FLAGS_REG))]
10824   "!TARGET_64BIT"
10825   "#"
10826   [(set_attr "type" "multi")])
10827
10828 ;; By default we don't ask for a scratch register, because when DImode
10829 ;; values are manipulated, registers are already at a premium.  But if
10830 ;; we have one handy, we won't turn it away.
10831 (define_peephole2
10832   [(match_scratch:SI 3 "r")
10833    (parallel [(set (match_operand:DI 0 "register_operand" "")
10834                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10835                               (match_operand:QI 2 "nonmemory_operand" "")))
10836               (clobber (reg:CC FLAGS_REG))])
10837    (match_dup 3)]
10838   "!TARGET_64BIT && TARGET_CMOVE"
10839   [(const_int 0)]
10840   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10841
10842 (define_split
10843   [(set (match_operand:DI 0 "register_operand" "")
10844         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10845                    (match_operand:QI 2 "nonmemory_operand" "")))
10846    (clobber (reg:CC FLAGS_REG))]
10847   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10848                      ? flow2_completed : reload_completed)"
10849   [(const_int 0)]
10850   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10851
10852 (define_insn "x86_shld_1"
10853   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10854         (ior:SI (ashift:SI (match_dup 0)
10855                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10856                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10857                   (minus:QI (const_int 32) (match_dup 2)))))
10858    (clobber (reg:CC FLAGS_REG))]
10859   ""
10860   "@
10861    shld{l}\t{%2, %1, %0|%0, %1, %2}
10862    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10863   [(set_attr "type" "ishift")
10864    (set_attr "prefix_0f" "1")
10865    (set_attr "mode" "SI")
10866    (set_attr "pent_pair" "np")
10867    (set_attr "athlon_decode" "vector")
10868    (set_attr "amdfam10_decode" "vector")])   
10869
10870 (define_expand "x86_shift_adj_1"
10871   [(set (reg:CCZ FLAGS_REG)
10872         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10873                              (const_int 32))
10874                      (const_int 0)))
10875    (set (match_operand:SI 0 "register_operand" "")
10876         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10877                          (match_operand:SI 1 "register_operand" "")
10878                          (match_dup 0)))
10879    (set (match_dup 1)
10880         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10881                          (match_operand:SI 3 "register_operand" "r")
10882                          (match_dup 1)))]
10883   "TARGET_CMOVE"
10884   "")
10885
10886 (define_expand "x86_shift_adj_2"
10887   [(use (match_operand:SI 0 "register_operand" ""))
10888    (use (match_operand:SI 1 "register_operand" ""))
10889    (use (match_operand:QI 2 "register_operand" ""))]
10890   ""
10891 {
10892   rtx label = gen_label_rtx ();
10893   rtx tmp;
10894
10895   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10896
10897   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10898   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10899   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10900                               gen_rtx_LABEL_REF (VOIDmode, label),
10901                               pc_rtx);
10902   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10903   JUMP_LABEL (tmp) = label;
10904
10905   emit_move_insn (operands[0], operands[1]);
10906   ix86_expand_clear (operands[1]);
10907
10908   emit_label (label);
10909   LABEL_NUSES (label) = 1;
10910
10911   DONE;
10912 })
10913
10914 (define_expand "ashlsi3"
10915   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10916         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10917                    (match_operand:QI 2 "nonmemory_operand" "")))
10918    (clobber (reg:CC FLAGS_REG))]
10919   ""
10920   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10921
10922 (define_insn "*ashlsi3_1"
10923   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10924         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10925                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10926    (clobber (reg:CC FLAGS_REG))]
10927   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10928 {
10929   switch (get_attr_type (insn))
10930     {
10931     case TYPE_ALU:
10932       gcc_assert (operands[2] == const1_rtx);
10933       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10934       return "add{l}\t{%0, %0|%0, %0}";
10935
10936     case TYPE_LEA:
10937       return "#";
10938
10939     default:
10940       if (REG_P (operands[2]))
10941         return "sal{l}\t{%b2, %0|%0, %b2}";
10942       else if (operands[2] == const1_rtx
10943                && (TARGET_SHIFT1 || optimize_size))
10944         return "sal{l}\t%0";
10945       else
10946         return "sal{l}\t{%2, %0|%0, %2}";
10947     }
10948 }
10949   [(set (attr "type")
10950      (cond [(eq_attr "alternative" "1")
10951               (const_string "lea")
10952             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10953                           (const_int 0))
10954                       (match_operand 0 "register_operand" ""))
10955                  (match_operand 2 "const1_operand" ""))
10956               (const_string "alu")
10957            ]
10958            (const_string "ishift")))
10959    (set_attr "mode" "SI")])
10960
10961 ;; Convert lea to the lea pattern to avoid flags dependency.
10962 (define_split
10963   [(set (match_operand 0 "register_operand" "")
10964         (ashift (match_operand 1 "index_register_operand" "")
10965                 (match_operand:QI 2 "const_int_operand" "")))
10966    (clobber (reg:CC FLAGS_REG))]
10967   "reload_completed
10968    && true_regnum (operands[0]) != true_regnum (operands[1])
10969    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10970   [(const_int 0)]
10971 {
10972   rtx pat;
10973   enum machine_mode mode = GET_MODE (operands[0]);
10974
10975   if (GET_MODE_SIZE (mode) < 4)
10976     operands[0] = gen_lowpart (SImode, operands[0]);
10977   if (mode != Pmode)
10978     operands[1] = gen_lowpart (Pmode, operands[1]);
10979   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10980
10981   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10982   if (Pmode != SImode)
10983     pat = gen_rtx_SUBREG (SImode, pat, 0);
10984   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10985   DONE;
10986 })
10987
10988 ;; Rare case of shifting RSP is handled by generating move and shift
10989 (define_split
10990   [(set (match_operand 0 "register_operand" "")
10991         (ashift (match_operand 1 "register_operand" "")
10992                 (match_operand:QI 2 "const_int_operand" "")))
10993    (clobber (reg:CC FLAGS_REG))]
10994   "reload_completed
10995    && true_regnum (operands[0]) != true_regnum (operands[1])"
10996   [(const_int 0)]
10997 {
10998   rtx pat, clob;
10999   emit_move_insn (operands[0], operands[1]);
11000   pat = gen_rtx_SET (VOIDmode, operands[0],
11001                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11002                                      operands[0], operands[2]));
11003   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11004   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11005   DONE;
11006 })
11007
11008 (define_insn "*ashlsi3_1_zext"
11009   [(set (match_operand:DI 0 "register_operand" "=r,r")
11010         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11011                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11012    (clobber (reg:CC FLAGS_REG))]
11013   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11014 {
11015   switch (get_attr_type (insn))
11016     {
11017     case TYPE_ALU:
11018       gcc_assert (operands[2] == const1_rtx);
11019       return "add{l}\t{%k0, %k0|%k0, %k0}";
11020
11021     case TYPE_LEA:
11022       return "#";
11023
11024     default:
11025       if (REG_P (operands[2]))
11026         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11027       else if (operands[2] == const1_rtx
11028                && (TARGET_SHIFT1 || optimize_size))
11029         return "sal{l}\t%k0";
11030       else
11031         return "sal{l}\t{%2, %k0|%k0, %2}";
11032     }
11033 }
11034   [(set (attr "type")
11035      (cond [(eq_attr "alternative" "1")
11036               (const_string "lea")
11037             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11038                      (const_int 0))
11039                  (match_operand 2 "const1_operand" ""))
11040               (const_string "alu")
11041            ]
11042            (const_string "ishift")))
11043    (set_attr "mode" "SI")])
11044
11045 ;; Convert lea to the lea pattern to avoid flags dependency.
11046 (define_split
11047   [(set (match_operand:DI 0 "register_operand" "")
11048         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11049                                 (match_operand:QI 2 "const_int_operand" ""))))
11050    (clobber (reg:CC FLAGS_REG))]
11051   "TARGET_64BIT && reload_completed
11052    && true_regnum (operands[0]) != true_regnum (operands[1])"
11053   [(set (match_dup 0) (zero_extend:DI
11054                         (subreg:SI (mult:SI (match_dup 1)
11055                                             (match_dup 2)) 0)))]
11056 {
11057   operands[1] = gen_lowpart (Pmode, operands[1]);
11058   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11059 })
11060
11061 ;; This pattern can't accept a variable shift count, since shifts by
11062 ;; zero don't affect the flags.  We assume that shifts by constant
11063 ;; zero are optimized away.
11064 (define_insn "*ashlsi3_cmp"
11065   [(set (reg FLAGS_REG)
11066         (compare
11067           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11068                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11069           (const_int 0)))
11070    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11071         (ashift:SI (match_dup 1) (match_dup 2)))]
11072   "ix86_match_ccmode (insn, CCGOCmode)
11073    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11074    && (optimize_size
11075        || !TARGET_PARTIAL_FLAG_REG_STALL
11076        || (operands[2] == const1_rtx
11077            && (TARGET_SHIFT1
11078                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11079 {
11080   switch (get_attr_type (insn))
11081     {
11082     case TYPE_ALU:
11083       gcc_assert (operands[2] == const1_rtx);
11084       return "add{l}\t{%0, %0|%0, %0}";
11085
11086     default:
11087       if (REG_P (operands[2]))
11088         return "sal{l}\t{%b2, %0|%0, %b2}";
11089       else if (operands[2] == const1_rtx
11090                && (TARGET_SHIFT1 || optimize_size))
11091         return "sal{l}\t%0";
11092       else
11093         return "sal{l}\t{%2, %0|%0, %2}";
11094     }
11095 }
11096   [(set (attr "type")
11097      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11098                           (const_int 0))
11099                       (match_operand 0 "register_operand" ""))
11100                  (match_operand 2 "const1_operand" ""))
11101               (const_string "alu")
11102            ]
11103            (const_string "ishift")))
11104    (set_attr "mode" "SI")])
11105
11106 (define_insn "*ashlsi3_cconly"
11107   [(set (reg FLAGS_REG)
11108         (compare
11109           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11110                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11111           (const_int 0)))
11112    (clobber (match_scratch:SI 0 "=r"))]
11113   "ix86_match_ccmode (insn, CCGOCmode)
11114    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11115    && (optimize_size
11116        || !TARGET_PARTIAL_FLAG_REG_STALL
11117        || (operands[2] == const1_rtx
11118            && (TARGET_SHIFT1
11119                || TARGET_DOUBLE_WITH_ADD)))"
11120 {
11121   switch (get_attr_type (insn))
11122     {
11123     case TYPE_ALU:
11124       gcc_assert (operands[2] == const1_rtx);
11125       return "add{l}\t{%0, %0|%0, %0}";
11126
11127     default:
11128       if (REG_P (operands[2]))
11129         return "sal{l}\t{%b2, %0|%0, %b2}";
11130       else if (operands[2] == const1_rtx
11131                && (TARGET_SHIFT1 || optimize_size))
11132         return "sal{l}\t%0";
11133       else
11134         return "sal{l}\t{%2, %0|%0, %2}";
11135     }
11136 }
11137   [(set (attr "type")
11138      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11139                           (const_int 0))
11140                       (match_operand 0 "register_operand" ""))
11141                  (match_operand 2 "const1_operand" ""))
11142               (const_string "alu")
11143            ]
11144            (const_string "ishift")))
11145    (set_attr "mode" "SI")])
11146
11147 (define_insn "*ashlsi3_cmp_zext"
11148   [(set (reg FLAGS_REG)
11149         (compare
11150           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11151                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11152           (const_int 0)))
11153    (set (match_operand:DI 0 "register_operand" "=r")
11154         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11155   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11156    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11157    && (optimize_size
11158        || !TARGET_PARTIAL_FLAG_REG_STALL
11159        || (operands[2] == const1_rtx
11160            && (TARGET_SHIFT1
11161                || TARGET_DOUBLE_WITH_ADD)))"
11162 {
11163   switch (get_attr_type (insn))
11164     {
11165     case TYPE_ALU:
11166       gcc_assert (operands[2] == const1_rtx);
11167       return "add{l}\t{%k0, %k0|%k0, %k0}";
11168
11169     default:
11170       if (REG_P (operands[2]))
11171         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11172       else if (operands[2] == const1_rtx
11173                && (TARGET_SHIFT1 || optimize_size))
11174         return "sal{l}\t%k0";
11175       else
11176         return "sal{l}\t{%2, %k0|%k0, %2}";
11177     }
11178 }
11179   [(set (attr "type")
11180      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11181                      (const_int 0))
11182                  (match_operand 2 "const1_operand" ""))
11183               (const_string "alu")
11184            ]
11185            (const_string "ishift")))
11186    (set_attr "mode" "SI")])
11187
11188 (define_expand "ashlhi3"
11189   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11190         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11191                    (match_operand:QI 2 "nonmemory_operand" "")))
11192    (clobber (reg:CC FLAGS_REG))]
11193   "TARGET_HIMODE_MATH"
11194   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11195
11196 (define_insn "*ashlhi3_1_lea"
11197   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11198         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11199                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11200    (clobber (reg:CC FLAGS_REG))]
11201   "!TARGET_PARTIAL_REG_STALL
11202    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11203 {
11204   switch (get_attr_type (insn))
11205     {
11206     case TYPE_LEA:
11207       return "#";
11208     case TYPE_ALU:
11209       gcc_assert (operands[2] == const1_rtx);
11210       return "add{w}\t{%0, %0|%0, %0}";
11211
11212     default:
11213       if (REG_P (operands[2]))
11214         return "sal{w}\t{%b2, %0|%0, %b2}";
11215       else if (operands[2] == const1_rtx
11216                && (TARGET_SHIFT1 || optimize_size))
11217         return "sal{w}\t%0";
11218       else
11219         return "sal{w}\t{%2, %0|%0, %2}";
11220     }
11221 }
11222   [(set (attr "type")
11223      (cond [(eq_attr "alternative" "1")
11224               (const_string "lea")
11225             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11226                           (const_int 0))
11227                       (match_operand 0 "register_operand" ""))
11228                  (match_operand 2 "const1_operand" ""))
11229               (const_string "alu")
11230            ]
11231            (const_string "ishift")))
11232    (set_attr "mode" "HI,SI")])
11233
11234 (define_insn "*ashlhi3_1"
11235   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11236         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11237                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11238    (clobber (reg:CC FLAGS_REG))]
11239   "TARGET_PARTIAL_REG_STALL
11240    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11241 {
11242   switch (get_attr_type (insn))
11243     {
11244     case TYPE_ALU:
11245       gcc_assert (operands[2] == const1_rtx);
11246       return "add{w}\t{%0, %0|%0, %0}";
11247
11248     default:
11249       if (REG_P (operands[2]))
11250         return "sal{w}\t{%b2, %0|%0, %b2}";
11251       else if (operands[2] == const1_rtx
11252                && (TARGET_SHIFT1 || optimize_size))
11253         return "sal{w}\t%0";
11254       else
11255         return "sal{w}\t{%2, %0|%0, %2}";
11256     }
11257 }
11258   [(set (attr "type")
11259      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11260                           (const_int 0))
11261                       (match_operand 0 "register_operand" ""))
11262                  (match_operand 2 "const1_operand" ""))
11263               (const_string "alu")
11264            ]
11265            (const_string "ishift")))
11266    (set_attr "mode" "HI")])
11267
11268 ;; This pattern can't accept a variable shift count, since shifts by
11269 ;; zero don't affect the flags.  We assume that shifts by constant
11270 ;; zero are optimized away.
11271 (define_insn "*ashlhi3_cmp"
11272   [(set (reg FLAGS_REG)
11273         (compare
11274           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11275                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11276           (const_int 0)))
11277    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11278         (ashift:HI (match_dup 1) (match_dup 2)))]
11279   "ix86_match_ccmode (insn, CCGOCmode)
11280    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11281    && (optimize_size
11282        || !TARGET_PARTIAL_FLAG_REG_STALL
11283        || (operands[2] == const1_rtx
11284            && (TARGET_SHIFT1
11285                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11286 {
11287   switch (get_attr_type (insn))
11288     {
11289     case TYPE_ALU:
11290       gcc_assert (operands[2] == const1_rtx);
11291       return "add{w}\t{%0, %0|%0, %0}";
11292
11293     default:
11294       if (REG_P (operands[2]))
11295         return "sal{w}\t{%b2, %0|%0, %b2}";
11296       else if (operands[2] == const1_rtx
11297                && (TARGET_SHIFT1 || optimize_size))
11298         return "sal{w}\t%0";
11299       else
11300         return "sal{w}\t{%2, %0|%0, %2}";
11301     }
11302 }
11303   [(set (attr "type")
11304      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11305                           (const_int 0))
11306                       (match_operand 0 "register_operand" ""))
11307                  (match_operand 2 "const1_operand" ""))
11308               (const_string "alu")
11309            ]
11310            (const_string "ishift")))
11311    (set_attr "mode" "HI")])
11312
11313 (define_insn "*ashlhi3_cconly"
11314   [(set (reg FLAGS_REG)
11315         (compare
11316           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11317                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11318           (const_int 0)))
11319    (clobber (match_scratch:HI 0 "=r"))]
11320   "ix86_match_ccmode (insn, CCGOCmode)
11321    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11322    && (optimize_size
11323        || !TARGET_PARTIAL_FLAG_REG_STALL
11324        || (operands[2] == const1_rtx
11325            && (TARGET_SHIFT1
11326                || TARGET_DOUBLE_WITH_ADD)))"
11327 {
11328   switch (get_attr_type (insn))
11329     {
11330     case TYPE_ALU:
11331       gcc_assert (operands[2] == const1_rtx);
11332       return "add{w}\t{%0, %0|%0, %0}";
11333
11334     default:
11335       if (REG_P (operands[2]))
11336         return "sal{w}\t{%b2, %0|%0, %b2}";
11337       else if (operands[2] == const1_rtx
11338                && (TARGET_SHIFT1 || optimize_size))
11339         return "sal{w}\t%0";
11340       else
11341         return "sal{w}\t{%2, %0|%0, %2}";
11342     }
11343 }
11344   [(set (attr "type")
11345      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11346                           (const_int 0))
11347                       (match_operand 0 "register_operand" ""))
11348                  (match_operand 2 "const1_operand" ""))
11349               (const_string "alu")
11350            ]
11351            (const_string "ishift")))
11352    (set_attr "mode" "HI")])
11353
11354 (define_expand "ashlqi3"
11355   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11356         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11357                    (match_operand:QI 2 "nonmemory_operand" "")))
11358    (clobber (reg:CC FLAGS_REG))]
11359   "TARGET_QIMODE_MATH"
11360   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11361
11362 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11363
11364 (define_insn "*ashlqi3_1_lea"
11365   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11366         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11367                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11368    (clobber (reg:CC FLAGS_REG))]
11369   "!TARGET_PARTIAL_REG_STALL
11370    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11371 {
11372   switch (get_attr_type (insn))
11373     {
11374     case TYPE_LEA:
11375       return "#";
11376     case TYPE_ALU:
11377       gcc_assert (operands[2] == const1_rtx);
11378       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11379         return "add{l}\t{%k0, %k0|%k0, %k0}";
11380       else
11381         return "add{b}\t{%0, %0|%0, %0}";
11382
11383     default:
11384       if (REG_P (operands[2]))
11385         {
11386           if (get_attr_mode (insn) == MODE_SI)
11387             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11388           else
11389             return "sal{b}\t{%b2, %0|%0, %b2}";
11390         }
11391       else if (operands[2] == const1_rtx
11392                && (TARGET_SHIFT1 || optimize_size))
11393         {
11394           if (get_attr_mode (insn) == MODE_SI)
11395             return "sal{l}\t%0";
11396           else
11397             return "sal{b}\t%0";
11398         }
11399       else
11400         {
11401           if (get_attr_mode (insn) == MODE_SI)
11402             return "sal{l}\t{%2, %k0|%k0, %2}";
11403           else
11404             return "sal{b}\t{%2, %0|%0, %2}";
11405         }
11406     }
11407 }
11408   [(set (attr "type")
11409      (cond [(eq_attr "alternative" "2")
11410               (const_string "lea")
11411             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11412                           (const_int 0))
11413                       (match_operand 0 "register_operand" ""))
11414                  (match_operand 2 "const1_operand" ""))
11415               (const_string "alu")
11416            ]
11417            (const_string "ishift")))
11418    (set_attr "mode" "QI,SI,SI")])
11419
11420 (define_insn "*ashlqi3_1"
11421   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11422         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11423                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11424    (clobber (reg:CC FLAGS_REG))]
11425   "TARGET_PARTIAL_REG_STALL
11426    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11427 {
11428   switch (get_attr_type (insn))
11429     {
11430     case TYPE_ALU:
11431       gcc_assert (operands[2] == const1_rtx);
11432       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11433         return "add{l}\t{%k0, %k0|%k0, %k0}";
11434       else
11435         return "add{b}\t{%0, %0|%0, %0}";
11436
11437     default:
11438       if (REG_P (operands[2]))
11439         {
11440           if (get_attr_mode (insn) == MODE_SI)
11441             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11442           else
11443             return "sal{b}\t{%b2, %0|%0, %b2}";
11444         }
11445       else if (operands[2] == const1_rtx
11446                && (TARGET_SHIFT1 || optimize_size))
11447         {
11448           if (get_attr_mode (insn) == MODE_SI)
11449             return "sal{l}\t%0";
11450           else
11451             return "sal{b}\t%0";
11452         }
11453       else
11454         {
11455           if (get_attr_mode (insn) == MODE_SI)
11456             return "sal{l}\t{%2, %k0|%k0, %2}";
11457           else
11458             return "sal{b}\t{%2, %0|%0, %2}";
11459         }
11460     }
11461 }
11462   [(set (attr "type")
11463      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11464                           (const_int 0))
11465                       (match_operand 0 "register_operand" ""))
11466                  (match_operand 2 "const1_operand" ""))
11467               (const_string "alu")
11468            ]
11469            (const_string "ishift")))
11470    (set_attr "mode" "QI,SI")])
11471
11472 ;; This pattern can't accept a variable shift count, since shifts by
11473 ;; zero don't affect the flags.  We assume that shifts by constant
11474 ;; zero are optimized away.
11475 (define_insn "*ashlqi3_cmp"
11476   [(set (reg FLAGS_REG)
11477         (compare
11478           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11479                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11480           (const_int 0)))
11481    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11482         (ashift:QI (match_dup 1) (match_dup 2)))]
11483   "ix86_match_ccmode (insn, CCGOCmode)
11484    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11485    && (optimize_size
11486        || !TARGET_PARTIAL_FLAG_REG_STALL
11487        || (operands[2] == const1_rtx
11488            && (TARGET_SHIFT1
11489                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11490 {
11491   switch (get_attr_type (insn))
11492     {
11493     case TYPE_ALU:
11494       gcc_assert (operands[2] == const1_rtx);
11495       return "add{b}\t{%0, %0|%0, %0}";
11496
11497     default:
11498       if (REG_P (operands[2]))
11499         return "sal{b}\t{%b2, %0|%0, %b2}";
11500       else if (operands[2] == const1_rtx
11501                && (TARGET_SHIFT1 || optimize_size))
11502         return "sal{b}\t%0";
11503       else
11504         return "sal{b}\t{%2, %0|%0, %2}";
11505     }
11506 }
11507   [(set (attr "type")
11508      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11509                           (const_int 0))
11510                       (match_operand 0 "register_operand" ""))
11511                  (match_operand 2 "const1_operand" ""))
11512               (const_string "alu")
11513            ]
11514            (const_string "ishift")))
11515    (set_attr "mode" "QI")])
11516
11517 (define_insn "*ashlqi3_cconly"
11518   [(set (reg FLAGS_REG)
11519         (compare
11520           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11521                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11522           (const_int 0)))
11523    (clobber (match_scratch:QI 0 "=q"))]
11524   "ix86_match_ccmode (insn, CCGOCmode)
11525    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11526    && (optimize_size
11527        || !TARGET_PARTIAL_FLAG_REG_STALL
11528        || (operands[2] == const1_rtx
11529            && (TARGET_SHIFT1
11530                || TARGET_DOUBLE_WITH_ADD)))"
11531 {
11532   switch (get_attr_type (insn))
11533     {
11534     case TYPE_ALU:
11535       gcc_assert (operands[2] == const1_rtx);
11536       return "add{b}\t{%0, %0|%0, %0}";
11537
11538     default:
11539       if (REG_P (operands[2]))
11540         return "sal{b}\t{%b2, %0|%0, %b2}";
11541       else if (operands[2] == const1_rtx
11542                && (TARGET_SHIFT1 || optimize_size))
11543         return "sal{b}\t%0";
11544       else
11545         return "sal{b}\t{%2, %0|%0, %2}";
11546     }
11547 }
11548   [(set (attr "type")
11549      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11550                           (const_int 0))
11551                       (match_operand 0 "register_operand" ""))
11552                  (match_operand 2 "const1_operand" ""))
11553               (const_string "alu")
11554            ]
11555            (const_string "ishift")))
11556    (set_attr "mode" "QI")])
11557
11558 ;; See comment above `ashldi3' about how this works.
11559
11560 (define_expand "ashrti3"
11561   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11562                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11563                                 (match_operand:QI 2 "nonmemory_operand" "")))
11564               (clobber (reg:CC FLAGS_REG))])]
11565   "TARGET_64BIT"
11566 {
11567   if (! immediate_operand (operands[2], QImode))
11568     {
11569       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11570       DONE;
11571     }
11572   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11573   DONE;
11574 })
11575
11576 (define_insn "ashrti3_1"
11577   [(set (match_operand:TI 0 "register_operand" "=r")
11578         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11579                      (match_operand:QI 2 "register_operand" "c")))
11580    (clobber (match_scratch:DI 3 "=&r"))
11581    (clobber (reg:CC FLAGS_REG))]
11582   "TARGET_64BIT"
11583   "#"
11584   [(set_attr "type" "multi")])
11585
11586 (define_insn "*ashrti3_2"
11587   [(set (match_operand:TI 0 "register_operand" "=r")
11588         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11589                      (match_operand:QI 2 "immediate_operand" "O")))
11590    (clobber (reg:CC FLAGS_REG))]
11591   "TARGET_64BIT"
11592   "#"
11593   [(set_attr "type" "multi")])
11594
11595 (define_split
11596   [(set (match_operand:TI 0 "register_operand" "")
11597         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11598                      (match_operand:QI 2 "register_operand" "")))
11599    (clobber (match_scratch:DI 3 ""))
11600    (clobber (reg:CC FLAGS_REG))]
11601   "TARGET_64BIT && reload_completed"
11602   [(const_int 0)]
11603   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11604
11605 (define_split
11606   [(set (match_operand:TI 0 "register_operand" "")
11607         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11608                      (match_operand:QI 2 "immediate_operand" "")))
11609    (clobber (reg:CC FLAGS_REG))]
11610   "TARGET_64BIT && reload_completed"
11611   [(const_int 0)]
11612   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11613
11614 (define_insn "x86_64_shrd"
11615   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11616         (ior:DI (ashiftrt:DI (match_dup 0)
11617                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11618                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11619                   (minus:QI (const_int 64) (match_dup 2)))))
11620    (clobber (reg:CC FLAGS_REG))]
11621   "TARGET_64BIT"
11622   "@
11623    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11624    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11625   [(set_attr "type" "ishift")
11626    (set_attr "prefix_0f" "1")
11627    (set_attr "mode" "DI")
11628    (set_attr "athlon_decode" "vector")
11629    (set_attr "amdfam10_decode" "vector")])   
11630
11631 (define_expand "ashrdi3"
11632   [(set (match_operand:DI 0 "shiftdi_operand" "")
11633         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11634                      (match_operand:QI 2 "nonmemory_operand" "")))]
11635   ""
11636   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11637
11638 (define_insn "*ashrdi3_63_rex64"
11639   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11640         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11641                      (match_operand:DI 2 "const_int_operand" "i,i")))
11642    (clobber (reg:CC FLAGS_REG))]
11643   "TARGET_64BIT && INTVAL (operands[2]) == 63
11644    && (TARGET_USE_CLTD || optimize_size)
11645    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11646   "@
11647    {cqto|cqo}
11648    sar{q}\t{%2, %0|%0, %2}"
11649   [(set_attr "type" "imovx,ishift")
11650    (set_attr "prefix_0f" "0,*")
11651    (set_attr "length_immediate" "0,*")
11652    (set_attr "modrm" "0,1")
11653    (set_attr "mode" "DI")])
11654
11655 (define_insn "*ashrdi3_1_one_bit_rex64"
11656   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11657         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11658                      (match_operand:QI 2 "const1_operand" "")))
11659    (clobber (reg:CC FLAGS_REG))]
11660   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11661    && (TARGET_SHIFT1 || optimize_size)"
11662   "sar{q}\t%0"
11663   [(set_attr "type" "ishift")
11664    (set (attr "length")
11665      (if_then_else (match_operand:DI 0 "register_operand" "")
11666         (const_string "2")
11667         (const_string "*")))])
11668
11669 (define_insn "*ashrdi3_1_rex64"
11670   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11671         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11672                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11673    (clobber (reg:CC FLAGS_REG))]
11674   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11675   "@
11676    sar{q}\t{%2, %0|%0, %2}
11677    sar{q}\t{%b2, %0|%0, %b2}"
11678   [(set_attr "type" "ishift")
11679    (set_attr "mode" "DI")])
11680
11681 ;; This pattern can't accept a variable shift count, since shifts by
11682 ;; zero don't affect the flags.  We assume that shifts by constant
11683 ;; zero are optimized away.
11684 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11685   [(set (reg FLAGS_REG)
11686         (compare
11687           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11688                        (match_operand:QI 2 "const1_operand" ""))
11689           (const_int 0)))
11690    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11691         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11692   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11693    && (TARGET_SHIFT1 || optimize_size)
11694    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11695   "sar{q}\t%0"
11696   [(set_attr "type" "ishift")
11697    (set (attr "length")
11698      (if_then_else (match_operand:DI 0 "register_operand" "")
11699         (const_string "2")
11700         (const_string "*")))])
11701
11702 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11703   [(set (reg FLAGS_REG)
11704         (compare
11705           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11706                        (match_operand:QI 2 "const1_operand" ""))
11707           (const_int 0)))
11708    (clobber (match_scratch:DI 0 "=r"))]
11709   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11710    && (TARGET_SHIFT1 || optimize_size)
11711    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11712   "sar{q}\t%0"
11713   [(set_attr "type" "ishift")
11714    (set_attr "length" "2")])
11715
11716 ;; This pattern can't accept a variable shift count, since shifts by
11717 ;; zero don't affect the flags.  We assume that shifts by constant
11718 ;; zero are optimized away.
11719 (define_insn "*ashrdi3_cmp_rex64"
11720   [(set (reg FLAGS_REG)
11721         (compare
11722           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11723                        (match_operand:QI 2 "const_int_operand" "n"))
11724           (const_int 0)))
11725    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11726         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11727   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11728    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11729    && (optimize_size
11730        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11731   "sar{q}\t{%2, %0|%0, %2}"
11732   [(set_attr "type" "ishift")
11733    (set_attr "mode" "DI")])
11734
11735 (define_insn "*ashrdi3_cconly_rex64"
11736   [(set (reg FLAGS_REG)
11737         (compare
11738           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11739                        (match_operand:QI 2 "const_int_operand" "n"))
11740           (const_int 0)))
11741    (clobber (match_scratch:DI 0 "=r"))]
11742   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11743    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11744    && (optimize_size
11745        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11746   "sar{q}\t{%2, %0|%0, %2}"
11747   [(set_attr "type" "ishift")
11748    (set_attr "mode" "DI")])
11749
11750 (define_insn "*ashrdi3_1"
11751   [(set (match_operand:DI 0 "register_operand" "=r")
11752         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11753                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11754    (clobber (reg:CC FLAGS_REG))]
11755   "!TARGET_64BIT"
11756   "#"
11757   [(set_attr "type" "multi")])
11758
11759 ;; By default we don't ask for a scratch register, because when DImode
11760 ;; values are manipulated, registers are already at a premium.  But if
11761 ;; we have one handy, we won't turn it away.
11762 (define_peephole2
11763   [(match_scratch:SI 3 "r")
11764    (parallel [(set (match_operand:DI 0 "register_operand" "")
11765                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11766                                 (match_operand:QI 2 "nonmemory_operand" "")))
11767               (clobber (reg:CC FLAGS_REG))])
11768    (match_dup 3)]
11769   "!TARGET_64BIT && TARGET_CMOVE"
11770   [(const_int 0)]
11771   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11772
11773 (define_split
11774   [(set (match_operand:DI 0 "register_operand" "")
11775         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11776                      (match_operand:QI 2 "nonmemory_operand" "")))
11777    (clobber (reg:CC FLAGS_REG))]
11778   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11779                      ? flow2_completed : reload_completed)"
11780   [(const_int 0)]
11781   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11782
11783 (define_insn "x86_shrd_1"
11784   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11785         (ior:SI (ashiftrt:SI (match_dup 0)
11786                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11787                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11788                   (minus:QI (const_int 32) (match_dup 2)))))
11789    (clobber (reg:CC FLAGS_REG))]
11790   ""
11791   "@
11792    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11793    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11794   [(set_attr "type" "ishift")
11795    (set_attr "prefix_0f" "1")
11796    (set_attr "pent_pair" "np")
11797    (set_attr "mode" "SI")])
11798
11799 (define_expand "x86_shift_adj_3"
11800   [(use (match_operand:SI 0 "register_operand" ""))
11801    (use (match_operand:SI 1 "register_operand" ""))
11802    (use (match_operand:QI 2 "register_operand" ""))]
11803   ""
11804 {
11805   rtx label = gen_label_rtx ();
11806   rtx tmp;
11807
11808   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11809
11810   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11811   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11812   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11813                               gen_rtx_LABEL_REF (VOIDmode, label),
11814                               pc_rtx);
11815   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11816   JUMP_LABEL (tmp) = label;
11817
11818   emit_move_insn (operands[0], operands[1]);
11819   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11820
11821   emit_label (label);
11822   LABEL_NUSES (label) = 1;
11823
11824   DONE;
11825 })
11826
11827 (define_insn "ashrsi3_31"
11828   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11829         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11830                      (match_operand:SI 2 "const_int_operand" "i,i")))
11831    (clobber (reg:CC FLAGS_REG))]
11832   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11833    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11834   "@
11835    {cltd|cdq}
11836    sar{l}\t{%2, %0|%0, %2}"
11837   [(set_attr "type" "imovx,ishift")
11838    (set_attr "prefix_0f" "0,*")
11839    (set_attr "length_immediate" "0,*")
11840    (set_attr "modrm" "0,1")
11841    (set_attr "mode" "SI")])
11842
11843 (define_insn "*ashrsi3_31_zext"
11844   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11845         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11846                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11847    (clobber (reg:CC FLAGS_REG))]
11848   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11849    && INTVAL (operands[2]) == 31
11850    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11851   "@
11852    {cltd|cdq}
11853    sar{l}\t{%2, %k0|%k0, %2}"
11854   [(set_attr "type" "imovx,ishift")
11855    (set_attr "prefix_0f" "0,*")
11856    (set_attr "length_immediate" "0,*")
11857    (set_attr "modrm" "0,1")
11858    (set_attr "mode" "SI")])
11859
11860 (define_expand "ashrsi3"
11861   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11862         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11863                      (match_operand:QI 2 "nonmemory_operand" "")))
11864    (clobber (reg:CC FLAGS_REG))]
11865   ""
11866   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11867
11868 (define_insn "*ashrsi3_1_one_bit"
11869   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11870         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11871                      (match_operand:QI 2 "const1_operand" "")))
11872    (clobber (reg:CC FLAGS_REG))]
11873   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11874    && (TARGET_SHIFT1 || optimize_size)"
11875   "sar{l}\t%0"
11876   [(set_attr "type" "ishift")
11877    (set (attr "length")
11878      (if_then_else (match_operand:SI 0 "register_operand" "")
11879         (const_string "2")
11880         (const_string "*")))])
11881
11882 (define_insn "*ashrsi3_1_one_bit_zext"
11883   [(set (match_operand:DI 0 "register_operand" "=r")
11884         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11885                                      (match_operand:QI 2 "const1_operand" ""))))
11886    (clobber (reg:CC FLAGS_REG))]
11887   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11888    && (TARGET_SHIFT1 || optimize_size)"
11889   "sar{l}\t%k0"
11890   [(set_attr "type" "ishift")
11891    (set_attr "length" "2")])
11892
11893 (define_insn "*ashrsi3_1"
11894   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11895         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11896                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11897    (clobber (reg:CC FLAGS_REG))]
11898   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11899   "@
11900    sar{l}\t{%2, %0|%0, %2}
11901    sar{l}\t{%b2, %0|%0, %b2}"
11902   [(set_attr "type" "ishift")
11903    (set_attr "mode" "SI")])
11904
11905 (define_insn "*ashrsi3_1_zext"
11906   [(set (match_operand:DI 0 "register_operand" "=r,r")
11907         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11908                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11909    (clobber (reg:CC FLAGS_REG))]
11910   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11911   "@
11912    sar{l}\t{%2, %k0|%k0, %2}
11913    sar{l}\t{%b2, %k0|%k0, %b2}"
11914   [(set_attr "type" "ishift")
11915    (set_attr "mode" "SI")])
11916
11917 ;; This pattern can't accept a variable shift count, since shifts by
11918 ;; zero don't affect the flags.  We assume that shifts by constant
11919 ;; zero are optimized away.
11920 (define_insn "*ashrsi3_one_bit_cmp"
11921   [(set (reg FLAGS_REG)
11922         (compare
11923           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11924                        (match_operand:QI 2 "const1_operand" ""))
11925           (const_int 0)))
11926    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11927         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11928   "ix86_match_ccmode (insn, CCGOCmode)
11929    && (TARGET_SHIFT1 || optimize_size)
11930    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11931   "sar{l}\t%0"
11932   [(set_attr "type" "ishift")
11933    (set (attr "length")
11934      (if_then_else (match_operand:SI 0 "register_operand" "")
11935         (const_string "2")
11936         (const_string "*")))])
11937
11938 (define_insn "*ashrsi3_one_bit_cconly"
11939   [(set (reg FLAGS_REG)
11940         (compare
11941           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11942                        (match_operand:QI 2 "const1_operand" ""))
11943           (const_int 0)))
11944    (clobber (match_scratch:SI 0 "=r"))]
11945   "ix86_match_ccmode (insn, CCGOCmode)
11946    && (TARGET_SHIFT1 || optimize_size)
11947    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11948   "sar{l}\t%0"
11949   [(set_attr "type" "ishift")
11950    (set_attr "length" "2")])
11951
11952 (define_insn "*ashrsi3_one_bit_cmp_zext"
11953   [(set (reg FLAGS_REG)
11954         (compare
11955           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11956                        (match_operand:QI 2 "const1_operand" ""))
11957           (const_int 0)))
11958    (set (match_operand:DI 0 "register_operand" "=r")
11959         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11960   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11961    && (TARGET_SHIFT1 || optimize_size)
11962    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11963   "sar{l}\t%k0"
11964   [(set_attr "type" "ishift")
11965    (set_attr "length" "2")])
11966
11967 ;; This pattern can't accept a variable shift count, since shifts by
11968 ;; zero don't affect the flags.  We assume that shifts by constant
11969 ;; zero are optimized away.
11970 (define_insn "*ashrsi3_cmp"
11971   [(set (reg FLAGS_REG)
11972         (compare
11973           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11974                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11975           (const_int 0)))
11976    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11977         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11978   "ix86_match_ccmode (insn, CCGOCmode)
11979    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11980    && (optimize_size
11981        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11982   "sar{l}\t{%2, %0|%0, %2}"
11983   [(set_attr "type" "ishift")
11984    (set_attr "mode" "SI")])
11985
11986 (define_insn "*ashrsi3_cconly"
11987   [(set (reg FLAGS_REG)
11988         (compare
11989           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11990                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11991           (const_int 0)))
11992    (clobber (match_scratch:SI 0 "=r"))]
11993   "ix86_match_ccmode (insn, CCGOCmode)
11994    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11995    && (optimize_size
11996        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11997   "sar{l}\t{%2, %0|%0, %2}"
11998   [(set_attr "type" "ishift")
11999    (set_attr "mode" "SI")])
12000
12001 (define_insn "*ashrsi3_cmp_zext"
12002   [(set (reg FLAGS_REG)
12003         (compare
12004           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12005                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12006           (const_int 0)))
12007    (set (match_operand:DI 0 "register_operand" "=r")
12008         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12009   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12010    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12011    && (optimize_size
12012        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12013   "sar{l}\t{%2, %k0|%k0, %2}"
12014   [(set_attr "type" "ishift")
12015    (set_attr "mode" "SI")])
12016
12017 (define_expand "ashrhi3"
12018   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12019         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12020                      (match_operand:QI 2 "nonmemory_operand" "")))
12021    (clobber (reg:CC FLAGS_REG))]
12022   "TARGET_HIMODE_MATH"
12023   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12024
12025 (define_insn "*ashrhi3_1_one_bit"
12026   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12027         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12028                      (match_operand:QI 2 "const1_operand" "")))
12029    (clobber (reg:CC FLAGS_REG))]
12030   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12031    && (TARGET_SHIFT1 || optimize_size)"
12032   "sar{w}\t%0"
12033   [(set_attr "type" "ishift")
12034    (set (attr "length")
12035      (if_then_else (match_operand 0 "register_operand" "")
12036         (const_string "2")
12037         (const_string "*")))])
12038
12039 (define_insn "*ashrhi3_1"
12040   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12041         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12042                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12043    (clobber (reg:CC FLAGS_REG))]
12044   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12045   "@
12046    sar{w}\t{%2, %0|%0, %2}
12047    sar{w}\t{%b2, %0|%0, %b2}"
12048   [(set_attr "type" "ishift")
12049    (set_attr "mode" "HI")])
12050
12051 ;; This pattern can't accept a variable shift count, since shifts by
12052 ;; zero don't affect the flags.  We assume that shifts by constant
12053 ;; zero are optimized away.
12054 (define_insn "*ashrhi3_one_bit_cmp"
12055   [(set (reg FLAGS_REG)
12056         (compare
12057           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12058                        (match_operand:QI 2 "const1_operand" ""))
12059           (const_int 0)))
12060    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12061         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12062   "ix86_match_ccmode (insn, CCGOCmode)
12063    && (TARGET_SHIFT1 || optimize_size)
12064    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12065   "sar{w}\t%0"
12066   [(set_attr "type" "ishift")
12067    (set (attr "length")
12068      (if_then_else (match_operand 0 "register_operand" "")
12069         (const_string "2")
12070         (const_string "*")))])
12071
12072 (define_insn "*ashrhi3_one_bit_cconly"
12073   [(set (reg FLAGS_REG)
12074         (compare
12075           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12076                        (match_operand:QI 2 "const1_operand" ""))
12077           (const_int 0)))
12078    (clobber (match_scratch:HI 0 "=r"))]
12079   "ix86_match_ccmode (insn, CCGOCmode)
12080    && (TARGET_SHIFT1 || optimize_size)
12081    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12082   "sar{w}\t%0"
12083   [(set_attr "type" "ishift")
12084    (set_attr "length" "2")])
12085
12086 ;; This pattern can't accept a variable shift count, since shifts by
12087 ;; zero don't affect the flags.  We assume that shifts by constant
12088 ;; zero are optimized away.
12089 (define_insn "*ashrhi3_cmp"
12090   [(set (reg FLAGS_REG)
12091         (compare
12092           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12093                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12094           (const_int 0)))
12095    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12096         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12097   "ix86_match_ccmode (insn, CCGOCmode)
12098    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12099    && (optimize_size
12100        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12101   "sar{w}\t{%2, %0|%0, %2}"
12102   [(set_attr "type" "ishift")
12103    (set_attr "mode" "HI")])
12104
12105 (define_insn "*ashrhi3_cconly"
12106   [(set (reg FLAGS_REG)
12107         (compare
12108           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12109                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12110           (const_int 0)))
12111    (clobber (match_scratch:HI 0 "=r"))]
12112   "ix86_match_ccmode (insn, CCGOCmode)
12113    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12114    && (optimize_size
12115        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12116   "sar{w}\t{%2, %0|%0, %2}"
12117   [(set_attr "type" "ishift")
12118    (set_attr "mode" "HI")])
12119
12120 (define_expand "ashrqi3"
12121   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12122         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12123                      (match_operand:QI 2 "nonmemory_operand" "")))
12124    (clobber (reg:CC FLAGS_REG))]
12125   "TARGET_QIMODE_MATH"
12126   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12127
12128 (define_insn "*ashrqi3_1_one_bit"
12129   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12130         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12131                      (match_operand:QI 2 "const1_operand" "")))
12132    (clobber (reg:CC FLAGS_REG))]
12133   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12134    && (TARGET_SHIFT1 || optimize_size)"
12135   "sar{b}\t%0"
12136   [(set_attr "type" "ishift")
12137    (set (attr "length")
12138      (if_then_else (match_operand 0 "register_operand" "")
12139         (const_string "2")
12140         (const_string "*")))])
12141
12142 (define_insn "*ashrqi3_1_one_bit_slp"
12143   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12144         (ashiftrt:QI (match_dup 0)
12145                      (match_operand:QI 1 "const1_operand" "")))
12146    (clobber (reg:CC FLAGS_REG))]
12147   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12148    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12149    && (TARGET_SHIFT1 || optimize_size)"
12150   "sar{b}\t%0"
12151   [(set_attr "type" "ishift1")
12152    (set (attr "length")
12153      (if_then_else (match_operand 0 "register_operand" "")
12154         (const_string "2")
12155         (const_string "*")))])
12156
12157 (define_insn "*ashrqi3_1"
12158   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12159         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12160                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12161    (clobber (reg:CC FLAGS_REG))]
12162   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12163   "@
12164    sar{b}\t{%2, %0|%0, %2}
12165    sar{b}\t{%b2, %0|%0, %b2}"
12166   [(set_attr "type" "ishift")
12167    (set_attr "mode" "QI")])
12168
12169 (define_insn "*ashrqi3_1_slp"
12170   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12171         (ashiftrt:QI (match_dup 0)
12172                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12173    (clobber (reg:CC FLAGS_REG))]
12174   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12175    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12176   "@
12177    sar{b}\t{%1, %0|%0, %1}
12178    sar{b}\t{%b1, %0|%0, %b1}"
12179   [(set_attr "type" "ishift1")
12180    (set_attr "mode" "QI")])
12181
12182 ;; This pattern can't accept a variable shift count, since shifts by
12183 ;; zero don't affect the flags.  We assume that shifts by constant
12184 ;; zero are optimized away.
12185 (define_insn "*ashrqi3_one_bit_cmp"
12186   [(set (reg FLAGS_REG)
12187         (compare
12188           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12189                        (match_operand:QI 2 "const1_operand" "I"))
12190           (const_int 0)))
12191    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12192         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12193   "ix86_match_ccmode (insn, CCGOCmode)
12194    && (TARGET_SHIFT1 || optimize_size)
12195    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12196   "sar{b}\t%0"
12197   [(set_attr "type" "ishift")
12198    (set (attr "length")
12199      (if_then_else (match_operand 0 "register_operand" "")
12200         (const_string "2")
12201         (const_string "*")))])
12202
12203 (define_insn "*ashrqi3_one_bit_cconly"
12204   [(set (reg FLAGS_REG)
12205         (compare
12206           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12207                        (match_operand:QI 2 "const1_operand" "I"))
12208           (const_int 0)))
12209    (clobber (match_scratch:QI 0 "=q"))]
12210   "ix86_match_ccmode (insn, CCGOCmode)
12211    && (TARGET_SHIFT1 || optimize_size)
12212    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12213   "sar{b}\t%0"
12214   [(set_attr "type" "ishift")
12215    (set_attr "length" "2")])
12216
12217 ;; This pattern can't accept a variable shift count, since shifts by
12218 ;; zero don't affect the flags.  We assume that shifts by constant
12219 ;; zero are optimized away.
12220 (define_insn "*ashrqi3_cmp"
12221   [(set (reg FLAGS_REG)
12222         (compare
12223           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12224                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12225           (const_int 0)))
12226    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12227         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12228   "ix86_match_ccmode (insn, CCGOCmode)
12229    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12230    && (optimize_size
12231        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12232   "sar{b}\t{%2, %0|%0, %2}"
12233   [(set_attr "type" "ishift")
12234    (set_attr "mode" "QI")])
12235
12236 (define_insn "*ashrqi3_cconly"
12237   [(set (reg FLAGS_REG)
12238         (compare
12239           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12240                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12241           (const_int 0)))
12242    (clobber (match_scratch:QI 0 "=q"))]
12243   "ix86_match_ccmode (insn, CCGOCmode)
12244    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12245    && (optimize_size
12246        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12247   "sar{b}\t{%2, %0|%0, %2}"
12248   [(set_attr "type" "ishift")
12249    (set_attr "mode" "QI")])
12250
12251 \f
12252 ;; Logical shift instructions
12253
12254 ;; See comment above `ashldi3' about how this works.
12255
12256 (define_expand "lshrti3"
12257   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12258                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12259                                 (match_operand:QI 2 "nonmemory_operand" "")))
12260               (clobber (reg:CC FLAGS_REG))])]
12261   "TARGET_64BIT"
12262 {
12263   if (! immediate_operand (operands[2], QImode))
12264     {
12265       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12266       DONE;
12267     }
12268   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12269   DONE;
12270 })
12271
12272 (define_insn "lshrti3_1"
12273   [(set (match_operand:TI 0 "register_operand" "=r")
12274         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12275                      (match_operand:QI 2 "register_operand" "c")))
12276    (clobber (match_scratch:DI 3 "=&r"))
12277    (clobber (reg:CC FLAGS_REG))]
12278   "TARGET_64BIT"
12279   "#"
12280   [(set_attr "type" "multi")])
12281
12282 (define_insn "*lshrti3_2"
12283   [(set (match_operand:TI 0 "register_operand" "=r")
12284         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12285                      (match_operand:QI 2 "immediate_operand" "O")))
12286    (clobber (reg:CC FLAGS_REG))]
12287   "TARGET_64BIT"
12288   "#"
12289   [(set_attr "type" "multi")])
12290
12291 (define_split
12292   [(set (match_operand:TI 0 "register_operand" "")
12293         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12294                      (match_operand:QI 2 "register_operand" "")))
12295    (clobber (match_scratch:DI 3 ""))
12296    (clobber (reg:CC FLAGS_REG))]
12297   "TARGET_64BIT && reload_completed"
12298   [(const_int 0)]
12299   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12300
12301 (define_split
12302   [(set (match_operand:TI 0 "register_operand" "")
12303         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12304                      (match_operand:QI 2 "immediate_operand" "")))
12305    (clobber (reg:CC FLAGS_REG))]
12306   "TARGET_64BIT && reload_completed"
12307   [(const_int 0)]
12308   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12309
12310 (define_expand "lshrdi3"
12311   [(set (match_operand:DI 0 "shiftdi_operand" "")
12312         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12313                      (match_operand:QI 2 "nonmemory_operand" "")))]
12314   ""
12315   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12316
12317 (define_insn "*lshrdi3_1_one_bit_rex64"
12318   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12319         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12320                      (match_operand:QI 2 "const1_operand" "")))
12321    (clobber (reg:CC FLAGS_REG))]
12322   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12323    && (TARGET_SHIFT1 || optimize_size)"
12324   "shr{q}\t%0"
12325   [(set_attr "type" "ishift")
12326    (set (attr "length")
12327      (if_then_else (match_operand:DI 0 "register_operand" "")
12328         (const_string "2")
12329         (const_string "*")))])
12330
12331 (define_insn "*lshrdi3_1_rex64"
12332   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12333         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12334                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12335    (clobber (reg:CC FLAGS_REG))]
12336   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12337   "@
12338    shr{q}\t{%2, %0|%0, %2}
12339    shr{q}\t{%b2, %0|%0, %b2}"
12340   [(set_attr "type" "ishift")
12341    (set_attr "mode" "DI")])
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 "*lshrdi3_cmp_one_bit_rex64"
12347   [(set (reg FLAGS_REG)
12348         (compare
12349           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12350                        (match_operand:QI 2 "const1_operand" ""))
12351           (const_int 0)))
12352    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12353         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12354   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12355    && (TARGET_SHIFT1 || optimize_size)
12356    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12357   "shr{q}\t%0"
12358   [(set_attr "type" "ishift")
12359    (set (attr "length")
12360      (if_then_else (match_operand:DI 0 "register_operand" "")
12361         (const_string "2")
12362         (const_string "*")))])
12363
12364 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12365   [(set (reg FLAGS_REG)
12366         (compare
12367           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12368                        (match_operand:QI 2 "const1_operand" ""))
12369           (const_int 0)))
12370    (clobber (match_scratch:DI 0 "=r"))]
12371   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12372    && (TARGET_SHIFT1 || optimize_size)
12373    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12374   "shr{q}\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 "*lshrdi3_cmp_rex64"
12382   [(set (reg FLAGS_REG)
12383         (compare
12384           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12385                        (match_operand:QI 2 "const_int_operand" "e"))
12386           (const_int 0)))
12387    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12388         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12389   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12390    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12391    && (optimize_size
12392        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12393   "shr{q}\t{%2, %0|%0, %2}"
12394   [(set_attr "type" "ishift")
12395    (set_attr "mode" "DI")])
12396
12397 (define_insn "*lshrdi3_cconly_rex64"
12398   [(set (reg FLAGS_REG)
12399         (compare
12400           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12401                        (match_operand:QI 2 "const_int_operand" "e"))
12402           (const_int 0)))
12403    (clobber (match_scratch:DI 0 "=r"))]
12404   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12405    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12406    && (optimize_size
12407        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12408   "shr{q}\t{%2, %0|%0, %2}"
12409   [(set_attr "type" "ishift")
12410    (set_attr "mode" "DI")])
12411
12412 (define_insn "*lshrdi3_1"
12413   [(set (match_operand:DI 0 "register_operand" "=r")
12414         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12415                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12416    (clobber (reg:CC FLAGS_REG))]
12417   "!TARGET_64BIT"
12418   "#"
12419   [(set_attr "type" "multi")])
12420
12421 ;; By default we don't ask for a scratch register, because when DImode
12422 ;; values are manipulated, registers are already at a premium.  But if
12423 ;; we have one handy, we won't turn it away.
12424 (define_peephole2
12425   [(match_scratch:SI 3 "r")
12426    (parallel [(set (match_operand:DI 0 "register_operand" "")
12427                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12428                                 (match_operand:QI 2 "nonmemory_operand" "")))
12429               (clobber (reg:CC FLAGS_REG))])
12430    (match_dup 3)]
12431   "!TARGET_64BIT && TARGET_CMOVE"
12432   [(const_int 0)]
12433   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12434
12435 (define_split
12436   [(set (match_operand:DI 0 "register_operand" "")
12437         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12438                      (match_operand:QI 2 "nonmemory_operand" "")))
12439    (clobber (reg:CC FLAGS_REG))]
12440   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12441                      ? flow2_completed : reload_completed)"
12442   [(const_int 0)]
12443   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12444
12445 (define_expand "lshrsi3"
12446   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12447         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12448                      (match_operand:QI 2 "nonmemory_operand" "")))
12449    (clobber (reg:CC FLAGS_REG))]
12450   ""
12451   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12452
12453 (define_insn "*lshrsi3_1_one_bit"
12454   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12455         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12456                      (match_operand:QI 2 "const1_operand" "")))
12457    (clobber (reg:CC FLAGS_REG))]
12458   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12459    && (TARGET_SHIFT1 || optimize_size)"
12460   "shr{l}\t%0"
12461   [(set_attr "type" "ishift")
12462    (set (attr "length")
12463      (if_then_else (match_operand:SI 0 "register_operand" "")
12464         (const_string "2")
12465         (const_string "*")))])
12466
12467 (define_insn "*lshrsi3_1_one_bit_zext"
12468   [(set (match_operand:DI 0 "register_operand" "=r")
12469         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12470                      (match_operand:QI 2 "const1_operand" "")))
12471    (clobber (reg:CC FLAGS_REG))]
12472   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12473    && (TARGET_SHIFT1 || optimize_size)"
12474   "shr{l}\t%k0"
12475   [(set_attr "type" "ishift")
12476    (set_attr "length" "2")])
12477
12478 (define_insn "*lshrsi3_1"
12479   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12480         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12481                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12482    (clobber (reg:CC FLAGS_REG))]
12483   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12484   "@
12485    shr{l}\t{%2, %0|%0, %2}
12486    shr{l}\t{%b2, %0|%0, %b2}"
12487   [(set_attr "type" "ishift")
12488    (set_attr "mode" "SI")])
12489
12490 (define_insn "*lshrsi3_1_zext"
12491   [(set (match_operand:DI 0 "register_operand" "=r,r")
12492         (zero_extend:DI
12493           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12494                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12495    (clobber (reg:CC FLAGS_REG))]
12496   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12497   "@
12498    shr{l}\t{%2, %k0|%k0, %2}
12499    shr{l}\t{%b2, %k0|%k0, %b2}"
12500   [(set_attr "type" "ishift")
12501    (set_attr "mode" "SI")])
12502
12503 ;; This pattern can't accept a variable shift count, since shifts by
12504 ;; zero don't affect the flags.  We assume that shifts by constant
12505 ;; zero are optimized away.
12506 (define_insn "*lshrsi3_one_bit_cmp"
12507   [(set (reg FLAGS_REG)
12508         (compare
12509           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12510                        (match_operand:QI 2 "const1_operand" ""))
12511           (const_int 0)))
12512    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12513         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12514   "ix86_match_ccmode (insn, CCGOCmode)
12515    && (TARGET_SHIFT1 || optimize_size)
12516    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12517   "shr{l}\t%0"
12518   [(set_attr "type" "ishift")
12519    (set (attr "length")
12520      (if_then_else (match_operand:SI 0 "register_operand" "")
12521         (const_string "2")
12522         (const_string "*")))])
12523
12524 (define_insn "*lshrsi3_one_bit_cconly"
12525   [(set (reg FLAGS_REG)
12526         (compare
12527           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12528                        (match_operand:QI 2 "const1_operand" ""))
12529           (const_int 0)))
12530    (clobber (match_scratch:SI 0 "=r"))]
12531   "ix86_match_ccmode (insn, CCGOCmode)
12532    && (TARGET_SHIFT1 || optimize_size)
12533    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12534   "shr{l}\t%0"
12535   [(set_attr "type" "ishift")
12536    (set_attr "length" "2")])
12537
12538 (define_insn "*lshrsi3_cmp_one_bit_zext"
12539   [(set (reg FLAGS_REG)
12540         (compare
12541           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12542                        (match_operand:QI 2 "const1_operand" ""))
12543           (const_int 0)))
12544    (set (match_operand:DI 0 "register_operand" "=r")
12545         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12546   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12547    && (TARGET_SHIFT1 || optimize_size)
12548    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12549   "shr{l}\t%k0"
12550   [(set_attr "type" "ishift")
12551    (set_attr "length" "2")])
12552
12553 ;; This pattern can't accept a variable shift count, since shifts by
12554 ;; zero don't affect the flags.  We assume that shifts by constant
12555 ;; zero are optimized away.
12556 (define_insn "*lshrsi3_cmp"
12557   [(set (reg FLAGS_REG)
12558         (compare
12559           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12560                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12561           (const_int 0)))
12562    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12563         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12564   "ix86_match_ccmode (insn, CCGOCmode)
12565    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12566    && (optimize_size
12567        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12568   "shr{l}\t{%2, %0|%0, %2}"
12569   [(set_attr "type" "ishift")
12570    (set_attr "mode" "SI")])
12571
12572 (define_insn "*lshrsi3_cconly"
12573   [(set (reg FLAGS_REG)
12574       (compare
12575         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12576                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12577         (const_int 0)))
12578    (clobber (match_scratch:SI 0 "=r"))]
12579   "ix86_match_ccmode (insn, CCGOCmode)
12580    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12581    && (optimize_size
12582        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12583   "shr{l}\t{%2, %0|%0, %2}"
12584   [(set_attr "type" "ishift")
12585    (set_attr "mode" "SI")])
12586
12587 (define_insn "*lshrsi3_cmp_zext"
12588   [(set (reg FLAGS_REG)
12589         (compare
12590           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12591                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12592           (const_int 0)))
12593    (set (match_operand:DI 0 "register_operand" "=r")
12594         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12595   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12596    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12597    && (optimize_size
12598        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12599   "shr{l}\t{%2, %k0|%k0, %2}"
12600   [(set_attr "type" "ishift")
12601    (set_attr "mode" "SI")])
12602
12603 (define_expand "lshrhi3"
12604   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12605         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12606                      (match_operand:QI 2 "nonmemory_operand" "")))
12607    (clobber (reg:CC FLAGS_REG))]
12608   "TARGET_HIMODE_MATH"
12609   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12610
12611 (define_insn "*lshrhi3_1_one_bit"
12612   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12613         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12614                      (match_operand:QI 2 "const1_operand" "")))
12615    (clobber (reg:CC FLAGS_REG))]
12616   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12617    && (TARGET_SHIFT1 || optimize_size)"
12618   "shr{w}\t%0"
12619   [(set_attr "type" "ishift")
12620    (set (attr "length")
12621      (if_then_else (match_operand 0 "register_operand" "")
12622         (const_string "2")
12623         (const_string "*")))])
12624
12625 (define_insn "*lshrhi3_1"
12626   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12627         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12628                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12629    (clobber (reg:CC FLAGS_REG))]
12630   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12631   "@
12632    shr{w}\t{%2, %0|%0, %2}
12633    shr{w}\t{%b2, %0|%0, %b2}"
12634   [(set_attr "type" "ishift")
12635    (set_attr "mode" "HI")])
12636
12637 ;; This pattern can't accept a variable shift count, since shifts by
12638 ;; zero don't affect the flags.  We assume that shifts by constant
12639 ;; zero are optimized away.
12640 (define_insn "*lshrhi3_one_bit_cmp"
12641   [(set (reg FLAGS_REG)
12642         (compare
12643           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12644                        (match_operand:QI 2 "const1_operand" ""))
12645           (const_int 0)))
12646    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12647         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12648   "ix86_match_ccmode (insn, CCGOCmode)
12649    && (TARGET_SHIFT1 || optimize_size)
12650    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12651   "shr{w}\t%0"
12652   [(set_attr "type" "ishift")
12653    (set (attr "length")
12654      (if_then_else (match_operand:SI 0 "register_operand" "")
12655         (const_string "2")
12656         (const_string "*")))])
12657
12658 (define_insn "*lshrhi3_one_bit_cconly"
12659   [(set (reg FLAGS_REG)
12660         (compare
12661           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12662                        (match_operand:QI 2 "const1_operand" ""))
12663           (const_int 0)))
12664    (clobber (match_scratch:HI 0 "=r"))]
12665   "ix86_match_ccmode (insn, CCGOCmode)
12666    && (TARGET_SHIFT1 || optimize_size)
12667    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12668   "shr{w}\t%0"
12669   [(set_attr "type" "ishift")
12670    (set_attr "length" "2")])
12671
12672 ;; This pattern can't accept a variable shift count, since shifts by
12673 ;; zero don't affect the flags.  We assume that shifts by constant
12674 ;; zero are optimized away.
12675 (define_insn "*lshrhi3_cmp"
12676   [(set (reg FLAGS_REG)
12677         (compare
12678           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12679                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12680           (const_int 0)))
12681    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12682         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12683   "ix86_match_ccmode (insn, CCGOCmode)
12684    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12685    && (optimize_size
12686        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12687   "shr{w}\t{%2, %0|%0, %2}"
12688   [(set_attr "type" "ishift")
12689    (set_attr "mode" "HI")])
12690
12691 (define_insn "*lshrhi3_cconly"
12692   [(set (reg FLAGS_REG)
12693         (compare
12694           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12695                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12696           (const_int 0)))
12697    (clobber (match_scratch:HI 0 "=r"))]
12698   "ix86_match_ccmode (insn, CCGOCmode)
12699    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12700    && (optimize_size
12701        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12702   "shr{w}\t{%2, %0|%0, %2}"
12703   [(set_attr "type" "ishift")
12704    (set_attr "mode" "HI")])
12705
12706 (define_expand "lshrqi3"
12707   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12708         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12709                      (match_operand:QI 2 "nonmemory_operand" "")))
12710    (clobber (reg:CC FLAGS_REG))]
12711   "TARGET_QIMODE_MATH"
12712   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12713
12714 (define_insn "*lshrqi3_1_one_bit"
12715   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12716         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12717                      (match_operand:QI 2 "const1_operand" "")))
12718    (clobber (reg:CC FLAGS_REG))]
12719   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12720    && (TARGET_SHIFT1 || optimize_size)"
12721   "shr{b}\t%0"
12722   [(set_attr "type" "ishift")
12723    (set (attr "length")
12724      (if_then_else (match_operand 0 "register_operand" "")
12725         (const_string "2")
12726         (const_string "*")))])
12727
12728 (define_insn "*lshrqi3_1_one_bit_slp"
12729   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12730         (lshiftrt:QI (match_dup 0)
12731                      (match_operand:QI 1 "const1_operand" "")))
12732    (clobber (reg:CC FLAGS_REG))]
12733   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12734    && (TARGET_SHIFT1 || optimize_size)"
12735   "shr{b}\t%0"
12736   [(set_attr "type" "ishift1")
12737    (set (attr "length")
12738      (if_then_else (match_operand 0 "register_operand" "")
12739         (const_string "2")
12740         (const_string "*")))])
12741
12742 (define_insn "*lshrqi3_1"
12743   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12744         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12745                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12746    (clobber (reg:CC FLAGS_REG))]
12747   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12748   "@
12749    shr{b}\t{%2, %0|%0, %2}
12750    shr{b}\t{%b2, %0|%0, %b2}"
12751   [(set_attr "type" "ishift")
12752    (set_attr "mode" "QI")])
12753
12754 (define_insn "*lshrqi3_1_slp"
12755   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12756         (lshiftrt:QI (match_dup 0)
12757                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12758    (clobber (reg:CC FLAGS_REG))]
12759   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12760    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12761   "@
12762    shr{b}\t{%1, %0|%0, %1}
12763    shr{b}\t{%b1, %0|%0, %b1}"
12764   [(set_attr "type" "ishift1")
12765    (set_attr "mode" "QI")])
12766
12767 ;; This pattern can't accept a variable shift count, since shifts by
12768 ;; zero don't affect the flags.  We assume that shifts by constant
12769 ;; zero are optimized away.
12770 (define_insn "*lshrqi2_one_bit_cmp"
12771   [(set (reg FLAGS_REG)
12772         (compare
12773           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12774                        (match_operand:QI 2 "const1_operand" ""))
12775           (const_int 0)))
12776    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12777         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12778   "ix86_match_ccmode (insn, CCGOCmode)
12779    && (TARGET_SHIFT1 || optimize_size)
12780    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12781   "shr{b}\t%0"
12782   [(set_attr "type" "ishift")
12783    (set (attr "length")
12784      (if_then_else (match_operand:SI 0 "register_operand" "")
12785         (const_string "2")
12786         (const_string "*")))])
12787
12788 (define_insn "*lshrqi2_one_bit_cconly"
12789   [(set (reg FLAGS_REG)
12790         (compare
12791           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12792                        (match_operand:QI 2 "const1_operand" ""))
12793           (const_int 0)))
12794    (clobber (match_scratch:QI 0 "=q"))]
12795   "ix86_match_ccmode (insn, CCGOCmode)
12796    && (TARGET_SHIFT1 || optimize_size)
12797    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12798   "shr{b}\t%0"
12799   [(set_attr "type" "ishift")
12800    (set_attr "length" "2")])
12801
12802 ;; This pattern can't accept a variable shift count, since shifts by
12803 ;; zero don't affect the flags.  We assume that shifts by constant
12804 ;; zero are optimized away.
12805 (define_insn "*lshrqi2_cmp"
12806   [(set (reg FLAGS_REG)
12807         (compare
12808           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12809                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12810           (const_int 0)))
12811    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12812         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12813   "ix86_match_ccmode (insn, CCGOCmode)
12814    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12815    && (optimize_size
12816        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12817   "shr{b}\t{%2, %0|%0, %2}"
12818   [(set_attr "type" "ishift")
12819    (set_attr "mode" "QI")])
12820
12821 (define_insn "*lshrqi2_cconly"
12822   [(set (reg FLAGS_REG)
12823         (compare
12824           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12825                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12826           (const_int 0)))
12827    (clobber (match_scratch:QI 0 "=q"))]
12828   "ix86_match_ccmode (insn, CCGOCmode)
12829    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12830    && (optimize_size
12831        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12832   "shr{b}\t{%2, %0|%0, %2}"
12833   [(set_attr "type" "ishift")
12834    (set_attr "mode" "QI")])
12835 \f
12836 ;; Rotate instructions
12837
12838 (define_expand "rotldi3"
12839   [(set (match_operand:DI 0 "shiftdi_operand" "")
12840         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12841                    (match_operand:QI 2 "nonmemory_operand" "")))
12842    (clobber (reg:CC FLAGS_REG))]
12843  ""
12844 {
12845   if (TARGET_64BIT)
12846     {
12847       ix86_expand_binary_operator (ROTATE, DImode, operands);
12848       DONE;
12849     }
12850   if (!const_1_to_31_operand (operands[2], VOIDmode))
12851     FAIL;
12852   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12853   DONE;
12854 })
12855
12856 ;; Implement rotation using two double-precision shift instructions
12857 ;; and a scratch register.
12858 (define_insn_and_split "ix86_rotldi3"
12859  [(set (match_operand:DI 0 "register_operand" "=r")
12860        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12861                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12862   (clobber (reg:CC FLAGS_REG))
12863   (clobber (match_scratch:SI 3 "=&r"))]
12864  "!TARGET_64BIT"
12865  ""
12866  "&& reload_completed"
12867  [(set (match_dup 3) (match_dup 4))
12868   (parallel
12869    [(set (match_dup 4)
12870          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12871                  (lshiftrt:SI (match_dup 5)
12872                               (minus:QI (const_int 32) (match_dup 2)))))
12873     (clobber (reg:CC FLAGS_REG))])
12874   (parallel
12875    [(set (match_dup 5)
12876          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12877                  (lshiftrt:SI (match_dup 3)
12878                               (minus:QI (const_int 32) (match_dup 2)))))
12879     (clobber (reg:CC FLAGS_REG))])]
12880  "split_di (operands, 1, operands + 4, operands + 5);")
12881
12882 (define_insn "*rotlsi3_1_one_bit_rex64"
12883   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12884         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12885                    (match_operand:QI 2 "const1_operand" "")))
12886    (clobber (reg:CC FLAGS_REG))]
12887   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12888    && (TARGET_SHIFT1 || optimize_size)"
12889   "rol{q}\t%0"
12890   [(set_attr "type" "rotate")
12891    (set (attr "length")
12892      (if_then_else (match_operand:DI 0 "register_operand" "")
12893         (const_string "2")
12894         (const_string "*")))])
12895
12896 (define_insn "*rotldi3_1_rex64"
12897   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12898         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12899                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12900    (clobber (reg:CC FLAGS_REG))]
12901   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12902   "@
12903    rol{q}\t{%2, %0|%0, %2}
12904    rol{q}\t{%b2, %0|%0, %b2}"
12905   [(set_attr "type" "rotate")
12906    (set_attr "mode" "DI")])
12907
12908 (define_expand "rotlsi3"
12909   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12910         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12911                    (match_operand:QI 2 "nonmemory_operand" "")))
12912    (clobber (reg:CC FLAGS_REG))]
12913   ""
12914   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12915
12916 (define_insn "*rotlsi3_1_one_bit"
12917   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12918         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12919                    (match_operand:QI 2 "const1_operand" "")))
12920    (clobber (reg:CC FLAGS_REG))]
12921   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12922    && (TARGET_SHIFT1 || optimize_size)"
12923   "rol{l}\t%0"
12924   [(set_attr "type" "rotate")
12925    (set (attr "length")
12926      (if_then_else (match_operand:SI 0 "register_operand" "")
12927         (const_string "2")
12928         (const_string "*")))])
12929
12930 (define_insn "*rotlsi3_1_one_bit_zext"
12931   [(set (match_operand:DI 0 "register_operand" "=r")
12932         (zero_extend:DI
12933           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12934                      (match_operand:QI 2 "const1_operand" ""))))
12935    (clobber (reg:CC FLAGS_REG))]
12936   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12937    && (TARGET_SHIFT1 || optimize_size)"
12938   "rol{l}\t%k0"
12939   [(set_attr "type" "rotate")
12940    (set_attr "length" "2")])
12941
12942 (define_insn "*rotlsi3_1"
12943   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12944         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12945                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12946    (clobber (reg:CC FLAGS_REG))]
12947   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12948   "@
12949    rol{l}\t{%2, %0|%0, %2}
12950    rol{l}\t{%b2, %0|%0, %b2}"
12951   [(set_attr "type" "rotate")
12952    (set_attr "mode" "SI")])
12953
12954 (define_insn "*rotlsi3_1_zext"
12955   [(set (match_operand:DI 0 "register_operand" "=r,r")
12956         (zero_extend:DI
12957           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12958                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12959    (clobber (reg:CC FLAGS_REG))]
12960   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12961   "@
12962    rol{l}\t{%2, %k0|%k0, %2}
12963    rol{l}\t{%b2, %k0|%k0, %b2}"
12964   [(set_attr "type" "rotate")
12965    (set_attr "mode" "SI")])
12966
12967 (define_expand "rotlhi3"
12968   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12969         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12970                    (match_operand:QI 2 "nonmemory_operand" "")))
12971    (clobber (reg:CC FLAGS_REG))]
12972   "TARGET_HIMODE_MATH"
12973   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12974
12975 (define_insn "*rotlhi3_1_one_bit"
12976   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12977         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12978                    (match_operand:QI 2 "const1_operand" "")))
12979    (clobber (reg:CC FLAGS_REG))]
12980   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12981    && (TARGET_SHIFT1 || optimize_size)"
12982   "rol{w}\t%0"
12983   [(set_attr "type" "rotate")
12984    (set (attr "length")
12985      (if_then_else (match_operand 0 "register_operand" "")
12986         (const_string "2")
12987         (const_string "*")))])
12988
12989 (define_insn "*rotlhi3_1"
12990   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12991         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12992                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12993    (clobber (reg:CC FLAGS_REG))]
12994   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12995   "@
12996    rol{w}\t{%2, %0|%0, %2}
12997    rol{w}\t{%b2, %0|%0, %b2}"
12998   [(set_attr "type" "rotate")
12999    (set_attr "mode" "HI")])
13000
13001 (define_expand "rotlqi3"
13002   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13003         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13004                    (match_operand:QI 2 "nonmemory_operand" "")))
13005    (clobber (reg:CC FLAGS_REG))]
13006   "TARGET_QIMODE_MATH"
13007   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13008
13009 (define_insn "*rotlqi3_1_one_bit_slp"
13010   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13011         (rotate:QI (match_dup 0)
13012                    (match_operand:QI 1 "const1_operand" "")))
13013    (clobber (reg:CC FLAGS_REG))]
13014   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13015    && (TARGET_SHIFT1 || optimize_size)"
13016   "rol{b}\t%0"
13017   [(set_attr "type" "rotate1")
13018    (set (attr "length")
13019      (if_then_else (match_operand 0 "register_operand" "")
13020         (const_string "2")
13021         (const_string "*")))])
13022
13023 (define_insn "*rotlqi3_1_one_bit"
13024   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13025         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13026                    (match_operand:QI 2 "const1_operand" "")))
13027    (clobber (reg:CC FLAGS_REG))]
13028   "ix86_binary_operator_ok (ROTATE, QImode, operands)
13029    && (TARGET_SHIFT1 || optimize_size)"
13030   "rol{b}\t%0"
13031   [(set_attr "type" "rotate")
13032    (set (attr "length")
13033      (if_then_else (match_operand 0 "register_operand" "")
13034         (const_string "2")
13035         (const_string "*")))])
13036
13037 (define_insn "*rotlqi3_1_slp"
13038   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13039         (rotate:QI (match_dup 0)
13040                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13041    (clobber (reg:CC FLAGS_REG))]
13042   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13043    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13044   "@
13045    rol{b}\t{%1, %0|%0, %1}
13046    rol{b}\t{%b1, %0|%0, %b1}"
13047   [(set_attr "type" "rotate1")
13048    (set_attr "mode" "QI")])
13049
13050 (define_insn "*rotlqi3_1"
13051   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13052         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13053                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13054    (clobber (reg:CC FLAGS_REG))]
13055   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13056   "@
13057    rol{b}\t{%2, %0|%0, %2}
13058    rol{b}\t{%b2, %0|%0, %b2}"
13059   [(set_attr "type" "rotate")
13060    (set_attr "mode" "QI")])
13061
13062 (define_expand "rotrdi3"
13063   [(set (match_operand:DI 0 "shiftdi_operand" "")
13064         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13065                    (match_operand:QI 2 "nonmemory_operand" "")))
13066    (clobber (reg:CC FLAGS_REG))]
13067  ""
13068 {
13069   if (TARGET_64BIT)
13070     {
13071       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13072       DONE;
13073     }
13074   if (!const_1_to_31_operand (operands[2], VOIDmode))
13075     FAIL;
13076   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13077   DONE;
13078 })
13079
13080 ;; Implement rotation using two double-precision shift instructions
13081 ;; and a scratch register.
13082 (define_insn_and_split "ix86_rotrdi3"
13083  [(set (match_operand:DI 0 "register_operand" "=r")
13084        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13085                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13086   (clobber (reg:CC FLAGS_REG))
13087   (clobber (match_scratch:SI 3 "=&r"))]
13088  "!TARGET_64BIT"
13089  ""
13090  "&& reload_completed"
13091  [(set (match_dup 3) (match_dup 4))
13092   (parallel
13093    [(set (match_dup 4)
13094          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13095                  (ashift:SI (match_dup 5)
13096                             (minus:QI (const_int 32) (match_dup 2)))))
13097     (clobber (reg:CC FLAGS_REG))])
13098   (parallel
13099    [(set (match_dup 5)
13100          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13101                  (ashift:SI (match_dup 3)
13102                             (minus:QI (const_int 32) (match_dup 2)))))
13103     (clobber (reg:CC FLAGS_REG))])]
13104  "split_di (operands, 1, operands + 4, operands + 5);")
13105
13106 (define_insn "*rotrdi3_1_one_bit_rex64"
13107   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13108         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13109                      (match_operand:QI 2 "const1_operand" "")))
13110    (clobber (reg:CC FLAGS_REG))]
13111   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13112    && (TARGET_SHIFT1 || optimize_size)"
13113   "ror{q}\t%0"
13114   [(set_attr "type" "rotate")
13115    (set (attr "length")
13116      (if_then_else (match_operand:DI 0 "register_operand" "")
13117         (const_string "2")
13118         (const_string "*")))])
13119
13120 (define_insn "*rotrdi3_1_rex64"
13121   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13122         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13123                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13124    (clobber (reg:CC FLAGS_REG))]
13125   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13126   "@
13127    ror{q}\t{%2, %0|%0, %2}
13128    ror{q}\t{%b2, %0|%0, %b2}"
13129   [(set_attr "type" "rotate")
13130    (set_attr "mode" "DI")])
13131
13132 (define_expand "rotrsi3"
13133   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13134         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13135                      (match_operand:QI 2 "nonmemory_operand" "")))
13136    (clobber (reg:CC FLAGS_REG))]
13137   ""
13138   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13139
13140 (define_insn "*rotrsi3_1_one_bit"
13141   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13142         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13143                      (match_operand:QI 2 "const1_operand" "")))
13144    (clobber (reg:CC FLAGS_REG))]
13145   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13146    && (TARGET_SHIFT1 || optimize_size)"
13147   "ror{l}\t%0"
13148   [(set_attr "type" "rotate")
13149    (set (attr "length")
13150      (if_then_else (match_operand:SI 0 "register_operand" "")
13151         (const_string "2")
13152         (const_string "*")))])
13153
13154 (define_insn "*rotrsi3_1_one_bit_zext"
13155   [(set (match_operand:DI 0 "register_operand" "=r")
13156         (zero_extend:DI
13157           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13158                        (match_operand:QI 2 "const1_operand" ""))))
13159    (clobber (reg:CC FLAGS_REG))]
13160   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13161    && (TARGET_SHIFT1 || optimize_size)"
13162   "ror{l}\t%k0"
13163   [(set_attr "type" "rotate")
13164    (set (attr "length")
13165      (if_then_else (match_operand:SI 0 "register_operand" "")
13166         (const_string "2")
13167         (const_string "*")))])
13168
13169 (define_insn "*rotrsi3_1"
13170   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13171         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13172                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13173    (clobber (reg:CC FLAGS_REG))]
13174   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13175   "@
13176    ror{l}\t{%2, %0|%0, %2}
13177    ror{l}\t{%b2, %0|%0, %b2}"
13178   [(set_attr "type" "rotate")
13179    (set_attr "mode" "SI")])
13180
13181 (define_insn "*rotrsi3_1_zext"
13182   [(set (match_operand:DI 0 "register_operand" "=r,r")
13183         (zero_extend:DI
13184           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13185                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13186    (clobber (reg:CC FLAGS_REG))]
13187   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13188   "@
13189    ror{l}\t{%2, %k0|%k0, %2}
13190    ror{l}\t{%b2, %k0|%k0, %b2}"
13191   [(set_attr "type" "rotate")
13192    (set_attr "mode" "SI")])
13193
13194 (define_expand "rotrhi3"
13195   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13196         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13197                      (match_operand:QI 2 "nonmemory_operand" "")))
13198    (clobber (reg:CC FLAGS_REG))]
13199   "TARGET_HIMODE_MATH"
13200   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13201
13202 (define_insn "*rotrhi3_one_bit"
13203   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13204         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13205                      (match_operand:QI 2 "const1_operand" "")))
13206    (clobber (reg:CC FLAGS_REG))]
13207   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13208    && (TARGET_SHIFT1 || optimize_size)"
13209   "ror{w}\t%0"
13210   [(set_attr "type" "rotate")
13211    (set (attr "length")
13212      (if_then_else (match_operand 0 "register_operand" "")
13213         (const_string "2")
13214         (const_string "*")))])
13215
13216 (define_insn "*rotrhi3"
13217   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13218         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13219                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13220    (clobber (reg:CC FLAGS_REG))]
13221   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13222   "@
13223    ror{w}\t{%2, %0|%0, %2}
13224    ror{w}\t{%b2, %0|%0, %b2}"
13225   [(set_attr "type" "rotate")
13226    (set_attr "mode" "HI")])
13227
13228 (define_expand "rotrqi3"
13229   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13230         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13231                      (match_operand:QI 2 "nonmemory_operand" "")))
13232    (clobber (reg:CC FLAGS_REG))]
13233   "TARGET_QIMODE_MATH"
13234   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13235
13236 (define_insn "*rotrqi3_1_one_bit"
13237   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13238         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13239                      (match_operand:QI 2 "const1_operand" "")))
13240    (clobber (reg:CC FLAGS_REG))]
13241   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13242    && (TARGET_SHIFT1 || optimize_size)"
13243   "ror{b}\t%0"
13244   [(set_attr "type" "rotate")
13245    (set (attr "length")
13246      (if_then_else (match_operand 0 "register_operand" "")
13247         (const_string "2")
13248         (const_string "*")))])
13249
13250 (define_insn "*rotrqi3_1_one_bit_slp"
13251   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13252         (rotatert:QI (match_dup 0)
13253                      (match_operand:QI 1 "const1_operand" "")))
13254    (clobber (reg:CC FLAGS_REG))]
13255   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13256    && (TARGET_SHIFT1 || optimize_size)"
13257   "ror{b}\t%0"
13258   [(set_attr "type" "rotate1")
13259    (set (attr "length")
13260      (if_then_else (match_operand 0 "register_operand" "")
13261         (const_string "2")
13262         (const_string "*")))])
13263
13264 (define_insn "*rotrqi3_1"
13265   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13266         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13267                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13268    (clobber (reg:CC FLAGS_REG))]
13269   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13270   "@
13271    ror{b}\t{%2, %0|%0, %2}
13272    ror{b}\t{%b2, %0|%0, %b2}"
13273   [(set_attr "type" "rotate")
13274    (set_attr "mode" "QI")])
13275
13276 (define_insn "*rotrqi3_1_slp"
13277   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13278         (rotatert:QI (match_dup 0)
13279                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13280    (clobber (reg:CC FLAGS_REG))]
13281   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13282    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13283   "@
13284    ror{b}\t{%1, %0|%0, %1}
13285    ror{b}\t{%b1, %0|%0, %b1}"
13286   [(set_attr "type" "rotate1")
13287    (set_attr "mode" "QI")])
13288 \f
13289 ;; Bit set / bit test instructions
13290
13291 (define_expand "extv"
13292   [(set (match_operand:SI 0 "register_operand" "")
13293         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13294                          (match_operand:SI 2 "const8_operand" "")
13295                          (match_operand:SI 3 "const8_operand" "")))]
13296   ""
13297 {
13298   /* Handle extractions from %ah et al.  */
13299   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13300     FAIL;
13301
13302   /* From mips.md: extract_bit_field doesn't verify that our source
13303      matches the predicate, so check it again here.  */
13304   if (! ext_register_operand (operands[1], VOIDmode))
13305     FAIL;
13306 })
13307
13308 (define_expand "extzv"
13309   [(set (match_operand:SI 0 "register_operand" "")
13310         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13311                          (match_operand:SI 2 "const8_operand" "")
13312                          (match_operand:SI 3 "const8_operand" "")))]
13313   ""
13314 {
13315   /* Handle extractions from %ah et al.  */
13316   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13317     FAIL;
13318
13319   /* From mips.md: extract_bit_field doesn't verify that our source
13320      matches the predicate, so check it again here.  */
13321   if (! ext_register_operand (operands[1], VOIDmode))
13322     FAIL;
13323 })
13324
13325 (define_expand "insv"
13326   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13327                       (match_operand 1 "const8_operand" "")
13328                       (match_operand 2 "const8_operand" ""))
13329         (match_operand 3 "register_operand" ""))]
13330   ""
13331 {
13332   /* Handle insertions to %ah et al.  */
13333   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13334     FAIL;
13335
13336   /* From mips.md: insert_bit_field doesn't verify that our source
13337      matches the predicate, so check it again here.  */
13338   if (! ext_register_operand (operands[0], VOIDmode))
13339     FAIL;
13340
13341   if (TARGET_64BIT)
13342     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13343   else
13344     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13345
13346   DONE;
13347 })
13348
13349 ;; %%% bts, btr, btc, bt.
13350 ;; In general these instructions are *slow* when applied to memory,
13351 ;; since they enforce atomic operation.  When applied to registers,
13352 ;; it depends on the cpu implementation.  They're never faster than
13353 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13354 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13355 ;; within the instruction itself, so operating on bits in the high
13356 ;; 32-bits of a register becomes easier.
13357 ;;
13358 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13359 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13360 ;; negdf respectively, so they can never be disabled entirely.
13361
13362 (define_insn "*btsq"
13363   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13364                          (const_int 1)
13365                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13366         (const_int 1))
13367    (clobber (reg:CC FLAGS_REG))]
13368   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13369   "bts{q} %1,%0"
13370   [(set_attr "type" "alu1")])
13371
13372 (define_insn "*btrq"
13373   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13374                          (const_int 1)
13375                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13376         (const_int 0))
13377    (clobber (reg:CC FLAGS_REG))]
13378   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13379   "btr{q} %1,%0"
13380   [(set_attr "type" "alu1")])
13381
13382 (define_insn "*btcq"
13383   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13384                          (const_int 1)
13385                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13386         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13387    (clobber (reg:CC FLAGS_REG))]
13388   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13389   "btc{q} %1,%0"
13390   [(set_attr "type" "alu1")])
13391
13392 ;; Allow Nocona to avoid these instructions if a register is available.
13393
13394 (define_peephole2
13395   [(match_scratch:DI 2 "r")
13396    (parallel [(set (zero_extract:DI
13397                      (match_operand:DI 0 "register_operand" "")
13398                      (const_int 1)
13399                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13400                    (const_int 1))
13401               (clobber (reg:CC FLAGS_REG))])]
13402   "TARGET_64BIT && !TARGET_USE_BT"
13403   [(const_int 0)]
13404 {
13405   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13406   rtx op1;
13407
13408   if (HOST_BITS_PER_WIDE_INT >= 64)
13409     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13410   else if (i < HOST_BITS_PER_WIDE_INT)
13411     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13412   else
13413     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13414
13415   op1 = immed_double_const (lo, hi, DImode);
13416   if (i >= 31)
13417     {
13418       emit_move_insn (operands[2], op1);
13419       op1 = operands[2];
13420     }
13421
13422   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13423   DONE;
13424 })
13425
13426 (define_peephole2
13427   [(match_scratch:DI 2 "r")
13428    (parallel [(set (zero_extract:DI
13429                      (match_operand:DI 0 "register_operand" "")
13430                      (const_int 1)
13431                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13432                    (const_int 0))
13433               (clobber (reg:CC FLAGS_REG))])]
13434   "TARGET_64BIT && !TARGET_USE_BT"
13435   [(const_int 0)]
13436 {
13437   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13438   rtx op1;
13439
13440   if (HOST_BITS_PER_WIDE_INT >= 64)
13441     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13442   else if (i < HOST_BITS_PER_WIDE_INT)
13443     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13444   else
13445     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13446
13447   op1 = immed_double_const (~lo, ~hi, DImode);
13448   if (i >= 32)
13449     {
13450       emit_move_insn (operands[2], op1);
13451       op1 = operands[2];
13452     }
13453
13454   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13455   DONE;
13456 })
13457
13458 (define_peephole2
13459   [(match_scratch:DI 2 "r")
13460    (parallel [(set (zero_extract:DI
13461                      (match_operand:DI 0 "register_operand" "")
13462                      (const_int 1)
13463                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13464               (not:DI (zero_extract:DI
13465                         (match_dup 0) (const_int 1) (match_dup 1))))
13466               (clobber (reg:CC FLAGS_REG))])]
13467   "TARGET_64BIT && !TARGET_USE_BT"
13468   [(const_int 0)]
13469 {
13470   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13471   rtx op1;
13472
13473   if (HOST_BITS_PER_WIDE_INT >= 64)
13474     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13475   else if (i < HOST_BITS_PER_WIDE_INT)
13476     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13477   else
13478     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13479
13480   op1 = immed_double_const (lo, hi, DImode);
13481   if (i >= 31)
13482     {
13483       emit_move_insn (operands[2], op1);
13484       op1 = operands[2];
13485     }
13486
13487   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13488   DONE;
13489 })
13490 \f
13491 ;; Store-flag instructions.
13492
13493 ;; For all sCOND expanders, also expand the compare or test insn that
13494 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13495
13496 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13497 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13498 ;; way, which can later delete the movzx if only QImode is needed.
13499
13500 (define_expand "seq"
13501   [(set (match_operand:QI 0 "register_operand" "")
13502         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13503   ""
13504   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13505
13506 (define_expand "sne"
13507   [(set (match_operand:QI 0 "register_operand" "")
13508         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13509   ""
13510   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13511
13512 (define_expand "sgt"
13513   [(set (match_operand:QI 0 "register_operand" "")
13514         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13515   ""
13516   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13517
13518 (define_expand "sgtu"
13519   [(set (match_operand:QI 0 "register_operand" "")
13520         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13521   ""
13522   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13523
13524 (define_expand "slt"
13525   [(set (match_operand:QI 0 "register_operand" "")
13526         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13527   ""
13528   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13529
13530 (define_expand "sltu"
13531   [(set (match_operand:QI 0 "register_operand" "")
13532         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13533   ""
13534   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13535
13536 (define_expand "sge"
13537   [(set (match_operand:QI 0 "register_operand" "")
13538         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13539   ""
13540   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13541
13542 (define_expand "sgeu"
13543   [(set (match_operand:QI 0 "register_operand" "")
13544         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13545   ""
13546   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13547
13548 (define_expand "sle"
13549   [(set (match_operand:QI 0 "register_operand" "")
13550         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13551   ""
13552   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13553
13554 (define_expand "sleu"
13555   [(set (match_operand:QI 0 "register_operand" "")
13556         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13557   ""
13558   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13559
13560 (define_expand "sunordered"
13561   [(set (match_operand:QI 0 "register_operand" "")
13562         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13563   "TARGET_80387 || TARGET_SSE"
13564   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13565
13566 (define_expand "sordered"
13567   [(set (match_operand:QI 0 "register_operand" "")
13568         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13569   "TARGET_80387"
13570   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13571
13572 (define_expand "suneq"
13573   [(set (match_operand:QI 0 "register_operand" "")
13574         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13575   "TARGET_80387 || TARGET_SSE"
13576   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13577
13578 (define_expand "sunge"
13579   [(set (match_operand:QI 0 "register_operand" "")
13580         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13581   "TARGET_80387 || TARGET_SSE"
13582   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13583
13584 (define_expand "sungt"
13585   [(set (match_operand:QI 0 "register_operand" "")
13586         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13587   "TARGET_80387 || TARGET_SSE"
13588   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13589
13590 (define_expand "sunle"
13591   [(set (match_operand:QI 0 "register_operand" "")
13592         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13593   "TARGET_80387 || TARGET_SSE"
13594   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13595
13596 (define_expand "sunlt"
13597   [(set (match_operand:QI 0 "register_operand" "")
13598         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13599   "TARGET_80387 || TARGET_SSE"
13600   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13601
13602 (define_expand "sltgt"
13603   [(set (match_operand:QI 0 "register_operand" "")
13604         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13605   "TARGET_80387 || TARGET_SSE"
13606   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13607
13608 (define_insn "*setcc_1"
13609   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13610         (match_operator:QI 1 "ix86_comparison_operator"
13611           [(reg FLAGS_REG) (const_int 0)]))]
13612   ""
13613   "set%C1\t%0"
13614   [(set_attr "type" "setcc")
13615    (set_attr "mode" "QI")])
13616
13617 (define_insn "*setcc_2"
13618   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13619         (match_operator:QI 1 "ix86_comparison_operator"
13620           [(reg FLAGS_REG) (const_int 0)]))]
13621   ""
13622   "set%C1\t%0"
13623   [(set_attr "type" "setcc")
13624    (set_attr "mode" "QI")])
13625
13626 ;; In general it is not safe to assume too much about CCmode registers,
13627 ;; so simplify-rtx stops when it sees a second one.  Under certain
13628 ;; conditions this is safe on x86, so help combine not create
13629 ;;
13630 ;;      seta    %al
13631 ;;      testb   %al, %al
13632 ;;      sete    %al
13633
13634 (define_split
13635   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13636         (ne:QI (match_operator 1 "ix86_comparison_operator"
13637                  [(reg FLAGS_REG) (const_int 0)])
13638             (const_int 0)))]
13639   ""
13640   [(set (match_dup 0) (match_dup 1))]
13641 {
13642   PUT_MODE (operands[1], QImode);
13643 })
13644
13645 (define_split
13646   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13647         (ne:QI (match_operator 1 "ix86_comparison_operator"
13648                  [(reg FLAGS_REG) (const_int 0)])
13649             (const_int 0)))]
13650   ""
13651   [(set (match_dup 0) (match_dup 1))]
13652 {
13653   PUT_MODE (operands[1], QImode);
13654 })
13655
13656 (define_split
13657   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13658         (eq:QI (match_operator 1 "ix86_comparison_operator"
13659                  [(reg FLAGS_REG) (const_int 0)])
13660             (const_int 0)))]
13661   ""
13662   [(set (match_dup 0) (match_dup 1))]
13663 {
13664   rtx new_op1 = copy_rtx (operands[1]);
13665   operands[1] = new_op1;
13666   PUT_MODE (new_op1, QImode);
13667   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13668                                              GET_MODE (XEXP (new_op1, 0))));
13669
13670   /* Make sure that (a) the CCmode we have for the flags is strong
13671      enough for the reversed compare or (b) we have a valid FP compare.  */
13672   if (! ix86_comparison_operator (new_op1, VOIDmode))
13673     FAIL;
13674 })
13675
13676 (define_split
13677   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13678         (eq:QI (match_operator 1 "ix86_comparison_operator"
13679                  [(reg FLAGS_REG) (const_int 0)])
13680             (const_int 0)))]
13681   ""
13682   [(set (match_dup 0) (match_dup 1))]
13683 {
13684   rtx new_op1 = copy_rtx (operands[1]);
13685   operands[1] = new_op1;
13686   PUT_MODE (new_op1, QImode);
13687   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13688                                              GET_MODE (XEXP (new_op1, 0))));
13689
13690   /* Make sure that (a) the CCmode we have for the flags is strong
13691      enough for the reversed compare or (b) we have a valid FP compare.  */
13692   if (! ix86_comparison_operator (new_op1, VOIDmode))
13693     FAIL;
13694 })
13695
13696 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13697 ;; subsequent logical operations are used to imitate conditional moves.
13698 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13699 ;; it directly.
13700
13701 (define_insn "*sse_setccsf"
13702   [(set (match_operand:SF 0 "register_operand" "=x")
13703         (match_operator:SF 1 "sse_comparison_operator"
13704           [(match_operand:SF 2 "register_operand" "0")
13705            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13706   "TARGET_SSE"
13707   "cmp%D1ss\t{%3, %0|%0, %3}"
13708   [(set_attr "type" "ssecmp")
13709    (set_attr "mode" "SF")])
13710
13711 (define_insn "*sse_setccdf"
13712   [(set (match_operand:DF 0 "register_operand" "=x")
13713         (match_operator:DF 1 "sse_comparison_operator"
13714           [(match_operand:DF 2 "register_operand" "0")
13715            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13716   "TARGET_SSE2"
13717   "cmp%D1sd\t{%3, %0|%0, %3}"
13718   [(set_attr "type" "ssecmp")
13719    (set_attr "mode" "DF")])
13720 \f
13721 ;; Basic conditional jump instructions.
13722 ;; We ignore the overflow flag for signed branch instructions.
13723
13724 ;; For all bCOND expanders, also expand the compare or test insn that
13725 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13726
13727 (define_expand "beq"
13728   [(set (pc)
13729         (if_then_else (match_dup 1)
13730                       (label_ref (match_operand 0 "" ""))
13731                       (pc)))]
13732   ""
13733   "ix86_expand_branch (EQ, operands[0]); DONE;")
13734
13735 (define_expand "bne"
13736   [(set (pc)
13737         (if_then_else (match_dup 1)
13738                       (label_ref (match_operand 0 "" ""))
13739                       (pc)))]
13740   ""
13741   "ix86_expand_branch (NE, operands[0]); DONE;")
13742
13743 (define_expand "bgt"
13744   [(set (pc)
13745         (if_then_else (match_dup 1)
13746                       (label_ref (match_operand 0 "" ""))
13747                       (pc)))]
13748   ""
13749   "ix86_expand_branch (GT, operands[0]); DONE;")
13750
13751 (define_expand "bgtu"
13752   [(set (pc)
13753         (if_then_else (match_dup 1)
13754                       (label_ref (match_operand 0 "" ""))
13755                       (pc)))]
13756   ""
13757   "ix86_expand_branch (GTU, operands[0]); DONE;")
13758
13759 (define_expand "blt"
13760   [(set (pc)
13761         (if_then_else (match_dup 1)
13762                       (label_ref (match_operand 0 "" ""))
13763                       (pc)))]
13764   ""
13765   "ix86_expand_branch (LT, operands[0]); DONE;")
13766
13767 (define_expand "bltu"
13768   [(set (pc)
13769         (if_then_else (match_dup 1)
13770                       (label_ref (match_operand 0 "" ""))
13771                       (pc)))]
13772   ""
13773   "ix86_expand_branch (LTU, operands[0]); DONE;")
13774
13775 (define_expand "bge"
13776   [(set (pc)
13777         (if_then_else (match_dup 1)
13778                       (label_ref (match_operand 0 "" ""))
13779                       (pc)))]
13780   ""
13781   "ix86_expand_branch (GE, operands[0]); DONE;")
13782
13783 (define_expand "bgeu"
13784   [(set (pc)
13785         (if_then_else (match_dup 1)
13786                       (label_ref (match_operand 0 "" ""))
13787                       (pc)))]
13788   ""
13789   "ix86_expand_branch (GEU, operands[0]); DONE;")
13790
13791 (define_expand "ble"
13792   [(set (pc)
13793         (if_then_else (match_dup 1)
13794                       (label_ref (match_operand 0 "" ""))
13795                       (pc)))]
13796   ""
13797   "ix86_expand_branch (LE, operands[0]); DONE;")
13798
13799 (define_expand "bleu"
13800   [(set (pc)
13801         (if_then_else (match_dup 1)
13802                       (label_ref (match_operand 0 "" ""))
13803                       (pc)))]
13804   ""
13805   "ix86_expand_branch (LEU, operands[0]); DONE;")
13806
13807 (define_expand "bunordered"
13808   [(set (pc)
13809         (if_then_else (match_dup 1)
13810                       (label_ref (match_operand 0 "" ""))
13811                       (pc)))]
13812   "TARGET_80387 || TARGET_SSE_MATH"
13813   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13814
13815 (define_expand "bordered"
13816   [(set (pc)
13817         (if_then_else (match_dup 1)
13818                       (label_ref (match_operand 0 "" ""))
13819                       (pc)))]
13820   "TARGET_80387 || TARGET_SSE_MATH"
13821   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13822
13823 (define_expand "buneq"
13824   [(set (pc)
13825         (if_then_else (match_dup 1)
13826                       (label_ref (match_operand 0 "" ""))
13827                       (pc)))]
13828   "TARGET_80387 || TARGET_SSE_MATH"
13829   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13830
13831 (define_expand "bunge"
13832   [(set (pc)
13833         (if_then_else (match_dup 1)
13834                       (label_ref (match_operand 0 "" ""))
13835                       (pc)))]
13836   "TARGET_80387 || TARGET_SSE_MATH"
13837   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13838
13839 (define_expand "bungt"
13840   [(set (pc)
13841         (if_then_else (match_dup 1)
13842                       (label_ref (match_operand 0 "" ""))
13843                       (pc)))]
13844   "TARGET_80387 || TARGET_SSE_MATH"
13845   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13846
13847 (define_expand "bunle"
13848   [(set (pc)
13849         (if_then_else (match_dup 1)
13850                       (label_ref (match_operand 0 "" ""))
13851                       (pc)))]
13852   "TARGET_80387 || TARGET_SSE_MATH"
13853   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13854
13855 (define_expand "bunlt"
13856   [(set (pc)
13857         (if_then_else (match_dup 1)
13858                       (label_ref (match_operand 0 "" ""))
13859                       (pc)))]
13860   "TARGET_80387 || TARGET_SSE_MATH"
13861   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13862
13863 (define_expand "bltgt"
13864   [(set (pc)
13865         (if_then_else (match_dup 1)
13866                       (label_ref (match_operand 0 "" ""))
13867                       (pc)))]
13868   "TARGET_80387 || TARGET_SSE_MATH"
13869   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13870
13871 (define_insn "*jcc_1"
13872   [(set (pc)
13873         (if_then_else (match_operator 1 "ix86_comparison_operator"
13874                                       [(reg FLAGS_REG) (const_int 0)])
13875                       (label_ref (match_operand 0 "" ""))
13876                       (pc)))]
13877   ""
13878   "%+j%C1\t%l0"
13879   [(set_attr "type" "ibr")
13880    (set_attr "modrm" "0")
13881    (set (attr "length")
13882            (if_then_else (and (ge (minus (match_dup 0) (pc))
13883                                   (const_int -126))
13884                               (lt (minus (match_dup 0) (pc))
13885                                   (const_int 128)))
13886              (const_int 2)
13887              (const_int 6)))])
13888
13889 (define_insn "*jcc_2"
13890   [(set (pc)
13891         (if_then_else (match_operator 1 "ix86_comparison_operator"
13892                                       [(reg FLAGS_REG) (const_int 0)])
13893                       (pc)
13894                       (label_ref (match_operand 0 "" ""))))]
13895   ""
13896   "%+j%c1\t%l0"
13897   [(set_attr "type" "ibr")
13898    (set_attr "modrm" "0")
13899    (set (attr "length")
13900            (if_then_else (and (ge (minus (match_dup 0) (pc))
13901                                   (const_int -126))
13902                               (lt (minus (match_dup 0) (pc))
13903                                   (const_int 128)))
13904              (const_int 2)
13905              (const_int 6)))])
13906
13907 ;; In general it is not safe to assume too much about CCmode registers,
13908 ;; so simplify-rtx stops when it sees a second one.  Under certain
13909 ;; conditions this is safe on x86, so help combine not create
13910 ;;
13911 ;;      seta    %al
13912 ;;      testb   %al, %al
13913 ;;      je      Lfoo
13914
13915 (define_split
13916   [(set (pc)
13917         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13918                                       [(reg FLAGS_REG) (const_int 0)])
13919                           (const_int 0))
13920                       (label_ref (match_operand 1 "" ""))
13921                       (pc)))]
13922   ""
13923   [(set (pc)
13924         (if_then_else (match_dup 0)
13925                       (label_ref (match_dup 1))
13926                       (pc)))]
13927 {
13928   PUT_MODE (operands[0], VOIDmode);
13929 })
13930
13931 (define_split
13932   [(set (pc)
13933         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13934                                       [(reg FLAGS_REG) (const_int 0)])
13935                           (const_int 0))
13936                       (label_ref (match_operand 1 "" ""))
13937                       (pc)))]
13938   ""
13939   [(set (pc)
13940         (if_then_else (match_dup 0)
13941                       (label_ref (match_dup 1))
13942                       (pc)))]
13943 {
13944   rtx new_op0 = copy_rtx (operands[0]);
13945   operands[0] = new_op0;
13946   PUT_MODE (new_op0, VOIDmode);
13947   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13948                                              GET_MODE (XEXP (new_op0, 0))));
13949
13950   /* Make sure that (a) the CCmode we have for the flags is strong
13951      enough for the reversed compare or (b) we have a valid FP compare.  */
13952   if (! ix86_comparison_operator (new_op0, VOIDmode))
13953     FAIL;
13954 })
13955
13956 ;; Define combination compare-and-branch fp compare instructions to use
13957 ;; during early optimization.  Splitting the operation apart early makes
13958 ;; for bad code when we want to reverse the operation.
13959
13960 (define_insn "*fp_jcc_1_mixed"
13961   [(set (pc)
13962         (if_then_else (match_operator 0 "comparison_operator"
13963                         [(match_operand 1 "register_operand" "f,x")
13964                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13965           (label_ref (match_operand 3 "" ""))
13966           (pc)))
13967    (clobber (reg:CCFP FPSR_REG))
13968    (clobber (reg:CCFP FLAGS_REG))]
13969   "TARGET_MIX_SSE_I387
13970    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13971    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13972    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13973   "#")
13974
13975 (define_insn "*fp_jcc_1_sse"
13976   [(set (pc)
13977         (if_then_else (match_operator 0 "comparison_operator"
13978                         [(match_operand 1 "register_operand" "x")
13979                          (match_operand 2 "nonimmediate_operand" "xm")])
13980           (label_ref (match_operand 3 "" ""))
13981           (pc)))
13982    (clobber (reg:CCFP FPSR_REG))
13983    (clobber (reg:CCFP FLAGS_REG))]
13984   "TARGET_SSE_MATH
13985    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13986    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13987    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13988   "#")
13989
13990 (define_insn "*fp_jcc_1_387"
13991   [(set (pc)
13992         (if_then_else (match_operator 0 "comparison_operator"
13993                         [(match_operand 1 "register_operand" "f")
13994                          (match_operand 2 "register_operand" "f")])
13995           (label_ref (match_operand 3 "" ""))
13996           (pc)))
13997    (clobber (reg:CCFP FPSR_REG))
13998    (clobber (reg:CCFP FLAGS_REG))]
13999   "TARGET_CMOVE && TARGET_80387
14000    && FLOAT_MODE_P (GET_MODE (operands[1]))
14001    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14002    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14003   "#")
14004
14005 (define_insn "*fp_jcc_2_mixed"
14006   [(set (pc)
14007         (if_then_else (match_operator 0 "comparison_operator"
14008                         [(match_operand 1 "register_operand" "f,x")
14009                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14010           (pc)
14011           (label_ref (match_operand 3 "" ""))))
14012    (clobber (reg:CCFP FPSR_REG))
14013    (clobber (reg:CCFP FLAGS_REG))]
14014   "TARGET_MIX_SSE_I387
14015    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14016    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14017    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14018   "#")
14019
14020 (define_insn "*fp_jcc_2_sse"
14021   [(set (pc)
14022         (if_then_else (match_operator 0 "comparison_operator"
14023                         [(match_operand 1 "register_operand" "x")
14024                          (match_operand 2 "nonimmediate_operand" "xm")])
14025           (pc)
14026           (label_ref (match_operand 3 "" ""))))
14027    (clobber (reg:CCFP FPSR_REG))
14028    (clobber (reg:CCFP FLAGS_REG))]
14029   "TARGET_SSE_MATH
14030    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14031    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14032    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14033   "#")
14034
14035 (define_insn "*fp_jcc_2_387"
14036   [(set (pc)
14037         (if_then_else (match_operator 0 "comparison_operator"
14038                         [(match_operand 1 "register_operand" "f")
14039                          (match_operand 2 "register_operand" "f")])
14040           (pc)
14041           (label_ref (match_operand 3 "" ""))))
14042    (clobber (reg:CCFP FPSR_REG))
14043    (clobber (reg:CCFP FLAGS_REG))]
14044   "TARGET_CMOVE && TARGET_80387
14045    && FLOAT_MODE_P (GET_MODE (operands[1]))
14046    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14047    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14048   "#")
14049
14050 (define_insn "*fp_jcc_3_387"
14051   [(set (pc)
14052         (if_then_else (match_operator 0 "comparison_operator"
14053                         [(match_operand 1 "register_operand" "f")
14054                          (match_operand 2 "nonimmediate_operand" "fm")])
14055           (label_ref (match_operand 3 "" ""))
14056           (pc)))
14057    (clobber (reg:CCFP FPSR_REG))
14058    (clobber (reg:CCFP FLAGS_REG))
14059    (clobber (match_scratch:HI 4 "=a"))]
14060   "TARGET_80387
14061    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14062    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14063    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14064    && SELECT_CC_MODE (GET_CODE (operands[0]),
14065                       operands[1], operands[2]) == CCFPmode
14066    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14067   "#")
14068
14069 (define_insn "*fp_jcc_4_387"
14070   [(set (pc)
14071         (if_then_else (match_operator 0 "comparison_operator"
14072                         [(match_operand 1 "register_operand" "f")
14073                          (match_operand 2 "nonimmediate_operand" "fm")])
14074           (pc)
14075           (label_ref (match_operand 3 "" ""))))
14076    (clobber (reg:CCFP FPSR_REG))
14077    (clobber (reg:CCFP FLAGS_REG))
14078    (clobber (match_scratch:HI 4 "=a"))]
14079   "TARGET_80387
14080    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14081    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14082    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14083    && SELECT_CC_MODE (GET_CODE (operands[0]),
14084                       operands[1], operands[2]) == CCFPmode
14085    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14086   "#")
14087
14088 (define_insn "*fp_jcc_5_387"
14089   [(set (pc)
14090         (if_then_else (match_operator 0 "comparison_operator"
14091                         [(match_operand 1 "register_operand" "f")
14092                          (match_operand 2 "register_operand" "f")])
14093           (label_ref (match_operand 3 "" ""))
14094           (pc)))
14095    (clobber (reg:CCFP FPSR_REG))
14096    (clobber (reg:CCFP FLAGS_REG))
14097    (clobber (match_scratch:HI 4 "=a"))]
14098   "TARGET_80387
14099    && FLOAT_MODE_P (GET_MODE (operands[1]))
14100    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14101    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14102   "#")
14103
14104 (define_insn "*fp_jcc_6_387"
14105   [(set (pc)
14106         (if_then_else (match_operator 0 "comparison_operator"
14107                         [(match_operand 1 "register_operand" "f")
14108                          (match_operand 2 "register_operand" "f")])
14109           (pc)
14110           (label_ref (match_operand 3 "" ""))))
14111    (clobber (reg:CCFP FPSR_REG))
14112    (clobber (reg:CCFP FLAGS_REG))
14113    (clobber (match_scratch:HI 4 "=a"))]
14114   "TARGET_80387
14115    && FLOAT_MODE_P (GET_MODE (operands[1]))
14116    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14117    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14118   "#")
14119
14120 (define_insn "*fp_jcc_7_387"
14121   [(set (pc)
14122         (if_then_else (match_operator 0 "comparison_operator"
14123                         [(match_operand 1 "register_operand" "f")
14124                          (match_operand 2 "const0_operand" "X")])
14125           (label_ref (match_operand 3 "" ""))
14126           (pc)))
14127    (clobber (reg:CCFP FPSR_REG))
14128    (clobber (reg:CCFP FLAGS_REG))
14129    (clobber (match_scratch:HI 4 "=a"))]
14130   "TARGET_80387
14131    && FLOAT_MODE_P (GET_MODE (operands[1]))
14132    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14133    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14134    && SELECT_CC_MODE (GET_CODE (operands[0]),
14135                       operands[1], operands[2]) == CCFPmode
14136    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14137   "#")
14138
14139 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14140 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14141 ;; with a precedence over other operators and is always put in the first
14142 ;; place. Swap condition and operands to match ficom instruction.
14143
14144 (define_insn "*fp_jcc_8<mode>_387"
14145   [(set (pc)
14146         (if_then_else (match_operator 0 "comparison_operator"
14147                         [(match_operator 1 "float_operator"
14148                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14149                            (match_operand 3 "register_operand" "f,f")])
14150           (label_ref (match_operand 4 "" ""))
14151           (pc)))
14152    (clobber (reg:CCFP FPSR_REG))
14153    (clobber (reg:CCFP FLAGS_REG))
14154    (clobber (match_scratch:HI 5 "=a,a"))]
14155   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14156    && FLOAT_MODE_P (GET_MODE (operands[3]))
14157    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14158    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14159    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14160    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14161   "#")
14162
14163 (define_split
14164   [(set (pc)
14165         (if_then_else (match_operator 0 "comparison_operator"
14166                         [(match_operand 1 "register_operand" "")
14167                          (match_operand 2 "nonimmediate_operand" "")])
14168           (match_operand 3 "" "")
14169           (match_operand 4 "" "")))
14170    (clobber (reg:CCFP FPSR_REG))
14171    (clobber (reg:CCFP FLAGS_REG))]
14172   "reload_completed"
14173   [(const_int 0)]
14174 {
14175   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14176                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14177   DONE;
14178 })
14179
14180 (define_split
14181   [(set (pc)
14182         (if_then_else (match_operator 0 "comparison_operator"
14183                         [(match_operand 1 "register_operand" "")
14184                          (match_operand 2 "general_operand" "")])
14185           (match_operand 3 "" "")
14186           (match_operand 4 "" "")))
14187    (clobber (reg:CCFP FPSR_REG))
14188    (clobber (reg:CCFP FLAGS_REG))
14189    (clobber (match_scratch:HI 5 "=a"))]
14190   "reload_completed"
14191   [(const_int 0)]
14192 {
14193   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14194                         operands[3], operands[4], operands[5], NULL_RTX);
14195   DONE;
14196 })
14197
14198 (define_split
14199   [(set (pc)
14200         (if_then_else (match_operator 0 "comparison_operator"
14201                         [(match_operator 1 "float_operator"
14202                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14203                            (match_operand 3 "register_operand" "")])
14204           (match_operand 4 "" "")
14205           (match_operand 5 "" "")))
14206    (clobber (reg:CCFP FPSR_REG))
14207    (clobber (reg:CCFP FLAGS_REG))
14208    (clobber (match_scratch:HI 6 "=a"))]
14209   "reload_completed"
14210   [(const_int 0)]
14211 {
14212   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14213   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14214                         operands[3], operands[7],
14215                         operands[4], operands[5], operands[6], NULL_RTX);
14216   DONE;
14217 })
14218
14219 ;; %%% Kill this when reload knows how to do it.
14220 (define_split
14221   [(set (pc)
14222         (if_then_else (match_operator 0 "comparison_operator"
14223                         [(match_operator 1 "float_operator"
14224                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14225                            (match_operand 3 "register_operand" "")])
14226           (match_operand 4 "" "")
14227           (match_operand 5 "" "")))
14228    (clobber (reg:CCFP FPSR_REG))
14229    (clobber (reg:CCFP FLAGS_REG))
14230    (clobber (match_scratch:HI 6 "=a"))]
14231   "reload_completed"
14232   [(const_int 0)]
14233 {
14234   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14235   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14236   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14237                         operands[3], operands[7],
14238                         operands[4], operands[5], operands[6], operands[2]);
14239   DONE;
14240 })
14241 \f
14242 ;; Unconditional and other jump instructions
14243
14244 (define_insn "jump"
14245   [(set (pc)
14246         (label_ref (match_operand 0 "" "")))]
14247   ""
14248   "jmp\t%l0"
14249   [(set_attr "type" "ibr")
14250    (set (attr "length")
14251            (if_then_else (and (ge (minus (match_dup 0) (pc))
14252                                   (const_int -126))
14253                               (lt (minus (match_dup 0) (pc))
14254                                   (const_int 128)))
14255              (const_int 2)
14256              (const_int 5)))
14257    (set_attr "modrm" "0")])
14258
14259 (define_expand "indirect_jump"
14260   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14261   ""
14262   "")
14263
14264 (define_insn "*indirect_jump"
14265   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14266   "!TARGET_64BIT"
14267   "jmp\t%A0"
14268   [(set_attr "type" "ibr")
14269    (set_attr "length_immediate" "0")])
14270
14271 (define_insn "*indirect_jump_rtx64"
14272   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14273   "TARGET_64BIT"
14274   "jmp\t%A0"
14275   [(set_attr "type" "ibr")
14276    (set_attr "length_immediate" "0")])
14277
14278 (define_expand "tablejump"
14279   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14280               (use (label_ref (match_operand 1 "" "")))])]
14281   ""
14282 {
14283   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14284      relative.  Convert the relative address to an absolute address.  */
14285   if (flag_pic)
14286     {
14287       rtx op0, op1;
14288       enum rtx_code code;
14289
14290       if (TARGET_64BIT)
14291         {
14292           code = PLUS;
14293           op0 = operands[0];
14294           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14295         }
14296       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14297         {
14298           code = PLUS;
14299           op0 = operands[0];
14300           op1 = pic_offset_table_rtx;
14301         }
14302       else
14303         {
14304           code = MINUS;
14305           op0 = pic_offset_table_rtx;
14306           op1 = operands[0];
14307         }
14308
14309       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14310                                          OPTAB_DIRECT);
14311     }
14312 })
14313
14314 (define_insn "*tablejump_1"
14315   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14316    (use (label_ref (match_operand 1 "" "")))]
14317   "!TARGET_64BIT"
14318   "jmp\t%A0"
14319   [(set_attr "type" "ibr")
14320    (set_attr "length_immediate" "0")])
14321
14322 (define_insn "*tablejump_1_rtx64"
14323   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14324    (use (label_ref (match_operand 1 "" "")))]
14325   "TARGET_64BIT"
14326   "jmp\t%A0"
14327   [(set_attr "type" "ibr")
14328    (set_attr "length_immediate" "0")])
14329 \f
14330 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14331
14332 (define_peephole2
14333   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14334    (set (match_operand:QI 1 "register_operand" "")
14335         (match_operator:QI 2 "ix86_comparison_operator"
14336           [(reg FLAGS_REG) (const_int 0)]))
14337    (set (match_operand 3 "q_regs_operand" "")
14338         (zero_extend (match_dup 1)))]
14339   "(peep2_reg_dead_p (3, operands[1])
14340     || operands_match_p (operands[1], operands[3]))
14341    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14342   [(set (match_dup 4) (match_dup 0))
14343    (set (strict_low_part (match_dup 5))
14344         (match_dup 2))]
14345 {
14346   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14347   operands[5] = gen_lowpart (QImode, operands[3]);
14348   ix86_expand_clear (operands[3]);
14349 })
14350
14351 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14352
14353 (define_peephole2
14354   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14355    (set (match_operand:QI 1 "register_operand" "")
14356         (match_operator:QI 2 "ix86_comparison_operator"
14357           [(reg FLAGS_REG) (const_int 0)]))
14358    (parallel [(set (match_operand 3 "q_regs_operand" "")
14359                    (zero_extend (match_dup 1)))
14360               (clobber (reg:CC FLAGS_REG))])]
14361   "(peep2_reg_dead_p (3, operands[1])
14362     || operands_match_p (operands[1], operands[3]))
14363    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14364   [(set (match_dup 4) (match_dup 0))
14365    (set (strict_low_part (match_dup 5))
14366         (match_dup 2))]
14367 {
14368   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14369   operands[5] = gen_lowpart (QImode, operands[3]);
14370   ix86_expand_clear (operands[3]);
14371 })
14372 \f
14373 ;; Call instructions.
14374
14375 ;; The predicates normally associated with named expanders are not properly
14376 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14377 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14378
14379 ;; Call subroutine returning no value.
14380
14381 (define_expand "call_pop"
14382   [(parallel [(call (match_operand:QI 0 "" "")
14383                     (match_operand:SI 1 "" ""))
14384               (set (reg:SI SP_REG)
14385                    (plus:SI (reg:SI SP_REG)
14386                             (match_operand:SI 3 "" "")))])]
14387   "!TARGET_64BIT"
14388 {
14389   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14390   DONE;
14391 })
14392
14393 (define_insn "*call_pop_0"
14394   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14395          (match_operand:SI 1 "" ""))
14396    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14397                             (match_operand:SI 2 "immediate_operand" "")))]
14398   "!TARGET_64BIT"
14399 {
14400   if (SIBLING_CALL_P (insn))
14401     return "jmp\t%P0";
14402   else
14403     return "call\t%P0";
14404 }
14405   [(set_attr "type" "call")])
14406
14407 (define_insn "*call_pop_1"
14408   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14409          (match_operand:SI 1 "" ""))
14410    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14411                             (match_operand:SI 2 "immediate_operand" "i")))]
14412   "!TARGET_64BIT"
14413 {
14414   if (constant_call_address_operand (operands[0], Pmode))
14415     {
14416       if (SIBLING_CALL_P (insn))
14417         return "jmp\t%P0";
14418       else
14419         return "call\t%P0";
14420     }
14421   if (SIBLING_CALL_P (insn))
14422     return "jmp\t%A0";
14423   else
14424     return "call\t%A0";
14425 }
14426   [(set_attr "type" "call")])
14427
14428 (define_expand "call"
14429   [(call (match_operand:QI 0 "" "")
14430          (match_operand 1 "" ""))
14431    (use (match_operand 2 "" ""))]
14432   ""
14433 {
14434   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14435   DONE;
14436 })
14437
14438 (define_expand "sibcall"
14439   [(call (match_operand:QI 0 "" "")
14440          (match_operand 1 "" ""))
14441    (use (match_operand 2 "" ""))]
14442   ""
14443 {
14444   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14445   DONE;
14446 })
14447
14448 (define_insn "*call_0"
14449   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14450          (match_operand 1 "" ""))]
14451   ""
14452 {
14453   if (SIBLING_CALL_P (insn))
14454     return "jmp\t%P0";
14455   else
14456     return "call\t%P0";
14457 }
14458   [(set_attr "type" "call")])
14459
14460 (define_insn "*call_1"
14461   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14462          (match_operand 1 "" ""))]
14463   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14464 {
14465   if (constant_call_address_operand (operands[0], Pmode))
14466     return "call\t%P0";
14467   return "call\t%A0";
14468 }
14469   [(set_attr "type" "call")])
14470
14471 (define_insn "*sibcall_1"
14472   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14473          (match_operand 1 "" ""))]
14474   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14475 {
14476   if (constant_call_address_operand (operands[0], Pmode))
14477     return "jmp\t%P0";
14478   return "jmp\t%A0";
14479 }
14480   [(set_attr "type" "call")])
14481
14482 (define_insn "*call_1_rex64"
14483   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14484          (match_operand 1 "" ""))]
14485   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14486 {
14487   if (constant_call_address_operand (operands[0], Pmode))
14488     return "call\t%P0";
14489   return "call\t%A0";
14490 }
14491   [(set_attr "type" "call")])
14492
14493 (define_insn "*sibcall_1_rex64"
14494   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14495          (match_operand 1 "" ""))]
14496   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14497   "jmp\t%P0"
14498   [(set_attr "type" "call")])
14499
14500 (define_insn "*sibcall_1_rex64_v"
14501   [(call (mem:QI (reg:DI R11_REG))
14502          (match_operand 0 "" ""))]
14503   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14504   "jmp\t*%%r11"
14505   [(set_attr "type" "call")])
14506
14507
14508 ;; Call subroutine, returning value in operand 0
14509
14510 (define_expand "call_value_pop"
14511   [(parallel [(set (match_operand 0 "" "")
14512                    (call (match_operand:QI 1 "" "")
14513                          (match_operand:SI 2 "" "")))
14514               (set (reg:SI SP_REG)
14515                    (plus:SI (reg:SI SP_REG)
14516                             (match_operand:SI 4 "" "")))])]
14517   "!TARGET_64BIT"
14518 {
14519   ix86_expand_call (operands[0], operands[1], operands[2],
14520                     operands[3], operands[4], 0);
14521   DONE;
14522 })
14523
14524 (define_expand "call_value"
14525   [(set (match_operand 0 "" "")
14526         (call (match_operand:QI 1 "" "")
14527               (match_operand:SI 2 "" "")))
14528    (use (match_operand:SI 3 "" ""))]
14529   ;; Operand 2 not used on the i386.
14530   ""
14531 {
14532   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14533   DONE;
14534 })
14535
14536 (define_expand "sibcall_value"
14537   [(set (match_operand 0 "" "")
14538         (call (match_operand:QI 1 "" "")
14539               (match_operand:SI 2 "" "")))
14540    (use (match_operand:SI 3 "" ""))]
14541   ;; Operand 2 not used on the i386.
14542   ""
14543 {
14544   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14545   DONE;
14546 })
14547
14548 ;; Call subroutine returning any type.
14549
14550 (define_expand "untyped_call"
14551   [(parallel [(call (match_operand 0 "" "")
14552                     (const_int 0))
14553               (match_operand 1 "" "")
14554               (match_operand 2 "" "")])]
14555   ""
14556 {
14557   int i;
14558
14559   /* In order to give reg-stack an easier job in validating two
14560      coprocessor registers as containing a possible return value,
14561      simply pretend the untyped call returns a complex long double
14562      value.  */
14563
14564   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14565                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14566                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14567                     NULL, 0);
14568
14569   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14570     {
14571       rtx set = XVECEXP (operands[2], 0, i);
14572       emit_move_insn (SET_DEST (set), SET_SRC (set));
14573     }
14574
14575   /* The optimizer does not know that the call sets the function value
14576      registers we stored in the result block.  We avoid problems by
14577      claiming that all hard registers are used and clobbered at this
14578      point.  */
14579   emit_insn (gen_blockage (const0_rtx));
14580
14581   DONE;
14582 })
14583 \f
14584 ;; Prologue and epilogue instructions
14585
14586 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14587 ;; all of memory.  This blocks insns from being moved across this point.
14588
14589 (define_insn "blockage"
14590   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14591   ""
14592   ""
14593   [(set_attr "length" "0")])
14594
14595 ;; Insn emitted into the body of a function to return from a function.
14596 ;; This is only done if the function's epilogue is known to be simple.
14597 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14598
14599 (define_expand "return"
14600   [(return)]
14601   "ix86_can_use_return_insn_p ()"
14602 {
14603   if (current_function_pops_args)
14604     {
14605       rtx popc = GEN_INT (current_function_pops_args);
14606       emit_jump_insn (gen_return_pop_internal (popc));
14607       DONE;
14608     }
14609 })
14610
14611 (define_insn "return_internal"
14612   [(return)]
14613   "reload_completed"
14614   "ret"
14615   [(set_attr "length" "1")
14616    (set_attr "length_immediate" "0")
14617    (set_attr "modrm" "0")])
14618
14619 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14620 ;; instruction Athlon and K8 have.
14621
14622 (define_insn "return_internal_long"
14623   [(return)
14624    (unspec [(const_int 0)] UNSPEC_REP)]
14625   "reload_completed"
14626   "rep {;} ret"
14627   [(set_attr "length" "1")
14628    (set_attr "length_immediate" "0")
14629    (set_attr "prefix_rep" "1")
14630    (set_attr "modrm" "0")])
14631
14632 (define_insn "return_pop_internal"
14633   [(return)
14634    (use (match_operand:SI 0 "const_int_operand" ""))]
14635   "reload_completed"
14636   "ret\t%0"
14637   [(set_attr "length" "3")
14638    (set_attr "length_immediate" "2")
14639    (set_attr "modrm" "0")])
14640
14641 (define_insn "return_indirect_internal"
14642   [(return)
14643    (use (match_operand:SI 0 "register_operand" "r"))]
14644   "reload_completed"
14645   "jmp\t%A0"
14646   [(set_attr "type" "ibr")
14647    (set_attr "length_immediate" "0")])
14648
14649 (define_insn "nop"
14650   [(const_int 0)]
14651   ""
14652   "nop"
14653   [(set_attr "length" "1")
14654    (set_attr "length_immediate" "0")
14655    (set_attr "modrm" "0")])
14656
14657 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14658 ;; branch prediction penalty for the third jump in a 16-byte
14659 ;; block on K8.
14660
14661 (define_insn "align"
14662   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14663   ""
14664 {
14665 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14666   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14667 #else
14668   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14669      The align insn is used to avoid 3 jump instructions in the row to improve
14670      branch prediction and the benefits hardly outweigh the cost of extra 8
14671      nops on the average inserted by full alignment pseudo operation.  */
14672 #endif
14673   return "";
14674 }
14675   [(set_attr "length" "16")])
14676
14677 (define_expand "prologue"
14678   [(const_int 1)]
14679   ""
14680   "ix86_expand_prologue (); DONE;")
14681
14682 (define_insn "set_got"
14683   [(set (match_operand:SI 0 "register_operand" "=r")
14684         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14685    (clobber (reg:CC FLAGS_REG))]
14686   "!TARGET_64BIT"
14687   { return output_set_got (operands[0], NULL_RTX); }
14688   [(set_attr "type" "multi")
14689    (set_attr "length" "12")])
14690
14691 (define_insn "set_got_labelled"
14692   [(set (match_operand:SI 0 "register_operand" "=r")
14693         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14694          UNSPEC_SET_GOT))
14695    (clobber (reg:CC FLAGS_REG))]
14696   "!TARGET_64BIT"
14697   { return output_set_got (operands[0], operands[1]); }
14698   [(set_attr "type" "multi")
14699    (set_attr "length" "12")])
14700
14701 (define_insn "set_got_rex64"
14702   [(set (match_operand:DI 0 "register_operand" "=r")
14703         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14704   "TARGET_64BIT"
14705   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14706   [(set_attr "type" "lea")
14707    (set_attr "length" "6")])
14708
14709 (define_expand "epilogue"
14710   [(const_int 1)]
14711   ""
14712   "ix86_expand_epilogue (1); DONE;")
14713
14714 (define_expand "sibcall_epilogue"
14715   [(const_int 1)]
14716   ""
14717   "ix86_expand_epilogue (0); DONE;")
14718
14719 (define_expand "eh_return"
14720   [(use (match_operand 0 "register_operand" ""))]
14721   ""
14722 {
14723   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14724
14725   /* Tricky bit: we write the address of the handler to which we will
14726      be returning into someone else's stack frame, one word below the
14727      stack address we wish to restore.  */
14728   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14729   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14730   tmp = gen_rtx_MEM (Pmode, tmp);
14731   emit_move_insn (tmp, ra);
14732
14733   if (Pmode == SImode)
14734     emit_jump_insn (gen_eh_return_si (sa));
14735   else
14736     emit_jump_insn (gen_eh_return_di (sa));
14737   emit_barrier ();
14738   DONE;
14739 })
14740
14741 (define_insn_and_split "eh_return_si"
14742   [(set (pc)
14743         (unspec [(match_operand:SI 0 "register_operand" "c")]
14744                  UNSPEC_EH_RETURN))]
14745   "!TARGET_64BIT"
14746   "#"
14747   "reload_completed"
14748   [(const_int 1)]
14749   "ix86_expand_epilogue (2); DONE;")
14750
14751 (define_insn_and_split "eh_return_di"
14752   [(set (pc)
14753         (unspec [(match_operand:DI 0 "register_operand" "c")]
14754                  UNSPEC_EH_RETURN))]
14755   "TARGET_64BIT"
14756   "#"
14757   "reload_completed"
14758   [(const_int 1)]
14759   "ix86_expand_epilogue (2); DONE;")
14760
14761 (define_insn "leave"
14762   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14763    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14764    (clobber (mem:BLK (scratch)))]
14765   "!TARGET_64BIT"
14766   "leave"
14767   [(set_attr "type" "leave")])
14768
14769 (define_insn "leave_rex64"
14770   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14771    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14772    (clobber (mem:BLK (scratch)))]
14773   "TARGET_64BIT"
14774   "leave"
14775   [(set_attr "type" "leave")])
14776 \f
14777 (define_expand "ffssi2"
14778   [(parallel
14779      [(set (match_operand:SI 0 "register_operand" "")
14780            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14781       (clobber (match_scratch:SI 2 ""))
14782       (clobber (reg:CC FLAGS_REG))])]
14783   ""
14784   "")
14785
14786 (define_insn_and_split "*ffs_cmove"
14787   [(set (match_operand:SI 0 "register_operand" "=r")
14788         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14789    (clobber (match_scratch:SI 2 "=&r"))
14790    (clobber (reg:CC FLAGS_REG))]
14791   "TARGET_CMOVE"
14792   "#"
14793   "&& reload_completed"
14794   [(set (match_dup 2) (const_int -1))
14795    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14796               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14797    (set (match_dup 0) (if_then_else:SI
14798                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14799                         (match_dup 2)
14800                         (match_dup 0)))
14801    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14802               (clobber (reg:CC FLAGS_REG))])]
14803   "")
14804
14805 (define_insn_and_split "*ffs_no_cmove"
14806   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14807         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14808    (clobber (match_scratch:SI 2 "=&q"))
14809    (clobber (reg:CC FLAGS_REG))]
14810   ""
14811   "#"
14812   "reload_completed"
14813   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14814               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14815    (set (strict_low_part (match_dup 3))
14816         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14817    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14818               (clobber (reg:CC FLAGS_REG))])
14819    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14820               (clobber (reg:CC FLAGS_REG))])
14821    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14822               (clobber (reg:CC FLAGS_REG))])]
14823 {
14824   operands[3] = gen_lowpart (QImode, operands[2]);
14825   ix86_expand_clear (operands[2]);
14826 })
14827
14828 (define_insn "*ffssi_1"
14829   [(set (reg:CCZ FLAGS_REG)
14830         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14831                      (const_int 0)))
14832    (set (match_operand:SI 0 "register_operand" "=r")
14833         (ctz:SI (match_dup 1)))]
14834   ""
14835   "bsf{l}\t{%1, %0|%0, %1}"
14836   [(set_attr "prefix_0f" "1")])
14837
14838 (define_expand "ffsdi2"
14839   [(parallel
14840      [(set (match_operand:DI 0 "register_operand" "")
14841            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14842       (clobber (match_scratch:DI 2 ""))
14843       (clobber (reg:CC FLAGS_REG))])]
14844   "TARGET_64BIT && TARGET_CMOVE"
14845   "")
14846
14847 (define_insn_and_split "*ffs_rex64"
14848   [(set (match_operand:DI 0 "register_operand" "=r")
14849         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14850    (clobber (match_scratch:DI 2 "=&r"))
14851    (clobber (reg:CC FLAGS_REG))]
14852   "TARGET_64BIT && TARGET_CMOVE"
14853   "#"
14854   "&& reload_completed"
14855   [(set (match_dup 2) (const_int -1))
14856    (parallel [(set (reg:CCZ FLAGS_REG)
14857                    (compare:CCZ (match_dup 1) (const_int 0)))
14858               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14859    (set (match_dup 0) (if_then_else:DI
14860                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14861                         (match_dup 2)
14862                         (match_dup 0)))
14863    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14864               (clobber (reg:CC FLAGS_REG))])]
14865   "")
14866
14867 (define_insn "*ffsdi_1"
14868   [(set (reg:CCZ FLAGS_REG)
14869         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14870                      (const_int 0)))
14871    (set (match_operand:DI 0 "register_operand" "=r")
14872         (ctz:DI (match_dup 1)))]
14873   "TARGET_64BIT"
14874   "bsf{q}\t{%1, %0|%0, %1}"
14875   [(set_attr "prefix_0f" "1")])
14876
14877 (define_insn "ctzsi2"
14878   [(set (match_operand:SI 0 "register_operand" "=r")
14879         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14880    (clobber (reg:CC FLAGS_REG))]
14881   ""
14882   "bsf{l}\t{%1, %0|%0, %1}"
14883   [(set_attr "prefix_0f" "1")])
14884
14885 (define_insn "ctzdi2"
14886   [(set (match_operand:DI 0 "register_operand" "=r")
14887         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14888    (clobber (reg:CC FLAGS_REG))]
14889   "TARGET_64BIT"
14890   "bsf{q}\t{%1, %0|%0, %1}"
14891   [(set_attr "prefix_0f" "1")])
14892
14893 (define_expand "clzsi2"
14894   [(parallel
14895      [(set (match_operand:SI 0 "register_operand" "")
14896            (minus:SI (const_int 31)
14897                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14898       (clobber (reg:CC FLAGS_REG))])
14899    (parallel
14900      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14901       (clobber (reg:CC FLAGS_REG))])]
14902   ""
14903 {
14904   if (TARGET_ABM)
14905     {
14906       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14907       DONE;
14908     }
14909 })
14910
14911 (define_insn "clzsi2_abm"
14912   [(set (match_operand:SI 0 "register_operand" "=r")
14913         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14914    (clobber (reg:CC FLAGS_REG))]
14915   "TARGET_ABM"
14916   "lzcnt{l}\t{%1, %0|%0, %1}"
14917   [(set_attr "prefix_rep" "1")
14918    (set_attr "type" "bitmanip")
14919    (set_attr "mode" "SI")])
14920
14921 (define_insn "*bsr"
14922   [(set (match_operand:SI 0 "register_operand" "=r")
14923         (minus:SI (const_int 31)
14924                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14925    (clobber (reg:CC FLAGS_REG))]
14926   ""
14927   "bsr{l}\t{%1, %0|%0, %1}"
14928   [(set_attr "prefix_0f" "1")
14929    (set_attr "mode" "SI")])
14930
14931 (define_insn "popcountsi2"
14932   [(set (match_operand:SI 0 "register_operand" "=r")
14933         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14934    (clobber (reg:CC FLAGS_REG))]
14935   "TARGET_POPCNT"
14936   "popcnt{l}\t{%1, %0|%0, %1}"
14937   [(set_attr "prefix_rep" "1")
14938    (set_attr "type" "bitmanip")
14939    (set_attr "mode" "SI")])
14940
14941 (define_insn "*popcountsi2_cmp"
14942   [(set (reg FLAGS_REG)
14943         (compare
14944           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14945           (const_int 0)))
14946    (set (match_operand:SI 0 "register_operand" "=r")
14947         (popcount:SI (match_dup 1)))]
14948   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14949   "popcnt{l}\t{%1, %0|%0, %1}"
14950   [(set_attr "prefix_rep" "1")
14951    (set_attr "type" "bitmanip")
14952    (set_attr "mode" "SI")])
14953
14954 (define_insn "*popcountsi2_cmp_zext"
14955   [(set (reg FLAGS_REG)
14956         (compare
14957           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14958           (const_int 0)))
14959    (set (match_operand:DI 0 "register_operand" "=r")
14960         (zero_extend:DI(popcount:SI (match_dup 1))))]
14961   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14962   "popcnt{l}\t{%1, %0|%0, %1}"
14963   [(set_attr "prefix_rep" "1")
14964    (set_attr "type" "bitmanip")
14965    (set_attr "mode" "SI")])
14966
14967 (define_insn "bswapsi2"
14968   [(set (match_operand:SI 0 "register_operand" "=r")
14969         (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14970    (clobber (reg:CC FLAGS_REG))]
14971   "TARGET_BSWAP"
14972   "bswap\t%k0"
14973   [(set_attr "prefix_0f" "1")
14974    (set_attr "length" "2")])
14975
14976 (define_insn "*bswapdi2_rex"
14977   [(set (match_operand:DI 0 "register_operand" "=r")
14978         (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14979    (clobber (reg:CC FLAGS_REG))]
14980   "TARGET_64BIT && TARGET_BSWAP"
14981   "bswap\t%0"
14982   [(set_attr "prefix_0f" "1")
14983    (set_attr "length" "3")])
14984
14985 (define_expand "bswapdi2"
14986   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14987                    (bswap:DI (match_operand:DI 1 "register_operand" "")))
14988               (clobber (reg:CC FLAGS_REG))])]
14989   "TARGET_BSWAP"
14990   {
14991     if (!TARGET_64BIT)
14992       {
14993         rtx tmp1, tmp2;
14994         tmp1 = gen_reg_rtx (SImode);
14995         tmp2 = gen_reg_rtx (SImode);
14996         emit_insn (gen_bswapsi2 (tmp1, gen_lowpart (SImode, operands[1])));
14997         emit_insn (gen_bswapsi2 (tmp2, gen_highpart (SImode, operands[1])));
14998         emit_move_insn (gen_lowpart (SImode, operands[0]), tmp2);
14999         emit_move_insn (gen_highpart (SImode, operands[0]), tmp1);
15000         DONE;
15001       }
15002   })
15003
15004 (define_expand "clzdi2"
15005   [(parallel
15006      [(set (match_operand:DI 0 "register_operand" "")
15007            (minus:DI (const_int 63)
15008                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15009       (clobber (reg:CC FLAGS_REG))])
15010    (parallel
15011      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15012       (clobber (reg:CC FLAGS_REG))])]
15013   "TARGET_64BIT"
15014 {
15015   if (TARGET_ABM)
15016     {
15017       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15018       DONE;
15019     }
15020 })
15021
15022 (define_insn "clzdi2_abm"
15023   [(set (match_operand:DI 0 "register_operand" "=r")
15024         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15025    (clobber (reg:CC FLAGS_REG))]
15026   "TARGET_64BIT && TARGET_ABM"
15027   "lzcnt{q}\t{%1, %0|%0, %1}"
15028   [(set_attr "prefix_rep" "1")
15029    (set_attr "type" "bitmanip")
15030    (set_attr "mode" "DI")])
15031
15032 (define_insn "*bsr_rex64"
15033   [(set (match_operand:DI 0 "register_operand" "=r")
15034         (minus:DI (const_int 63)
15035                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15036    (clobber (reg:CC FLAGS_REG))]
15037   "TARGET_64BIT"
15038   "bsr{q}\t{%1, %0|%0, %1}"
15039   [(set_attr "prefix_0f" "1")
15040    (set_attr "mode" "DI")])
15041
15042 (define_insn "popcountdi2"
15043   [(set (match_operand:DI 0 "register_operand" "=r")
15044         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15045    (clobber (reg:CC FLAGS_REG))]
15046   "TARGET_64BIT && TARGET_POPCNT"
15047   "popcnt{q}\t{%1, %0|%0, %1}"
15048   [(set_attr "prefix_rep" "1")
15049    (set_attr "type" "bitmanip")
15050    (set_attr "mode" "DI")])
15051
15052 (define_insn "*popcountdi2_cmp"
15053   [(set (reg FLAGS_REG)
15054         (compare
15055           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15056           (const_int 0)))
15057    (set (match_operand:DI 0 "register_operand" "=r")
15058         (popcount:DI (match_dup 1)))]
15059   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15060   "popcnt{q}\t{%1, %0|%0, %1}"
15061   [(set_attr "prefix_rep" "1")
15062    (set_attr "type" "bitmanip")
15063    (set_attr "mode" "DI")])
15064
15065 (define_expand "clzhi2"
15066   [(parallel
15067      [(set (match_operand:HI 0 "register_operand" "")
15068            (minus:HI (const_int 15)
15069                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15070       (clobber (reg:CC FLAGS_REG))])
15071    (parallel
15072      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15073       (clobber (reg:CC FLAGS_REG))])]
15074   ""
15075 {
15076   if (TARGET_ABM)
15077     {
15078       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15079       DONE;
15080     }
15081 })
15082
15083 (define_insn "clzhi2_abm"
15084   [(set (match_operand:HI 0 "register_operand" "=r")
15085         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15086    (clobber (reg:CC FLAGS_REG))]
15087   "TARGET_ABM"
15088   "lzcnt{w}\t{%1, %0|%0, %1}"
15089   [(set_attr "prefix_rep" "1")
15090    (set_attr "type" "bitmanip")
15091    (set_attr "mode" "HI")])
15092
15093 (define_insn "*bsrhi"
15094   [(set (match_operand:HI 0 "register_operand" "=r")
15095         (minus:HI (const_int 15)
15096                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15097    (clobber (reg:CC FLAGS_REG))]
15098   ""
15099   "bsr{w}\t{%1, %0|%0, %1}"
15100   [(set_attr "prefix_0f" "1")
15101    (set_attr "mode" "HI")])
15102
15103 (define_insn "popcounthi2"
15104   [(set (match_operand:HI 0 "register_operand" "=r")
15105         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15106    (clobber (reg:CC FLAGS_REG))]
15107   "TARGET_POPCNT"
15108   "popcnt{w}\t{%1, %0|%0, %1}"
15109   [(set_attr "prefix_rep" "1")
15110    (set_attr "type" "bitmanip")
15111    (set_attr "mode" "HI")])
15112
15113 (define_insn "*popcounthi2_cmp"
15114   [(set (reg FLAGS_REG)
15115         (compare
15116           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15117           (const_int 0)))
15118    (set (match_operand:HI 0 "register_operand" "=r")
15119         (popcount:HI (match_dup 1)))]
15120   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15121   "popcnt{w}\t{%1, %0|%0, %1}"
15122   [(set_attr "prefix_rep" "1")
15123    (set_attr "type" "bitmanip")
15124    (set_attr "mode" "HI")])
15125 \f
15126 ;; Thread-local storage patterns for ELF.
15127 ;;
15128 ;; Note that these code sequences must appear exactly as shown
15129 ;; in order to allow linker relaxation.
15130
15131 (define_insn "*tls_global_dynamic_32_gnu"
15132   [(set (match_operand:SI 0 "register_operand" "=a")
15133         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15134                     (match_operand:SI 2 "tls_symbolic_operand" "")
15135                     (match_operand:SI 3 "call_insn_operand" "")]
15136                     UNSPEC_TLS_GD))
15137    (clobber (match_scratch:SI 4 "=d"))
15138    (clobber (match_scratch:SI 5 "=c"))
15139    (clobber (reg:CC FLAGS_REG))]
15140   "!TARGET_64BIT && TARGET_GNU_TLS"
15141   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15142   [(set_attr "type" "multi")
15143    (set_attr "length" "12")])
15144
15145 (define_insn "*tls_global_dynamic_32_sun"
15146   [(set (match_operand:SI 0 "register_operand" "=a")
15147         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15148                     (match_operand:SI 2 "tls_symbolic_operand" "")
15149                     (match_operand:SI 3 "call_insn_operand" "")]
15150                     UNSPEC_TLS_GD))
15151    (clobber (match_scratch:SI 4 "=d"))
15152    (clobber (match_scratch:SI 5 "=c"))
15153    (clobber (reg:CC FLAGS_REG))]
15154   "!TARGET_64BIT && TARGET_SUN_TLS"
15155   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15156         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15157   [(set_attr "type" "multi")
15158    (set_attr "length" "14")])
15159
15160 (define_expand "tls_global_dynamic_32"
15161   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15162                    (unspec:SI
15163                     [(match_dup 2)
15164                      (match_operand:SI 1 "tls_symbolic_operand" "")
15165                      (match_dup 3)]
15166                     UNSPEC_TLS_GD))
15167               (clobber (match_scratch:SI 4 ""))
15168               (clobber (match_scratch:SI 5 ""))
15169               (clobber (reg:CC FLAGS_REG))])]
15170   ""
15171 {
15172   if (flag_pic)
15173     operands[2] = pic_offset_table_rtx;
15174   else
15175     {
15176       operands[2] = gen_reg_rtx (Pmode);
15177       emit_insn (gen_set_got (operands[2]));
15178     }
15179   if (TARGET_GNU2_TLS)
15180     {
15181        emit_insn (gen_tls_dynamic_gnu2_32
15182                   (operands[0], operands[1], operands[2]));
15183        DONE;
15184     }
15185   operands[3] = ix86_tls_get_addr ();
15186 })
15187
15188 (define_insn "*tls_global_dynamic_64"
15189   [(set (match_operand:DI 0 "register_operand" "=a")
15190         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15191                  (match_operand:DI 3 "" "")))
15192    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15193               UNSPEC_TLS_GD)]
15194   "TARGET_64BIT"
15195   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15196   [(set_attr "type" "multi")
15197    (set_attr "length" "16")])
15198
15199 (define_expand "tls_global_dynamic_64"
15200   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15201                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15202               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15203                          UNSPEC_TLS_GD)])]
15204   ""
15205 {
15206   if (TARGET_GNU2_TLS)
15207     {
15208        emit_insn (gen_tls_dynamic_gnu2_64
15209                   (operands[0], operands[1]));
15210        DONE;
15211     }
15212   operands[2] = ix86_tls_get_addr ();
15213 })
15214
15215 (define_insn "*tls_local_dynamic_base_32_gnu"
15216   [(set (match_operand:SI 0 "register_operand" "=a")
15217         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15218                     (match_operand:SI 2 "call_insn_operand" "")]
15219                    UNSPEC_TLS_LD_BASE))
15220    (clobber (match_scratch:SI 3 "=d"))
15221    (clobber (match_scratch:SI 4 "=c"))
15222    (clobber (reg:CC FLAGS_REG))]
15223   "!TARGET_64BIT && TARGET_GNU_TLS"
15224   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15225   [(set_attr "type" "multi")
15226    (set_attr "length" "11")])
15227
15228 (define_insn "*tls_local_dynamic_base_32_sun"
15229   [(set (match_operand:SI 0 "register_operand" "=a")
15230         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15231                     (match_operand:SI 2 "call_insn_operand" "")]
15232                    UNSPEC_TLS_LD_BASE))
15233    (clobber (match_scratch:SI 3 "=d"))
15234    (clobber (match_scratch:SI 4 "=c"))
15235    (clobber (reg:CC FLAGS_REG))]
15236   "!TARGET_64BIT && TARGET_SUN_TLS"
15237   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15238         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15239   [(set_attr "type" "multi")
15240    (set_attr "length" "13")])
15241
15242 (define_expand "tls_local_dynamic_base_32"
15243   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15244                    (unspec:SI [(match_dup 1) (match_dup 2)]
15245                               UNSPEC_TLS_LD_BASE))
15246               (clobber (match_scratch:SI 3 ""))
15247               (clobber (match_scratch:SI 4 ""))
15248               (clobber (reg:CC FLAGS_REG))])]
15249   ""
15250 {
15251   if (flag_pic)
15252     operands[1] = pic_offset_table_rtx;
15253   else
15254     {
15255       operands[1] = gen_reg_rtx (Pmode);
15256       emit_insn (gen_set_got (operands[1]));
15257     }
15258   if (TARGET_GNU2_TLS)
15259     {
15260        emit_insn (gen_tls_dynamic_gnu2_32
15261                   (operands[0], ix86_tls_module_base (), operands[1]));
15262        DONE;
15263     }
15264   operands[2] = ix86_tls_get_addr ();
15265 })
15266
15267 (define_insn "*tls_local_dynamic_base_64"
15268   [(set (match_operand:DI 0 "register_operand" "=a")
15269         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15270                  (match_operand:DI 2 "" "")))
15271    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15272   "TARGET_64BIT"
15273   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15274   [(set_attr "type" "multi")
15275    (set_attr "length" "12")])
15276
15277 (define_expand "tls_local_dynamic_base_64"
15278   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15279                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15280               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15281   ""
15282 {
15283   if (TARGET_GNU2_TLS)
15284     {
15285        emit_insn (gen_tls_dynamic_gnu2_64
15286                   (operands[0], ix86_tls_module_base ()));
15287        DONE;
15288     }
15289   operands[1] = ix86_tls_get_addr ();
15290 })
15291
15292 ;; Local dynamic of a single variable is a lose.  Show combine how
15293 ;; to convert that back to global dynamic.
15294
15295 (define_insn_and_split "*tls_local_dynamic_32_once"
15296   [(set (match_operand:SI 0 "register_operand" "=a")
15297         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15298                              (match_operand:SI 2 "call_insn_operand" "")]
15299                             UNSPEC_TLS_LD_BASE)
15300                  (const:SI (unspec:SI
15301                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15302                             UNSPEC_DTPOFF))))
15303    (clobber (match_scratch:SI 4 "=d"))
15304    (clobber (match_scratch:SI 5 "=c"))
15305    (clobber (reg:CC FLAGS_REG))]
15306   ""
15307   "#"
15308   ""
15309   [(parallel [(set (match_dup 0)
15310                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15311                               UNSPEC_TLS_GD))
15312               (clobber (match_dup 4))
15313               (clobber (match_dup 5))
15314               (clobber (reg:CC FLAGS_REG))])]
15315   "")
15316
15317 ;; Load and add the thread base pointer from %gs:0.
15318
15319 (define_insn "*load_tp_si"
15320   [(set (match_operand:SI 0 "register_operand" "=r")
15321         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15322   "!TARGET_64BIT"
15323   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15324   [(set_attr "type" "imov")
15325    (set_attr "modrm" "0")
15326    (set_attr "length" "7")
15327    (set_attr "memory" "load")
15328    (set_attr "imm_disp" "false")])
15329
15330 (define_insn "*add_tp_si"
15331   [(set (match_operand:SI 0 "register_operand" "=r")
15332         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15333                  (match_operand:SI 1 "register_operand" "0")))
15334    (clobber (reg:CC FLAGS_REG))]
15335   "!TARGET_64BIT"
15336   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15337   [(set_attr "type" "alu")
15338    (set_attr "modrm" "0")
15339    (set_attr "length" "7")
15340    (set_attr "memory" "load")
15341    (set_attr "imm_disp" "false")])
15342
15343 (define_insn "*load_tp_di"
15344   [(set (match_operand:DI 0 "register_operand" "=r")
15345         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15346   "TARGET_64BIT"
15347   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15348   [(set_attr "type" "imov")
15349    (set_attr "modrm" "0")
15350    (set_attr "length" "7")
15351    (set_attr "memory" "load")
15352    (set_attr "imm_disp" "false")])
15353
15354 (define_insn "*add_tp_di"
15355   [(set (match_operand:DI 0 "register_operand" "=r")
15356         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15357                  (match_operand:DI 1 "register_operand" "0")))
15358    (clobber (reg:CC FLAGS_REG))]
15359   "TARGET_64BIT"
15360   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15361   [(set_attr "type" "alu")
15362    (set_attr "modrm" "0")
15363    (set_attr "length" "7")
15364    (set_attr "memory" "load")
15365    (set_attr "imm_disp" "false")])
15366
15367 ;; GNU2 TLS patterns can be split.
15368
15369 (define_expand "tls_dynamic_gnu2_32"
15370   [(set (match_dup 3)
15371         (plus:SI (match_operand:SI 2 "register_operand" "")
15372                  (const:SI
15373                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15374                              UNSPEC_TLSDESC))))
15375    (parallel
15376     [(set (match_operand:SI 0 "register_operand" "")
15377           (unspec:SI [(match_dup 1) (match_dup 3)
15378                       (match_dup 2) (reg:SI SP_REG)]
15379                       UNSPEC_TLSDESC))
15380      (clobber (reg:CC FLAGS_REG))])]
15381   "!TARGET_64BIT && TARGET_GNU2_TLS"
15382 {
15383   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15384   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15385 })
15386
15387 (define_insn "*tls_dynamic_lea_32"
15388   [(set (match_operand:SI 0 "register_operand" "=r")
15389         (plus:SI (match_operand:SI 1 "register_operand" "b")
15390                  (const:SI
15391                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15392                               UNSPEC_TLSDESC))))]
15393   "!TARGET_64BIT && TARGET_GNU2_TLS"
15394   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15395   [(set_attr "type" "lea")
15396    (set_attr "mode" "SI")
15397    (set_attr "length" "6")
15398    (set_attr "length_address" "4")])
15399
15400 (define_insn "*tls_dynamic_call_32"
15401   [(set (match_operand:SI 0 "register_operand" "=a")
15402         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15403                     (match_operand:SI 2 "register_operand" "0")
15404                     ;; we have to make sure %ebx still points to the GOT
15405                     (match_operand:SI 3 "register_operand" "b")
15406                     (reg:SI SP_REG)]
15407                    UNSPEC_TLSDESC))
15408    (clobber (reg:CC FLAGS_REG))]
15409   "!TARGET_64BIT && TARGET_GNU2_TLS"
15410   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15411   [(set_attr "type" "call")
15412    (set_attr "length" "2")
15413    (set_attr "length_address" "0")])
15414
15415 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15416   [(set (match_operand:SI 0 "register_operand" "=&a")
15417         (plus:SI
15418          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15419                      (match_operand:SI 4 "" "")
15420                      (match_operand:SI 2 "register_operand" "b")
15421                      (reg:SI SP_REG)]
15422                     UNSPEC_TLSDESC)
15423          (const:SI (unspec:SI
15424                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15425                     UNSPEC_DTPOFF))))
15426    (clobber (reg:CC FLAGS_REG))]
15427   "!TARGET_64BIT && TARGET_GNU2_TLS"
15428   "#"
15429   ""
15430   [(set (match_dup 0) (match_dup 5))]
15431 {
15432   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15433   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15434 })
15435
15436 (define_expand "tls_dynamic_gnu2_64"
15437   [(set (match_dup 2)
15438         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15439                    UNSPEC_TLSDESC))
15440    (parallel
15441     [(set (match_operand:DI 0 "register_operand" "")
15442           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15443                      UNSPEC_TLSDESC))
15444      (clobber (reg:CC FLAGS_REG))])]
15445   "TARGET_64BIT && TARGET_GNU2_TLS"
15446 {
15447   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15448   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15449 })
15450
15451 (define_insn "*tls_dynamic_lea_64"
15452   [(set (match_operand:DI 0 "register_operand" "=r")
15453         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15454                    UNSPEC_TLSDESC))]
15455   "TARGET_64BIT && TARGET_GNU2_TLS"
15456   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15457   [(set_attr "type" "lea")
15458    (set_attr "mode" "DI")
15459    (set_attr "length" "7")
15460    (set_attr "length_address" "4")])
15461
15462 (define_insn "*tls_dynamic_call_64"
15463   [(set (match_operand:DI 0 "register_operand" "=a")
15464         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15465                     (match_operand:DI 2 "register_operand" "0")
15466                     (reg:DI SP_REG)]
15467                    UNSPEC_TLSDESC))
15468    (clobber (reg:CC FLAGS_REG))]
15469   "TARGET_64BIT && TARGET_GNU2_TLS"
15470   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15471   [(set_attr "type" "call")
15472    (set_attr "length" "2")
15473    (set_attr "length_address" "0")])
15474
15475 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15476   [(set (match_operand:DI 0 "register_operand" "=&a")
15477         (plus:DI
15478          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15479                      (match_operand:DI 3 "" "")
15480                      (reg:DI SP_REG)]
15481                     UNSPEC_TLSDESC)
15482          (const:DI (unspec:DI
15483                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15484                     UNSPEC_DTPOFF))))
15485    (clobber (reg:CC FLAGS_REG))]
15486   "TARGET_64BIT && TARGET_GNU2_TLS"
15487   "#"
15488   ""
15489   [(set (match_dup 0) (match_dup 4))]
15490 {
15491   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15492   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15493 })
15494
15495 ;;
15496 \f
15497 ;; These patterns match the binary 387 instructions for addM3, subM3,
15498 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15499 ;; SFmode.  The first is the normal insn, the second the same insn but
15500 ;; with one operand a conversion, and the third the same insn but with
15501 ;; the other operand a conversion.  The conversion may be SFmode or
15502 ;; SImode if the target mode DFmode, but only SImode if the target mode
15503 ;; is SFmode.
15504
15505 ;; Gcc is slightly more smart about handling normal two address instructions
15506 ;; so use special patterns for add and mull.
15507
15508 (define_insn "*fop_sf_comm_mixed"
15509   [(set (match_operand:SF 0 "register_operand" "=f,x")
15510         (match_operator:SF 3 "binary_fp_operator"
15511                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15512                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15513   "TARGET_MIX_SSE_I387
15514    && COMMUTATIVE_ARITH_P (operands[3])
15515    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15516   "* return output_387_binary_op (insn, operands);"
15517   [(set (attr "type")
15518         (if_then_else (eq_attr "alternative" "1")
15519            (if_then_else (match_operand:SF 3 "mult_operator" "")
15520               (const_string "ssemul")
15521               (const_string "sseadd"))
15522            (if_then_else (match_operand:SF 3 "mult_operator" "")
15523               (const_string "fmul")
15524               (const_string "fop"))))
15525    (set_attr "mode" "SF")])
15526
15527 (define_insn "*fop_sf_comm_sse"
15528   [(set (match_operand:SF 0 "register_operand" "=x")
15529         (match_operator:SF 3 "binary_fp_operator"
15530                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15531                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15532   "TARGET_SSE_MATH
15533    && COMMUTATIVE_ARITH_P (operands[3])
15534    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15535   "* return output_387_binary_op (insn, operands);"
15536   [(set (attr "type")
15537         (if_then_else (match_operand:SF 3 "mult_operator" "")
15538            (const_string "ssemul")
15539            (const_string "sseadd")))
15540    (set_attr "mode" "SF")])
15541
15542 (define_insn "*fop_sf_comm_i387"
15543   [(set (match_operand:SF 0 "register_operand" "=f")
15544         (match_operator:SF 3 "binary_fp_operator"
15545                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15546                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15547   "TARGET_80387
15548    && COMMUTATIVE_ARITH_P (operands[3])
15549    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15550   "* return output_387_binary_op (insn, operands);"
15551   [(set (attr "type")
15552         (if_then_else (match_operand:SF 3 "mult_operator" "")
15553            (const_string "fmul")
15554            (const_string "fop")))
15555    (set_attr "mode" "SF")])
15556
15557 (define_insn "*fop_sf_1_mixed"
15558   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15559         (match_operator:SF 3 "binary_fp_operator"
15560                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15561                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15562   "TARGET_MIX_SSE_I387
15563    && !COMMUTATIVE_ARITH_P (operands[3])
15564    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15565   "* return output_387_binary_op (insn, operands);"
15566   [(set (attr "type")
15567         (cond [(and (eq_attr "alternative" "2")
15568                     (match_operand:SF 3 "mult_operator" ""))
15569                  (const_string "ssemul")
15570                (and (eq_attr "alternative" "2")
15571                     (match_operand:SF 3 "div_operator" ""))
15572                  (const_string "ssediv")
15573                (eq_attr "alternative" "2")
15574                  (const_string "sseadd")
15575                (match_operand:SF 3 "mult_operator" "")
15576                  (const_string "fmul")
15577                (match_operand:SF 3 "div_operator" "")
15578                  (const_string "fdiv")
15579               ]
15580               (const_string "fop")))
15581    (set_attr "mode" "SF")])
15582
15583 (define_insn "*fop_sf_1_sse"
15584   [(set (match_operand:SF 0 "register_operand" "=x")
15585         (match_operator:SF 3 "binary_fp_operator"
15586                         [(match_operand:SF 1 "register_operand" "0")
15587                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15588   "TARGET_SSE_MATH
15589    && !COMMUTATIVE_ARITH_P (operands[3])"
15590   "* return output_387_binary_op (insn, operands);"
15591   [(set (attr "type")
15592         (cond [(match_operand:SF 3 "mult_operator" "")
15593                  (const_string "ssemul")
15594                (match_operand:SF 3 "div_operator" "")
15595                  (const_string "ssediv")
15596               ]
15597               (const_string "sseadd")))
15598    (set_attr "mode" "SF")])
15599
15600 ;; This pattern is not fully shadowed by the pattern above.
15601 (define_insn "*fop_sf_1_i387"
15602   [(set (match_operand:SF 0 "register_operand" "=f,f")
15603         (match_operator:SF 3 "binary_fp_operator"
15604                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15605                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15606   "TARGET_80387 && !TARGET_SSE_MATH
15607    && !COMMUTATIVE_ARITH_P (operands[3])
15608    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15609   "* return output_387_binary_op (insn, operands);"
15610   [(set (attr "type")
15611         (cond [(match_operand:SF 3 "mult_operator" "")
15612                  (const_string "fmul")
15613                (match_operand:SF 3 "div_operator" "")
15614                  (const_string "fdiv")
15615               ]
15616               (const_string "fop")))
15617    (set_attr "mode" "SF")])
15618
15619 ;; ??? Add SSE splitters for these!
15620 (define_insn "*fop_sf_2<mode>_i387"
15621   [(set (match_operand:SF 0 "register_operand" "=f,f")
15622         (match_operator:SF 3 "binary_fp_operator"
15623           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15624            (match_operand:SF 2 "register_operand" "0,0")]))]
15625   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15626   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15627   [(set (attr "type")
15628         (cond [(match_operand:SF 3 "mult_operator" "")
15629                  (const_string "fmul")
15630                (match_operand:SF 3 "div_operator" "")
15631                  (const_string "fdiv")
15632               ]
15633               (const_string "fop")))
15634    (set_attr "fp_int_src" "true")
15635    (set_attr "mode" "<MODE>")])
15636
15637 (define_insn "*fop_sf_3<mode>_i387"
15638   [(set (match_operand:SF 0 "register_operand" "=f,f")
15639         (match_operator:SF 3 "binary_fp_operator"
15640           [(match_operand:SF 1 "register_operand" "0,0")
15641            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15642   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15643   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15644   [(set (attr "type")
15645         (cond [(match_operand:SF 3 "mult_operator" "")
15646                  (const_string "fmul")
15647                (match_operand:SF 3 "div_operator" "")
15648                  (const_string "fdiv")
15649               ]
15650               (const_string "fop")))
15651    (set_attr "fp_int_src" "true")
15652    (set_attr "mode" "<MODE>")])
15653
15654 (define_insn "*fop_df_comm_mixed"
15655   [(set (match_operand:DF 0 "register_operand" "=f,x")
15656         (match_operator:DF 3 "binary_fp_operator"
15657           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15658            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15659   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15660    && COMMUTATIVE_ARITH_P (operands[3])
15661    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15662   "* return output_387_binary_op (insn, operands);"
15663   [(set (attr "type")
15664         (if_then_else (eq_attr "alternative" "1")
15665            (if_then_else (match_operand:DF 3 "mult_operator" "")
15666               (const_string "ssemul")
15667               (const_string "sseadd"))
15668            (if_then_else (match_operand:DF 3 "mult_operator" "")
15669               (const_string "fmul")
15670               (const_string "fop"))))
15671    (set_attr "mode" "DF")])
15672
15673 (define_insn "*fop_df_comm_sse"
15674   [(set (match_operand:DF 0 "register_operand" "=x")
15675         (match_operator:DF 3 "binary_fp_operator"
15676           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15677            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15678   "TARGET_SSE2 && TARGET_SSE_MATH
15679    && COMMUTATIVE_ARITH_P (operands[3])
15680    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15681   "* return output_387_binary_op (insn, operands);"
15682   [(set (attr "type")
15683         (if_then_else (match_operand:DF 3 "mult_operator" "")
15684            (const_string "ssemul")
15685            (const_string "sseadd")))
15686    (set_attr "mode" "DF")])
15687
15688 (define_insn "*fop_df_comm_i387"
15689   [(set (match_operand:DF 0 "register_operand" "=f")
15690         (match_operator:DF 3 "binary_fp_operator"
15691                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15692                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15693   "TARGET_80387
15694    && COMMUTATIVE_ARITH_P (operands[3])
15695    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15696   "* return output_387_binary_op (insn, operands);"
15697   [(set (attr "type")
15698         (if_then_else (match_operand:DF 3 "mult_operator" "")
15699            (const_string "fmul")
15700            (const_string "fop")))
15701    (set_attr "mode" "DF")])
15702
15703 (define_insn "*fop_df_1_mixed"
15704   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15705         (match_operator:DF 3 "binary_fp_operator"
15706           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15707            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15708   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15709    && !COMMUTATIVE_ARITH_P (operands[3])
15710    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15711   "* return output_387_binary_op (insn, operands);"
15712   [(set (attr "type")
15713         (cond [(and (eq_attr "alternative" "2")
15714                     (match_operand:DF 3 "mult_operator" ""))
15715                  (const_string "ssemul")
15716                (and (eq_attr "alternative" "2")
15717                     (match_operand:DF 3 "div_operator" ""))
15718                  (const_string "ssediv")
15719                (eq_attr "alternative" "2")
15720                  (const_string "sseadd")
15721                (match_operand:DF 3 "mult_operator" "")
15722                  (const_string "fmul")
15723                (match_operand:DF 3 "div_operator" "")
15724                  (const_string "fdiv")
15725               ]
15726               (const_string "fop")))
15727    (set_attr "mode" "DF")])
15728
15729 (define_insn "*fop_df_1_sse"
15730   [(set (match_operand:DF 0 "register_operand" "=x")
15731         (match_operator:DF 3 "binary_fp_operator"
15732           [(match_operand:DF 1 "register_operand" "0")
15733            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15734   "TARGET_SSE2 && TARGET_SSE_MATH
15735    && !COMMUTATIVE_ARITH_P (operands[3])"
15736   "* return output_387_binary_op (insn, operands);"
15737   [(set_attr "mode" "DF")
15738    (set (attr "type")
15739         (cond [(match_operand:DF 3 "mult_operator" "")
15740                  (const_string "ssemul")
15741                (match_operand:DF 3 "div_operator" "")
15742                  (const_string "ssediv")
15743               ]
15744               (const_string "sseadd")))])
15745
15746 ;; This pattern is not fully shadowed by the pattern above.
15747 (define_insn "*fop_df_1_i387"
15748   [(set (match_operand:DF 0 "register_operand" "=f,f")
15749         (match_operator:DF 3 "binary_fp_operator"
15750                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15751                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15752   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15753    && !COMMUTATIVE_ARITH_P (operands[3])
15754    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15755   "* return output_387_binary_op (insn, operands);"
15756   [(set (attr "type")
15757         (cond [(match_operand:DF 3 "mult_operator" "")
15758                  (const_string "fmul")
15759                (match_operand:DF 3 "div_operator" "")
15760                  (const_string "fdiv")
15761               ]
15762               (const_string "fop")))
15763    (set_attr "mode" "DF")])
15764
15765 ;; ??? Add SSE splitters for these!
15766 (define_insn "*fop_df_2<mode>_i387"
15767   [(set (match_operand:DF 0 "register_operand" "=f,f")
15768         (match_operator:DF 3 "binary_fp_operator"
15769            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15770             (match_operand:DF 2 "register_operand" "0,0")]))]
15771   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15772    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15773   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15774   [(set (attr "type")
15775         (cond [(match_operand:DF 3 "mult_operator" "")
15776                  (const_string "fmul")
15777                (match_operand:DF 3 "div_operator" "")
15778                  (const_string "fdiv")
15779               ]
15780               (const_string "fop")))
15781    (set_attr "fp_int_src" "true")
15782    (set_attr "mode" "<MODE>")])
15783
15784 (define_insn "*fop_df_3<mode>_i387"
15785   [(set (match_operand:DF 0 "register_operand" "=f,f")
15786         (match_operator:DF 3 "binary_fp_operator"
15787            [(match_operand:DF 1 "register_operand" "0,0")
15788             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15789   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15790    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15791   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15792   [(set (attr "type")
15793         (cond [(match_operand:DF 3 "mult_operator" "")
15794                  (const_string "fmul")
15795                (match_operand:DF 3 "div_operator" "")
15796                  (const_string "fdiv")
15797               ]
15798               (const_string "fop")))
15799    (set_attr "fp_int_src" "true")
15800    (set_attr "mode" "<MODE>")])
15801
15802 (define_insn "*fop_df_4_i387"
15803   [(set (match_operand:DF 0 "register_operand" "=f,f")
15804         (match_operator:DF 3 "binary_fp_operator"
15805            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15806             (match_operand:DF 2 "register_operand" "0,f")]))]
15807   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15808    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15809   "* return output_387_binary_op (insn, operands);"
15810   [(set (attr "type")
15811         (cond [(match_operand:DF 3 "mult_operator" "")
15812                  (const_string "fmul")
15813                (match_operand:DF 3 "div_operator" "")
15814                  (const_string "fdiv")
15815               ]
15816               (const_string "fop")))
15817    (set_attr "mode" "SF")])
15818
15819 (define_insn "*fop_df_5_i387"
15820   [(set (match_operand:DF 0 "register_operand" "=f,f")
15821         (match_operator:DF 3 "binary_fp_operator"
15822           [(match_operand:DF 1 "register_operand" "0,f")
15823            (float_extend:DF
15824             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15825   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15826   "* return output_387_binary_op (insn, operands);"
15827   [(set (attr "type")
15828         (cond [(match_operand:DF 3 "mult_operator" "")
15829                  (const_string "fmul")
15830                (match_operand:DF 3 "div_operator" "")
15831                  (const_string "fdiv")
15832               ]
15833               (const_string "fop")))
15834    (set_attr "mode" "SF")])
15835
15836 (define_insn "*fop_df_6_i387"
15837   [(set (match_operand:DF 0 "register_operand" "=f,f")
15838         (match_operator:DF 3 "binary_fp_operator"
15839           [(float_extend:DF
15840             (match_operand:SF 1 "register_operand" "0,f"))
15841            (float_extend:DF
15842             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15843   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15844   "* return output_387_binary_op (insn, operands);"
15845   [(set (attr "type")
15846         (cond [(match_operand:DF 3 "mult_operator" "")
15847                  (const_string "fmul")
15848                (match_operand:DF 3 "div_operator" "")
15849                  (const_string "fdiv")
15850               ]
15851               (const_string "fop")))
15852    (set_attr "mode" "SF")])
15853
15854 (define_insn "*fop_xf_comm_i387"
15855   [(set (match_operand:XF 0 "register_operand" "=f")
15856         (match_operator:XF 3 "binary_fp_operator"
15857                         [(match_operand:XF 1 "register_operand" "%0")
15858                          (match_operand:XF 2 "register_operand" "f")]))]
15859   "TARGET_80387
15860    && COMMUTATIVE_ARITH_P (operands[3])"
15861   "* return output_387_binary_op (insn, operands);"
15862   [(set (attr "type")
15863         (if_then_else (match_operand:XF 3 "mult_operator" "")
15864            (const_string "fmul")
15865            (const_string "fop")))
15866    (set_attr "mode" "XF")])
15867
15868 (define_insn "*fop_xf_1_i387"
15869   [(set (match_operand:XF 0 "register_operand" "=f,f")
15870         (match_operator:XF 3 "binary_fp_operator"
15871                         [(match_operand:XF 1 "register_operand" "0,f")
15872                          (match_operand:XF 2 "register_operand" "f,0")]))]
15873   "TARGET_80387
15874    && !COMMUTATIVE_ARITH_P (operands[3])"
15875   "* return output_387_binary_op (insn, operands);"
15876   [(set (attr "type")
15877         (cond [(match_operand:XF 3 "mult_operator" "")
15878                  (const_string "fmul")
15879                (match_operand:XF 3 "div_operator" "")
15880                  (const_string "fdiv")
15881               ]
15882               (const_string "fop")))
15883    (set_attr "mode" "XF")])
15884
15885 (define_insn "*fop_xf_2<mode>_i387"
15886   [(set (match_operand:XF 0 "register_operand" "=f,f")
15887         (match_operator:XF 3 "binary_fp_operator"
15888            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15889             (match_operand:XF 2 "register_operand" "0,0")]))]
15890   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15891   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15892   [(set (attr "type")
15893         (cond [(match_operand:XF 3 "mult_operator" "")
15894                  (const_string "fmul")
15895                (match_operand:XF 3 "div_operator" "")
15896                  (const_string "fdiv")
15897               ]
15898               (const_string "fop")))
15899    (set_attr "fp_int_src" "true")
15900    (set_attr "mode" "<MODE>")])
15901
15902 (define_insn "*fop_xf_3<mode>_i387"
15903   [(set (match_operand:XF 0 "register_operand" "=f,f")
15904         (match_operator:XF 3 "binary_fp_operator"
15905           [(match_operand:XF 1 "register_operand" "0,0")
15906            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15907   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15908   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15909   [(set (attr "type")
15910         (cond [(match_operand:XF 3 "mult_operator" "")
15911                  (const_string "fmul")
15912                (match_operand:XF 3 "div_operator" "")
15913                  (const_string "fdiv")
15914               ]
15915               (const_string "fop")))
15916    (set_attr "fp_int_src" "true")
15917    (set_attr "mode" "<MODE>")])
15918
15919 (define_insn "*fop_xf_4_i387"
15920   [(set (match_operand:XF 0 "register_operand" "=f,f")
15921         (match_operator:XF 3 "binary_fp_operator"
15922            [(float_extend:XF
15923               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15924             (match_operand:XF 2 "register_operand" "0,f")]))]
15925   "TARGET_80387"
15926   "* return output_387_binary_op (insn, operands);"
15927   [(set (attr "type")
15928         (cond [(match_operand:XF 3 "mult_operator" "")
15929                  (const_string "fmul")
15930                (match_operand:XF 3 "div_operator" "")
15931                  (const_string "fdiv")
15932               ]
15933               (const_string "fop")))
15934    (set_attr "mode" "SF")])
15935
15936 (define_insn "*fop_xf_5_i387"
15937   [(set (match_operand:XF 0 "register_operand" "=f,f")
15938         (match_operator:XF 3 "binary_fp_operator"
15939           [(match_operand:XF 1 "register_operand" "0,f")
15940            (float_extend:XF
15941              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15942   "TARGET_80387"
15943   "* return output_387_binary_op (insn, operands);"
15944   [(set (attr "type")
15945         (cond [(match_operand:XF 3 "mult_operator" "")
15946                  (const_string "fmul")
15947                (match_operand:XF 3 "div_operator" "")
15948                  (const_string "fdiv")
15949               ]
15950               (const_string "fop")))
15951    (set_attr "mode" "SF")])
15952
15953 (define_insn "*fop_xf_6_i387"
15954   [(set (match_operand:XF 0 "register_operand" "=f,f")
15955         (match_operator:XF 3 "binary_fp_operator"
15956           [(float_extend:XF
15957              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15958            (float_extend:XF
15959              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15960   "TARGET_80387"
15961   "* return output_387_binary_op (insn, operands);"
15962   [(set (attr "type")
15963         (cond [(match_operand:XF 3 "mult_operator" "")
15964                  (const_string "fmul")
15965                (match_operand:XF 3 "div_operator" "")
15966                  (const_string "fdiv")
15967               ]
15968               (const_string "fop")))
15969    (set_attr "mode" "SF")])
15970
15971 (define_split
15972   [(set (match_operand 0 "register_operand" "")
15973         (match_operator 3 "binary_fp_operator"
15974            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15975             (match_operand 2 "register_operand" "")]))]
15976   "TARGET_80387 && reload_completed
15977    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15978   [(const_int 0)]
15979 {
15980   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15981   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15982   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15983                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15984                                           GET_MODE (operands[3]),
15985                                           operands[4],
15986                                           operands[2])));
15987   ix86_free_from_memory (GET_MODE (operands[1]));
15988   DONE;
15989 })
15990
15991 (define_split
15992   [(set (match_operand 0 "register_operand" "")
15993         (match_operator 3 "binary_fp_operator"
15994            [(match_operand 1 "register_operand" "")
15995             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15996   "TARGET_80387 && reload_completed
15997    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15998   [(const_int 0)]
15999 {
16000   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16001   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16002   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16003                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16004                                           GET_MODE (operands[3]),
16005                                           operands[1],
16006                                           operands[4])));
16007   ix86_free_from_memory (GET_MODE (operands[2]));
16008   DONE;
16009 })
16010 \f
16011 ;; FPU special functions.
16012
16013 ;; This pattern implements a no-op XFmode truncation for
16014 ;; all fancy i386 XFmode math functions.
16015
16016 (define_insn "truncxf<mode>2_i387_noop_unspec"
16017   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16018         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16019         UNSPEC_TRUNC_NOOP))]
16020   "TARGET_USE_FANCY_MATH_387"
16021   "* return output_387_reg_move (insn, operands);"
16022   [(set_attr "type" "fmov")
16023    (set_attr "mode" "<MODE>")])
16024
16025 (define_insn "sqrtxf2"
16026   [(set (match_operand:XF 0 "register_operand" "=f")
16027         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16028   "TARGET_USE_FANCY_MATH_387"
16029   "fsqrt"
16030   [(set_attr "type" "fpspc")
16031    (set_attr "mode" "XF")
16032    (set_attr "athlon_decode" "direct")
16033    (set_attr "amdfam10_decode" "direct")])
16034
16035 (define_insn "sqrt_extend<mode>xf2_i387"
16036   [(set (match_operand:XF 0 "register_operand" "=f")
16037         (sqrt:XF
16038           (float_extend:XF
16039             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16040   "TARGET_USE_FANCY_MATH_387"
16041   "fsqrt"
16042   [(set_attr "type" "fpspc")
16043    (set_attr "mode" "XF")
16044    (set_attr "athlon_decode" "direct")   
16045    (set_attr "amdfam10_decode" "direct")])
16046
16047 (define_insn "*sqrt<mode>2_sse"
16048   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16049         (sqrt:SSEMODEF
16050           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16051   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16052   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16053   [(set_attr "type" "sse")
16054    (set_attr "mode" "<MODE>")
16055    (set_attr "athlon_decode" "*")
16056    (set_attr "amdfam10_decode" "*")])
16057
16058 (define_expand "sqrt<mode>2"
16059   [(set (match_operand:X87MODEF12 0 "register_operand" "")
16060         (sqrt:X87MODEF12
16061           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16062   "TARGET_USE_FANCY_MATH_387
16063    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16064 {
16065   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16066     {
16067       rtx op0 = gen_reg_rtx (XFmode);
16068       rtx op1 = force_reg (<MODE>mode, operands[1]);
16069
16070       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16071       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16072       DONE;
16073    }
16074 })
16075
16076 (define_insn "fpremxf4_i387"
16077   [(set (match_operand:XF 0 "register_operand" "=f")
16078         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16079                     (match_operand:XF 3 "register_operand" "1")]
16080                    UNSPEC_FPREM_F))
16081    (set (match_operand:XF 1 "register_operand" "=u")
16082         (unspec:XF [(match_dup 2) (match_dup 3)]
16083                    UNSPEC_FPREM_U))
16084    (set (reg:CCFP FPSR_REG)
16085         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16086   "TARGET_USE_FANCY_MATH_387"
16087   "fprem"
16088   [(set_attr "type" "fpspc")
16089    (set_attr "mode" "XF")])
16090
16091 (define_expand "fmodxf3"
16092   [(use (match_operand:XF 0 "register_operand" ""))
16093    (use (match_operand:XF 1 "register_operand" ""))
16094    (use (match_operand:XF 2 "register_operand" ""))]
16095   "TARGET_USE_FANCY_MATH_387"
16096 {
16097   rtx label = gen_label_rtx ();
16098
16099   emit_label (label);
16100
16101   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16102                                 operands[1], operands[2]));
16103   ix86_emit_fp_unordered_jump (label);
16104
16105   emit_move_insn (operands[0], operands[1]);
16106   DONE;
16107 })
16108
16109 (define_expand "fmod<mode>3"
16110   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16111    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16112    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16113   "TARGET_USE_FANCY_MATH_387"
16114 {
16115   rtx label = gen_label_rtx ();
16116
16117   rtx op1 = gen_reg_rtx (XFmode);
16118   rtx op2 = gen_reg_rtx (XFmode);
16119
16120   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16121   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16122
16123   emit_label (label);
16124   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16125   ix86_emit_fp_unordered_jump (label);
16126
16127   /* Truncate the result properly for strict SSE math.  */
16128   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16129       && !TARGET_MIX_SSE_I387)
16130     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16131   else
16132     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16133
16134   DONE;
16135 })
16136
16137 (define_insn "fprem1xf4_i387"
16138   [(set (match_operand:XF 0 "register_operand" "=f")
16139         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16140                     (match_operand:XF 3 "register_operand" "1")]
16141                    UNSPEC_FPREM1_F))
16142    (set (match_operand:XF 1 "register_operand" "=u")
16143         (unspec:XF [(match_dup 2) (match_dup 3)]
16144                    UNSPEC_FPREM1_U))
16145    (set (reg:CCFP FPSR_REG)
16146         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16147   "TARGET_USE_FANCY_MATH_387"
16148   "fprem1"
16149   [(set_attr "type" "fpspc")
16150    (set_attr "mode" "XF")])
16151
16152 (define_expand "remainderxf3"
16153   [(use (match_operand:XF 0 "register_operand" ""))
16154    (use (match_operand:XF 1 "register_operand" ""))
16155    (use (match_operand:XF 2 "register_operand" ""))]
16156   "TARGET_USE_FANCY_MATH_387"
16157 {
16158   rtx label = gen_label_rtx ();
16159
16160   emit_label (label);
16161
16162   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16163                                  operands[1], operands[2]));
16164   ix86_emit_fp_unordered_jump (label);
16165
16166   emit_move_insn (operands[0], operands[1]);
16167   DONE;
16168 })
16169
16170 (define_expand "remainder<mode>3"
16171   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16172    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16173    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16174   "TARGET_USE_FANCY_MATH_387"
16175 {
16176   rtx label = gen_label_rtx ();
16177
16178   rtx op1 = gen_reg_rtx (XFmode);
16179   rtx op2 = gen_reg_rtx (XFmode);
16180
16181   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16182   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16183
16184   emit_label (label);
16185
16186   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16187   ix86_emit_fp_unordered_jump (label);
16188
16189   /* Truncate the result properly for strict SSE math.  */
16190   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16191       && !TARGET_MIX_SSE_I387)
16192     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16193   else
16194     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16195
16196   DONE;
16197 })
16198
16199 (define_insn "*sinxf2_i387"
16200   [(set (match_operand:XF 0 "register_operand" "=f")
16201         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16202   "TARGET_USE_FANCY_MATH_387
16203    && flag_unsafe_math_optimizations"
16204   "fsin"
16205   [(set_attr "type" "fpspc")
16206    (set_attr "mode" "XF")])
16207
16208 (define_insn "*sin_extend<mode>xf2_i387"
16209   [(set (match_operand:XF 0 "register_operand" "=f")
16210         (unspec:XF [(float_extend:XF
16211                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16212                    UNSPEC_SIN))]
16213   "TARGET_USE_FANCY_MATH_387
16214    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16215        || TARGET_MIX_SSE_I387)
16216    && flag_unsafe_math_optimizations"
16217   "fsin"
16218   [(set_attr "type" "fpspc")
16219    (set_attr "mode" "XF")])
16220
16221 (define_insn "*cosxf2_i387"
16222   [(set (match_operand:XF 0 "register_operand" "=f")
16223         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16224   "TARGET_USE_FANCY_MATH_387
16225    && flag_unsafe_math_optimizations"
16226   "fcos"
16227   [(set_attr "type" "fpspc")
16228    (set_attr "mode" "XF")])
16229
16230 (define_insn "*cos_extend<mode>xf2_i387"
16231   [(set (match_operand:XF 0 "register_operand" "=f")
16232         (unspec:XF [(float_extend:XF
16233                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16234                    UNSPEC_COS))]
16235   "TARGET_USE_FANCY_MATH_387
16236    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16237        || TARGET_MIX_SSE_I387)
16238    && flag_unsafe_math_optimizations"
16239   "fcos"
16240   [(set_attr "type" "fpspc")
16241    (set_attr "mode" "XF")])
16242
16243 ;; When sincos pattern is defined, sin and cos builtin functions will be
16244 ;; expanded to sincos pattern with one of its outputs left unused.
16245 ;; CSE pass will figure out if two sincos patterns can be combined,
16246 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16247 ;; depending on the unused output.
16248
16249 (define_insn "sincosxf3"
16250   [(set (match_operand:XF 0 "register_operand" "=f")
16251         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16252                    UNSPEC_SINCOS_COS))
16253    (set (match_operand:XF 1 "register_operand" "=u")
16254         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16255   "TARGET_USE_FANCY_MATH_387
16256    && flag_unsafe_math_optimizations"
16257   "fsincos"
16258   [(set_attr "type" "fpspc")
16259    (set_attr "mode" "XF")])
16260
16261 (define_split
16262   [(set (match_operand:XF 0 "register_operand" "")
16263         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16264                    UNSPEC_SINCOS_COS))
16265    (set (match_operand:XF 1 "register_operand" "")
16266         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16267   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16268    && !reload_completed && !reload_in_progress"
16269   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16270   "")
16271
16272 (define_split
16273   [(set (match_operand:XF 0 "register_operand" "")
16274         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16275                    UNSPEC_SINCOS_COS))
16276    (set (match_operand:XF 1 "register_operand" "")
16277         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16278   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16279    && !reload_completed && !reload_in_progress"
16280   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16281   "")
16282
16283 (define_insn "sincos_extend<mode>xf3_i387"
16284   [(set (match_operand:XF 0 "register_operand" "=f")
16285         (unspec:XF [(float_extend:XF
16286                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16287                    UNSPEC_SINCOS_COS))
16288    (set (match_operand:XF 1 "register_operand" "=u")
16289         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16290   "TARGET_USE_FANCY_MATH_387
16291    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16292        || TARGET_MIX_SSE_I387)
16293    && flag_unsafe_math_optimizations"
16294   "fsincos"
16295   [(set_attr "type" "fpspc")
16296    (set_attr "mode" "XF")])
16297
16298 (define_split
16299   [(set (match_operand:XF 0 "register_operand" "")
16300         (unspec:XF [(float_extend:XF
16301                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16302                    UNSPEC_SINCOS_COS))
16303    (set (match_operand:XF 1 "register_operand" "")
16304         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16305   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16306    && !reload_completed && !reload_in_progress"
16307   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16308   "")
16309
16310 (define_split
16311   [(set (match_operand:XF 0 "register_operand" "")
16312         (unspec:XF [(float_extend:XF
16313                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16314                    UNSPEC_SINCOS_COS))
16315    (set (match_operand:XF 1 "register_operand" "")
16316         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16317   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16318    && !reload_completed && !reload_in_progress"
16319   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16320   "")
16321
16322 (define_expand "sincos<mode>3"
16323   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16324    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16325    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16326   "TARGET_USE_FANCY_MATH_387
16327    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16328        || TARGET_MIX_SSE_I387)
16329    && flag_unsafe_math_optimizations"
16330 {
16331   rtx op0 = gen_reg_rtx (XFmode);
16332   rtx op1 = gen_reg_rtx (XFmode);
16333
16334   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16335   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16336   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16337   DONE;
16338 })
16339
16340 (define_insn "fptanxf4_i387"
16341   [(set (match_operand:XF 0 "register_operand" "=f")
16342         (match_operand:XF 3 "const_double_operand" "F"))
16343    (set (match_operand:XF 1 "register_operand" "=u")
16344         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16345                    UNSPEC_TAN))]
16346   "TARGET_USE_FANCY_MATH_387
16347    && flag_unsafe_math_optimizations
16348    && standard_80387_constant_p (operands[3]) == 2"
16349   "fptan"
16350   [(set_attr "type" "fpspc")
16351    (set_attr "mode" "XF")])
16352
16353 (define_insn "fptan_extend<mode>xf4_i387"
16354   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16355         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16356    (set (match_operand:XF 1 "register_operand" "=u")
16357         (unspec:XF [(float_extend:XF
16358                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16359                    UNSPEC_TAN))]
16360   "TARGET_USE_FANCY_MATH_387
16361    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16362        || TARGET_MIX_SSE_I387)
16363    && flag_unsafe_math_optimizations
16364    && standard_80387_constant_p (operands[3]) == 2"
16365   "fptan"
16366   [(set_attr "type" "fpspc")
16367    (set_attr "mode" "XF")])
16368
16369 (define_expand "tanxf2"
16370   [(use (match_operand:XF 0 "register_operand" ""))
16371    (use (match_operand:XF 1 "register_operand" ""))]
16372   "TARGET_USE_FANCY_MATH_387
16373    && flag_unsafe_math_optimizations"
16374 {
16375   rtx one = gen_reg_rtx (XFmode);
16376   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16377
16378   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16379   DONE;
16380 })
16381
16382 (define_expand "tan<mode>2"
16383   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16384    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16385   "TARGET_USE_FANCY_MATH_387
16386    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16387        || TARGET_MIX_SSE_I387)
16388    && flag_unsafe_math_optimizations"
16389 {
16390   rtx op0 = gen_reg_rtx (XFmode);
16391
16392   rtx one = gen_reg_rtx (<MODE>mode);
16393   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16394
16395   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16396                                              operands[1], op2));
16397   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16398   DONE;
16399 })
16400
16401 (define_insn "*fpatanxf3_i387"
16402   [(set (match_operand:XF 0 "register_operand" "=f")
16403         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16404                     (match_operand:XF 2 "register_operand" "u")]
16405                    UNSPEC_FPATAN))
16406    (clobber (match_scratch:XF 3 "=2"))]
16407   "TARGET_USE_FANCY_MATH_387
16408    && flag_unsafe_math_optimizations"
16409   "fpatan"
16410   [(set_attr "type" "fpspc")
16411    (set_attr "mode" "XF")])
16412
16413 (define_insn "fpatan_extend<mode>xf3_i387"
16414   [(set (match_operand:XF 0 "register_operand" "=f")
16415         (unspec:XF [(float_extend:XF
16416                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16417                     (float_extend:XF
16418                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
16419                    UNSPEC_FPATAN))
16420    (clobber (match_scratch:XF 3 "=2"))]
16421   "TARGET_USE_FANCY_MATH_387
16422    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16423        || TARGET_MIX_SSE_I387)
16424    && flag_unsafe_math_optimizations"
16425   "fpatan"
16426   [(set_attr "type" "fpspc")
16427    (set_attr "mode" "XF")])
16428
16429 (define_expand "atan2xf3"
16430   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16431                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16432                                (match_operand:XF 1 "register_operand" "")]
16433                               UNSPEC_FPATAN))
16434               (clobber (match_scratch:XF 3 ""))])]
16435   "TARGET_USE_FANCY_MATH_387
16436    && flag_unsafe_math_optimizations"
16437   "")
16438
16439 (define_expand "atan2<mode>3"
16440   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16441    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16442    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16443   "TARGET_USE_FANCY_MATH_387
16444    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16445        || TARGET_MIX_SSE_I387)
16446    && flag_unsafe_math_optimizations"
16447 {
16448   rtx op0 = gen_reg_rtx (XFmode);
16449
16450   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16451   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16452   DONE;
16453 })
16454
16455 (define_expand "atanxf2"
16456   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16457                    (unspec:XF [(match_dup 2)
16458                                (match_operand:XF 1 "register_operand" "")]
16459                               UNSPEC_FPATAN))
16460               (clobber (match_scratch:XF 3 ""))])]
16461   "TARGET_USE_FANCY_MATH_387
16462    && flag_unsafe_math_optimizations"
16463 {
16464   operands[2] = gen_reg_rtx (XFmode);
16465   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16466 })
16467
16468 (define_expand "atan<mode>2"
16469   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16470    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16471   "TARGET_USE_FANCY_MATH_387
16472    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16473        || TARGET_MIX_SSE_I387)
16474    && flag_unsafe_math_optimizations"
16475 {
16476   rtx op0 = gen_reg_rtx (XFmode);
16477
16478   rtx op2 = gen_reg_rtx (<MODE>mode);
16479   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16480
16481   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16482   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16483   DONE;
16484 })
16485
16486 (define_expand "asinxf2"
16487   [(set (match_dup 2)
16488         (mult:XF (match_operand:XF 1 "register_operand" "")
16489                  (match_dup 1)))
16490    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16491    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16492    (parallel [(set (match_operand:XF 0 "register_operand" "")
16493                    (unspec:XF [(match_dup 5) (match_dup 1)]
16494                               UNSPEC_FPATAN))
16495               (clobber (match_scratch:XF 6 ""))])]
16496   "TARGET_USE_FANCY_MATH_387
16497    && flag_unsafe_math_optimizations && !optimize_size"
16498 {
16499   int i;
16500
16501   for (i = 2; i < 6; i++)
16502     operands[i] = gen_reg_rtx (XFmode);
16503
16504   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16505 })
16506
16507 (define_expand "asin<mode>2"
16508   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16509    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16510  "TARGET_USE_FANCY_MATH_387
16511    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16512        || TARGET_MIX_SSE_I387)
16513    && flag_unsafe_math_optimizations && !optimize_size"
16514 {
16515   rtx op0 = gen_reg_rtx (XFmode);
16516   rtx op1 = gen_reg_rtx (XFmode);
16517
16518   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16519   emit_insn (gen_asinxf2 (op0, op1));
16520   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16521   DONE;
16522 })
16523
16524 (define_expand "acosxf2"
16525   [(set (match_dup 2)
16526         (mult:XF (match_operand:XF 1 "register_operand" "")
16527                  (match_dup 1)))
16528    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16529    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16530    (parallel [(set (match_operand:XF 0 "register_operand" "")
16531                    (unspec:XF [(match_dup 1) (match_dup 5)]
16532                               UNSPEC_FPATAN))
16533               (clobber (match_scratch:XF 6 ""))])]
16534   "TARGET_USE_FANCY_MATH_387
16535    && flag_unsafe_math_optimizations && !optimize_size"
16536 {
16537   int i;
16538
16539   for (i = 2; i < 6; i++)
16540     operands[i] = gen_reg_rtx (XFmode);
16541
16542   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16543 })
16544
16545 (define_expand "acos<mode>2"
16546   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16547    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16548  "TARGET_USE_FANCY_MATH_387
16549    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16550        || TARGET_MIX_SSE_I387)
16551    && flag_unsafe_math_optimizations && !optimize_size"
16552 {
16553   rtx op0 = gen_reg_rtx (XFmode);
16554   rtx op1 = gen_reg_rtx (XFmode);
16555
16556   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16557   emit_insn (gen_acosxf2 (op0, op1));
16558   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16559   DONE;
16560 })
16561
16562 (define_insn "fyl2xxf3_i387"
16563   [(set (match_operand:XF 0 "register_operand" "=f")
16564         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16565                     (match_operand:XF 2 "register_operand" "u")]
16566                    UNSPEC_FYL2X))
16567    (clobber (match_scratch:XF 3 "=2"))]
16568   "TARGET_USE_FANCY_MATH_387
16569    && flag_unsafe_math_optimizations"
16570   "fyl2x"
16571   [(set_attr "type" "fpspc")
16572    (set_attr "mode" "XF")])
16573
16574 (define_insn "fyl2x_extend<mode>xf3_i387"
16575   [(set (match_operand:XF 0 "register_operand" "=f")
16576         (unspec:XF [(float_extend:XF
16577                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16578                     (match_operand:XF 2 "register_operand" "u")]
16579                    UNSPEC_FYL2X))
16580    (clobber (match_scratch:XF 3 "=2"))]
16581   "TARGET_USE_FANCY_MATH_387
16582    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16583        || TARGET_MIX_SSE_I387)
16584    && flag_unsafe_math_optimizations"
16585   "fyl2x"
16586   [(set_attr "type" "fpspc")
16587    (set_attr "mode" "XF")])
16588
16589 (define_expand "logxf2"
16590   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16591                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16592                                (match_dup 2)] UNSPEC_FYL2X))
16593               (clobber (match_scratch:XF 3 ""))])]
16594   "TARGET_USE_FANCY_MATH_387
16595    && flag_unsafe_math_optimizations"
16596 {
16597   operands[2] = gen_reg_rtx (XFmode);
16598   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16599 })
16600
16601 (define_expand "log<mode>2"
16602   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16603    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16604   "TARGET_USE_FANCY_MATH_387
16605    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16606        || TARGET_MIX_SSE_I387)
16607    && flag_unsafe_math_optimizations"
16608 {
16609   rtx op0 = gen_reg_rtx (XFmode);
16610
16611   rtx op2 = gen_reg_rtx (XFmode);
16612   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16613
16614   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16615   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16616   DONE;
16617 })
16618
16619 (define_expand "log10xf2"
16620   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16621                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16622                                (match_dup 2)] UNSPEC_FYL2X))
16623               (clobber (match_scratch:XF 3 ""))])]
16624   "TARGET_USE_FANCY_MATH_387
16625    && flag_unsafe_math_optimizations"
16626 {
16627   operands[2] = gen_reg_rtx (XFmode);
16628   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16629 })
16630
16631 (define_expand "log10<mode>2"
16632   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16633    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16634   "TARGET_USE_FANCY_MATH_387
16635    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16636        || TARGET_MIX_SSE_I387)
16637    && flag_unsafe_math_optimizations"
16638 {
16639   rtx op0 = gen_reg_rtx (XFmode);
16640
16641   rtx op2 = gen_reg_rtx (XFmode);
16642   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16643
16644   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16645   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16646   DONE;
16647 })
16648
16649 (define_expand "log2xf2"
16650   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16651                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16652                                (match_dup 2)] UNSPEC_FYL2X))
16653               (clobber (match_scratch:XF 3 ""))])]
16654   "TARGET_USE_FANCY_MATH_387
16655    && flag_unsafe_math_optimizations"
16656 {
16657   operands[2] = gen_reg_rtx (XFmode);
16658   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16659 })
16660
16661 (define_expand "log2<mode>2"
16662   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16663    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16664   "TARGET_USE_FANCY_MATH_387
16665    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16666        || TARGET_MIX_SSE_I387)
16667    && flag_unsafe_math_optimizations"
16668 {
16669   rtx op0 = gen_reg_rtx (XFmode);
16670
16671   rtx op2 = gen_reg_rtx (XFmode);
16672   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16673
16674   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16675   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16676   DONE;
16677 })
16678
16679 (define_insn "fyl2xp1xf3_i387"
16680   [(set (match_operand:XF 0 "register_operand" "=f")
16681         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16682                     (match_operand:XF 2 "register_operand" "u")]
16683                    UNSPEC_FYL2XP1))
16684    (clobber (match_scratch:XF 3 "=2"))]
16685   "TARGET_USE_FANCY_MATH_387
16686    && flag_unsafe_math_optimizations"
16687   "fyl2xp1"
16688   [(set_attr "type" "fpspc")
16689    (set_attr "mode" "XF")])
16690
16691 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16692   [(set (match_operand:XF 0 "register_operand" "=f")
16693         (unspec:XF [(float_extend:XF
16694                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16695                     (match_operand:XF 2 "register_operand" "u")]
16696                    UNSPEC_FYL2XP1))
16697    (clobber (match_scratch:XF 3 "=2"))]
16698   "TARGET_USE_FANCY_MATH_387
16699    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16700        || TARGET_MIX_SSE_I387)
16701    && flag_unsafe_math_optimizations"
16702   "fyl2xp1"
16703   [(set_attr "type" "fpspc")
16704    (set_attr "mode" "XF")])
16705
16706 (define_expand "log1pxf2"
16707   [(use (match_operand:XF 0 "register_operand" ""))
16708    (use (match_operand:XF 1 "register_operand" ""))]
16709   "TARGET_USE_FANCY_MATH_387
16710    && flag_unsafe_math_optimizations && !optimize_size"
16711 {
16712   ix86_emit_i387_log1p (operands[0], operands[1]);
16713   DONE;
16714 })
16715
16716 (define_expand "log1p<mode>2"
16717   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16718    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16719   "TARGET_USE_FANCY_MATH_387
16720    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16721        || TARGET_MIX_SSE_I387)
16722    && flag_unsafe_math_optimizations && !optimize_size"
16723 {
16724   rtx op0 = gen_reg_rtx (XFmode);
16725
16726   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16727
16728   ix86_emit_i387_log1p (op0, operands[1]);
16729   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16730   DONE;
16731 })
16732
16733 (define_insn "fxtractxf3_i387"
16734   [(set (match_operand:XF 0 "register_operand" "=f")
16735         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16736                    UNSPEC_XTRACT_FRACT))
16737    (set (match_operand:XF 1 "register_operand" "=u")
16738         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16739   "TARGET_USE_FANCY_MATH_387
16740    && flag_unsafe_math_optimizations"
16741   "fxtract"
16742   [(set_attr "type" "fpspc")
16743    (set_attr "mode" "XF")])
16744
16745 (define_insn "fxtract_extend<mode>xf3_i387"
16746   [(set (match_operand:XF 0 "register_operand" "=f")
16747         (unspec:XF [(float_extend:XF
16748                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16749                    UNSPEC_XTRACT_FRACT))
16750    (set (match_operand:XF 1 "register_operand" "=u")
16751         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16752   "TARGET_USE_FANCY_MATH_387
16753    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16754        || TARGET_MIX_SSE_I387)
16755    && flag_unsafe_math_optimizations"
16756   "fxtract"
16757   [(set_attr "type" "fpspc")
16758    (set_attr "mode" "XF")])
16759
16760 (define_expand "logbxf2"
16761   [(parallel [(set (match_dup 2)
16762                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16763                               UNSPEC_XTRACT_FRACT))
16764               (set (match_operand:XF 0 "register_operand" "")
16765                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16766   "TARGET_USE_FANCY_MATH_387
16767    && flag_unsafe_math_optimizations"
16768 {
16769   operands[2] = gen_reg_rtx (XFmode);
16770 })
16771
16772 (define_expand "logb<mode>2"
16773   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16774    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16775   "TARGET_USE_FANCY_MATH_387
16776    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16777        || TARGET_MIX_SSE_I387)
16778    && flag_unsafe_math_optimizations"
16779 {
16780   rtx op0 = gen_reg_rtx (XFmode);
16781   rtx op1 = gen_reg_rtx (XFmode);
16782
16783   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16784   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16785   DONE;
16786 })
16787
16788 (define_expand "ilogbxf2"
16789   [(use (match_operand:SI 0 "register_operand" ""))
16790    (use (match_operand:XF 1 "register_operand" ""))]
16791   "TARGET_USE_FANCY_MATH_387
16792    && flag_unsafe_math_optimizations && !optimize_size"
16793 {
16794   rtx op0 = gen_reg_rtx (XFmode);
16795   rtx op1 = gen_reg_rtx (XFmode);
16796
16797   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16798   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16799   DONE;
16800 })
16801
16802 (define_expand "ilogb<mode>2"
16803   [(use (match_operand:SI 0 "register_operand" ""))
16804    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16805   "TARGET_USE_FANCY_MATH_387
16806    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16807        || TARGET_MIX_SSE_I387)
16808    && flag_unsafe_math_optimizations && !optimize_size"
16809 {
16810   rtx op0 = gen_reg_rtx (XFmode);
16811   rtx op1 = gen_reg_rtx (XFmode);
16812
16813   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16814   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16815   DONE;
16816 })
16817
16818 (define_insn "*f2xm1xf2_i387"
16819   [(set (match_operand:XF 0 "register_operand" "=f")
16820         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16821                    UNSPEC_F2XM1))]
16822   "TARGET_USE_FANCY_MATH_387
16823    && flag_unsafe_math_optimizations"
16824   "f2xm1"
16825   [(set_attr "type" "fpspc")
16826    (set_attr "mode" "XF")])
16827
16828 (define_insn "*fscalexf4_i387"
16829   [(set (match_operand:XF 0 "register_operand" "=f")
16830         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16831                     (match_operand:XF 3 "register_operand" "1")]
16832                    UNSPEC_FSCALE_FRACT))
16833    (set (match_operand:XF 1 "register_operand" "=u")
16834         (unspec:XF [(match_dup 2) (match_dup 3)]
16835                    UNSPEC_FSCALE_EXP))]
16836   "TARGET_USE_FANCY_MATH_387
16837    && flag_unsafe_math_optimizations"
16838   "fscale"
16839   [(set_attr "type" "fpspc")
16840    (set_attr "mode" "XF")])
16841
16842 (define_expand "expNcorexf3"
16843   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16844                                (match_operand:XF 2 "register_operand" "")))
16845    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16846    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16847    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16848    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16849    (parallel [(set (match_operand:XF 0 "register_operand" "")
16850                    (unspec:XF [(match_dup 8) (match_dup 4)]
16851                               UNSPEC_FSCALE_FRACT))
16852               (set (match_dup 9)
16853                    (unspec:XF [(match_dup 8) (match_dup 4)]
16854                               UNSPEC_FSCALE_EXP))])]
16855   "TARGET_USE_FANCY_MATH_387
16856    && flag_unsafe_math_optimizations && !optimize_size"
16857 {
16858   int i;
16859
16860   for (i = 3; i < 10; i++)
16861     operands[i] = gen_reg_rtx (XFmode);
16862
16863   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16864 })
16865
16866 (define_expand "expxf2"
16867   [(use (match_operand:XF 0 "register_operand" ""))
16868    (use (match_operand:XF 1 "register_operand" ""))]
16869   "TARGET_USE_FANCY_MATH_387
16870    && flag_unsafe_math_optimizations && !optimize_size"
16871 {
16872   rtx op2 = gen_reg_rtx (XFmode);
16873   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16874
16875   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16876   DONE;
16877 })
16878
16879 (define_expand "exp<mode>2"
16880   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16881    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16882  "TARGET_USE_FANCY_MATH_387
16883    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16884        || TARGET_MIX_SSE_I387)
16885    && flag_unsafe_math_optimizations && !optimize_size"
16886 {
16887   rtx op0 = gen_reg_rtx (XFmode);
16888   rtx op1 = gen_reg_rtx (XFmode);
16889
16890   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16891   emit_insn (gen_expxf2 (op0, op1));
16892   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16893   DONE;
16894 })
16895
16896 (define_expand "exp10xf2"
16897   [(use (match_operand:XF 0 "register_operand" ""))
16898    (use (match_operand:XF 1 "register_operand" ""))]
16899   "TARGET_USE_FANCY_MATH_387
16900    && flag_unsafe_math_optimizations && !optimize_size"
16901 {
16902   rtx op2 = gen_reg_rtx (XFmode);
16903   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16904
16905   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16906   DONE;
16907 })
16908
16909 (define_expand "exp10<mode>2"
16910   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16911    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16912  "TARGET_USE_FANCY_MATH_387
16913    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16914        || TARGET_MIX_SSE_I387)
16915    && flag_unsafe_math_optimizations && !optimize_size"
16916 {
16917   rtx op0 = gen_reg_rtx (XFmode);
16918   rtx op1 = gen_reg_rtx (XFmode);
16919
16920   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16921   emit_insn (gen_exp10xf2 (op0, op1));
16922   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16923   DONE;
16924 })
16925
16926 (define_expand "exp2xf2"
16927   [(use (match_operand:XF 0 "register_operand" ""))
16928    (use (match_operand:XF 1 "register_operand" ""))]
16929   "TARGET_USE_FANCY_MATH_387
16930    && flag_unsafe_math_optimizations && !optimize_size"
16931 {
16932   rtx op2 = gen_reg_rtx (XFmode);
16933   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16934
16935   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16936   DONE;
16937 })
16938
16939 (define_expand "exp2<mode>2"
16940   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16941    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16942  "TARGET_USE_FANCY_MATH_387
16943    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16944        || TARGET_MIX_SSE_I387)
16945    && flag_unsafe_math_optimizations && !optimize_size"
16946 {
16947   rtx op0 = gen_reg_rtx (XFmode);
16948   rtx op1 = gen_reg_rtx (XFmode);
16949
16950   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16951   emit_insn (gen_exp2xf2 (op0, op1));
16952   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16953   DONE;
16954 })
16955
16956 (define_expand "expm1xf2"
16957   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16958                                (match_dup 2)))
16959    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16960    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16961    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16962    (parallel [(set (match_dup 7)
16963                    (unspec:XF [(match_dup 6) (match_dup 4)]
16964                               UNSPEC_FSCALE_FRACT))
16965                    (set (match_dup 8)
16966                    (unspec:XF [(match_dup 6) (match_dup 4)]
16967                               UNSPEC_FSCALE_EXP))])
16968    (parallel [(set (match_dup 10)
16969                    (unspec:XF [(match_dup 9) (match_dup 8)]
16970                               UNSPEC_FSCALE_FRACT))
16971               (set (match_dup 11)
16972                    (unspec:XF [(match_dup 9) (match_dup 8)]
16973                               UNSPEC_FSCALE_EXP))])
16974    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16975    (set (match_operand:XF 0 "register_operand" "")
16976         (plus:XF (match_dup 12) (match_dup 7)))]
16977   "TARGET_USE_FANCY_MATH_387
16978    && flag_unsafe_math_optimizations && !optimize_size"
16979 {
16980   int i;
16981
16982   for (i = 2; i < 13; i++)
16983     operands[i] = gen_reg_rtx (XFmode);
16984  
16985   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16986   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16987 })
16988
16989 (define_expand "expm1<mode>2"
16990   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16991    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16992  "TARGET_USE_FANCY_MATH_387
16993    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16994        || TARGET_MIX_SSE_I387)
16995    && flag_unsafe_math_optimizations && !optimize_size"
16996 {
16997   rtx op0 = gen_reg_rtx (XFmode);
16998   rtx op1 = gen_reg_rtx (XFmode);
16999
17000   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17001   emit_insn (gen_expm1xf2 (op0, op1));
17002   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17003   DONE;
17004 })
17005
17006 (define_expand "ldexpxf3"
17007   [(set (match_dup 3)
17008         (float:XF (match_operand:SI 2 "register_operand" "")))
17009    (parallel [(set (match_operand:XF 0 " register_operand" "")
17010                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17011                                (match_dup 3)]
17012                               UNSPEC_FSCALE_FRACT))
17013               (set (match_dup 4)
17014                    (unspec:XF [(match_dup 1) (match_dup 3)]
17015                               UNSPEC_FSCALE_EXP))])]
17016   "TARGET_USE_FANCY_MATH_387
17017    && flag_unsafe_math_optimizations && !optimize_size"
17018 {
17019   operands[3] = gen_reg_rtx (XFmode);
17020   operands[4] = gen_reg_rtx (XFmode);
17021 })
17022
17023 (define_expand "ldexp<mode>3"
17024   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17025    (use (match_operand:X87MODEF12 1 "general_operand" ""))
17026    (use (match_operand:SI 2 "register_operand" ""))]
17027  "TARGET_USE_FANCY_MATH_387
17028    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17029        || TARGET_MIX_SSE_I387)
17030    && flag_unsafe_math_optimizations && !optimize_size"
17031 {
17032   rtx op0 = gen_reg_rtx (XFmode);
17033   rtx op1 = gen_reg_rtx (XFmode);
17034
17035   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17036   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17037   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17038   DONE;
17039 })
17040 \f
17041
17042 (define_insn "frndintxf2"
17043   [(set (match_operand:XF 0 "register_operand" "=f")
17044         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17045          UNSPEC_FRNDINT))]
17046   "TARGET_USE_FANCY_MATH_387
17047    && flag_unsafe_math_optimizations"
17048   "frndint"
17049   [(set_attr "type" "fpspc")
17050    (set_attr "mode" "XF")])
17051
17052 (define_expand "rintdf2"
17053   [(use (match_operand:DF 0 "register_operand" ""))
17054    (use (match_operand:DF 1 "register_operand" ""))]
17055   "(TARGET_USE_FANCY_MATH_387
17056     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17057     && flag_unsafe_math_optimizations)
17058    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17059        && !flag_trapping_math
17060        && !optimize_size)"
17061 {
17062   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17063       && !flag_trapping_math
17064       && !optimize_size)
17065     ix86_expand_rint (operand0, operand1);
17066   else
17067     {
17068       rtx op0 = gen_reg_rtx (XFmode);
17069       rtx op1 = gen_reg_rtx (XFmode);
17070
17071       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17072       emit_insn (gen_frndintxf2 (op0, op1));
17073
17074       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17075     }
17076   DONE;
17077 })
17078
17079 (define_expand "rintsf2"
17080   [(use (match_operand:SF 0 "register_operand" ""))
17081    (use (match_operand:SF 1 "register_operand" ""))]
17082   "(TARGET_USE_FANCY_MATH_387
17083     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17084     && flag_unsafe_math_optimizations)
17085    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17086        && !flag_trapping_math
17087        && !optimize_size)"
17088 {
17089   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17090       && !flag_trapping_math
17091       && !optimize_size)
17092     ix86_expand_rint (operand0, operand1);
17093   else
17094     {
17095       rtx op0 = gen_reg_rtx (XFmode);
17096       rtx op1 = gen_reg_rtx (XFmode);
17097
17098       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17099       emit_insn (gen_frndintxf2 (op0, op1));
17100
17101       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17102     }
17103   DONE;
17104 })
17105
17106 (define_expand "rintxf2"
17107   [(use (match_operand:XF 0 "register_operand" ""))
17108    (use (match_operand:XF 1 "register_operand" ""))]
17109   "TARGET_USE_FANCY_MATH_387
17110    && flag_unsafe_math_optimizations && !optimize_size"
17111 {
17112   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17113   DONE;
17114 })
17115
17116 (define_expand "roundsf2"
17117   [(match_operand:SF 0 "register_operand" "")
17118    (match_operand:SF 1 "nonimmediate_operand" "")]
17119   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17120    && !flag_trapping_math && !flag_rounding_math
17121    && !optimize_size"
17122 {
17123   ix86_expand_round (operand0, operand1);
17124   DONE;
17125 })
17126
17127 (define_expand "rounddf2"
17128   [(match_operand:DF 0 "register_operand" "")
17129    (match_operand:DF 1 "nonimmediate_operand" "")]
17130   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17131    && !flag_trapping_math && !flag_rounding_math
17132    && !optimize_size"
17133 {
17134   if (TARGET_64BIT)
17135     ix86_expand_round (operand0, operand1);
17136   else
17137     ix86_expand_rounddf_32 (operand0, operand1);
17138   DONE;
17139 })
17140
17141 (define_insn_and_split "*fistdi2_1"
17142   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17143         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17144          UNSPEC_FIST))]
17145   "TARGET_USE_FANCY_MATH_387
17146    && !(reload_completed || reload_in_progress)"
17147   "#"
17148   "&& 1"
17149   [(const_int 0)]
17150 {
17151   if (memory_operand (operands[0], VOIDmode))
17152     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17153   else
17154     {
17155       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17156       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17157                                          operands[2]));
17158     }
17159   DONE;
17160 }
17161   [(set_attr "type" "fpspc")
17162    (set_attr "mode" "DI")])
17163
17164 (define_insn "fistdi2"
17165   [(set (match_operand:DI 0 "memory_operand" "=m")
17166         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17167          UNSPEC_FIST))
17168    (clobber (match_scratch:XF 2 "=&1f"))]
17169   "TARGET_USE_FANCY_MATH_387"
17170   "* return output_fix_trunc (insn, operands, 0);"
17171   [(set_attr "type" "fpspc")
17172    (set_attr "mode" "DI")])
17173
17174 (define_insn "fistdi2_with_temp"
17175   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17176         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17177          UNSPEC_FIST))
17178    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17179    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17180   "TARGET_USE_FANCY_MATH_387"
17181   "#"
17182   [(set_attr "type" "fpspc")
17183    (set_attr "mode" "DI")])
17184
17185 (define_split
17186   [(set (match_operand:DI 0 "register_operand" "")
17187         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17188          UNSPEC_FIST))
17189    (clobber (match_operand:DI 2 "memory_operand" ""))
17190    (clobber (match_scratch 3 ""))]
17191   "reload_completed"
17192   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17193               (clobber (match_dup 3))])
17194    (set (match_dup 0) (match_dup 2))]
17195   "")
17196
17197 (define_split
17198   [(set (match_operand:DI 0 "memory_operand" "")
17199         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17200          UNSPEC_FIST))
17201    (clobber (match_operand:DI 2 "memory_operand" ""))
17202    (clobber (match_scratch 3 ""))]
17203   "reload_completed"
17204   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17205               (clobber (match_dup 3))])]
17206   "")
17207
17208 (define_insn_and_split "*fist<mode>2_1"
17209   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17210         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17211          UNSPEC_FIST))]
17212   "TARGET_USE_FANCY_MATH_387
17213    && !(reload_completed || reload_in_progress)"
17214   "#"
17215   "&& 1"
17216   [(const_int 0)]
17217 {
17218   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17219   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17220                                         operands[2]));
17221   DONE;
17222 }
17223   [(set_attr "type" "fpspc")
17224    (set_attr "mode" "<MODE>")])
17225
17226 (define_insn "fist<mode>2"
17227   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17228         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17229          UNSPEC_FIST))]
17230   "TARGET_USE_FANCY_MATH_387"
17231   "* return output_fix_trunc (insn, operands, 0);"
17232   [(set_attr "type" "fpspc")
17233    (set_attr "mode" "<MODE>")])
17234
17235 (define_insn "fist<mode>2_with_temp"
17236   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17237         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17238          UNSPEC_FIST))
17239    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17240   "TARGET_USE_FANCY_MATH_387"
17241   "#"
17242   [(set_attr "type" "fpspc")
17243    (set_attr "mode" "<MODE>")])
17244
17245 (define_split
17246   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17247         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17248          UNSPEC_FIST))
17249    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17250   "reload_completed"
17251   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17252                        UNSPEC_FIST))
17253    (set (match_dup 0) (match_dup 2))]
17254   "")
17255
17256 (define_split
17257   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17258         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17259          UNSPEC_FIST))
17260    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17261   "reload_completed"
17262   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17263                        UNSPEC_FIST))]
17264   "")
17265
17266 (define_expand "lrintxf<mode>2"
17267   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17268      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17269       UNSPEC_FIST))]
17270   "TARGET_USE_FANCY_MATH_387"
17271   "")
17272
17273 (define_expand "lrint<mode>di2"
17274   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17275      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17276       UNSPEC_FIX_NOTRUNC))]
17277   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17278   "")
17279
17280 (define_expand "lrint<mode>si2"
17281   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17282      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17283       UNSPEC_FIX_NOTRUNC))]
17284   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17285   "")
17286
17287 (define_expand "lround<mode>di2"
17288   [(match_operand:DI 0 "nonimmediate_operand" "")
17289    (match_operand:SSEMODEF 1 "register_operand" "")]
17290   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17291    && !flag_trapping_math && !flag_rounding_math
17292    && !optimize_size"
17293 {
17294   ix86_expand_lround (operand0, operand1);
17295   DONE;
17296 })
17297
17298 (define_expand "lround<mode>si2"
17299   [(match_operand:SI 0 "nonimmediate_operand" "")
17300    (match_operand:SSEMODEF 1 "register_operand" "")]
17301   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17302    && !flag_trapping_math && !flag_rounding_math
17303    && !optimize_size"
17304 {
17305   ix86_expand_lround (operand0, operand1);
17306   DONE;
17307 })
17308
17309 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17310 (define_insn_and_split "frndintxf2_floor"
17311   [(set (match_operand:XF 0 "register_operand" "=f")
17312         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17313          UNSPEC_FRNDINT_FLOOR))
17314    (clobber (reg:CC FLAGS_REG))]
17315   "TARGET_USE_FANCY_MATH_387
17316    && flag_unsafe_math_optimizations
17317    && !(reload_completed || reload_in_progress)"
17318   "#"
17319   "&& 1"
17320   [(const_int 0)]
17321 {
17322   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17323
17324   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17325   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17326
17327   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17328                                         operands[2], operands[3]));
17329   DONE;
17330 }
17331   [(set_attr "type" "frndint")
17332    (set_attr "i387_cw" "floor")
17333    (set_attr "mode" "XF")])
17334
17335 (define_insn "frndintxf2_floor_i387"
17336   [(set (match_operand:XF 0 "register_operand" "=f")
17337         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17338          UNSPEC_FRNDINT_FLOOR))
17339    (use (match_operand:HI 2 "memory_operand" "m"))
17340    (use (match_operand:HI 3 "memory_operand" "m"))]
17341   "TARGET_USE_FANCY_MATH_387
17342    && flag_unsafe_math_optimizations"
17343   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17344   [(set_attr "type" "frndint")
17345    (set_attr "i387_cw" "floor")
17346    (set_attr "mode" "XF")])
17347
17348 (define_expand "floorxf2"
17349   [(use (match_operand:XF 0 "register_operand" ""))
17350    (use (match_operand:XF 1 "register_operand" ""))]
17351   "TARGET_USE_FANCY_MATH_387
17352    && flag_unsafe_math_optimizations && !optimize_size"
17353 {
17354   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17355   DONE;
17356 })
17357
17358 (define_expand "floordf2"
17359   [(use (match_operand:DF 0 "register_operand" ""))
17360    (use (match_operand:DF 1 "register_operand" ""))]
17361   "((TARGET_USE_FANCY_MATH_387
17362      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17363      && flag_unsafe_math_optimizations)
17364     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17365         && !flag_trapping_math))
17366    && !optimize_size"
17367 {
17368   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17369       && !flag_trapping_math)
17370     {
17371       if (TARGET_64BIT)
17372         ix86_expand_floorceil (operand0, operand1, true);
17373       else
17374         ix86_expand_floorceildf_32 (operand0, operand1, true);
17375     }
17376   else
17377     {
17378       rtx op0 = gen_reg_rtx (XFmode);
17379       rtx op1 = gen_reg_rtx (XFmode);
17380
17381       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17382       emit_insn (gen_frndintxf2_floor (op0, op1));
17383
17384       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17385     }
17386   DONE;
17387 })
17388
17389 (define_expand "floorsf2"
17390   [(use (match_operand:SF 0 "register_operand" ""))
17391    (use (match_operand:SF 1 "register_operand" ""))]
17392   "((TARGET_USE_FANCY_MATH_387
17393      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17394      && flag_unsafe_math_optimizations)
17395     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17396         && !flag_trapping_math))
17397    && !optimize_size"
17398 {
17399   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17400       && !flag_trapping_math)
17401     ix86_expand_floorceil (operand0, operand1, true);
17402   else
17403     {
17404       rtx op0 = gen_reg_rtx (XFmode);
17405       rtx op1 = gen_reg_rtx (XFmode);
17406
17407       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17408       emit_insn (gen_frndintxf2_floor (op0, op1));
17409
17410       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17411     }
17412   DONE;
17413 })
17414
17415 (define_insn_and_split "*fist<mode>2_floor_1"
17416   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17417         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17418          UNSPEC_FIST_FLOOR))
17419    (clobber (reg:CC FLAGS_REG))]
17420   "TARGET_USE_FANCY_MATH_387
17421    && flag_unsafe_math_optimizations
17422    && !(reload_completed || reload_in_progress)"
17423   "#"
17424   "&& 1"
17425   [(const_int 0)]
17426 {
17427   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17428
17429   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17430   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17431   if (memory_operand (operands[0], VOIDmode))
17432     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17433                                       operands[2], operands[3]));
17434   else
17435     {
17436       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17437       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17438                                                   operands[2], operands[3],
17439                                                   operands[4]));
17440     }
17441   DONE;
17442 }
17443   [(set_attr "type" "fistp")
17444    (set_attr "i387_cw" "floor")
17445    (set_attr "mode" "<MODE>")])
17446
17447 (define_insn "fistdi2_floor"
17448   [(set (match_operand:DI 0 "memory_operand" "=m")
17449         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17450          UNSPEC_FIST_FLOOR))
17451    (use (match_operand:HI 2 "memory_operand" "m"))
17452    (use (match_operand:HI 3 "memory_operand" "m"))
17453    (clobber (match_scratch:XF 4 "=&1f"))]
17454   "TARGET_USE_FANCY_MATH_387
17455    && flag_unsafe_math_optimizations"
17456   "* return output_fix_trunc (insn, operands, 0);"
17457   [(set_attr "type" "fistp")
17458    (set_attr "i387_cw" "floor")
17459    (set_attr "mode" "DI")])
17460
17461 (define_insn "fistdi2_floor_with_temp"
17462   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17463         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17464          UNSPEC_FIST_FLOOR))
17465    (use (match_operand:HI 2 "memory_operand" "m,m"))
17466    (use (match_operand:HI 3 "memory_operand" "m,m"))
17467    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17468    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17469   "TARGET_USE_FANCY_MATH_387
17470    && flag_unsafe_math_optimizations"
17471   "#"
17472   [(set_attr "type" "fistp")
17473    (set_attr "i387_cw" "floor")
17474    (set_attr "mode" "DI")])
17475
17476 (define_split
17477   [(set (match_operand:DI 0 "register_operand" "")
17478         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17479          UNSPEC_FIST_FLOOR))
17480    (use (match_operand:HI 2 "memory_operand" ""))
17481    (use (match_operand:HI 3 "memory_operand" ""))
17482    (clobber (match_operand:DI 4 "memory_operand" ""))
17483    (clobber (match_scratch 5 ""))]
17484   "reload_completed"
17485   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17486               (use (match_dup 2))
17487               (use (match_dup 3))
17488               (clobber (match_dup 5))])
17489    (set (match_dup 0) (match_dup 4))]
17490   "")
17491
17492 (define_split
17493   [(set (match_operand:DI 0 "memory_operand" "")
17494         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17495          UNSPEC_FIST_FLOOR))
17496    (use (match_operand:HI 2 "memory_operand" ""))
17497    (use (match_operand:HI 3 "memory_operand" ""))
17498    (clobber (match_operand:DI 4 "memory_operand" ""))
17499    (clobber (match_scratch 5 ""))]
17500   "reload_completed"
17501   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17502               (use (match_dup 2))
17503               (use (match_dup 3))
17504               (clobber (match_dup 5))])]
17505   "")
17506
17507 (define_insn "fist<mode>2_floor"
17508   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17509         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17510          UNSPEC_FIST_FLOOR))
17511    (use (match_operand:HI 2 "memory_operand" "m"))
17512    (use (match_operand:HI 3 "memory_operand" "m"))]
17513   "TARGET_USE_FANCY_MATH_387
17514    && flag_unsafe_math_optimizations"
17515   "* return output_fix_trunc (insn, operands, 0);"
17516   [(set_attr "type" "fistp")
17517    (set_attr "i387_cw" "floor")
17518    (set_attr "mode" "<MODE>")])
17519
17520 (define_insn "fist<mode>2_floor_with_temp"
17521   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17522         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17523          UNSPEC_FIST_FLOOR))
17524    (use (match_operand:HI 2 "memory_operand" "m,m"))
17525    (use (match_operand:HI 3 "memory_operand" "m,m"))
17526    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17527   "TARGET_USE_FANCY_MATH_387
17528    && flag_unsafe_math_optimizations"
17529   "#"
17530   [(set_attr "type" "fistp")
17531    (set_attr "i387_cw" "floor")
17532    (set_attr "mode" "<MODE>")])
17533
17534 (define_split
17535   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17536         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17537          UNSPEC_FIST_FLOOR))
17538    (use (match_operand:HI 2 "memory_operand" ""))
17539    (use (match_operand:HI 3 "memory_operand" ""))
17540    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17541   "reload_completed"
17542   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17543                                   UNSPEC_FIST_FLOOR))
17544               (use (match_dup 2))
17545               (use (match_dup 3))])
17546    (set (match_dup 0) (match_dup 4))]
17547   "")
17548
17549 (define_split
17550   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17551         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17552          UNSPEC_FIST_FLOOR))
17553    (use (match_operand:HI 2 "memory_operand" ""))
17554    (use (match_operand:HI 3 "memory_operand" ""))
17555    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17556   "reload_completed"
17557   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17558                                   UNSPEC_FIST_FLOOR))
17559               (use (match_dup 2))
17560               (use (match_dup 3))])]
17561   "")
17562
17563 (define_expand "lfloorxf<mode>2"
17564   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17565                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17566                     UNSPEC_FIST_FLOOR))
17567               (clobber (reg:CC FLAGS_REG))])]
17568   "TARGET_USE_FANCY_MATH_387
17569    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17570    && flag_unsafe_math_optimizations"
17571   "")
17572
17573 (define_expand "lfloor<mode>di2"
17574   [(match_operand:DI 0 "nonimmediate_operand" "")
17575    (match_operand:SSEMODEF 1 "register_operand" "")]
17576   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17577    && !flag_trapping_math
17578    && !optimize_size"
17579 {
17580   ix86_expand_lfloorceil (operand0, operand1, true);
17581   DONE;
17582 })
17583
17584 (define_expand "lfloor<mode>si2"
17585   [(match_operand:SI 0 "nonimmediate_operand" "")
17586    (match_operand:SSEMODEF 1 "register_operand" "")]
17587   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17588    && !flag_trapping_math
17589    && (!optimize_size || !TARGET_64BIT)"
17590 {
17591   ix86_expand_lfloorceil (operand0, operand1, true);
17592   DONE;
17593 })
17594
17595 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17596 (define_insn_and_split "frndintxf2_ceil"
17597   [(set (match_operand:XF 0 "register_operand" "=f")
17598         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17599          UNSPEC_FRNDINT_CEIL))
17600    (clobber (reg:CC FLAGS_REG))]
17601   "TARGET_USE_FANCY_MATH_387
17602    && flag_unsafe_math_optimizations
17603    && !(reload_completed || reload_in_progress)"
17604   "#"
17605   "&& 1"
17606   [(const_int 0)]
17607 {
17608   ix86_optimize_mode_switching[I387_CEIL] = 1;
17609
17610   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17611   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17612
17613   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17614                                        operands[2], operands[3]));
17615   DONE;
17616 }
17617   [(set_attr "type" "frndint")
17618    (set_attr "i387_cw" "ceil")
17619    (set_attr "mode" "XF")])
17620
17621 (define_insn "frndintxf2_ceil_i387"
17622   [(set (match_operand:XF 0 "register_operand" "=f")
17623         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17624          UNSPEC_FRNDINT_CEIL))
17625    (use (match_operand:HI 2 "memory_operand" "m"))
17626    (use (match_operand:HI 3 "memory_operand" "m"))]
17627   "TARGET_USE_FANCY_MATH_387
17628    && flag_unsafe_math_optimizations"
17629   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17630   [(set_attr "type" "frndint")
17631    (set_attr "i387_cw" "ceil")
17632    (set_attr "mode" "XF")])
17633
17634 (define_expand "ceilxf2"
17635   [(use (match_operand:XF 0 "register_operand" ""))
17636    (use (match_operand:XF 1 "register_operand" ""))]
17637   "TARGET_USE_FANCY_MATH_387
17638    && flag_unsafe_math_optimizations && !optimize_size"
17639 {
17640   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17641   DONE;
17642 })
17643
17644 (define_expand "ceildf2"
17645   [(use (match_operand:DF 0 "register_operand" ""))
17646    (use (match_operand:DF 1 "register_operand" ""))]
17647   "((TARGET_USE_FANCY_MATH_387
17648      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17649      && flag_unsafe_math_optimizations)
17650     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17651         && !flag_trapping_math))
17652    && !optimize_size"
17653 {
17654   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17655       && !flag_trapping_math)
17656     {
17657       if (TARGET_64BIT)
17658         ix86_expand_floorceil (operand0, operand1, false);
17659       else
17660         ix86_expand_floorceildf_32 (operand0, operand1, false);
17661     }
17662   else
17663     {
17664       rtx op0 = gen_reg_rtx (XFmode);
17665       rtx op1 = gen_reg_rtx (XFmode);
17666
17667       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17668       emit_insn (gen_frndintxf2_ceil (op0, op1));
17669
17670       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17671     }
17672   DONE;
17673 })
17674
17675 (define_expand "ceilsf2"
17676   [(use (match_operand:SF 0 "register_operand" ""))
17677    (use (match_operand:SF 1 "register_operand" ""))]
17678   "((TARGET_USE_FANCY_MATH_387
17679      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17680      && flag_unsafe_math_optimizations)
17681     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17682         && !flag_trapping_math))
17683    && !optimize_size"
17684 {
17685   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17686       && !flag_trapping_math)
17687     ix86_expand_floorceil (operand0, operand1, false);
17688   else
17689     {
17690       rtx op0 = gen_reg_rtx (XFmode);
17691       rtx op1 = gen_reg_rtx (XFmode);
17692
17693       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17694       emit_insn (gen_frndintxf2_ceil (op0, op1));
17695
17696       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17697     }
17698   DONE;
17699 })
17700
17701 (define_insn_and_split "*fist<mode>2_ceil_1"
17702   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17703         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17704          UNSPEC_FIST_CEIL))
17705    (clobber (reg:CC FLAGS_REG))]
17706   "TARGET_USE_FANCY_MATH_387
17707    && flag_unsafe_math_optimizations
17708    && !(reload_completed || reload_in_progress)"
17709   "#"
17710   "&& 1"
17711   [(const_int 0)]
17712 {
17713   ix86_optimize_mode_switching[I387_CEIL] = 1;
17714
17715   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17716   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17717   if (memory_operand (operands[0], VOIDmode))
17718     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17719                                      operands[2], operands[3]));
17720   else
17721     {
17722       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17723       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17724                                                  operands[2], operands[3],
17725                                                  operands[4]));
17726     }
17727   DONE;
17728 }
17729   [(set_attr "type" "fistp")
17730    (set_attr "i387_cw" "ceil")
17731    (set_attr "mode" "<MODE>")])
17732
17733 (define_insn "fistdi2_ceil"
17734   [(set (match_operand:DI 0 "memory_operand" "=m")
17735         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17736          UNSPEC_FIST_CEIL))
17737    (use (match_operand:HI 2 "memory_operand" "m"))
17738    (use (match_operand:HI 3 "memory_operand" "m"))
17739    (clobber (match_scratch:XF 4 "=&1f"))]
17740   "TARGET_USE_FANCY_MATH_387
17741    && flag_unsafe_math_optimizations"
17742   "* return output_fix_trunc (insn, operands, 0);"
17743   [(set_attr "type" "fistp")
17744    (set_attr "i387_cw" "ceil")
17745    (set_attr "mode" "DI")])
17746
17747 (define_insn "fistdi2_ceil_with_temp"
17748   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17749         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17750          UNSPEC_FIST_CEIL))
17751    (use (match_operand:HI 2 "memory_operand" "m,m"))
17752    (use (match_operand:HI 3 "memory_operand" "m,m"))
17753    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17754    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17755   "TARGET_USE_FANCY_MATH_387
17756    && flag_unsafe_math_optimizations"
17757   "#"
17758   [(set_attr "type" "fistp")
17759    (set_attr "i387_cw" "ceil")
17760    (set_attr "mode" "DI")])
17761
17762 (define_split
17763   [(set (match_operand:DI 0 "register_operand" "")
17764         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17765          UNSPEC_FIST_CEIL))
17766    (use (match_operand:HI 2 "memory_operand" ""))
17767    (use (match_operand:HI 3 "memory_operand" ""))
17768    (clobber (match_operand:DI 4 "memory_operand" ""))
17769    (clobber (match_scratch 5 ""))]
17770   "reload_completed"
17771   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17772               (use (match_dup 2))
17773               (use (match_dup 3))
17774               (clobber (match_dup 5))])
17775    (set (match_dup 0) (match_dup 4))]
17776   "")
17777
17778 (define_split
17779   [(set (match_operand:DI 0 "memory_operand" "")
17780         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17781          UNSPEC_FIST_CEIL))
17782    (use (match_operand:HI 2 "memory_operand" ""))
17783    (use (match_operand:HI 3 "memory_operand" ""))
17784    (clobber (match_operand:DI 4 "memory_operand" ""))
17785    (clobber (match_scratch 5 ""))]
17786   "reload_completed"
17787   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17788               (use (match_dup 2))
17789               (use (match_dup 3))
17790               (clobber (match_dup 5))])]
17791   "")
17792
17793 (define_insn "fist<mode>2_ceil"
17794   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17795         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17796          UNSPEC_FIST_CEIL))
17797    (use (match_operand:HI 2 "memory_operand" "m"))
17798    (use (match_operand:HI 3 "memory_operand" "m"))]
17799   "TARGET_USE_FANCY_MATH_387
17800    && flag_unsafe_math_optimizations"
17801   "* return output_fix_trunc (insn, operands, 0);"
17802   [(set_attr "type" "fistp")
17803    (set_attr "i387_cw" "ceil")
17804    (set_attr "mode" "<MODE>")])
17805
17806 (define_insn "fist<mode>2_ceil_with_temp"
17807   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17808         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17809          UNSPEC_FIST_CEIL))
17810    (use (match_operand:HI 2 "memory_operand" "m,m"))
17811    (use (match_operand:HI 3 "memory_operand" "m,m"))
17812    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17813   "TARGET_USE_FANCY_MATH_387
17814    && flag_unsafe_math_optimizations"
17815   "#"
17816   [(set_attr "type" "fistp")
17817    (set_attr "i387_cw" "ceil")
17818    (set_attr "mode" "<MODE>")])
17819
17820 (define_split
17821   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17822         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17823          UNSPEC_FIST_CEIL))
17824    (use (match_operand:HI 2 "memory_operand" ""))
17825    (use (match_operand:HI 3 "memory_operand" ""))
17826    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17827   "reload_completed"
17828   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17829                                   UNSPEC_FIST_CEIL))
17830               (use (match_dup 2))
17831               (use (match_dup 3))])
17832    (set (match_dup 0) (match_dup 4))]
17833   "")
17834
17835 (define_split
17836   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17837         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17838          UNSPEC_FIST_CEIL))
17839    (use (match_operand:HI 2 "memory_operand" ""))
17840    (use (match_operand:HI 3 "memory_operand" ""))
17841    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17842   "reload_completed"
17843   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17844                                   UNSPEC_FIST_CEIL))
17845               (use (match_dup 2))
17846               (use (match_dup 3))])]
17847   "")
17848
17849 (define_expand "lceilxf<mode>2"
17850   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17851                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17852                     UNSPEC_FIST_CEIL))
17853               (clobber (reg:CC FLAGS_REG))])]
17854   "TARGET_USE_FANCY_MATH_387
17855    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17856    && flag_unsafe_math_optimizations"
17857   "")
17858
17859 (define_expand "lceil<mode>di2"
17860   [(match_operand:DI 0 "nonimmediate_operand" "")
17861    (match_operand:SSEMODEF 1 "register_operand" "")]
17862   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17863    && !flag_trapping_math"
17864 {
17865   ix86_expand_lfloorceil (operand0, operand1, false);
17866   DONE;
17867 })
17868
17869 (define_expand "lceil<mode>si2"
17870   [(match_operand:SI 0 "nonimmediate_operand" "")
17871    (match_operand:SSEMODEF 1 "register_operand" "")]
17872   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17873    && !flag_trapping_math"
17874 {
17875   ix86_expand_lfloorceil (operand0, operand1, false);
17876   DONE;
17877 })
17878
17879 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17880 (define_insn_and_split "frndintxf2_trunc"
17881   [(set (match_operand:XF 0 "register_operand" "=f")
17882         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17883          UNSPEC_FRNDINT_TRUNC))
17884    (clobber (reg:CC FLAGS_REG))]
17885   "TARGET_USE_FANCY_MATH_387
17886    && flag_unsafe_math_optimizations
17887    && !(reload_completed || reload_in_progress)"
17888   "#"
17889   "&& 1"
17890   [(const_int 0)]
17891 {
17892   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17893
17894   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17895   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17896
17897   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17898                                         operands[2], operands[3]));
17899   DONE;
17900 }
17901   [(set_attr "type" "frndint")
17902    (set_attr "i387_cw" "trunc")
17903    (set_attr "mode" "XF")])
17904
17905 (define_insn "frndintxf2_trunc_i387"
17906   [(set (match_operand:XF 0 "register_operand" "=f")
17907         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17908          UNSPEC_FRNDINT_TRUNC))
17909    (use (match_operand:HI 2 "memory_operand" "m"))
17910    (use (match_operand:HI 3 "memory_operand" "m"))]
17911   "TARGET_USE_FANCY_MATH_387
17912    && flag_unsafe_math_optimizations"
17913   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17914   [(set_attr "type" "frndint")
17915    (set_attr "i387_cw" "trunc")
17916    (set_attr "mode" "XF")])
17917
17918 (define_expand "btruncxf2"
17919   [(use (match_operand:XF 0 "register_operand" ""))
17920    (use (match_operand:XF 1 "register_operand" ""))]
17921   "TARGET_USE_FANCY_MATH_387
17922    && flag_unsafe_math_optimizations && !optimize_size"
17923 {
17924   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17925   DONE;
17926 })
17927
17928 (define_expand "btruncdf2"
17929   [(use (match_operand:DF 0 "register_operand" ""))
17930    (use (match_operand:DF 1 "register_operand" ""))]
17931   "((TARGET_USE_FANCY_MATH_387
17932      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17933      && flag_unsafe_math_optimizations)
17934     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17935         && !flag_trapping_math))
17936    && !optimize_size"
17937 {
17938   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17939       && !flag_trapping_math)
17940     {
17941       if (TARGET_64BIT)
17942         ix86_expand_trunc (operand0, operand1);
17943       else
17944         ix86_expand_truncdf_32 (operand0, operand1);
17945     }
17946   else
17947     {
17948       rtx op0 = gen_reg_rtx (XFmode);
17949       rtx op1 = gen_reg_rtx (XFmode);
17950
17951       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17952       emit_insn (gen_frndintxf2_trunc (op0, op1));
17953
17954       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17955     }
17956   DONE;
17957 })
17958
17959 (define_expand "btruncsf2"
17960   [(use (match_operand:SF 0 "register_operand" ""))
17961    (use (match_operand:SF 1 "register_operand" ""))]
17962   "((TARGET_USE_FANCY_MATH_387
17963      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17964      && flag_unsafe_math_optimizations)
17965     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17966         && !flag_trapping_math))
17967    && !optimize_size"
17968 {
17969   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17970       && !flag_trapping_math)
17971     ix86_expand_trunc (operand0, operand1);
17972   else
17973     {
17974       rtx op0 = gen_reg_rtx (XFmode);
17975       rtx op1 = gen_reg_rtx (XFmode);
17976
17977       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17978       emit_insn (gen_frndintxf2_trunc (op0, op1));
17979
17980       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17981     }
17982   DONE;
17983 })
17984
17985 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17986 (define_insn_and_split "frndintxf2_mask_pm"
17987   [(set (match_operand:XF 0 "register_operand" "=f")
17988         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17989          UNSPEC_FRNDINT_MASK_PM))
17990    (clobber (reg:CC FLAGS_REG))]
17991   "TARGET_USE_FANCY_MATH_387
17992    && flag_unsafe_math_optimizations
17993    && !(reload_completed || reload_in_progress)"
17994   "#"
17995   "&& 1"
17996   [(const_int 0)]
17997 {
17998   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17999
18000   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18001   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18002
18003   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18004                                           operands[2], operands[3]));
18005   DONE;
18006 }
18007   [(set_attr "type" "frndint")
18008    (set_attr "i387_cw" "mask_pm")
18009    (set_attr "mode" "XF")])
18010
18011 (define_insn "frndintxf2_mask_pm_i387"
18012   [(set (match_operand:XF 0 "register_operand" "=f")
18013         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18014          UNSPEC_FRNDINT_MASK_PM))
18015    (use (match_operand:HI 2 "memory_operand" "m"))
18016    (use (match_operand:HI 3 "memory_operand" "m"))]
18017   "TARGET_USE_FANCY_MATH_387
18018    && flag_unsafe_math_optimizations"
18019   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18020   [(set_attr "type" "frndint")
18021    (set_attr "i387_cw" "mask_pm")
18022    (set_attr "mode" "XF")])
18023
18024 (define_expand "nearbyintxf2"
18025   [(use (match_operand:XF 0 "register_operand" ""))
18026    (use (match_operand:XF 1 "register_operand" ""))]
18027   "TARGET_USE_FANCY_MATH_387
18028    && flag_unsafe_math_optimizations"
18029 {
18030   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18031
18032   DONE;
18033 })
18034
18035 (define_expand "nearbyintdf2"
18036   [(use (match_operand:DF 0 "register_operand" ""))
18037    (use (match_operand:DF 1 "register_operand" ""))]
18038   "TARGET_USE_FANCY_MATH_387
18039    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18040    && flag_unsafe_math_optimizations"
18041 {
18042   rtx op0 = gen_reg_rtx (XFmode);
18043   rtx op1 = gen_reg_rtx (XFmode);
18044
18045   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18046   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18047
18048   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18049   DONE;
18050 })
18051
18052 (define_expand "nearbyintsf2"
18053   [(use (match_operand:SF 0 "register_operand" ""))
18054    (use (match_operand:SF 1 "register_operand" ""))]
18055   "TARGET_USE_FANCY_MATH_387
18056    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18057    && flag_unsafe_math_optimizations"
18058 {
18059   rtx op0 = gen_reg_rtx (XFmode);
18060   rtx op1 = gen_reg_rtx (XFmode);
18061
18062   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18063   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18064
18065   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18066   DONE;
18067 })
18068
18069 (define_insn "fxam<mode>2_i387"
18070   [(set (match_operand:HI 0 "register_operand" "=a")
18071         (unspec:HI
18072           [(match_operand:X87MODEF 1 "register_operand" "f")]
18073           UNSPEC_FXAM))]
18074   "TARGET_USE_FANCY_MATH_387"
18075   "fxam\n\tfnstsw\t%0"
18076   [(set_attr "type" "multi")
18077    (set_attr "unit" "i387")
18078    (set_attr "mode" "<MODE>")])
18079
18080 (define_expand "isinf<mode>2"
18081   [(use (match_operand:SI 0 "register_operand" ""))
18082    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18083   "TARGET_USE_FANCY_MATH_387
18084   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18085       || TARGET_MIX_SSE_I387)"
18086 {
18087   rtx mask = GEN_INT (0x45);
18088   rtx val = GEN_INT (0x05);
18089
18090   rtx cond;
18091
18092   rtx scratch = gen_reg_rtx (HImode);
18093   rtx res = gen_reg_rtx (QImode);
18094
18095   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18096   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18097   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18098   cond = gen_rtx_fmt_ee (EQ, QImode,
18099                          gen_rtx_REG (CCmode, FLAGS_REG),
18100                          const0_rtx);
18101   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18102   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18103   DONE;
18104 })
18105
18106 \f
18107 ;; Block operation instructions
18108
18109 (define_expand "movmemsi"
18110   [(use (match_operand:BLK 0 "memory_operand" ""))
18111    (use (match_operand:BLK 1 "memory_operand" ""))
18112    (use (match_operand:SI 2 "nonmemory_operand" ""))
18113    (use (match_operand:SI 3 "const_int_operand" ""))
18114    (use (match_operand:SI 4 "const_int_operand" ""))
18115    (use (match_operand:SI 5 "const_int_operand" ""))]
18116   ""
18117 {
18118  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18119                          operands[4], operands[5]))
18120    DONE;
18121  else
18122    FAIL;
18123 })
18124
18125 (define_expand "movmemdi"
18126   [(use (match_operand:BLK 0 "memory_operand" ""))
18127    (use (match_operand:BLK 1 "memory_operand" ""))
18128    (use (match_operand:DI 2 "nonmemory_operand" ""))
18129    (use (match_operand:DI 3 "const_int_operand" ""))
18130    (use (match_operand:SI 4 "const_int_operand" ""))
18131    (use (match_operand:SI 5 "const_int_operand" ""))]
18132   "TARGET_64BIT"
18133 {
18134  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18135                          operands[4], operands[5]))
18136    DONE;
18137  else
18138    FAIL;
18139 })
18140
18141 ;; Most CPUs don't like single string operations
18142 ;; Handle this case here to simplify previous expander.
18143
18144 (define_expand "strmov"
18145   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18146    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18147    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18148               (clobber (reg:CC FLAGS_REG))])
18149    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18150               (clobber (reg:CC FLAGS_REG))])]
18151   ""
18152 {
18153   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18154
18155   /* If .md ever supports :P for Pmode, these can be directly
18156      in the pattern above.  */
18157   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18158   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18159
18160   if (TARGET_SINGLE_STRINGOP || optimize_size)
18161     {
18162       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18163                                       operands[2], operands[3],
18164                                       operands[5], operands[6]));
18165       DONE;
18166     }
18167
18168   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18169 })
18170
18171 (define_expand "strmov_singleop"
18172   [(parallel [(set (match_operand 1 "memory_operand" "")
18173                    (match_operand 3 "memory_operand" ""))
18174               (set (match_operand 0 "register_operand" "")
18175                    (match_operand 4 "" ""))
18176               (set (match_operand 2 "register_operand" "")
18177                    (match_operand 5 "" ""))])]
18178   "TARGET_SINGLE_STRINGOP || optimize_size"
18179   "")
18180
18181 (define_insn "*strmovdi_rex_1"
18182   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18183         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18184    (set (match_operand:DI 0 "register_operand" "=D")
18185         (plus:DI (match_dup 2)
18186                  (const_int 8)))
18187    (set (match_operand:DI 1 "register_operand" "=S")
18188         (plus:DI (match_dup 3)
18189                  (const_int 8)))]
18190   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18191   "movsq"
18192   [(set_attr "type" "str")
18193    (set_attr "mode" "DI")
18194    (set_attr "memory" "both")])
18195
18196 (define_insn "*strmovsi_1"
18197   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18198         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18199    (set (match_operand:SI 0 "register_operand" "=D")
18200         (plus:SI (match_dup 2)
18201                  (const_int 4)))
18202    (set (match_operand:SI 1 "register_operand" "=S")
18203         (plus:SI (match_dup 3)
18204                  (const_int 4)))]
18205   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18206   "{movsl|movsd}"
18207   [(set_attr "type" "str")
18208    (set_attr "mode" "SI")
18209    (set_attr "memory" "both")])
18210
18211 (define_insn "*strmovsi_rex_1"
18212   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18213         (mem:SI (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 4)))
18217    (set (match_operand:DI 1 "register_operand" "=S")
18218         (plus:DI (match_dup 3)
18219                  (const_int 4)))]
18220   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18221   "{movsl|movsd}"
18222   [(set_attr "type" "str")
18223    (set_attr "mode" "SI")
18224    (set_attr "memory" "both")])
18225
18226 (define_insn "*strmovhi_1"
18227   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18228         (mem:HI (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 2)))
18232    (set (match_operand:SI 1 "register_operand" "=S")
18233         (plus:SI (match_dup 3)
18234                  (const_int 2)))]
18235   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18236   "movsw"
18237   [(set_attr "type" "str")
18238    (set_attr "memory" "both")
18239    (set_attr "mode" "HI")])
18240
18241 (define_insn "*strmovhi_rex_1"
18242   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18243         (mem:HI (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 2)))
18247    (set (match_operand:DI 1 "register_operand" "=S")
18248         (plus:DI (match_dup 3)
18249                  (const_int 2)))]
18250   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18251   "movsw"
18252   [(set_attr "type" "str")
18253    (set_attr "memory" "both")
18254    (set_attr "mode" "HI")])
18255
18256 (define_insn "*strmovqi_1"
18257   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18258         (mem:QI (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 1)))
18262    (set (match_operand:SI 1 "register_operand" "=S")
18263         (plus:SI (match_dup 3)
18264                  (const_int 1)))]
18265   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18266   "movsb"
18267   [(set_attr "type" "str")
18268    (set_attr "memory" "both")
18269    (set_attr "mode" "QI")])
18270
18271 (define_insn "*strmovqi_rex_1"
18272   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18273         (mem:QI (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 1)))
18277    (set (match_operand:DI 1 "register_operand" "=S")
18278         (plus:DI (match_dup 3)
18279                  (const_int 1)))]
18280   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18281   "movsb"
18282   [(set_attr "type" "str")
18283    (set_attr "memory" "both")
18284    (set_attr "mode" "QI")])
18285
18286 (define_expand "rep_mov"
18287   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18288               (set (match_operand 0 "register_operand" "")
18289                    (match_operand 5 "" ""))
18290               (set (match_operand 2 "register_operand" "")
18291                    (match_operand 6 "" ""))
18292               (set (match_operand 1 "memory_operand" "")
18293                    (match_operand 3 "memory_operand" ""))
18294               (use (match_dup 4))])]
18295   ""
18296   "")
18297
18298 (define_insn "*rep_movdi_rex64"
18299   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18300    (set (match_operand:DI 0 "register_operand" "=D")
18301         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18302                             (const_int 3))
18303                  (match_operand:DI 3 "register_operand" "0")))
18304    (set (match_operand:DI 1 "register_operand" "=S")
18305         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18306                  (match_operand:DI 4 "register_operand" "1")))
18307    (set (mem:BLK (match_dup 3))
18308         (mem:BLK (match_dup 4)))
18309    (use (match_dup 5))]
18310   "TARGET_64BIT"
18311   "{rep\;movsq|rep movsq}"
18312   [(set_attr "type" "str")
18313    (set_attr "prefix_rep" "1")
18314    (set_attr "memory" "both")
18315    (set_attr "mode" "DI")])
18316
18317 (define_insn "*rep_movsi"
18318   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18319    (set (match_operand:SI 0 "register_operand" "=D")
18320         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18321                             (const_int 2))
18322                  (match_operand:SI 3 "register_operand" "0")))
18323    (set (match_operand:SI 1 "register_operand" "=S")
18324         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18325                  (match_operand:SI 4 "register_operand" "1")))
18326    (set (mem:BLK (match_dup 3))
18327         (mem:BLK (match_dup 4)))
18328    (use (match_dup 5))]
18329   "!TARGET_64BIT"
18330   "{rep\;movsl|rep movsd}"
18331   [(set_attr "type" "str")
18332    (set_attr "prefix_rep" "1")
18333    (set_attr "memory" "both")
18334    (set_attr "mode" "SI")])
18335
18336 (define_insn "*rep_movsi_rex64"
18337   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18338    (set (match_operand:DI 0 "register_operand" "=D")
18339         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18340                             (const_int 2))
18341                  (match_operand:DI 3 "register_operand" "0")))
18342    (set (match_operand:DI 1 "register_operand" "=S")
18343         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18344                  (match_operand:DI 4 "register_operand" "1")))
18345    (set (mem:BLK (match_dup 3))
18346         (mem:BLK (match_dup 4)))
18347    (use (match_dup 5))]
18348   "TARGET_64BIT"
18349   "{rep\;movsl|rep movsd}"
18350   [(set_attr "type" "str")
18351    (set_attr "prefix_rep" "1")
18352    (set_attr "memory" "both")
18353    (set_attr "mode" "SI")])
18354
18355 (define_insn "*rep_movqi"
18356   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18357    (set (match_operand:SI 0 "register_operand" "=D")
18358         (plus:SI (match_operand:SI 3 "register_operand" "0")
18359                  (match_operand:SI 5 "register_operand" "2")))
18360    (set (match_operand:SI 1 "register_operand" "=S")
18361         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18362    (set (mem:BLK (match_dup 3))
18363         (mem:BLK (match_dup 4)))
18364    (use (match_dup 5))]
18365   "!TARGET_64BIT"
18366   "{rep\;movsb|rep movsb}"
18367   [(set_attr "type" "str")
18368    (set_attr "prefix_rep" "1")
18369    (set_attr "memory" "both")
18370    (set_attr "mode" "SI")])
18371
18372 (define_insn "*rep_movqi_rex64"
18373   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18374    (set (match_operand:DI 0 "register_operand" "=D")
18375         (plus:DI (match_operand:DI 3 "register_operand" "0")
18376                  (match_operand:DI 5 "register_operand" "2")))
18377    (set (match_operand:DI 1 "register_operand" "=S")
18378         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18379    (set (mem:BLK (match_dup 3))
18380         (mem:BLK (match_dup 4)))
18381    (use (match_dup 5))]
18382   "TARGET_64BIT"
18383   "{rep\;movsb|rep movsb}"
18384   [(set_attr "type" "str")
18385    (set_attr "prefix_rep" "1")
18386    (set_attr "memory" "both")
18387    (set_attr "mode" "SI")])
18388
18389 (define_expand "setmemsi"
18390    [(use (match_operand:BLK 0 "memory_operand" ""))
18391     (use (match_operand:SI 1 "nonmemory_operand" ""))
18392     (use (match_operand 2 "const_int_operand" ""))
18393     (use (match_operand 3 "const_int_operand" ""))
18394     (use (match_operand:SI 4 "const_int_operand" ""))
18395     (use (match_operand:SI 5 "const_int_operand" ""))]
18396   ""
18397 {
18398  if (ix86_expand_setmem (operands[0], operands[1],
18399                          operands[2], operands[3],
18400                          operands[4], operands[5]))
18401    DONE;
18402  else
18403    FAIL;
18404 })
18405
18406 (define_expand "setmemdi"
18407    [(use (match_operand:BLK 0 "memory_operand" ""))
18408     (use (match_operand:DI 1 "nonmemory_operand" ""))
18409     (use (match_operand 2 "const_int_operand" ""))
18410     (use (match_operand 3 "const_int_operand" ""))
18411     (use (match_operand 4 "const_int_operand" ""))
18412     (use (match_operand 5 "const_int_operand" ""))]
18413   "TARGET_64BIT"
18414 {
18415  if (ix86_expand_setmem (operands[0], operands[1],
18416                          operands[2], operands[3],
18417                          operands[4], operands[5]))
18418    DONE;
18419  else
18420    FAIL;
18421 })
18422
18423 ;; Most CPUs don't like single string operations
18424 ;; Handle this case here to simplify previous expander.
18425
18426 (define_expand "strset"
18427   [(set (match_operand 1 "memory_operand" "")
18428         (match_operand 2 "register_operand" ""))
18429    (parallel [(set (match_operand 0 "register_operand" "")
18430                    (match_dup 3))
18431               (clobber (reg:CC FLAGS_REG))])]
18432   ""
18433 {
18434   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18435     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18436
18437   /* If .md ever supports :P for Pmode, this can be directly
18438      in the pattern above.  */
18439   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18440                               GEN_INT (GET_MODE_SIZE (GET_MODE
18441                                                       (operands[2]))));
18442   if (TARGET_SINGLE_STRINGOP || optimize_size)
18443     {
18444       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18445                                       operands[3]));
18446       DONE;
18447     }
18448 })
18449
18450 (define_expand "strset_singleop"
18451   [(parallel [(set (match_operand 1 "memory_operand" "")
18452                    (match_operand 2 "register_operand" ""))
18453               (set (match_operand 0 "register_operand" "")
18454                    (match_operand 3 "" ""))])]
18455   "TARGET_SINGLE_STRINGOP || optimize_size"
18456   "")
18457
18458 (define_insn "*strsetdi_rex_1"
18459   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18460         (match_operand:DI 2 "register_operand" "a"))
18461    (set (match_operand:DI 0 "register_operand" "=D")
18462         (plus:DI (match_dup 1)
18463                  (const_int 8)))]
18464   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18465   "stosq"
18466   [(set_attr "type" "str")
18467    (set_attr "memory" "store")
18468    (set_attr "mode" "DI")])
18469
18470 (define_insn "*strsetsi_1"
18471   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18472         (match_operand:SI 2 "register_operand" "a"))
18473    (set (match_operand:SI 0 "register_operand" "=D")
18474         (plus:SI (match_dup 1)
18475                  (const_int 4)))]
18476   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18477   "{stosl|stosd}"
18478   [(set_attr "type" "str")
18479    (set_attr "memory" "store")
18480    (set_attr "mode" "SI")])
18481
18482 (define_insn "*strsetsi_rex_1"
18483   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18484         (match_operand:SI 2 "register_operand" "a"))
18485    (set (match_operand:DI 0 "register_operand" "=D")
18486         (plus:DI (match_dup 1)
18487                  (const_int 4)))]
18488   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18489   "{stosl|stosd}"
18490   [(set_attr "type" "str")
18491    (set_attr "memory" "store")
18492    (set_attr "mode" "SI")])
18493
18494 (define_insn "*strsethi_1"
18495   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18496         (match_operand:HI 2 "register_operand" "a"))
18497    (set (match_operand:SI 0 "register_operand" "=D")
18498         (plus:SI (match_dup 1)
18499                  (const_int 2)))]
18500   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18501   "stosw"
18502   [(set_attr "type" "str")
18503    (set_attr "memory" "store")
18504    (set_attr "mode" "HI")])
18505
18506 (define_insn "*strsethi_rex_1"
18507   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18508         (match_operand:HI 2 "register_operand" "a"))
18509    (set (match_operand:DI 0 "register_operand" "=D")
18510         (plus:DI (match_dup 1)
18511                  (const_int 2)))]
18512   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18513   "stosw"
18514   [(set_attr "type" "str")
18515    (set_attr "memory" "store")
18516    (set_attr "mode" "HI")])
18517
18518 (define_insn "*strsetqi_1"
18519   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18520         (match_operand:QI 2 "register_operand" "a"))
18521    (set (match_operand:SI 0 "register_operand" "=D")
18522         (plus:SI (match_dup 1)
18523                  (const_int 1)))]
18524   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18525   "stosb"
18526   [(set_attr "type" "str")
18527    (set_attr "memory" "store")
18528    (set_attr "mode" "QI")])
18529
18530 (define_insn "*strsetqi_rex_1"
18531   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18532         (match_operand:QI 2 "register_operand" "a"))
18533    (set (match_operand:DI 0 "register_operand" "=D")
18534         (plus:DI (match_dup 1)
18535                  (const_int 1)))]
18536   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18537   "stosb"
18538   [(set_attr "type" "str")
18539    (set_attr "memory" "store")
18540    (set_attr "mode" "QI")])
18541
18542 (define_expand "rep_stos"
18543   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18544               (set (match_operand 0 "register_operand" "")
18545                    (match_operand 4 "" ""))
18546               (set (match_operand 2 "memory_operand" "") (const_int 0))
18547               (use (match_operand 3 "register_operand" ""))
18548               (use (match_dup 1))])]
18549   ""
18550   "")
18551
18552 (define_insn "*rep_stosdi_rex64"
18553   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18554    (set (match_operand:DI 0 "register_operand" "=D")
18555         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18556                             (const_int 3))
18557                  (match_operand:DI 3 "register_operand" "0")))
18558    (set (mem:BLK (match_dup 3))
18559         (const_int 0))
18560    (use (match_operand:DI 2 "register_operand" "a"))
18561    (use (match_dup 4))]
18562   "TARGET_64BIT"
18563   "{rep\;stosq|rep stosq}"
18564   [(set_attr "type" "str")
18565    (set_attr "prefix_rep" "1")
18566    (set_attr "memory" "store")
18567    (set_attr "mode" "DI")])
18568
18569 (define_insn "*rep_stossi"
18570   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18571    (set (match_operand:SI 0 "register_operand" "=D")
18572         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18573                             (const_int 2))
18574                  (match_operand:SI 3 "register_operand" "0")))
18575    (set (mem:BLK (match_dup 3))
18576         (const_int 0))
18577    (use (match_operand:SI 2 "register_operand" "a"))
18578    (use (match_dup 4))]
18579   "!TARGET_64BIT"
18580   "{rep\;stosl|rep stosd}"
18581   [(set_attr "type" "str")
18582    (set_attr "prefix_rep" "1")
18583    (set_attr "memory" "store")
18584    (set_attr "mode" "SI")])
18585
18586 (define_insn "*rep_stossi_rex64"
18587   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18588    (set (match_operand:DI 0 "register_operand" "=D")
18589         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18590                             (const_int 2))
18591                  (match_operand:DI 3 "register_operand" "0")))
18592    (set (mem:BLK (match_dup 3))
18593         (const_int 0))
18594    (use (match_operand:SI 2 "register_operand" "a"))
18595    (use (match_dup 4))]
18596   "TARGET_64BIT"
18597   "{rep\;stosl|rep stosd}"
18598   [(set_attr "type" "str")
18599    (set_attr "prefix_rep" "1")
18600    (set_attr "memory" "store")
18601    (set_attr "mode" "SI")])
18602
18603 (define_insn "*rep_stosqi"
18604   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18605    (set (match_operand:SI 0 "register_operand" "=D")
18606         (plus:SI (match_operand:SI 3 "register_operand" "0")
18607                  (match_operand:SI 4 "register_operand" "1")))
18608    (set (mem:BLK (match_dup 3))
18609         (const_int 0))
18610    (use (match_operand:QI 2 "register_operand" "a"))
18611    (use (match_dup 4))]
18612   "!TARGET_64BIT"
18613   "{rep\;stosb|rep stosb}"
18614   [(set_attr "type" "str")
18615    (set_attr "prefix_rep" "1")
18616    (set_attr "memory" "store")
18617    (set_attr "mode" "QI")])
18618
18619 (define_insn "*rep_stosqi_rex64"
18620   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18621    (set (match_operand:DI 0 "register_operand" "=D")
18622         (plus:DI (match_operand:DI 3 "register_operand" "0")
18623                  (match_operand:DI 4 "register_operand" "1")))
18624    (set (mem:BLK (match_dup 3))
18625         (const_int 0))
18626    (use (match_operand:QI 2 "register_operand" "a"))
18627    (use (match_dup 4))]
18628   "TARGET_64BIT"
18629   "{rep\;stosb|rep stosb}"
18630   [(set_attr "type" "str")
18631    (set_attr "prefix_rep" "1")
18632    (set_attr "memory" "store")
18633    (set_attr "mode" "QI")])
18634
18635 (define_expand "cmpstrnsi"
18636   [(set (match_operand:SI 0 "register_operand" "")
18637         (compare:SI (match_operand:BLK 1 "general_operand" "")
18638                     (match_operand:BLK 2 "general_operand" "")))
18639    (use (match_operand 3 "general_operand" ""))
18640    (use (match_operand 4 "immediate_operand" ""))]
18641   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18642 {
18643   rtx addr1, addr2, out, outlow, count, countreg, align;
18644
18645   /* Can't use this if the user has appropriated esi or edi.  */
18646   if (global_regs[4] || global_regs[5])
18647     FAIL;
18648
18649   out = operands[0];
18650   if (!REG_P (out))
18651     out = gen_reg_rtx (SImode);
18652
18653   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18654   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18655   if (addr1 != XEXP (operands[1], 0))
18656     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18657   if (addr2 != XEXP (operands[2], 0))
18658     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18659
18660   count = operands[3];
18661   countreg = ix86_zero_extend_to_Pmode (count);
18662
18663   /* %%% Iff we are testing strict equality, we can use known alignment
18664      to good advantage.  This may be possible with combine, particularly
18665      once cc0 is dead.  */
18666   align = operands[4];
18667
18668   if (CONST_INT_P (count))
18669     {
18670       if (INTVAL (count) == 0)
18671         {
18672           emit_move_insn (operands[0], const0_rtx);
18673           DONE;
18674         }
18675       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18676                                      operands[1], operands[2]));
18677     }
18678   else
18679     {
18680       if (TARGET_64BIT)
18681         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18682       else
18683         emit_insn (gen_cmpsi_1 (countreg, countreg));
18684       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18685                                   operands[1], operands[2]));
18686     }
18687
18688   outlow = gen_lowpart (QImode, out);
18689   emit_insn (gen_cmpintqi (outlow));
18690   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18691
18692   if (operands[0] != out)
18693     emit_move_insn (operands[0], out);
18694
18695   DONE;
18696 })
18697
18698 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18699
18700 (define_expand "cmpintqi"
18701   [(set (match_dup 1)
18702         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18703    (set (match_dup 2)
18704         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18705    (parallel [(set (match_operand:QI 0 "register_operand" "")
18706                    (minus:QI (match_dup 1)
18707                              (match_dup 2)))
18708               (clobber (reg:CC FLAGS_REG))])]
18709   ""
18710   "operands[1] = gen_reg_rtx (QImode);
18711    operands[2] = gen_reg_rtx (QImode);")
18712
18713 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18714 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18715
18716 (define_expand "cmpstrnqi_nz_1"
18717   [(parallel [(set (reg:CC FLAGS_REG)
18718                    (compare:CC (match_operand 4 "memory_operand" "")
18719                                (match_operand 5 "memory_operand" "")))
18720               (use (match_operand 2 "register_operand" ""))
18721               (use (match_operand:SI 3 "immediate_operand" ""))
18722               (clobber (match_operand 0 "register_operand" ""))
18723               (clobber (match_operand 1 "register_operand" ""))
18724               (clobber (match_dup 2))])]
18725   ""
18726   "")
18727
18728 (define_insn "*cmpstrnqi_nz_1"
18729   [(set (reg:CC FLAGS_REG)
18730         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18731                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18732    (use (match_operand:SI 6 "register_operand" "2"))
18733    (use (match_operand:SI 3 "immediate_operand" "i"))
18734    (clobber (match_operand:SI 0 "register_operand" "=S"))
18735    (clobber (match_operand:SI 1 "register_operand" "=D"))
18736    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18737   "!TARGET_64BIT"
18738   "repz{\;| }cmpsb"
18739   [(set_attr "type" "str")
18740    (set_attr "mode" "QI")
18741    (set_attr "prefix_rep" "1")])
18742
18743 (define_insn "*cmpstrnqi_nz_rex_1"
18744   [(set (reg:CC FLAGS_REG)
18745         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18746                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18747    (use (match_operand:DI 6 "register_operand" "2"))
18748    (use (match_operand:SI 3 "immediate_operand" "i"))
18749    (clobber (match_operand:DI 0 "register_operand" "=S"))
18750    (clobber (match_operand:DI 1 "register_operand" "=D"))
18751    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18752   "TARGET_64BIT"
18753   "repz{\;| }cmpsb"
18754   [(set_attr "type" "str")
18755    (set_attr "mode" "QI")
18756    (set_attr "prefix_rep" "1")])
18757
18758 ;; The same, but the count is not known to not be zero.
18759
18760 (define_expand "cmpstrnqi_1"
18761   [(parallel [(set (reg:CC FLAGS_REG)
18762                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18763                                      (const_int 0))
18764                   (compare:CC (match_operand 4 "memory_operand" "")
18765                               (match_operand 5 "memory_operand" ""))
18766                   (const_int 0)))
18767               (use (match_operand:SI 3 "immediate_operand" ""))
18768               (use (reg:CC FLAGS_REG))
18769               (clobber (match_operand 0 "register_operand" ""))
18770               (clobber (match_operand 1 "register_operand" ""))
18771               (clobber (match_dup 2))])]
18772   ""
18773   "")
18774
18775 (define_insn "*cmpstrnqi_1"
18776   [(set (reg:CC FLAGS_REG)
18777         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18778                              (const_int 0))
18779           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18780                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18781           (const_int 0)))
18782    (use (match_operand:SI 3 "immediate_operand" "i"))
18783    (use (reg:CC FLAGS_REG))
18784    (clobber (match_operand:SI 0 "register_operand" "=S"))
18785    (clobber (match_operand:SI 1 "register_operand" "=D"))
18786    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18787   "!TARGET_64BIT"
18788   "repz{\;| }cmpsb"
18789   [(set_attr "type" "str")
18790    (set_attr "mode" "QI")
18791    (set_attr "prefix_rep" "1")])
18792
18793 (define_insn "*cmpstrnqi_rex_1"
18794   [(set (reg:CC FLAGS_REG)
18795         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18796                              (const_int 0))
18797           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18798                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18799           (const_int 0)))
18800    (use (match_operand:SI 3 "immediate_operand" "i"))
18801    (use (reg:CC FLAGS_REG))
18802    (clobber (match_operand:DI 0 "register_operand" "=S"))
18803    (clobber (match_operand:DI 1 "register_operand" "=D"))
18804    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18805   "TARGET_64BIT"
18806   "repz{\;| }cmpsb"
18807   [(set_attr "type" "str")
18808    (set_attr "mode" "QI")
18809    (set_attr "prefix_rep" "1")])
18810
18811 (define_expand "strlensi"
18812   [(set (match_operand:SI 0 "register_operand" "")
18813         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18814                     (match_operand:QI 2 "immediate_operand" "")
18815                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18816   ""
18817 {
18818  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18819    DONE;
18820  else
18821    FAIL;
18822 })
18823
18824 (define_expand "strlendi"
18825   [(set (match_operand:DI 0 "register_operand" "")
18826         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18827                     (match_operand:QI 2 "immediate_operand" "")
18828                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18829   ""
18830 {
18831  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18832    DONE;
18833  else
18834    FAIL;
18835 })
18836
18837 (define_expand "strlenqi_1"
18838   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18839               (clobber (match_operand 1 "register_operand" ""))
18840               (clobber (reg:CC FLAGS_REG))])]
18841   ""
18842   "")
18843
18844 (define_insn "*strlenqi_1"
18845   [(set (match_operand:SI 0 "register_operand" "=&c")
18846         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18847                     (match_operand:QI 2 "register_operand" "a")
18848                     (match_operand:SI 3 "immediate_operand" "i")
18849                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18850    (clobber (match_operand:SI 1 "register_operand" "=D"))
18851    (clobber (reg:CC FLAGS_REG))]
18852   "!TARGET_64BIT"
18853   "repnz{\;| }scasb"
18854   [(set_attr "type" "str")
18855    (set_attr "mode" "QI")
18856    (set_attr "prefix_rep" "1")])
18857
18858 (define_insn "*strlenqi_rex_1"
18859   [(set (match_operand:DI 0 "register_operand" "=&c")
18860         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18861                     (match_operand:QI 2 "register_operand" "a")
18862                     (match_operand:DI 3 "immediate_operand" "i")
18863                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18864    (clobber (match_operand:DI 1 "register_operand" "=D"))
18865    (clobber (reg:CC FLAGS_REG))]
18866   "TARGET_64BIT"
18867   "repnz{\;| }scasb"
18868   [(set_attr "type" "str")
18869    (set_attr "mode" "QI")
18870    (set_attr "prefix_rep" "1")])
18871
18872 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18873 ;; handled in combine, but it is not currently up to the task.
18874 ;; When used for their truth value, the cmpstrn* expanders generate
18875 ;; code like this:
18876 ;;
18877 ;;   repz cmpsb
18878 ;;   seta       %al
18879 ;;   setb       %dl
18880 ;;   cmpb       %al, %dl
18881 ;;   jcc        label
18882 ;;
18883 ;; The intermediate three instructions are unnecessary.
18884
18885 ;; This one handles cmpstrn*_nz_1...
18886 (define_peephole2
18887   [(parallel[
18888      (set (reg:CC FLAGS_REG)
18889           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18890                       (mem:BLK (match_operand 5 "register_operand" ""))))
18891      (use (match_operand 6 "register_operand" ""))
18892      (use (match_operand:SI 3 "immediate_operand" ""))
18893      (clobber (match_operand 0 "register_operand" ""))
18894      (clobber (match_operand 1 "register_operand" ""))
18895      (clobber (match_operand 2 "register_operand" ""))])
18896    (set (match_operand:QI 7 "register_operand" "")
18897         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18898    (set (match_operand:QI 8 "register_operand" "")
18899         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18900    (set (reg FLAGS_REG)
18901         (compare (match_dup 7) (match_dup 8)))
18902   ]
18903   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18904   [(parallel[
18905      (set (reg:CC FLAGS_REG)
18906           (compare:CC (mem:BLK (match_dup 4))
18907                       (mem:BLK (match_dup 5))))
18908      (use (match_dup 6))
18909      (use (match_dup 3))
18910      (clobber (match_dup 0))
18911      (clobber (match_dup 1))
18912      (clobber (match_dup 2))])]
18913   "")
18914
18915 ;; ...and this one handles cmpstrn*_1.
18916 (define_peephole2
18917   [(parallel[
18918      (set (reg:CC FLAGS_REG)
18919           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18920                                (const_int 0))
18921             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18922                         (mem:BLK (match_operand 5 "register_operand" "")))
18923             (const_int 0)))
18924      (use (match_operand:SI 3 "immediate_operand" ""))
18925      (use (reg:CC FLAGS_REG))
18926      (clobber (match_operand 0 "register_operand" ""))
18927      (clobber (match_operand 1 "register_operand" ""))
18928      (clobber (match_operand 2 "register_operand" ""))])
18929    (set (match_operand:QI 7 "register_operand" "")
18930         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18931    (set (match_operand:QI 8 "register_operand" "")
18932         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18933    (set (reg FLAGS_REG)
18934         (compare (match_dup 7) (match_dup 8)))
18935   ]
18936   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18937   [(parallel[
18938      (set (reg:CC FLAGS_REG)
18939           (if_then_else:CC (ne (match_dup 6)
18940                                (const_int 0))
18941             (compare:CC (mem:BLK (match_dup 4))
18942                         (mem:BLK (match_dup 5)))
18943             (const_int 0)))
18944      (use (match_dup 3))
18945      (use (reg:CC FLAGS_REG))
18946      (clobber (match_dup 0))
18947      (clobber (match_dup 1))
18948      (clobber (match_dup 2))])]
18949   "")
18950
18951
18952 \f
18953 ;; Conditional move instructions.
18954
18955 (define_expand "movdicc"
18956   [(set (match_operand:DI 0 "register_operand" "")
18957         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18958                          (match_operand:DI 2 "general_operand" "")
18959                          (match_operand:DI 3 "general_operand" "")))]
18960   "TARGET_64BIT"
18961   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18962
18963 (define_insn "x86_movdicc_0_m1_rex64"
18964   [(set (match_operand:DI 0 "register_operand" "=r")
18965         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18966           (const_int -1)
18967           (const_int 0)))
18968    (clobber (reg:CC FLAGS_REG))]
18969   "TARGET_64BIT"
18970   "sbb{q}\t%0, %0"
18971   ; Since we don't have the proper number of operands for an alu insn,
18972   ; fill in all the blanks.
18973   [(set_attr "type" "alu")
18974    (set_attr "pent_pair" "pu")
18975    (set_attr "memory" "none")
18976    (set_attr "imm_disp" "false")
18977    (set_attr "mode" "DI")
18978    (set_attr "length_immediate" "0")])
18979
18980 (define_insn "*movdicc_c_rex64"
18981   [(set (match_operand:DI 0 "register_operand" "=r,r")
18982         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18983                                 [(reg FLAGS_REG) (const_int 0)])
18984                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18985                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18986   "TARGET_64BIT && TARGET_CMOVE
18987    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18988   "@
18989    cmov%O2%C1\t{%2, %0|%0, %2}
18990    cmov%O2%c1\t{%3, %0|%0, %3}"
18991   [(set_attr "type" "icmov")
18992    (set_attr "mode" "DI")])
18993
18994 (define_expand "movsicc"
18995   [(set (match_operand:SI 0 "register_operand" "")
18996         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18997                          (match_operand:SI 2 "general_operand" "")
18998                          (match_operand:SI 3 "general_operand" "")))]
18999   ""
19000   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19001
19002 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19003 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19004 ;; So just document what we're doing explicitly.
19005
19006 (define_insn "x86_movsicc_0_m1"
19007   [(set (match_operand:SI 0 "register_operand" "=r")
19008         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19009           (const_int -1)
19010           (const_int 0)))
19011    (clobber (reg:CC FLAGS_REG))]
19012   ""
19013   "sbb{l}\t%0, %0"
19014   ; Since we don't have the proper number of operands for an alu insn,
19015   ; fill in all the blanks.
19016   [(set_attr "type" "alu")
19017    (set_attr "pent_pair" "pu")
19018    (set_attr "memory" "none")
19019    (set_attr "imm_disp" "false")
19020    (set_attr "mode" "SI")
19021    (set_attr "length_immediate" "0")])
19022
19023 (define_insn "*movsicc_noc"
19024   [(set (match_operand:SI 0 "register_operand" "=r,r")
19025         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19026                                 [(reg FLAGS_REG) (const_int 0)])
19027                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19028                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19029   "TARGET_CMOVE
19030    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19031   "@
19032    cmov%O2%C1\t{%2, %0|%0, %2}
19033    cmov%O2%c1\t{%3, %0|%0, %3}"
19034   [(set_attr "type" "icmov")
19035    (set_attr "mode" "SI")])
19036
19037 (define_expand "movhicc"
19038   [(set (match_operand:HI 0 "register_operand" "")
19039         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19040                          (match_operand:HI 2 "general_operand" "")
19041                          (match_operand:HI 3 "general_operand" "")))]
19042   "TARGET_HIMODE_MATH"
19043   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19044
19045 (define_insn "*movhicc_noc"
19046   [(set (match_operand:HI 0 "register_operand" "=r,r")
19047         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19048                                 [(reg FLAGS_REG) (const_int 0)])
19049                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19050                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19051   "TARGET_CMOVE
19052    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19053   "@
19054    cmov%O2%C1\t{%2, %0|%0, %2}
19055    cmov%O2%c1\t{%3, %0|%0, %3}"
19056   [(set_attr "type" "icmov")
19057    (set_attr "mode" "HI")])
19058
19059 (define_expand "movqicc"
19060   [(set (match_operand:QI 0 "register_operand" "")
19061         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19062                          (match_operand:QI 2 "general_operand" "")
19063                          (match_operand:QI 3 "general_operand" "")))]
19064   "TARGET_QIMODE_MATH"
19065   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19066
19067 (define_insn_and_split "*movqicc_noc"
19068   [(set (match_operand:QI 0 "register_operand" "=r,r")
19069         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19070                                 [(match_operand 4 "flags_reg_operand" "")
19071                                  (const_int 0)])
19072                       (match_operand:QI 2 "register_operand" "r,0")
19073                       (match_operand:QI 3 "register_operand" "0,r")))]
19074   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19075   "#"
19076   "&& reload_completed"
19077   [(set (match_dup 0)
19078         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19079                       (match_dup 2)
19080                       (match_dup 3)))]
19081   "operands[0] = gen_lowpart (SImode, operands[0]);
19082    operands[2] = gen_lowpart (SImode, operands[2]);
19083    operands[3] = gen_lowpart (SImode, operands[3]);"
19084   [(set_attr "type" "icmov")
19085    (set_attr "mode" "SI")])
19086
19087 (define_expand "movsfcc"
19088   [(set (match_operand:SF 0 "register_operand" "")
19089         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19090                          (match_operand:SF 2 "register_operand" "")
19091                          (match_operand:SF 3 "register_operand" "")))]
19092   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19093   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19094
19095 (define_insn "*movsfcc_1_387"
19096   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19097         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19098                                 [(reg FLAGS_REG) (const_int 0)])
19099                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19100                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19101   "TARGET_80387 && TARGET_CMOVE
19102    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19103   "@
19104    fcmov%F1\t{%2, %0|%0, %2}
19105    fcmov%f1\t{%3, %0|%0, %3}
19106    cmov%O2%C1\t{%2, %0|%0, %2}
19107    cmov%O2%c1\t{%3, %0|%0, %3}"
19108   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19109    (set_attr "mode" "SF,SF,SI,SI")])
19110
19111 (define_expand "movdfcc"
19112   [(set (match_operand:DF 0 "register_operand" "")
19113         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19114                          (match_operand:DF 2 "register_operand" "")
19115                          (match_operand:DF 3 "register_operand" "")))]
19116   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19117   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19118
19119 (define_insn "*movdfcc_1"
19120   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19121         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19122                                 [(reg FLAGS_REG) (const_int 0)])
19123                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19124                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19125   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19126    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19127   "@
19128    fcmov%F1\t{%2, %0|%0, %2}
19129    fcmov%f1\t{%3, %0|%0, %3}
19130    #
19131    #"
19132   [(set_attr "type" "fcmov,fcmov,multi,multi")
19133    (set_attr "mode" "DF")])
19134
19135 (define_insn "*movdfcc_1_rex64"
19136   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19137         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19138                                 [(reg FLAGS_REG) (const_int 0)])
19139                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19140                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19141   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19142    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19143   "@
19144    fcmov%F1\t{%2, %0|%0, %2}
19145    fcmov%f1\t{%3, %0|%0, %3}
19146    cmov%O2%C1\t{%2, %0|%0, %2}
19147    cmov%O2%c1\t{%3, %0|%0, %3}"
19148   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19149    (set_attr "mode" "DF")])
19150
19151 (define_split
19152   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19153         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19154                                 [(match_operand 4 "flags_reg_operand" "")
19155                                  (const_int 0)])
19156                       (match_operand:DF 2 "nonimmediate_operand" "")
19157                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19158   "!TARGET_64BIT && reload_completed"
19159   [(set (match_dup 2)
19160         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19161                       (match_dup 5)
19162                       (match_dup 7)))
19163    (set (match_dup 3)
19164         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19165                       (match_dup 6)
19166                       (match_dup 8)))]
19167   "split_di (operands+2, 1, operands+5, operands+6);
19168    split_di (operands+3, 1, operands+7, operands+8);
19169    split_di (operands, 1, operands+2, operands+3);")
19170
19171 (define_expand "movxfcc"
19172   [(set (match_operand:XF 0 "register_operand" "")
19173         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19174                          (match_operand:XF 2 "register_operand" "")
19175                          (match_operand:XF 3 "register_operand" "")))]
19176   "TARGET_80387 && TARGET_CMOVE"
19177   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19178
19179 (define_insn "*movxfcc_1"
19180   [(set (match_operand:XF 0 "register_operand" "=f,f")
19181         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19182                                 [(reg FLAGS_REG) (const_int 0)])
19183                       (match_operand:XF 2 "register_operand" "f,0")
19184                       (match_operand:XF 3 "register_operand" "0,f")))]
19185   "TARGET_80387 && TARGET_CMOVE"
19186   "@
19187    fcmov%F1\t{%2, %0|%0, %2}
19188    fcmov%f1\t{%3, %0|%0, %3}"
19189   [(set_attr "type" "fcmov")
19190    (set_attr "mode" "XF")])
19191
19192 ;; These versions of the min/max patterns are intentionally ignorant of
19193 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19194 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19195 ;; are undefined in this condition, we're certain this is correct.
19196
19197 (define_insn "sminsf3"
19198   [(set (match_operand:SF 0 "register_operand" "=x")
19199         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19200                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19201   "TARGET_SSE_MATH"
19202   "minss\t{%2, %0|%0, %2}"
19203   [(set_attr "type" "sseadd")
19204    (set_attr "mode" "SF")])
19205
19206 (define_insn "smaxsf3"
19207   [(set (match_operand:SF 0 "register_operand" "=x")
19208         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19209                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19210   "TARGET_SSE_MATH"
19211   "maxss\t{%2, %0|%0, %2}"
19212   [(set_attr "type" "sseadd")
19213    (set_attr "mode" "SF")])
19214
19215 (define_insn "smindf3"
19216   [(set (match_operand:DF 0 "register_operand" "=x")
19217         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19218                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19219   "TARGET_SSE2 && TARGET_SSE_MATH"
19220   "minsd\t{%2, %0|%0, %2}"
19221   [(set_attr "type" "sseadd")
19222    (set_attr "mode" "DF")])
19223
19224 (define_insn "smaxdf3"
19225   [(set (match_operand:DF 0 "register_operand" "=x")
19226         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19227                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19228   "TARGET_SSE2 && TARGET_SSE_MATH"
19229   "maxsd\t{%2, %0|%0, %2}"
19230   [(set_attr "type" "sseadd")
19231    (set_attr "mode" "DF")])
19232
19233 ;; These versions of the min/max patterns implement exactly the operations
19234 ;;   min = (op1 < op2 ? op1 : op2)
19235 ;;   max = (!(op1 < op2) ? op1 : op2)
19236 ;; Their operands are not commutative, and thus they may be used in the
19237 ;; presence of -0.0 and NaN.
19238
19239 (define_insn "*ieee_sminsf3"
19240   [(set (match_operand:SF 0 "register_operand" "=x")
19241         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19242                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19243                    UNSPEC_IEEE_MIN))]
19244   "TARGET_SSE_MATH"
19245   "minss\t{%2, %0|%0, %2}"
19246   [(set_attr "type" "sseadd")
19247    (set_attr "mode" "SF")])
19248
19249 (define_insn "*ieee_smaxsf3"
19250   [(set (match_operand:SF 0 "register_operand" "=x")
19251         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19252                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19253                    UNSPEC_IEEE_MAX))]
19254   "TARGET_SSE_MATH"
19255   "maxss\t{%2, %0|%0, %2}"
19256   [(set_attr "type" "sseadd")
19257    (set_attr "mode" "SF")])
19258
19259 (define_insn "*ieee_smindf3"
19260   [(set (match_operand:DF 0 "register_operand" "=x")
19261         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19262                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19263                    UNSPEC_IEEE_MIN))]
19264   "TARGET_SSE2 && TARGET_SSE_MATH"
19265   "minsd\t{%2, %0|%0, %2}"
19266   [(set_attr "type" "sseadd")
19267    (set_attr "mode" "DF")])
19268
19269 (define_insn "*ieee_smaxdf3"
19270   [(set (match_operand:DF 0 "register_operand" "=x")
19271         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19272                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19273                    UNSPEC_IEEE_MAX))]
19274   "TARGET_SSE2 && TARGET_SSE_MATH"
19275   "maxsd\t{%2, %0|%0, %2}"
19276   [(set_attr "type" "sseadd")
19277    (set_attr "mode" "DF")])
19278
19279 ;; Make two stack loads independent:
19280 ;;   fld aa              fld aa
19281 ;;   fld %st(0)     ->   fld bb
19282 ;;   fmul bb             fmul %st(1), %st
19283 ;;
19284 ;; Actually we only match the last two instructions for simplicity.
19285 (define_peephole2
19286   [(set (match_operand 0 "fp_register_operand" "")
19287         (match_operand 1 "fp_register_operand" ""))
19288    (set (match_dup 0)
19289         (match_operator 2 "binary_fp_operator"
19290            [(match_dup 0)
19291             (match_operand 3 "memory_operand" "")]))]
19292   "REGNO (operands[0]) != REGNO (operands[1])"
19293   [(set (match_dup 0) (match_dup 3))
19294    (set (match_dup 0) (match_dup 4))]
19295
19296   ;; The % modifier is not operational anymore in peephole2's, so we have to
19297   ;; swap the operands manually in the case of addition and multiplication.
19298   "if (COMMUTATIVE_ARITH_P (operands[2]))
19299      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19300                                  operands[0], operands[1]);
19301    else
19302      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19303                                  operands[1], operands[0]);")
19304
19305 ;; Conditional addition patterns
19306 (define_expand "addqicc"
19307   [(match_operand:QI 0 "register_operand" "")
19308    (match_operand 1 "comparison_operator" "")
19309    (match_operand:QI 2 "register_operand" "")
19310    (match_operand:QI 3 "const_int_operand" "")]
19311   ""
19312   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19313
19314 (define_expand "addhicc"
19315   [(match_operand:HI 0 "register_operand" "")
19316    (match_operand 1 "comparison_operator" "")
19317    (match_operand:HI 2 "register_operand" "")
19318    (match_operand:HI 3 "const_int_operand" "")]
19319   ""
19320   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19321
19322 (define_expand "addsicc"
19323   [(match_operand:SI 0 "register_operand" "")
19324    (match_operand 1 "comparison_operator" "")
19325    (match_operand:SI 2 "register_operand" "")
19326    (match_operand:SI 3 "const_int_operand" "")]
19327   ""
19328   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19329
19330 (define_expand "adddicc"
19331   [(match_operand:DI 0 "register_operand" "")
19332    (match_operand 1 "comparison_operator" "")
19333    (match_operand:DI 2 "register_operand" "")
19334    (match_operand:DI 3 "const_int_operand" "")]
19335   "TARGET_64BIT"
19336   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19337
19338 \f
19339 ;; Misc patterns (?)
19340
19341 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19342 ;; Otherwise there will be nothing to keep
19343 ;;
19344 ;; [(set (reg ebp) (reg esp))]
19345 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19346 ;;  (clobber (eflags)]
19347 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19348 ;;
19349 ;; in proper program order.
19350 (define_insn "pro_epilogue_adjust_stack_1"
19351   [(set (match_operand:SI 0 "register_operand" "=r,r")
19352         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19353                  (match_operand:SI 2 "immediate_operand" "i,i")))
19354    (clobber (reg:CC FLAGS_REG))
19355    (clobber (mem:BLK (scratch)))]
19356   "!TARGET_64BIT"
19357 {
19358   switch (get_attr_type (insn))
19359     {
19360     case TYPE_IMOV:
19361       return "mov{l}\t{%1, %0|%0, %1}";
19362
19363     case TYPE_ALU:
19364       if (CONST_INT_P (operands[2])
19365           && (INTVAL (operands[2]) == 128
19366               || (INTVAL (operands[2]) < 0
19367                   && INTVAL (operands[2]) != -128)))
19368         {
19369           operands[2] = GEN_INT (-INTVAL (operands[2]));
19370           return "sub{l}\t{%2, %0|%0, %2}";
19371         }
19372       return "add{l}\t{%2, %0|%0, %2}";
19373
19374     case TYPE_LEA:
19375       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19376       return "lea{l}\t{%a2, %0|%0, %a2}";
19377
19378     default:
19379       gcc_unreachable ();
19380     }
19381 }
19382   [(set (attr "type")
19383         (cond [(eq_attr "alternative" "0")
19384                  (const_string "alu")
19385                (match_operand:SI 2 "const0_operand" "")
19386                  (const_string "imov")
19387               ]
19388               (const_string "lea")))
19389    (set_attr "mode" "SI")])
19390
19391 (define_insn "pro_epilogue_adjust_stack_rex64"
19392   [(set (match_operand:DI 0 "register_operand" "=r,r")
19393         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19394                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19395    (clobber (reg:CC FLAGS_REG))
19396    (clobber (mem:BLK (scratch)))]
19397   "TARGET_64BIT"
19398 {
19399   switch (get_attr_type (insn))
19400     {
19401     case TYPE_IMOV:
19402       return "mov{q}\t{%1, %0|%0, %1}";
19403
19404     case TYPE_ALU:
19405       if (CONST_INT_P (operands[2])
19406           /* Avoid overflows.  */
19407           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19408           && (INTVAL (operands[2]) == 128
19409               || (INTVAL (operands[2]) < 0
19410                   && INTVAL (operands[2]) != -128)))
19411         {
19412           operands[2] = GEN_INT (-INTVAL (operands[2]));
19413           return "sub{q}\t{%2, %0|%0, %2}";
19414         }
19415       return "add{q}\t{%2, %0|%0, %2}";
19416
19417     case TYPE_LEA:
19418       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19419       return "lea{q}\t{%a2, %0|%0, %a2}";
19420
19421     default:
19422       gcc_unreachable ();
19423     }
19424 }
19425   [(set (attr "type")
19426         (cond [(eq_attr "alternative" "0")
19427                  (const_string "alu")
19428                (match_operand:DI 2 "const0_operand" "")
19429                  (const_string "imov")
19430               ]
19431               (const_string "lea")))
19432    (set_attr "mode" "DI")])
19433
19434 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19435   [(set (match_operand:DI 0 "register_operand" "=r,r")
19436         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19437                  (match_operand:DI 3 "immediate_operand" "i,i")))
19438    (use (match_operand:DI 2 "register_operand" "r,r"))
19439    (clobber (reg:CC FLAGS_REG))
19440    (clobber (mem:BLK (scratch)))]
19441   "TARGET_64BIT"
19442 {
19443   switch (get_attr_type (insn))
19444     {
19445     case TYPE_ALU:
19446       return "add{q}\t{%2, %0|%0, %2}";
19447
19448     case TYPE_LEA:
19449       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19450       return "lea{q}\t{%a2, %0|%0, %a2}";
19451
19452     default:
19453       gcc_unreachable ();
19454     }
19455 }
19456   [(set_attr "type" "alu,lea")
19457    (set_attr "mode" "DI")])
19458
19459 (define_expand "allocate_stack_worker"
19460   [(match_operand:SI 0 "register_operand" "")]
19461   "TARGET_STACK_PROBE"
19462 {
19463   if (reload_completed)
19464     {
19465       if (TARGET_64BIT)
19466         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19467       else
19468         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19469     }
19470   else
19471     {
19472       if (TARGET_64BIT)
19473         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19474       else
19475         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19476     }
19477   DONE;
19478 })
19479
19480 (define_insn "allocate_stack_worker_1"
19481   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19482     UNSPECV_STACK_PROBE)
19483    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19484    (clobber (match_scratch:SI 1 "=0"))
19485    (clobber (reg:CC FLAGS_REG))]
19486   "!TARGET_64BIT && TARGET_STACK_PROBE"
19487   "call\t__alloca"
19488   [(set_attr "type" "multi")
19489    (set_attr "length" "5")])
19490
19491 (define_expand "allocate_stack_worker_postreload"
19492   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19493                                     UNSPECV_STACK_PROBE)
19494               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19495               (clobber (match_dup 0))
19496               (clobber (reg:CC FLAGS_REG))])]
19497   ""
19498   "")
19499
19500 (define_insn "allocate_stack_worker_rex64"
19501   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19502     UNSPECV_STACK_PROBE)
19503    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19504    (clobber (match_scratch:DI 1 "=0"))
19505    (clobber (reg:CC FLAGS_REG))]
19506   "TARGET_64BIT && TARGET_STACK_PROBE"
19507   "call\t__alloca"
19508   [(set_attr "type" "multi")
19509    (set_attr "length" "5")])
19510
19511 (define_expand "allocate_stack_worker_rex64_postreload"
19512   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19513                                     UNSPECV_STACK_PROBE)
19514               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19515               (clobber (match_dup 0))
19516               (clobber (reg:CC FLAGS_REG))])]
19517   ""
19518   "")
19519
19520 (define_expand "allocate_stack"
19521   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19522                    (minus:SI (reg:SI SP_REG)
19523                              (match_operand:SI 1 "general_operand" "")))
19524               (clobber (reg:CC FLAGS_REG))])
19525    (parallel [(set (reg:SI SP_REG)
19526                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19527               (clobber (reg:CC FLAGS_REG))])]
19528   "TARGET_STACK_PROBE"
19529 {
19530 #ifdef CHECK_STACK_LIMIT
19531   if (CONST_INT_P (operands[1])
19532       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19533     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19534                            operands[1]));
19535   else
19536 #endif
19537     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19538                                                             operands[1])));
19539
19540   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19541   DONE;
19542 })
19543
19544 (define_expand "builtin_setjmp_receiver"
19545   [(label_ref (match_operand 0 "" ""))]
19546   "!TARGET_64BIT && flag_pic"
19547 {
19548   if (TARGET_MACHO)
19549     {
19550       rtx xops[3];
19551       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19552       rtx label_rtx = gen_label_rtx ();
19553       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19554       xops[0] = xops[1] = picreg;
19555       xops[2] = gen_rtx_CONST (SImode,
19556                   gen_rtx_MINUS (SImode,
19557                     gen_rtx_LABEL_REF (SImode, label_rtx),
19558                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19559       ix86_expand_binary_operator (MINUS, SImode, xops);
19560     }
19561   else
19562     emit_insn (gen_set_got (pic_offset_table_rtx));
19563   DONE;
19564 })
19565 \f
19566 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19567
19568 (define_split
19569   [(set (match_operand 0 "register_operand" "")
19570         (match_operator 3 "promotable_binary_operator"
19571            [(match_operand 1 "register_operand" "")
19572             (match_operand 2 "aligned_operand" "")]))
19573    (clobber (reg:CC FLAGS_REG))]
19574   "! TARGET_PARTIAL_REG_STALL && reload_completed
19575    && ((GET_MODE (operands[0]) == HImode
19576         && ((!optimize_size && !TARGET_FAST_PREFIX)
19577             /* ??? next two lines just !satisfies_constraint_K (...) */
19578             || !CONST_INT_P (operands[2])
19579             || satisfies_constraint_K (operands[2])))
19580        || (GET_MODE (operands[0]) == QImode
19581            && (TARGET_PROMOTE_QImode || optimize_size)))"
19582   [(parallel [(set (match_dup 0)
19583                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19584               (clobber (reg:CC FLAGS_REG))])]
19585   "operands[0] = gen_lowpart (SImode, operands[0]);
19586    operands[1] = gen_lowpart (SImode, operands[1]);
19587    if (GET_CODE (operands[3]) != ASHIFT)
19588      operands[2] = gen_lowpart (SImode, operands[2]);
19589    PUT_MODE (operands[3], SImode);")
19590
19591 ; Promote the QImode tests, as i386 has encoding of the AND
19592 ; instruction with 32-bit sign-extended immediate and thus the
19593 ; instruction size is unchanged, except in the %eax case for
19594 ; which it is increased by one byte, hence the ! optimize_size.
19595 (define_split
19596   [(set (match_operand 0 "flags_reg_operand" "")
19597         (match_operator 2 "compare_operator"
19598           [(and (match_operand 3 "aligned_operand" "")
19599                 (match_operand 4 "const_int_operand" ""))
19600            (const_int 0)]))
19601    (set (match_operand 1 "register_operand" "")
19602         (and (match_dup 3) (match_dup 4)))]
19603   "! TARGET_PARTIAL_REG_STALL && reload_completed
19604    /* Ensure that the operand will remain sign-extended immediate.  */
19605    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19606    && ! optimize_size
19607    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19608        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19609   [(parallel [(set (match_dup 0)
19610                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19611                                     (const_int 0)]))
19612               (set (match_dup 1)
19613                    (and:SI (match_dup 3) (match_dup 4)))])]
19614 {
19615   operands[4]
19616     = gen_int_mode (INTVAL (operands[4])
19617                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19618   operands[1] = gen_lowpart (SImode, operands[1]);
19619   operands[3] = gen_lowpart (SImode, operands[3]);
19620 })
19621
19622 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19623 ; the TEST instruction with 32-bit sign-extended immediate and thus
19624 ; the instruction size would at least double, which is not what we
19625 ; want even with ! optimize_size.
19626 (define_split
19627   [(set (match_operand 0 "flags_reg_operand" "")
19628         (match_operator 1 "compare_operator"
19629           [(and (match_operand:HI 2 "aligned_operand" "")
19630                 (match_operand:HI 3 "const_int_operand" ""))
19631            (const_int 0)]))]
19632   "! TARGET_PARTIAL_REG_STALL && reload_completed
19633    /* Ensure that the operand will remain sign-extended immediate.  */
19634    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19635    && ! TARGET_FAST_PREFIX
19636    && ! optimize_size"
19637   [(set (match_dup 0)
19638         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19639                          (const_int 0)]))]
19640 {
19641   operands[3]
19642     = gen_int_mode (INTVAL (operands[3])
19643                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19644   operands[2] = gen_lowpart (SImode, operands[2]);
19645 })
19646
19647 (define_split
19648   [(set (match_operand 0 "register_operand" "")
19649         (neg (match_operand 1 "register_operand" "")))
19650    (clobber (reg:CC FLAGS_REG))]
19651   "! TARGET_PARTIAL_REG_STALL && reload_completed
19652    && (GET_MODE (operands[0]) == HImode
19653        || (GET_MODE (operands[0]) == QImode
19654            && (TARGET_PROMOTE_QImode || optimize_size)))"
19655   [(parallel [(set (match_dup 0)
19656                    (neg:SI (match_dup 1)))
19657               (clobber (reg:CC FLAGS_REG))])]
19658   "operands[0] = gen_lowpart (SImode, operands[0]);
19659    operands[1] = gen_lowpart (SImode, operands[1]);")
19660
19661 (define_split
19662   [(set (match_operand 0 "register_operand" "")
19663         (not (match_operand 1 "register_operand" "")))]
19664   "! TARGET_PARTIAL_REG_STALL && reload_completed
19665    && (GET_MODE (operands[0]) == HImode
19666        || (GET_MODE (operands[0]) == QImode
19667            && (TARGET_PROMOTE_QImode || optimize_size)))"
19668   [(set (match_dup 0)
19669         (not:SI (match_dup 1)))]
19670   "operands[0] = gen_lowpart (SImode, operands[0]);
19671    operands[1] = gen_lowpart (SImode, operands[1]);")
19672
19673 (define_split
19674   [(set (match_operand 0 "register_operand" "")
19675         (if_then_else (match_operator 1 "comparison_operator"
19676                                 [(reg FLAGS_REG) (const_int 0)])
19677                       (match_operand 2 "register_operand" "")
19678                       (match_operand 3 "register_operand" "")))]
19679   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19680    && (GET_MODE (operands[0]) == HImode
19681        || (GET_MODE (operands[0]) == QImode
19682            && (TARGET_PROMOTE_QImode || optimize_size)))"
19683   [(set (match_dup 0)
19684         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19685   "operands[0] = gen_lowpart (SImode, operands[0]);
19686    operands[2] = gen_lowpart (SImode, operands[2]);
19687    operands[3] = gen_lowpart (SImode, operands[3]);")
19688
19689 \f
19690 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19691 ;; transform a complex memory operation into two memory to register operations.
19692
19693 ;; Don't push memory operands
19694 (define_peephole2
19695   [(set (match_operand:SI 0 "push_operand" "")
19696         (match_operand:SI 1 "memory_operand" ""))
19697    (match_scratch:SI 2 "r")]
19698   "!optimize_size && !TARGET_PUSH_MEMORY
19699    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19700   [(set (match_dup 2) (match_dup 1))
19701    (set (match_dup 0) (match_dup 2))]
19702   "")
19703
19704 (define_peephole2
19705   [(set (match_operand:DI 0 "push_operand" "")
19706         (match_operand:DI 1 "memory_operand" ""))
19707    (match_scratch:DI 2 "r")]
19708   "!optimize_size && !TARGET_PUSH_MEMORY
19709    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19710   [(set (match_dup 2) (match_dup 1))
19711    (set (match_dup 0) (match_dup 2))]
19712   "")
19713
19714 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19715 ;; SImode pushes.
19716 (define_peephole2
19717   [(set (match_operand:SF 0 "push_operand" "")
19718         (match_operand:SF 1 "memory_operand" ""))
19719    (match_scratch:SF 2 "r")]
19720   "!optimize_size && !TARGET_PUSH_MEMORY
19721    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19722   [(set (match_dup 2) (match_dup 1))
19723    (set (match_dup 0) (match_dup 2))]
19724   "")
19725
19726 (define_peephole2
19727   [(set (match_operand:HI 0 "push_operand" "")
19728         (match_operand:HI 1 "memory_operand" ""))
19729    (match_scratch:HI 2 "r")]
19730   "!optimize_size && !TARGET_PUSH_MEMORY
19731    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19732   [(set (match_dup 2) (match_dup 1))
19733    (set (match_dup 0) (match_dup 2))]
19734   "")
19735
19736 (define_peephole2
19737   [(set (match_operand:QI 0 "push_operand" "")
19738         (match_operand:QI 1 "memory_operand" ""))
19739    (match_scratch:QI 2 "q")]
19740   "!optimize_size && !TARGET_PUSH_MEMORY
19741    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19742   [(set (match_dup 2) (match_dup 1))
19743    (set (match_dup 0) (match_dup 2))]
19744   "")
19745
19746 ;; Don't move an immediate directly to memory when the instruction
19747 ;; gets too big.
19748 (define_peephole2
19749   [(match_scratch:SI 1 "r")
19750    (set (match_operand:SI 0 "memory_operand" "")
19751         (const_int 0))]
19752   "! optimize_size
19753    && ! TARGET_USE_MOV0
19754    && TARGET_SPLIT_LONG_MOVES
19755    && get_attr_length (insn) >= ix86_cost->large_insn
19756    && peep2_regno_dead_p (0, FLAGS_REG)"
19757   [(parallel [(set (match_dup 1) (const_int 0))
19758               (clobber (reg:CC FLAGS_REG))])
19759    (set (match_dup 0) (match_dup 1))]
19760   "")
19761
19762 (define_peephole2
19763   [(match_scratch:HI 1 "r")
19764    (set (match_operand:HI 0 "memory_operand" "")
19765         (const_int 0))]
19766   "! optimize_size
19767    && ! TARGET_USE_MOV0
19768    && TARGET_SPLIT_LONG_MOVES
19769    && get_attr_length (insn) >= ix86_cost->large_insn
19770    && peep2_regno_dead_p (0, FLAGS_REG)"
19771   [(parallel [(set (match_dup 2) (const_int 0))
19772               (clobber (reg:CC FLAGS_REG))])
19773    (set (match_dup 0) (match_dup 1))]
19774   "operands[2] = gen_lowpart (SImode, operands[1]);")
19775
19776 (define_peephole2
19777   [(match_scratch:QI 1 "q")
19778    (set (match_operand:QI 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 2) (const_int 0))
19786               (clobber (reg:CC FLAGS_REG))])
19787    (set (match_dup 0) (match_dup 1))]
19788   "operands[2] = gen_lowpart (SImode, operands[1]);")
19789
19790 (define_peephole2
19791   [(match_scratch:SI 2 "r")
19792    (set (match_operand:SI 0 "memory_operand" "")
19793         (match_operand:SI 1 "immediate_operand" ""))]
19794   "! optimize_size
19795    && get_attr_length (insn) >= ix86_cost->large_insn
19796    && TARGET_SPLIT_LONG_MOVES"
19797   [(set (match_dup 2) (match_dup 1))
19798    (set (match_dup 0) (match_dup 2))]
19799   "")
19800
19801 (define_peephole2
19802   [(match_scratch:HI 2 "r")
19803    (set (match_operand:HI 0 "memory_operand" "")
19804         (match_operand:HI 1 "immediate_operand" ""))]
19805   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19806   && TARGET_SPLIT_LONG_MOVES"
19807   [(set (match_dup 2) (match_dup 1))
19808    (set (match_dup 0) (match_dup 2))]
19809   "")
19810
19811 (define_peephole2
19812   [(match_scratch:QI 2 "q")
19813    (set (match_operand:QI 0 "memory_operand" "")
19814         (match_operand:QI 1 "immediate_operand" ""))]
19815   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19816   && TARGET_SPLIT_LONG_MOVES"
19817   [(set (match_dup 2) (match_dup 1))
19818    (set (match_dup 0) (match_dup 2))]
19819   "")
19820
19821 ;; Don't compare memory with zero, load and use a test instead.
19822 (define_peephole2
19823   [(set (match_operand 0 "flags_reg_operand" "")
19824         (match_operator 1 "compare_operator"
19825           [(match_operand:SI 2 "memory_operand" "")
19826            (const_int 0)]))
19827    (match_scratch:SI 3 "r")]
19828   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19829   [(set (match_dup 3) (match_dup 2))
19830    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19831   "")
19832
19833 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19834 ;; Don't split NOTs with a displacement operand, because resulting XOR
19835 ;; will not be pairable anyway.
19836 ;;
19837 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19838 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19839 ;; so this split helps here as well.
19840 ;;
19841 ;; Note: Can't do this as a regular split because we can't get proper
19842 ;; lifetime information then.
19843
19844 (define_peephole2
19845   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19846         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19847   "!optimize_size
19848    && peep2_regno_dead_p (0, FLAGS_REG)
19849    && ((TARGET_PENTIUM
19850         && (!MEM_P (operands[0])
19851             || !memory_displacement_operand (operands[0], SImode)))
19852        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19853   [(parallel [(set (match_dup 0)
19854                    (xor:SI (match_dup 1) (const_int -1)))
19855               (clobber (reg:CC FLAGS_REG))])]
19856   "")
19857
19858 (define_peephole2
19859   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19860         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19861   "!optimize_size
19862    && peep2_regno_dead_p (0, FLAGS_REG)
19863    && ((TARGET_PENTIUM
19864         && (!MEM_P (operands[0])
19865             || !memory_displacement_operand (operands[0], HImode)))
19866        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19867   [(parallel [(set (match_dup 0)
19868                    (xor:HI (match_dup 1) (const_int -1)))
19869               (clobber (reg:CC FLAGS_REG))])]
19870   "")
19871
19872 (define_peephole2
19873   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19874         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19875   "!optimize_size
19876    && peep2_regno_dead_p (0, FLAGS_REG)
19877    && ((TARGET_PENTIUM
19878         && (!MEM_P (operands[0])
19879             || !memory_displacement_operand (operands[0], QImode)))
19880        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19881   [(parallel [(set (match_dup 0)
19882                    (xor:QI (match_dup 1) (const_int -1)))
19883               (clobber (reg:CC FLAGS_REG))])]
19884   "")
19885
19886 ;; Non pairable "test imm, reg" instructions can be translated to
19887 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19888 ;; byte opcode instead of two, have a short form for byte operands),
19889 ;; so do it for other CPUs as well.  Given that the value was dead,
19890 ;; this should not create any new dependencies.  Pass on the sub-word
19891 ;; versions if we're concerned about partial register stalls.
19892
19893 (define_peephole2
19894   [(set (match_operand 0 "flags_reg_operand" "")
19895         (match_operator 1 "compare_operator"
19896           [(and:SI (match_operand:SI 2 "register_operand" "")
19897                    (match_operand:SI 3 "immediate_operand" ""))
19898            (const_int 0)]))]
19899   "ix86_match_ccmode (insn, CCNOmode)
19900    && (true_regnum (operands[2]) != 0
19901        || satisfies_constraint_K (operands[3]))
19902    && peep2_reg_dead_p (1, operands[2])"
19903   [(parallel
19904      [(set (match_dup 0)
19905            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19906                             (const_int 0)]))
19907       (set (match_dup 2)
19908            (and:SI (match_dup 2) (match_dup 3)))])]
19909   "")
19910
19911 ;; We don't need to handle HImode case, because it will be promoted to SImode
19912 ;; on ! TARGET_PARTIAL_REG_STALL
19913
19914 (define_peephole2
19915   [(set (match_operand 0 "flags_reg_operand" "")
19916         (match_operator 1 "compare_operator"
19917           [(and:QI (match_operand:QI 2 "register_operand" "")
19918                    (match_operand:QI 3 "immediate_operand" ""))
19919            (const_int 0)]))]
19920   "! TARGET_PARTIAL_REG_STALL
19921    && ix86_match_ccmode (insn, CCNOmode)
19922    && true_regnum (operands[2]) != 0
19923    && peep2_reg_dead_p (1, operands[2])"
19924   [(parallel
19925      [(set (match_dup 0)
19926            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19927                             (const_int 0)]))
19928       (set (match_dup 2)
19929            (and:QI (match_dup 2) (match_dup 3)))])]
19930   "")
19931
19932 (define_peephole2
19933   [(set (match_operand 0 "flags_reg_operand" "")
19934         (match_operator 1 "compare_operator"
19935           [(and:SI
19936              (zero_extract:SI
19937                (match_operand 2 "ext_register_operand" "")
19938                (const_int 8)
19939                (const_int 8))
19940              (match_operand 3 "const_int_operand" ""))
19941            (const_int 0)]))]
19942   "! TARGET_PARTIAL_REG_STALL
19943    && ix86_match_ccmode (insn, CCNOmode)
19944    && true_regnum (operands[2]) != 0
19945    && peep2_reg_dead_p (1, operands[2])"
19946   [(parallel [(set (match_dup 0)
19947                    (match_op_dup 1
19948                      [(and:SI
19949                         (zero_extract:SI
19950                           (match_dup 2)
19951                           (const_int 8)
19952                           (const_int 8))
19953                         (match_dup 3))
19954                       (const_int 0)]))
19955               (set (zero_extract:SI (match_dup 2)
19956                                     (const_int 8)
19957                                     (const_int 8))
19958                    (and:SI
19959                      (zero_extract:SI
19960                        (match_dup 2)
19961                        (const_int 8)
19962                        (const_int 8))
19963                      (match_dup 3)))])]
19964   "")
19965
19966 ;; Don't do logical operations with memory inputs.
19967 (define_peephole2
19968   [(match_scratch:SI 2 "r")
19969    (parallel [(set (match_operand:SI 0 "register_operand" "")
19970                    (match_operator:SI 3 "arith_or_logical_operator"
19971                      [(match_dup 0)
19972                       (match_operand:SI 1 "memory_operand" "")]))
19973               (clobber (reg:CC FLAGS_REG))])]
19974   "! optimize_size && ! TARGET_READ_MODIFY"
19975   [(set (match_dup 2) (match_dup 1))
19976    (parallel [(set (match_dup 0)
19977                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19978               (clobber (reg:CC FLAGS_REG))])]
19979   "")
19980
19981 (define_peephole2
19982   [(match_scratch:SI 2 "r")
19983    (parallel [(set (match_operand:SI 0 "register_operand" "")
19984                    (match_operator:SI 3 "arith_or_logical_operator"
19985                      [(match_operand:SI 1 "memory_operand" "")
19986                       (match_dup 0)]))
19987               (clobber (reg:CC FLAGS_REG))])]
19988   "! optimize_size && ! TARGET_READ_MODIFY"
19989   [(set (match_dup 2) (match_dup 1))
19990    (parallel [(set (match_dup 0)
19991                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19992               (clobber (reg:CC FLAGS_REG))])]
19993   "")
19994
19995 ; Don't do logical operations with memory outputs
19996 ;
19997 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19998 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19999 ; the same decoder scheduling characteristics as the original.
20000
20001 (define_peephole2
20002   [(match_scratch:SI 2 "r")
20003    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20004                    (match_operator:SI 3 "arith_or_logical_operator"
20005                      [(match_dup 0)
20006                       (match_operand:SI 1 "nonmemory_operand" "")]))
20007               (clobber (reg:CC FLAGS_REG))])]
20008   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20009   [(set (match_dup 2) (match_dup 0))
20010    (parallel [(set (match_dup 2)
20011                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20012               (clobber (reg:CC FLAGS_REG))])
20013    (set (match_dup 0) (match_dup 2))]
20014   "")
20015
20016 (define_peephole2
20017   [(match_scratch:SI 2 "r")
20018    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20019                    (match_operator:SI 3 "arith_or_logical_operator"
20020                      [(match_operand:SI 1 "nonmemory_operand" "")
20021                       (match_dup 0)]))
20022               (clobber (reg:CC FLAGS_REG))])]
20023   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20024   [(set (match_dup 2) (match_dup 0))
20025    (parallel [(set (match_dup 2)
20026                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20027               (clobber (reg:CC FLAGS_REG))])
20028    (set (match_dup 0) (match_dup 2))]
20029   "")
20030
20031 ;; Attempt to always use XOR for zeroing registers.
20032 (define_peephole2
20033   [(set (match_operand 0 "register_operand" "")
20034         (match_operand 1 "const0_operand" ""))]
20035   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20036    && (! TARGET_USE_MOV0 || optimize_size)
20037    && GENERAL_REG_P (operands[0])
20038    && peep2_regno_dead_p (0, FLAGS_REG)"
20039   [(parallel [(set (match_dup 0) (const_int 0))
20040               (clobber (reg:CC FLAGS_REG))])]
20041 {
20042   operands[0] = gen_lowpart (word_mode, operands[0]);
20043 })
20044
20045 (define_peephole2
20046   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20047         (const_int 0))]
20048   "(GET_MODE (operands[0]) == QImode
20049     || GET_MODE (operands[0]) == HImode)
20050    && (! TARGET_USE_MOV0 || optimize_size)
20051    && peep2_regno_dead_p (0, FLAGS_REG)"
20052   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20053               (clobber (reg:CC FLAGS_REG))])])
20054
20055 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20056 (define_peephole2
20057   [(set (match_operand 0 "register_operand" "")
20058         (const_int -1))]
20059   "(GET_MODE (operands[0]) == HImode
20060     || GET_MODE (operands[0]) == SImode
20061     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20062    && (optimize_size || TARGET_PENTIUM)
20063    && peep2_regno_dead_p (0, FLAGS_REG)"
20064   [(parallel [(set (match_dup 0) (const_int -1))
20065               (clobber (reg:CC FLAGS_REG))])]
20066   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20067                               operands[0]);")
20068
20069 ;; Attempt to convert simple leas to adds. These can be created by
20070 ;; move expanders.
20071 (define_peephole2
20072   [(set (match_operand:SI 0 "register_operand" "")
20073         (plus:SI (match_dup 0)
20074                  (match_operand:SI 1 "nonmemory_operand" "")))]
20075   "peep2_regno_dead_p (0, FLAGS_REG)"
20076   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20077               (clobber (reg:CC FLAGS_REG))])]
20078   "")
20079
20080 (define_peephole2
20081   [(set (match_operand:SI 0 "register_operand" "")
20082         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20083                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20084   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20085   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20086               (clobber (reg:CC FLAGS_REG))])]
20087   "operands[2] = gen_lowpart (SImode, operands[2]);")
20088
20089 (define_peephole2
20090   [(set (match_operand:DI 0 "register_operand" "")
20091         (plus:DI (match_dup 0)
20092                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20093   "peep2_regno_dead_p (0, FLAGS_REG)"
20094   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20095               (clobber (reg:CC FLAGS_REG))])]
20096   "")
20097
20098 (define_peephole2
20099   [(set (match_operand:SI 0 "register_operand" "")
20100         (mult:SI (match_dup 0)
20101                  (match_operand:SI 1 "const_int_operand" "")))]
20102   "exact_log2 (INTVAL (operands[1])) >= 0
20103    && peep2_regno_dead_p (0, FLAGS_REG)"
20104   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20105               (clobber (reg:CC FLAGS_REG))])]
20106   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20107
20108 (define_peephole2
20109   [(set (match_operand:DI 0 "register_operand" "")
20110         (mult:DI (match_dup 0)
20111                  (match_operand:DI 1 "const_int_operand" "")))]
20112   "exact_log2 (INTVAL (operands[1])) >= 0
20113    && peep2_regno_dead_p (0, FLAGS_REG)"
20114   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20115               (clobber (reg:CC FLAGS_REG))])]
20116   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20117
20118 (define_peephole2
20119   [(set (match_operand:SI 0 "register_operand" "")
20120         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20121                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20122   "exact_log2 (INTVAL (operands[2])) >= 0
20123    && REGNO (operands[0]) == REGNO (operands[1])
20124    && peep2_regno_dead_p (0, FLAGS_REG)"
20125   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20126               (clobber (reg:CC FLAGS_REG))])]
20127   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20128
20129 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20130 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20131 ;; many CPUs it is also faster, since special hardware to avoid esp
20132 ;; dependencies is present.
20133
20134 ;; While some of these conversions may be done using splitters, we use peepholes
20135 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20136
20137 ;; Convert prologue esp subtractions to push.
20138 ;; We need register to push.  In order to keep verify_flow_info happy we have
20139 ;; two choices
20140 ;; - use scratch and clobber it in order to avoid dependencies
20141 ;; - use already live register
20142 ;; We can't use the second way right now, since there is no reliable way how to
20143 ;; verify that given register is live.  First choice will also most likely in
20144 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20145 ;; call clobbered registers are dead.  We may want to use base pointer as an
20146 ;; alternative when no register is available later.
20147
20148 (define_peephole2
20149   [(match_scratch:SI 0 "r")
20150    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20151               (clobber (reg:CC FLAGS_REG))
20152               (clobber (mem:BLK (scratch)))])]
20153   "optimize_size || !TARGET_SUB_ESP_4"
20154   [(clobber (match_dup 0))
20155    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20156               (clobber (mem:BLK (scratch)))])])
20157
20158 (define_peephole2
20159   [(match_scratch:SI 0 "r")
20160    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20161               (clobber (reg:CC FLAGS_REG))
20162               (clobber (mem:BLK (scratch)))])]
20163   "optimize_size || !TARGET_SUB_ESP_8"
20164   [(clobber (match_dup 0))
20165    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20166    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20167               (clobber (mem:BLK (scratch)))])])
20168
20169 ;; Convert esp subtractions to push.
20170 (define_peephole2
20171   [(match_scratch:SI 0 "r")
20172    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20173               (clobber (reg:CC FLAGS_REG))])]
20174   "optimize_size || !TARGET_SUB_ESP_4"
20175   [(clobber (match_dup 0))
20176    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20177
20178 (define_peephole2
20179   [(match_scratch:SI 0 "r")
20180    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20181               (clobber (reg:CC FLAGS_REG))])]
20182   "optimize_size || !TARGET_SUB_ESP_8"
20183   [(clobber (match_dup 0))
20184    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20185    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20186
20187 ;; Convert epilogue deallocator to pop.
20188 (define_peephole2
20189   [(match_scratch:SI 0 "r")
20190    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20191               (clobber (reg:CC FLAGS_REG))
20192               (clobber (mem:BLK (scratch)))])]
20193   "optimize_size || !TARGET_ADD_ESP_4"
20194   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20195               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20196               (clobber (mem:BLK (scratch)))])]
20197   "")
20198
20199 ;; Two pops case is tricky, since pop causes dependency on destination register.
20200 ;; We use two registers if available.
20201 (define_peephole2
20202   [(match_scratch:SI 0 "r")
20203    (match_scratch:SI 1 "r")
20204    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20205               (clobber (reg:CC FLAGS_REG))
20206               (clobber (mem:BLK (scratch)))])]
20207   "optimize_size || !TARGET_ADD_ESP_8"
20208   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20209               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20210               (clobber (mem:BLK (scratch)))])
20211    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20212               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20213   "")
20214
20215 (define_peephole2
20216   [(match_scratch:SI 0 "r")
20217    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20218               (clobber (reg:CC FLAGS_REG))
20219               (clobber (mem:BLK (scratch)))])]
20220   "optimize_size"
20221   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20222               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20223               (clobber (mem:BLK (scratch)))])
20224    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20225               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20226   "")
20227
20228 ;; Convert esp additions to pop.
20229 (define_peephole2
20230   [(match_scratch:SI 0 "r")
20231    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20232               (clobber (reg:CC FLAGS_REG))])]
20233   ""
20234   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20235               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20236   "")
20237
20238 ;; Two pops case is tricky, since pop causes dependency on destination register.
20239 ;; We use two registers if available.
20240 (define_peephole2
20241   [(match_scratch:SI 0 "r")
20242    (match_scratch:SI 1 "r")
20243    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20244               (clobber (reg:CC FLAGS_REG))])]
20245   ""
20246   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20247               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20248    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20249               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20250   "")
20251
20252 (define_peephole2
20253   [(match_scratch:SI 0 "r")
20254    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20255               (clobber (reg:CC FLAGS_REG))])]
20256   "optimize_size"
20257   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20258               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20259    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20260               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20261   "")
20262 \f
20263 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20264 ;; required and register dies.  Similarly for 128 to plus -128.
20265 (define_peephole2
20266   [(set (match_operand 0 "flags_reg_operand" "")
20267         (match_operator 1 "compare_operator"
20268           [(match_operand 2 "register_operand" "")
20269            (match_operand 3 "const_int_operand" "")]))]
20270   "(INTVAL (operands[3]) == -1
20271     || INTVAL (operands[3]) == 1
20272     || INTVAL (operands[3]) == 128)
20273    && ix86_match_ccmode (insn, CCGCmode)
20274    && peep2_reg_dead_p (1, operands[2])"
20275   [(parallel [(set (match_dup 0)
20276                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20277               (clobber (match_dup 2))])]
20278   "")
20279 \f
20280 (define_peephole2
20281   [(match_scratch:DI 0 "r")
20282    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20283               (clobber (reg:CC FLAGS_REG))
20284               (clobber (mem:BLK (scratch)))])]
20285   "optimize_size || !TARGET_SUB_ESP_4"
20286   [(clobber (match_dup 0))
20287    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20288               (clobber (mem:BLK (scratch)))])])
20289
20290 (define_peephole2
20291   [(match_scratch:DI 0 "r")
20292    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20293               (clobber (reg:CC FLAGS_REG))
20294               (clobber (mem:BLK (scratch)))])]
20295   "optimize_size || !TARGET_SUB_ESP_8"
20296   [(clobber (match_dup 0))
20297    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20298    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20299               (clobber (mem:BLK (scratch)))])])
20300
20301 ;; Convert esp subtractions to push.
20302 (define_peephole2
20303   [(match_scratch:DI 0 "r")
20304    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20305               (clobber (reg:CC FLAGS_REG))])]
20306   "optimize_size || !TARGET_SUB_ESP_4"
20307   [(clobber (match_dup 0))
20308    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20309
20310 (define_peephole2
20311   [(match_scratch:DI 0 "r")
20312    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20313               (clobber (reg:CC FLAGS_REG))])]
20314   "optimize_size || !TARGET_SUB_ESP_8"
20315   [(clobber (match_dup 0))
20316    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20317    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20318
20319 ;; Convert epilogue deallocator to pop.
20320 (define_peephole2
20321   [(match_scratch:DI 0 "r")
20322    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20323               (clobber (reg:CC FLAGS_REG))
20324               (clobber (mem:BLK (scratch)))])]
20325   "optimize_size || !TARGET_ADD_ESP_4"
20326   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20327               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20328               (clobber (mem:BLK (scratch)))])]
20329   "")
20330
20331 ;; Two pops case is tricky, since pop causes dependency on destination register.
20332 ;; We use two registers if available.
20333 (define_peephole2
20334   [(match_scratch:DI 0 "r")
20335    (match_scratch:DI 1 "r")
20336    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20337               (clobber (reg:CC FLAGS_REG))
20338               (clobber (mem:BLK (scratch)))])]
20339   "optimize_size || !TARGET_ADD_ESP_8"
20340   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20341               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20342               (clobber (mem:BLK (scratch)))])
20343    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20344               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20345   "")
20346
20347 (define_peephole2
20348   [(match_scratch:DI 0 "r")
20349    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20350               (clobber (reg:CC FLAGS_REG))
20351               (clobber (mem:BLK (scratch)))])]
20352   "optimize_size"
20353   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20354               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20355               (clobber (mem:BLK (scratch)))])
20356    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20357               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20358   "")
20359
20360 ;; Convert esp additions to pop.
20361 (define_peephole2
20362   [(match_scratch:DI 0 "r")
20363    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20364               (clobber (reg:CC FLAGS_REG))])]
20365   ""
20366   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20367               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20368   "")
20369
20370 ;; Two pops case is tricky, since pop causes dependency on destination register.
20371 ;; We use two registers if available.
20372 (define_peephole2
20373   [(match_scratch:DI 0 "r")
20374    (match_scratch:DI 1 "r")
20375    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20376               (clobber (reg:CC FLAGS_REG))])]
20377   ""
20378   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20379               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20380    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20381               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20382   "")
20383
20384 (define_peephole2
20385   [(match_scratch:DI 0 "r")
20386    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20387               (clobber (reg:CC FLAGS_REG))])]
20388   "optimize_size"
20389   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20390               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20391    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20392               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20393   "")
20394 \f
20395 ;; Convert imul by three, five and nine into lea
20396 (define_peephole2
20397   [(parallel
20398     [(set (match_operand:SI 0 "register_operand" "")
20399           (mult:SI (match_operand:SI 1 "register_operand" "")
20400                    (match_operand:SI 2 "const_int_operand" "")))
20401      (clobber (reg:CC FLAGS_REG))])]
20402   "INTVAL (operands[2]) == 3
20403    || INTVAL (operands[2]) == 5
20404    || INTVAL (operands[2]) == 9"
20405   [(set (match_dup 0)
20406         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20407                  (match_dup 1)))]
20408   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20409
20410 (define_peephole2
20411   [(parallel
20412     [(set (match_operand:SI 0 "register_operand" "")
20413           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20414                    (match_operand:SI 2 "const_int_operand" "")))
20415      (clobber (reg:CC FLAGS_REG))])]
20416   "!optimize_size
20417    && (INTVAL (operands[2]) == 3
20418        || INTVAL (operands[2]) == 5
20419        || INTVAL (operands[2]) == 9)"
20420   [(set (match_dup 0) (match_dup 1))
20421    (set (match_dup 0)
20422         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20423                  (match_dup 0)))]
20424   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20425
20426 (define_peephole2
20427   [(parallel
20428     [(set (match_operand:DI 0 "register_operand" "")
20429           (mult:DI (match_operand:DI 1 "register_operand" "")
20430                    (match_operand:DI 2 "const_int_operand" "")))
20431      (clobber (reg:CC FLAGS_REG))])]
20432   "TARGET_64BIT
20433    && (INTVAL (operands[2]) == 3
20434        || INTVAL (operands[2]) == 5
20435        || INTVAL (operands[2]) == 9)"
20436   [(set (match_dup 0)
20437         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20438                  (match_dup 1)))]
20439   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20440
20441 (define_peephole2
20442   [(parallel
20443     [(set (match_operand:DI 0 "register_operand" "")
20444           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20445                    (match_operand:DI 2 "const_int_operand" "")))
20446      (clobber (reg:CC FLAGS_REG))])]
20447   "TARGET_64BIT
20448    && !optimize_size
20449    && (INTVAL (operands[2]) == 3
20450        || INTVAL (operands[2]) == 5
20451        || INTVAL (operands[2]) == 9)"
20452   [(set (match_dup 0) (match_dup 1))
20453    (set (match_dup 0)
20454         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20455                  (match_dup 0)))]
20456   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20457
20458 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20459 ;; imul $32bit_imm, reg, reg is direct decoded.
20460 (define_peephole2
20461   [(match_scratch:DI 3 "r")
20462    (parallel [(set (match_operand:DI 0 "register_operand" "")
20463                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20464                             (match_operand:DI 2 "immediate_operand" "")))
20465               (clobber (reg:CC FLAGS_REG))])]
20466   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20467    && !satisfies_constraint_K (operands[2])"
20468   [(set (match_dup 3) (match_dup 1))
20469    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20470               (clobber (reg:CC FLAGS_REG))])]
20471 "")
20472
20473 (define_peephole2
20474   [(match_scratch:SI 3 "r")
20475    (parallel [(set (match_operand:SI 0 "register_operand" "")
20476                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20477                             (match_operand:SI 2 "immediate_operand" "")))
20478               (clobber (reg:CC FLAGS_REG))])]
20479   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20480    && !satisfies_constraint_K (operands[2])"
20481   [(set (match_dup 3) (match_dup 1))
20482    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20483               (clobber (reg:CC FLAGS_REG))])]
20484 "")
20485
20486 (define_peephole2
20487   [(match_scratch:SI 3 "r")
20488    (parallel [(set (match_operand:DI 0 "register_operand" "")
20489                    (zero_extend:DI
20490                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20491                               (match_operand:SI 2 "immediate_operand" ""))))
20492               (clobber (reg:CC FLAGS_REG))])]
20493   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20494    && !satisfies_constraint_K (operands[2])"
20495   [(set (match_dup 3) (match_dup 1))
20496    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20497               (clobber (reg:CC FLAGS_REG))])]
20498 "")
20499
20500 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20501 ;; Convert it into imul reg, reg
20502 ;; It would be better to force assembler to encode instruction using long
20503 ;; immediate, but there is apparently no way to do so.
20504 (define_peephole2
20505   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20506                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20507                             (match_operand:DI 2 "const_int_operand" "")))
20508               (clobber (reg:CC FLAGS_REG))])
20509    (match_scratch:DI 3 "r")]
20510   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20511    && satisfies_constraint_K (operands[2])"
20512   [(set (match_dup 3) (match_dup 2))
20513    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20514               (clobber (reg:CC FLAGS_REG))])]
20515 {
20516   if (!rtx_equal_p (operands[0], operands[1]))
20517     emit_move_insn (operands[0], operands[1]);
20518 })
20519
20520 (define_peephole2
20521   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20522                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20523                             (match_operand:SI 2 "const_int_operand" "")))
20524               (clobber (reg:CC FLAGS_REG))])
20525    (match_scratch:SI 3 "r")]
20526   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20527    && satisfies_constraint_K (operands[2])"
20528   [(set (match_dup 3) (match_dup 2))
20529    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20530               (clobber (reg:CC FLAGS_REG))])]
20531 {
20532   if (!rtx_equal_p (operands[0], operands[1]))
20533     emit_move_insn (operands[0], operands[1]);
20534 })
20535
20536 (define_peephole2
20537   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20538                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20539                             (match_operand:HI 2 "immediate_operand" "")))
20540               (clobber (reg:CC FLAGS_REG))])
20541    (match_scratch:HI 3 "r")]
20542   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20543   [(set (match_dup 3) (match_dup 2))
20544    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20545               (clobber (reg:CC FLAGS_REG))])]
20546 {
20547   if (!rtx_equal_p (operands[0], operands[1]))
20548     emit_move_insn (operands[0], operands[1]);
20549 })
20550
20551 ;; After splitting up read-modify operations, array accesses with memory
20552 ;; operands might end up in form:
20553 ;;  sall    $2, %eax
20554 ;;  movl    4(%esp), %edx
20555 ;;  addl    %edx, %eax
20556 ;; instead of pre-splitting:
20557 ;;  sall    $2, %eax
20558 ;;  addl    4(%esp), %eax
20559 ;; Turn it into:
20560 ;;  movl    4(%esp), %edx
20561 ;;  leal    (%edx,%eax,4), %eax
20562
20563 (define_peephole2
20564   [(parallel [(set (match_operand 0 "register_operand" "")
20565                    (ashift (match_operand 1 "register_operand" "")
20566                            (match_operand 2 "const_int_operand" "")))
20567                (clobber (reg:CC FLAGS_REG))])
20568    (set (match_operand 3 "register_operand")
20569         (match_operand 4 "x86_64_general_operand" ""))
20570    (parallel [(set (match_operand 5 "register_operand" "")
20571                    (plus (match_operand 6 "register_operand" "")
20572                          (match_operand 7 "register_operand" "")))
20573                    (clobber (reg:CC FLAGS_REG))])]
20574   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20575    /* Validate MODE for lea.  */
20576    && ((!TARGET_PARTIAL_REG_STALL
20577         && (GET_MODE (operands[0]) == QImode
20578             || GET_MODE (operands[0]) == HImode))
20579        || GET_MODE (operands[0]) == SImode
20580        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20581    /* We reorder load and the shift.  */
20582    && !rtx_equal_p (operands[1], operands[3])
20583    && !reg_overlap_mentioned_p (operands[0], operands[4])
20584    /* Last PLUS must consist of operand 0 and 3.  */
20585    && !rtx_equal_p (operands[0], operands[3])
20586    && (rtx_equal_p (operands[3], operands[6])
20587        || rtx_equal_p (operands[3], operands[7]))
20588    && (rtx_equal_p (operands[0], operands[6])
20589        || rtx_equal_p (operands[0], operands[7]))
20590    /* The intermediate operand 0 must die or be same as output.  */
20591    && (rtx_equal_p (operands[0], operands[5])
20592        || peep2_reg_dead_p (3, operands[0]))"
20593   [(set (match_dup 3) (match_dup 4))
20594    (set (match_dup 0) (match_dup 1))]
20595 {
20596   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20597   int scale = 1 << INTVAL (operands[2]);
20598   rtx index = gen_lowpart (Pmode, operands[1]);
20599   rtx base = gen_lowpart (Pmode, operands[3]);
20600   rtx dest = gen_lowpart (mode, operands[5]);
20601
20602   operands[1] = gen_rtx_PLUS (Pmode, base,
20603                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20604   if (mode != Pmode)
20605     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20606   operands[0] = dest;
20607 })
20608 \f
20609 ;; Call-value patterns last so that the wildcard operand does not
20610 ;; disrupt insn-recog's switch tables.
20611
20612 (define_insn "*call_value_pop_0"
20613   [(set (match_operand 0 "" "")
20614         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20615               (match_operand:SI 2 "" "")))
20616    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20617                             (match_operand:SI 3 "immediate_operand" "")))]
20618   "!TARGET_64BIT"
20619 {
20620   if (SIBLING_CALL_P (insn))
20621     return "jmp\t%P1";
20622   else
20623     return "call\t%P1";
20624 }
20625   [(set_attr "type" "callv")])
20626
20627 (define_insn "*call_value_pop_1"
20628   [(set (match_operand 0 "" "")
20629         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20630               (match_operand:SI 2 "" "")))
20631    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20632                             (match_operand:SI 3 "immediate_operand" "i")))]
20633   "!TARGET_64BIT"
20634 {
20635   if (constant_call_address_operand (operands[1], Pmode))
20636     {
20637       if (SIBLING_CALL_P (insn))
20638         return "jmp\t%P1";
20639       else
20640         return "call\t%P1";
20641     }
20642   if (SIBLING_CALL_P (insn))
20643     return "jmp\t%A1";
20644   else
20645     return "call\t%A1";
20646 }
20647   [(set_attr "type" "callv")])
20648
20649 (define_insn "*call_value_0"
20650   [(set (match_operand 0 "" "")
20651         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20652               (match_operand:SI 2 "" "")))]
20653   "!TARGET_64BIT"
20654 {
20655   if (SIBLING_CALL_P (insn))
20656     return "jmp\t%P1";
20657   else
20658     return "call\t%P1";
20659 }
20660   [(set_attr "type" "callv")])
20661
20662 (define_insn "*call_value_0_rex64"
20663   [(set (match_operand 0 "" "")
20664         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20665               (match_operand:DI 2 "const_int_operand" "")))]
20666   "TARGET_64BIT"
20667 {
20668   if (SIBLING_CALL_P (insn))
20669     return "jmp\t%P1";
20670   else
20671     return "call\t%P1";
20672 }
20673   [(set_attr "type" "callv")])
20674
20675 (define_insn "*call_value_1"
20676   [(set (match_operand 0 "" "")
20677         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20678               (match_operand:SI 2 "" "")))]
20679   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20680 {
20681   if (constant_call_address_operand (operands[1], Pmode))
20682     return "call\t%P1";
20683   return "call\t%A1";
20684 }
20685   [(set_attr "type" "callv")])
20686
20687 (define_insn "*sibcall_value_1"
20688   [(set (match_operand 0 "" "")
20689         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20690               (match_operand:SI 2 "" "")))]
20691   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20692 {
20693   if (constant_call_address_operand (operands[1], Pmode))
20694     return "jmp\t%P1";
20695   return "jmp\t%A1";
20696 }
20697   [(set_attr "type" "callv")])
20698
20699 (define_insn "*call_value_1_rex64"
20700   [(set (match_operand 0 "" "")
20701         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20702               (match_operand:DI 2 "" "")))]
20703   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20704 {
20705   if (constant_call_address_operand (operands[1], Pmode))
20706     return "call\t%P1";
20707   return "call\t%A1";
20708 }
20709   [(set_attr "type" "callv")])
20710
20711 (define_insn "*sibcall_value_1_rex64"
20712   [(set (match_operand 0 "" "")
20713         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20714               (match_operand:DI 2 "" "")))]
20715   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20716   "jmp\t%P1"
20717   [(set_attr "type" "callv")])
20718
20719 (define_insn "*sibcall_value_1_rex64_v"
20720   [(set (match_operand 0 "" "")
20721         (call (mem:QI (reg:DI R11_REG))
20722               (match_operand:DI 1 "" "")))]
20723   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20724   "jmp\t*%%r11"
20725   [(set_attr "type" "callv")])
20726 \f
20727 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20728 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20729 ;; caught for use by garbage collectors and the like.  Using an insn that
20730 ;; maps to SIGILL makes it more likely the program will rightfully die.
20731 ;; Keeping with tradition, "6" is in honor of #UD.
20732 (define_insn "trap"
20733   [(trap_if (const_int 1) (const_int 6))]
20734   ""
20735   { return ASM_SHORT "0x0b0f"; }
20736   [(set_attr "length" "2")])
20737
20738 (define_expand "sse_prologue_save"
20739   [(parallel [(set (match_operand:BLK 0 "" "")
20740                    (unspec:BLK [(reg:DI 21)
20741                                 (reg:DI 22)
20742                                 (reg:DI 23)
20743                                 (reg:DI 24)
20744                                 (reg:DI 25)
20745                                 (reg:DI 26)
20746                                 (reg:DI 27)
20747                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20748               (use (match_operand:DI 1 "register_operand" ""))
20749               (use (match_operand:DI 2 "immediate_operand" ""))
20750               (use (label_ref:DI (match_operand 3 "" "")))])]
20751   "TARGET_64BIT"
20752   "")
20753
20754 (define_insn "*sse_prologue_save_insn"
20755   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20756                           (match_operand:DI 4 "const_int_operand" "n")))
20757         (unspec:BLK [(reg:DI 21)
20758                      (reg:DI 22)
20759                      (reg:DI 23)
20760                      (reg:DI 24)
20761                      (reg:DI 25)
20762                      (reg:DI 26)
20763                      (reg:DI 27)
20764                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20765    (use (match_operand:DI 1 "register_operand" "r"))
20766    (use (match_operand:DI 2 "const_int_operand" "i"))
20767    (use (label_ref:DI (match_operand 3 "" "X")))]
20768   "TARGET_64BIT
20769    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20770    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20771   "*
20772 {
20773   int i;
20774   operands[0] = gen_rtx_MEM (Pmode,
20775                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20776   output_asm_insn (\"jmp\\t%A1\", operands);
20777   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20778     {
20779       operands[4] = adjust_address (operands[0], DImode, i*16);
20780       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20781       PUT_MODE (operands[4], TImode);
20782       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20783         output_asm_insn (\"rex\", operands);
20784       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20785     }
20786   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20787                              CODE_LABEL_NUMBER (operands[3]));
20788   return \"\";
20789 }
20790   "
20791   [(set_attr "type" "other")
20792    (set_attr "length_immediate" "0")
20793    (set_attr "length_address" "0")
20794    (set_attr "length" "135")
20795    (set_attr "memory" "store")
20796    (set_attr "modrm" "0")
20797    (set_attr "mode" "DI")])
20798
20799 (define_expand "prefetch"
20800   [(prefetch (match_operand 0 "address_operand" "")
20801              (match_operand:SI 1 "const_int_operand" "")
20802              (match_operand:SI 2 "const_int_operand" ""))]
20803   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20804 {
20805   int rw = INTVAL (operands[1]);
20806   int locality = INTVAL (operands[2]);
20807
20808   gcc_assert (rw == 0 || rw == 1);
20809   gcc_assert (locality >= 0 && locality <= 3);
20810   gcc_assert (GET_MODE (operands[0]) == Pmode
20811               || GET_MODE (operands[0]) == VOIDmode);
20812
20813   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20814      supported by SSE counterpart or the SSE prefetch is not available
20815      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20816      of locality.  */
20817   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20818     operands[2] = GEN_INT (3);
20819   else
20820     operands[1] = const0_rtx;
20821 })
20822
20823 (define_insn "*prefetch_sse"
20824   [(prefetch (match_operand:SI 0 "address_operand" "p")
20825              (const_int 0)
20826              (match_operand:SI 1 "const_int_operand" ""))]
20827   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20828 {
20829   static const char * const patterns[4] = {
20830    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20831   };
20832
20833   int locality = INTVAL (operands[1]);
20834   gcc_assert (locality >= 0 && locality <= 3);
20835
20836   return patterns[locality];
20837 }
20838   [(set_attr "type" "sse")
20839    (set_attr "memory" "none")])
20840
20841 (define_insn "*prefetch_sse_rex"
20842   [(prefetch (match_operand:DI 0 "address_operand" "p")
20843              (const_int 0)
20844              (match_operand:SI 1 "const_int_operand" ""))]
20845   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20846 {
20847   static const char * const patterns[4] = {
20848    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20849   };
20850
20851   int locality = INTVAL (operands[1]);
20852   gcc_assert (locality >= 0 && locality <= 3);
20853
20854   return patterns[locality];
20855 }
20856   [(set_attr "type" "sse")
20857    (set_attr "memory" "none")])
20858
20859 (define_insn "*prefetch_3dnow"
20860   [(prefetch (match_operand:SI 0 "address_operand" "p")
20861              (match_operand:SI 1 "const_int_operand" "n")
20862              (const_int 3))]
20863   "TARGET_3DNOW && !TARGET_64BIT"
20864 {
20865   if (INTVAL (operands[1]) == 0)
20866     return "prefetch\t%a0";
20867   else
20868     return "prefetchw\t%a0";
20869 }
20870   [(set_attr "type" "mmx")
20871    (set_attr "memory" "none")])
20872
20873 (define_insn "*prefetch_3dnow_rex"
20874   [(prefetch (match_operand:DI 0 "address_operand" "p")
20875              (match_operand:SI 1 "const_int_operand" "n")
20876              (const_int 3))]
20877   "TARGET_3DNOW && TARGET_64BIT"
20878 {
20879   if (INTVAL (operands[1]) == 0)
20880     return "prefetch\t%a0";
20881   else
20882     return "prefetchw\t%a0";
20883 }
20884   [(set_attr "type" "mmx")
20885    (set_attr "memory" "none")])
20886
20887 (define_expand "stack_protect_set"
20888   [(match_operand 0 "memory_operand" "")
20889    (match_operand 1 "memory_operand" "")]
20890   ""
20891 {
20892 #ifdef TARGET_THREAD_SSP_OFFSET
20893   if (TARGET_64BIT)
20894     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20895                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20896   else
20897     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20898                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20899 #else
20900   if (TARGET_64BIT)
20901     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20902   else
20903     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20904 #endif
20905   DONE;
20906 })
20907
20908 (define_insn "stack_protect_set_si"
20909   [(set (match_operand:SI 0 "memory_operand" "=m")
20910         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20911    (set (match_scratch:SI 2 "=&r") (const_int 0))
20912    (clobber (reg:CC FLAGS_REG))]
20913   ""
20914   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20915   [(set_attr "type" "multi")])
20916
20917 (define_insn "stack_protect_set_di"
20918   [(set (match_operand:DI 0 "memory_operand" "=m")
20919         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20920    (set (match_scratch:DI 2 "=&r") (const_int 0))
20921    (clobber (reg:CC FLAGS_REG))]
20922   "TARGET_64BIT"
20923   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20924   [(set_attr "type" "multi")])
20925
20926 (define_insn "stack_tls_protect_set_si"
20927   [(set (match_operand:SI 0 "memory_operand" "=m")
20928         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20929    (set (match_scratch:SI 2 "=&r") (const_int 0))
20930    (clobber (reg:CC FLAGS_REG))]
20931   ""
20932   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20933   [(set_attr "type" "multi")])
20934
20935 (define_insn "stack_tls_protect_set_di"
20936   [(set (match_operand:DI 0 "memory_operand" "=m")
20937         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20938    (set (match_scratch:DI 2 "=&r") (const_int 0))
20939    (clobber (reg:CC FLAGS_REG))]
20940   "TARGET_64BIT"
20941   {
20942      /* The kernel uses a different segment register for performance reasons; a
20943         system call would not have to trash the userspace segment register,
20944         which would be expensive */
20945      if (ix86_cmodel != CM_KERNEL)
20946         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20947      else
20948         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20949   }
20950   [(set_attr "type" "multi")])
20951
20952 (define_expand "stack_protect_test"
20953   [(match_operand 0 "memory_operand" "")
20954    (match_operand 1 "memory_operand" "")
20955    (match_operand 2 "" "")]
20956   ""
20957 {
20958   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20959   ix86_compare_op0 = operands[0];
20960   ix86_compare_op1 = operands[1];
20961   ix86_compare_emitted = flags;
20962
20963 #ifdef TARGET_THREAD_SSP_OFFSET
20964   if (TARGET_64BIT)
20965     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20966                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20967   else
20968     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20969                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20970 #else
20971   if (TARGET_64BIT)
20972     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20973   else
20974     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20975 #endif
20976   emit_jump_insn (gen_beq (operands[2]));
20977   DONE;
20978 })
20979
20980 (define_insn "stack_protect_test_si"
20981   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20982         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20983                      (match_operand:SI 2 "memory_operand" "m")]
20984                     UNSPEC_SP_TEST))
20985    (clobber (match_scratch:SI 3 "=&r"))]
20986   ""
20987   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20988   [(set_attr "type" "multi")])
20989
20990 (define_insn "stack_protect_test_di"
20991   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20992         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20993                      (match_operand:DI 2 "memory_operand" "m")]
20994                     UNSPEC_SP_TEST))
20995    (clobber (match_scratch:DI 3 "=&r"))]
20996   "TARGET_64BIT"
20997   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20998   [(set_attr "type" "multi")])
20999
21000 (define_insn "stack_tls_protect_test_si"
21001   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21002         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21003                      (match_operand:SI 2 "const_int_operand" "i")]
21004                     UNSPEC_SP_TLS_TEST))
21005    (clobber (match_scratch:SI 3 "=r"))]
21006   ""
21007   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21008   [(set_attr "type" "multi")])
21009
21010 (define_insn "stack_tls_protect_test_di"
21011   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21012         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21013                      (match_operand:DI 2 "const_int_operand" "i")]
21014                     UNSPEC_SP_TLS_TEST))
21015    (clobber (match_scratch:DI 3 "=r"))]
21016   "TARGET_64BIT"
21017   {
21018      /* The kernel uses a different segment register for performance reasons; a
21019         system call would not have to trash the userspace segment register,
21020         which would be expensive */
21021      if (ix86_cmodel != CM_KERNEL)
21022         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21023      else
21024         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21025   }
21026   [(set_attr "type" "multi")])
21027
21028 (include "mmx.md")
21029 (include "sse.md")
21030 (include "sync.md")