OSDN Git Service

* config/i386/constraints.md (Ym): New constraint.
[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 ;; When SSE is available, it is always faster to use it!
4335 (define_insn "fix_truncsfdi_sse"
4336   [(set (match_operand:DI 0 "register_operand" "=r,r")
4337         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4338   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4339   "cvttss2si{q}\t{%1, %0|%0, %1}"
4340   [(set_attr "type" "sseicvt")
4341    (set_attr "mode" "SF")
4342    (set_attr "athlon_decode" "double,vector")
4343    (set_attr "amdfam10_decode" "double,double")])
4344
4345 (define_insn "fix_truncdfdi_sse"
4346   [(set (match_operand:DI 0 "register_operand" "=r,r")
4347         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4348   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4349   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4350   [(set_attr "type" "sseicvt")
4351    (set_attr "mode" "DF")
4352    (set_attr "athlon_decode" "double,vector")
4353    (set_attr "amdfam10_decode" "double,double")])
4354
4355 (define_insn "fix_truncsfsi_sse"
4356   [(set (match_operand:SI 0 "register_operand" "=r,r")
4357         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4358   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4359   "cvttss2si\t{%1, %0|%0, %1}"
4360   [(set_attr "type" "sseicvt")
4361    (set_attr "mode" "DF")
4362    (set_attr "athlon_decode" "double,vector")
4363    (set_attr "amdfam10_decode" "double,double")])
4364
4365 (define_insn "fix_truncdfsi_sse"
4366   [(set (match_operand:SI 0 "register_operand" "=r,r")
4367         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4368   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4369   "cvttsd2si\t{%1, %0|%0, %1}"
4370   [(set_attr "type" "sseicvt")
4371    (set_attr "mode" "DF")
4372    (set_attr "athlon_decode" "double,vector")
4373    (set_attr "amdfam10_decode" "double,double")])
4374
4375 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4376 (define_peephole2
4377   [(set (match_operand:DF 0 "register_operand" "")
4378         (match_operand:DF 1 "memory_operand" ""))
4379    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4380         (fix:SSEMODEI24 (match_dup 0)))]
4381   "!TARGET_K8
4382    && peep2_reg_dead_p (2, operands[0])"
4383   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4384   "")
4385
4386 (define_peephole2
4387   [(set (match_operand:SF 0 "register_operand" "")
4388         (match_operand:SF 1 "memory_operand" ""))
4389    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4390         (fix:SSEMODEI24 (match_dup 0)))]
4391   "!TARGET_K8
4392    && peep2_reg_dead_p (2, operands[0])"
4393   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4394   "")
4395
4396 ;; Avoid vector decoded forms of the instruction.
4397 (define_peephole2
4398   [(match_scratch:DF 2 "Y")
4399    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4400         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4401   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4402   [(set (match_dup 2) (match_dup 1))
4403    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4404   "")
4405
4406 (define_peephole2
4407   [(match_scratch:SF 2 "x")
4408    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4409         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4410   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4411   [(set (match_dup 2) (match_dup 1))
4412    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4413   "")
4414
4415 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4416   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4417         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4418   "TARGET_FISTTP
4419    && FLOAT_MODE_P (GET_MODE (operands[1]))
4420    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4421          && (TARGET_64BIT || <MODE>mode != DImode))
4422         && TARGET_SSE_MATH)
4423    && !(reload_completed || reload_in_progress)"
4424   "#"
4425   "&& 1"
4426   [(const_int 0)]
4427 {
4428   if (memory_operand (operands[0], VOIDmode))
4429     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4430   else
4431     {
4432       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4433       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4434                                                             operands[1],
4435                                                             operands[2]));
4436     }
4437   DONE;
4438 }
4439   [(set_attr "type" "fisttp")
4440    (set_attr "mode" "<MODE>")])
4441
4442 (define_insn "fix_trunc<mode>_i387_fisttp"
4443   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4444         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4445    (clobber (match_scratch:XF 2 "=&1f"))]
4446   "TARGET_FISTTP
4447    && FLOAT_MODE_P (GET_MODE (operands[1]))
4448    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4449          && (TARGET_64BIT || <MODE>mode != DImode))
4450         && TARGET_SSE_MATH)"
4451   "* return output_fix_trunc (insn, operands, 1);"
4452   [(set_attr "type" "fisttp")
4453    (set_attr "mode" "<MODE>")])
4454
4455 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4456   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4457         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4458    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4459    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4460   "TARGET_FISTTP
4461    && FLOAT_MODE_P (GET_MODE (operands[1]))
4462    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4463         && (TARGET_64BIT || <MODE>mode != DImode))
4464         && TARGET_SSE_MATH)"
4465   "#"
4466   [(set_attr "type" "fisttp")
4467    (set_attr "mode" "<MODE>")])
4468
4469 (define_split
4470   [(set (match_operand:X87MODEI 0 "register_operand" "")
4471         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4472    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4473    (clobber (match_scratch 3 ""))]
4474   "reload_completed"
4475   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4476               (clobber (match_dup 3))])
4477    (set (match_dup 0) (match_dup 2))]
4478   "")
4479
4480 (define_split
4481   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4482         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4483    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4484    (clobber (match_scratch 3 ""))]
4485   "reload_completed"
4486   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4487               (clobber (match_dup 3))])]
4488   "")
4489
4490 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4491 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4492 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4493 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4494 ;; function in i386.c.
4495 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4496   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4497         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4498    (clobber (reg:CC FLAGS_REG))]
4499   "TARGET_80387 && !TARGET_FISTTP
4500    && FLOAT_MODE_P (GET_MODE (operands[1]))
4501    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4502          && (TARGET_64BIT || <MODE>mode != DImode))
4503    && !(reload_completed || reload_in_progress)"
4504   "#"
4505   "&& 1"
4506   [(const_int 0)]
4507 {
4508   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4509
4510   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4511   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4512   if (memory_operand (operands[0], VOIDmode))
4513     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4514                                          operands[2], operands[3]));
4515   else
4516     {
4517       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4518       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4519                                                      operands[2], operands[3],
4520                                                      operands[4]));
4521     }
4522   DONE;
4523 }
4524   [(set_attr "type" "fistp")
4525    (set_attr "i387_cw" "trunc")
4526    (set_attr "mode" "<MODE>")])
4527
4528 (define_insn "fix_truncdi_i387"
4529   [(set (match_operand:DI 0 "memory_operand" "=m")
4530         (fix:DI (match_operand 1 "register_operand" "f")))
4531    (use (match_operand:HI 2 "memory_operand" "m"))
4532    (use (match_operand:HI 3 "memory_operand" "m"))
4533    (clobber (match_scratch:XF 4 "=&1f"))]
4534   "TARGET_80387 && !TARGET_FISTTP
4535    && FLOAT_MODE_P (GET_MODE (operands[1]))
4536    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4537   "* return output_fix_trunc (insn, operands, 0);"
4538   [(set_attr "type" "fistp")
4539    (set_attr "i387_cw" "trunc")
4540    (set_attr "mode" "DI")])
4541
4542 (define_insn "fix_truncdi_i387_with_temp"
4543   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4544         (fix:DI (match_operand 1 "register_operand" "f,f")))
4545    (use (match_operand:HI 2 "memory_operand" "m,m"))
4546    (use (match_operand:HI 3 "memory_operand" "m,m"))
4547    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4548    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4549   "TARGET_80387 && !TARGET_FISTTP
4550    && FLOAT_MODE_P (GET_MODE (operands[1]))
4551    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4552   "#"
4553   [(set_attr "type" "fistp")
4554    (set_attr "i387_cw" "trunc")
4555    (set_attr "mode" "DI")])
4556
4557 (define_split
4558   [(set (match_operand:DI 0 "register_operand" "")
4559         (fix:DI (match_operand 1 "register_operand" "")))
4560    (use (match_operand:HI 2 "memory_operand" ""))
4561    (use (match_operand:HI 3 "memory_operand" ""))
4562    (clobber (match_operand:DI 4 "memory_operand" ""))
4563    (clobber (match_scratch 5 ""))]
4564   "reload_completed"
4565   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4566               (use (match_dup 2))
4567               (use (match_dup 3))
4568               (clobber (match_dup 5))])
4569    (set (match_dup 0) (match_dup 4))]
4570   "")
4571
4572 (define_split
4573   [(set (match_operand:DI 0 "memory_operand" "")
4574         (fix:DI (match_operand 1 "register_operand" "")))
4575    (use (match_operand:HI 2 "memory_operand" ""))
4576    (use (match_operand:HI 3 "memory_operand" ""))
4577    (clobber (match_operand:DI 4 "memory_operand" ""))
4578    (clobber (match_scratch 5 ""))]
4579   "reload_completed"
4580   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4581               (use (match_dup 2))
4582               (use (match_dup 3))
4583               (clobber (match_dup 5))])]
4584   "")
4585
4586 (define_insn "fix_trunc<mode>_i387"
4587   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4588         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4589    (use (match_operand:HI 2 "memory_operand" "m"))
4590    (use (match_operand:HI 3 "memory_operand" "m"))]
4591   "TARGET_80387 && !TARGET_FISTTP
4592    && FLOAT_MODE_P (GET_MODE (operands[1]))
4593    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4594   "* return output_fix_trunc (insn, operands, 0);"
4595   [(set_attr "type" "fistp")
4596    (set_attr "i387_cw" "trunc")
4597    (set_attr "mode" "<MODE>")])
4598
4599 (define_insn "fix_trunc<mode>_i387_with_temp"
4600   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4601         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4602    (use (match_operand:HI 2 "memory_operand" "m,m"))
4603    (use (match_operand:HI 3 "memory_operand" "m,m"))
4604    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4605   "TARGET_80387 && !TARGET_FISTTP
4606    && FLOAT_MODE_P (GET_MODE (operands[1]))
4607    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4608   "#"
4609   [(set_attr "type" "fistp")
4610    (set_attr "i387_cw" "trunc")
4611    (set_attr "mode" "<MODE>")])
4612
4613 (define_split
4614   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4615         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4616    (use (match_operand:HI 2 "memory_operand" ""))
4617    (use (match_operand:HI 3 "memory_operand" ""))
4618    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4619   "reload_completed"
4620   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4621               (use (match_dup 2))
4622               (use (match_dup 3))])
4623    (set (match_dup 0) (match_dup 4))]
4624   "")
4625
4626 (define_split
4627   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4628         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4629    (use (match_operand:HI 2 "memory_operand" ""))
4630    (use (match_operand:HI 3 "memory_operand" ""))
4631    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4632   "reload_completed"
4633   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4634               (use (match_dup 2))
4635               (use (match_dup 3))])]
4636   "")
4637
4638 (define_insn "x86_fnstcw_1"
4639   [(set (match_operand:HI 0 "memory_operand" "=m")
4640         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4641   "TARGET_80387"
4642   "fnstcw\t%0"
4643   [(set_attr "length" "2")
4644    (set_attr "mode" "HI")
4645    (set_attr "unit" "i387")])
4646
4647 (define_insn "x86_fldcw_1"
4648   [(set (reg:HI FPCR_REG)
4649         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4650   "TARGET_80387"
4651   "fldcw\t%0"
4652   [(set_attr "length" "2")
4653    (set_attr "mode" "HI")
4654    (set_attr "unit" "i387")
4655    (set_attr "athlon_decode" "vector")
4656    (set_attr "amdfam10_decode" "vector")])   
4657 \f
4658 ;; Conversion between fixed point and floating point.
4659
4660 ;; Even though we only accept memory inputs, the backend _really_
4661 ;; wants to be able to do this between registers.
4662
4663 (define_expand "floathisf2"
4664   [(set (match_operand:SF 0 "register_operand" "")
4665         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4666   "TARGET_80387 || TARGET_SSE_MATH"
4667 {
4668   if (TARGET_SSE_MATH)
4669     {
4670       emit_insn (gen_floatsisf2 (operands[0],
4671                                  convert_to_mode (SImode, operands[1], 0)));
4672       DONE;
4673     }
4674 })
4675
4676 (define_insn "*floathisf2_i387"
4677   [(set (match_operand:SF 0 "register_operand" "=f,f")
4678         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4679   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4680   "@
4681    fild%z1\t%1
4682    #"
4683   [(set_attr "type" "fmov,multi")
4684    (set_attr "mode" "SF")
4685    (set_attr "unit" "*,i387")
4686    (set_attr "fp_int_src" "true")])
4687
4688 (define_expand "floatsisf2"
4689   [(set (match_operand:SF 0 "register_operand" "")
4690         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4691   "TARGET_80387 || TARGET_SSE_MATH"
4692   "")
4693
4694 (define_insn "*floatsisf2_mixed"
4695   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4696         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4697   "TARGET_MIX_SSE_I387"
4698   "@
4699    fild%z1\t%1
4700    #
4701    cvtsi2ss\t{%1, %0|%0, %1}
4702    cvtsi2ss\t{%1, %0|%0, %1}"
4703   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4704    (set_attr "mode" "SF")
4705    (set_attr "unit" "*,i387,*,*")
4706    (set_attr "athlon_decode" "*,*,vector,double")
4707    (set_attr "amdfam10_decode" "*,*,vector,double")
4708    (set_attr "fp_int_src" "true")])
4709
4710 (define_insn "*floatsisf2_sse"
4711   [(set (match_operand:SF 0 "register_operand" "=x,x")
4712         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4713   "TARGET_SSE_MATH"
4714   "cvtsi2ss\t{%1, %0|%0, %1}"
4715   [(set_attr "type" "sseicvt")
4716    (set_attr "mode" "SF")
4717    (set_attr "athlon_decode" "vector,double")
4718    (set_attr "amdfam10_decode" "vector,double")
4719    (set_attr "fp_int_src" "true")])
4720
4721 (define_insn "*floatsisf2_i387"
4722   [(set (match_operand:SF 0 "register_operand" "=f,f")
4723         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4724   "TARGET_80387"
4725   "@
4726    fild%z1\t%1
4727    #"
4728   [(set_attr "type" "fmov,multi")
4729    (set_attr "mode" "SF")
4730    (set_attr "unit" "*,i387")
4731    (set_attr "fp_int_src" "true")])
4732
4733 (define_expand "floatdisf2"
4734   [(set (match_operand:SF 0 "register_operand" "")
4735         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4736   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4737   "")
4738
4739 (define_insn "*floatdisf2_mixed"
4740   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4741         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4742   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4743   "@
4744    fild%z1\t%1
4745    #
4746    cvtsi2ss{q}\t{%1, %0|%0, %1}
4747    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4748   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4749    (set_attr "mode" "SF")
4750    (set_attr "unit" "*,i387,*,*")
4751    (set_attr "athlon_decode" "*,*,vector,double")
4752    (set_attr "amdfam10_decode" "*,*,vector,double")
4753    (set_attr "fp_int_src" "true")])
4754
4755 (define_insn "*floatdisf2_sse"
4756   [(set (match_operand:SF 0 "register_operand" "=x,x")
4757         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4758   "TARGET_64BIT && TARGET_SSE_MATH"
4759   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4760   [(set_attr "type" "sseicvt")
4761    (set_attr "mode" "SF")
4762    (set_attr "athlon_decode" "vector,double")
4763    (set_attr "amdfam10_decode" "vector,double")
4764    (set_attr "fp_int_src" "true")])
4765
4766 (define_insn "*floatdisf2_i387"
4767   [(set (match_operand:SF 0 "register_operand" "=f,f")
4768         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4769   "TARGET_80387"
4770   "@
4771    fild%z1\t%1
4772    #"
4773   [(set_attr "type" "fmov,multi")
4774    (set_attr "mode" "SF")
4775    (set_attr "unit" "*,i387")
4776    (set_attr "fp_int_src" "true")])
4777
4778 (define_expand "floathidf2"
4779   [(set (match_operand:DF 0 "register_operand" "")
4780         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4781   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4782 {
4783   if (TARGET_SSE2 && TARGET_SSE_MATH)
4784     {
4785       emit_insn (gen_floatsidf2 (operands[0],
4786                                  convert_to_mode (SImode, operands[1], 0)));
4787       DONE;
4788     }
4789 })
4790
4791 (define_insn "*floathidf2_i387"
4792   [(set (match_operand:DF 0 "register_operand" "=f,f")
4793         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4794   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4795   "@
4796    fild%z1\t%1
4797    #"
4798   [(set_attr "type" "fmov,multi")
4799    (set_attr "mode" "DF")
4800    (set_attr "unit" "*,i387")
4801    (set_attr "fp_int_src" "true")])
4802
4803 (define_expand "floatsidf2"
4804   [(set (match_operand:DF 0 "register_operand" "")
4805         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4806   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4807   "")
4808
4809 (define_insn "*floatsidf2_mixed"
4810   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4811         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4812   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4813   "@
4814    fild%z1\t%1
4815    #
4816    cvtsi2sd\t{%1, %0|%0, %1}
4817    cvtsi2sd\t{%1, %0|%0, %1}"
4818   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4819    (set_attr "mode" "DF")
4820    (set_attr "unit" "*,i387,*,*")
4821    (set_attr "athlon_decode" "*,*,double,direct")
4822    (set_attr "amdfam10_decode" "*,*,vector,double")
4823    (set_attr "fp_int_src" "true")])
4824
4825 (define_insn "*floatsidf2_sse"
4826   [(set (match_operand:DF 0 "register_operand" "=x,x")
4827         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4828   "TARGET_SSE2 && TARGET_SSE_MATH"
4829   "cvtsi2sd\t{%1, %0|%0, %1}"
4830   [(set_attr "type" "sseicvt")
4831    (set_attr "mode" "DF")
4832    (set_attr "athlon_decode" "double,direct")
4833    (set_attr "amdfam10_decode" "vector,double")
4834    (set_attr "fp_int_src" "true")])
4835
4836 (define_insn "*floatsidf2_i387"
4837   [(set (match_operand:DF 0 "register_operand" "=f,f")
4838         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4839   "TARGET_80387"
4840   "@
4841    fild%z1\t%1
4842    #"
4843   [(set_attr "type" "fmov,multi")
4844    (set_attr "mode" "DF")
4845    (set_attr "unit" "*,i387")
4846    (set_attr "fp_int_src" "true")])
4847
4848 (define_expand "floatdidf2"
4849   [(set (match_operand:DF 0 "register_operand" "")
4850         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4851   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4852   "")
4853
4854 (define_insn "*floatdidf2_mixed"
4855   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4856         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4857   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4858   "@
4859    fild%z1\t%1
4860    #
4861    cvtsi2sd{q}\t{%1, %0|%0, %1}
4862    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4863   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4864    (set_attr "mode" "DF")
4865    (set_attr "unit" "*,i387,*,*")
4866    (set_attr "athlon_decode" "*,*,double,direct")
4867    (set_attr "amdfam10_decode" "*,*,vector,double")
4868    (set_attr "fp_int_src" "true")])
4869
4870 (define_insn "*floatdidf2_sse"
4871   [(set (match_operand:DF 0 "register_operand" "=x,x")
4872         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4873   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4874   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4875   [(set_attr "type" "sseicvt")
4876    (set_attr "mode" "DF")
4877    (set_attr "athlon_decode" "double,direct")
4878    (set_attr "amdfam10_decode" "vector,double")
4879    (set_attr "fp_int_src" "true")])
4880
4881 (define_insn "*floatdidf2_i387"
4882   [(set (match_operand:DF 0 "register_operand" "=f,f")
4883         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4884   "TARGET_80387"
4885   "@
4886    fild%z1\t%1
4887    #"
4888   [(set_attr "type" "fmov,multi")
4889    (set_attr "mode" "DF")
4890    (set_attr "unit" "*,i387")
4891    (set_attr "fp_int_src" "true")])
4892
4893 (define_insn "floathixf2"
4894   [(set (match_operand:XF 0 "register_operand" "=f,f")
4895         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4896   "TARGET_80387"
4897   "@
4898    fild%z1\t%1
4899    #"
4900   [(set_attr "type" "fmov,multi")
4901    (set_attr "mode" "XF")
4902    (set_attr "unit" "*,i387")
4903    (set_attr "fp_int_src" "true")])
4904
4905 (define_insn "floatsixf2"
4906   [(set (match_operand:XF 0 "register_operand" "=f,f")
4907         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4908   "TARGET_80387"
4909   "@
4910    fild%z1\t%1
4911    #"
4912   [(set_attr "type" "fmov,multi")
4913    (set_attr "mode" "XF")
4914    (set_attr "unit" "*,i387")
4915    (set_attr "fp_int_src" "true")])
4916
4917 (define_insn "floatdixf2"
4918   [(set (match_operand:XF 0 "register_operand" "=f,f")
4919         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4920   "TARGET_80387"
4921   "@
4922    fild%z1\t%1
4923    #"
4924   [(set_attr "type" "fmov,multi")
4925    (set_attr "mode" "XF")
4926    (set_attr "unit" "*,i387")
4927    (set_attr "fp_int_src" "true")])
4928
4929 ;; %%% Kill these when reload knows how to do it.
4930 (define_split
4931   [(set (match_operand 0 "fp_register_operand" "")
4932         (float (match_operand 1 "register_operand" "")))]
4933   "reload_completed
4934    && TARGET_80387
4935    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4936   [(const_int 0)]
4937 {
4938   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4939   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4940   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4941   ix86_free_from_memory (GET_MODE (operands[1]));
4942   DONE;
4943 })
4944
4945 (define_expand "floatunssisf2"
4946   [(use (match_operand:SF 0 "register_operand" ""))
4947    (use (match_operand:SI 1 "register_operand" ""))]
4948   "!TARGET_64BIT && TARGET_SSE_MATH"
4949   "x86_emit_floatuns (operands); DONE;")
4950
4951 (define_expand "floatunsdisf2"
4952   [(use (match_operand:SF 0 "register_operand" ""))
4953    (use (match_operand:DI 1 "register_operand" ""))]
4954   "TARGET_64BIT && TARGET_SSE_MATH"
4955   "x86_emit_floatuns (operands); DONE;")
4956
4957 (define_expand "floatunsdidf2"
4958   [(use (match_operand:DF 0 "register_operand" ""))
4959    (use (match_operand:DI 1 "register_operand" ""))]
4960   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4961   "x86_emit_floatuns (operands); DONE;")
4962 \f
4963 ;; SSE extract/set expanders
4964
4965 \f
4966 ;; Add instructions
4967
4968 ;; %%% splits for addditi3
4969
4970 (define_expand "addti3"
4971   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4972         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4973                  (match_operand:TI 2 "x86_64_general_operand" "")))
4974    (clobber (reg:CC FLAGS_REG))]
4975   "TARGET_64BIT"
4976   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4977
4978 (define_insn "*addti3_1"
4979   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4980         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4981                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4982    (clobber (reg:CC FLAGS_REG))]
4983   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4984   "#")
4985
4986 (define_split
4987   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4988         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4989                  (match_operand:TI 2 "general_operand" "")))
4990    (clobber (reg:CC FLAGS_REG))]
4991   "TARGET_64BIT && reload_completed"
4992   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4993                                           UNSPEC_ADD_CARRY))
4994               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4995    (parallel [(set (match_dup 3)
4996                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4997                                      (match_dup 4))
4998                             (match_dup 5)))
4999               (clobber (reg:CC FLAGS_REG))])]
5000   "split_ti (operands+0, 1, operands+0, operands+3);
5001    split_ti (operands+1, 1, operands+1, operands+4);
5002    split_ti (operands+2, 1, operands+2, operands+5);")
5003
5004 ;; %%% splits for addsidi3
5005 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5006 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5007 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5008
5009 (define_expand "adddi3"
5010   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5011         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5012                  (match_operand:DI 2 "x86_64_general_operand" "")))
5013    (clobber (reg:CC FLAGS_REG))]
5014   ""
5015   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5016
5017 (define_insn "*adddi3_1"
5018   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5019         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5020                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5021    (clobber (reg:CC FLAGS_REG))]
5022   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5023   "#")
5024
5025 (define_split
5026   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5027         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5028                  (match_operand:DI 2 "general_operand" "")))
5029    (clobber (reg:CC FLAGS_REG))]
5030   "!TARGET_64BIT && reload_completed"
5031   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5032                                           UNSPEC_ADD_CARRY))
5033               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5034    (parallel [(set (match_dup 3)
5035                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5036                                      (match_dup 4))
5037                             (match_dup 5)))
5038               (clobber (reg:CC FLAGS_REG))])]
5039   "split_di (operands+0, 1, operands+0, operands+3);
5040    split_di (operands+1, 1, operands+1, operands+4);
5041    split_di (operands+2, 1, operands+2, operands+5);")
5042
5043 (define_insn "adddi3_carry_rex64"
5044   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5045           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5046                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5047                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5048    (clobber (reg:CC FLAGS_REG))]
5049   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5050   "adc{q}\t{%2, %0|%0, %2}"
5051   [(set_attr "type" "alu")
5052    (set_attr "pent_pair" "pu")
5053    (set_attr "mode" "DI")])
5054
5055 (define_insn "*adddi3_cc_rex64"
5056   [(set (reg:CC FLAGS_REG)
5057         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5058                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5059                    UNSPEC_ADD_CARRY))
5060    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5061         (plus:DI (match_dup 1) (match_dup 2)))]
5062   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5063   "add{q}\t{%2, %0|%0, %2}"
5064   [(set_attr "type" "alu")
5065    (set_attr "mode" "DI")])
5066
5067 (define_insn "addqi3_carry"
5068   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5069           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5070                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5071                    (match_operand:QI 2 "general_operand" "qi,qm")))
5072    (clobber (reg:CC FLAGS_REG))]
5073   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5074   "adc{b}\t{%2, %0|%0, %2}"
5075   [(set_attr "type" "alu")
5076    (set_attr "pent_pair" "pu")
5077    (set_attr "mode" "QI")])
5078
5079 (define_insn "addhi3_carry"
5080   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5081           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5082                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5083                    (match_operand:HI 2 "general_operand" "ri,rm")))
5084    (clobber (reg:CC FLAGS_REG))]
5085   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5086   "adc{w}\t{%2, %0|%0, %2}"
5087   [(set_attr "type" "alu")
5088    (set_attr "pent_pair" "pu")
5089    (set_attr "mode" "HI")])
5090
5091 (define_insn "addsi3_carry"
5092   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5093           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5094                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5095                    (match_operand:SI 2 "general_operand" "ri,rm")))
5096    (clobber (reg:CC FLAGS_REG))]
5097   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5098   "adc{l}\t{%2, %0|%0, %2}"
5099   [(set_attr "type" "alu")
5100    (set_attr "pent_pair" "pu")
5101    (set_attr "mode" "SI")])
5102
5103 (define_insn "*addsi3_carry_zext"
5104   [(set (match_operand:DI 0 "register_operand" "=r")
5105           (zero_extend:DI
5106             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5107                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5108                      (match_operand:SI 2 "general_operand" "rim"))))
5109    (clobber (reg:CC FLAGS_REG))]
5110   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5111   "adc{l}\t{%2, %k0|%k0, %2}"
5112   [(set_attr "type" "alu")
5113    (set_attr "pent_pair" "pu")
5114    (set_attr "mode" "SI")])
5115
5116 (define_insn "*addsi3_cc"
5117   [(set (reg:CC FLAGS_REG)
5118         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5119                     (match_operand:SI 2 "general_operand" "ri,rm")]
5120                    UNSPEC_ADD_CARRY))
5121    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5122         (plus:SI (match_dup 1) (match_dup 2)))]
5123   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5124   "add{l}\t{%2, %0|%0, %2}"
5125   [(set_attr "type" "alu")
5126    (set_attr "mode" "SI")])
5127
5128 (define_insn "addqi3_cc"
5129   [(set (reg:CC FLAGS_REG)
5130         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5131                     (match_operand:QI 2 "general_operand" "qi,qm")]
5132                    UNSPEC_ADD_CARRY))
5133    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5134         (plus:QI (match_dup 1) (match_dup 2)))]
5135   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5136   "add{b}\t{%2, %0|%0, %2}"
5137   [(set_attr "type" "alu")
5138    (set_attr "mode" "QI")])
5139
5140 (define_expand "addsi3"
5141   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5142                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5143                             (match_operand:SI 2 "general_operand" "")))
5144               (clobber (reg:CC FLAGS_REG))])]
5145   ""
5146   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5147
5148 (define_insn "*lea_1"
5149   [(set (match_operand:SI 0 "register_operand" "=r")
5150         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5151   "!TARGET_64BIT"
5152   "lea{l}\t{%a1, %0|%0, %a1}"
5153   [(set_attr "type" "lea")
5154    (set_attr "mode" "SI")])
5155
5156 (define_insn "*lea_1_rex64"
5157   [(set (match_operand:SI 0 "register_operand" "=r")
5158         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5159   "TARGET_64BIT"
5160   "lea{l}\t{%a1, %0|%0, %a1}"
5161   [(set_attr "type" "lea")
5162    (set_attr "mode" "SI")])
5163
5164 (define_insn "*lea_1_zext"
5165   [(set (match_operand:DI 0 "register_operand" "=r")
5166         (zero_extend:DI
5167          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5168   "TARGET_64BIT"
5169   "lea{l}\t{%a1, %k0|%k0, %a1}"
5170   [(set_attr "type" "lea")
5171    (set_attr "mode" "SI")])
5172
5173 (define_insn "*lea_2_rex64"
5174   [(set (match_operand:DI 0 "register_operand" "=r")
5175         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5176   "TARGET_64BIT"
5177   "lea{q}\t{%a1, %0|%0, %a1}"
5178   [(set_attr "type" "lea")
5179    (set_attr "mode" "DI")])
5180
5181 ;; The lea patterns for non-Pmodes needs to be matched by several
5182 ;; insns converted to real lea by splitters.
5183
5184 (define_insn_and_split "*lea_general_1"
5185   [(set (match_operand 0 "register_operand" "=r")
5186         (plus (plus (match_operand 1 "index_register_operand" "l")
5187                     (match_operand 2 "register_operand" "r"))
5188               (match_operand 3 "immediate_operand" "i")))]
5189   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5190     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5191    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5192    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5193    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5194    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5195        || GET_MODE (operands[3]) == VOIDmode)"
5196   "#"
5197   "&& reload_completed"
5198   [(const_int 0)]
5199 {
5200   rtx pat;
5201   operands[0] = gen_lowpart (SImode, operands[0]);
5202   operands[1] = gen_lowpart (Pmode, operands[1]);
5203   operands[2] = gen_lowpart (Pmode, operands[2]);
5204   operands[3] = gen_lowpart (Pmode, operands[3]);
5205   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5206                       operands[3]);
5207   if (Pmode != SImode)
5208     pat = gen_rtx_SUBREG (SImode, pat, 0);
5209   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5210   DONE;
5211 }
5212   [(set_attr "type" "lea")
5213    (set_attr "mode" "SI")])
5214
5215 (define_insn_and_split "*lea_general_1_zext"
5216   [(set (match_operand:DI 0 "register_operand" "=r")
5217         (zero_extend:DI
5218           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5219                             (match_operand:SI 2 "register_operand" "r"))
5220                    (match_operand:SI 3 "immediate_operand" "i"))))]
5221   "TARGET_64BIT"
5222   "#"
5223   "&& reload_completed"
5224   [(set (match_dup 0)
5225         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5226                                                      (match_dup 2))
5227                                             (match_dup 3)) 0)))]
5228 {
5229   operands[1] = gen_lowpart (Pmode, operands[1]);
5230   operands[2] = gen_lowpart (Pmode, operands[2]);
5231   operands[3] = gen_lowpart (Pmode, operands[3]);
5232 }
5233   [(set_attr "type" "lea")
5234    (set_attr "mode" "SI")])
5235
5236 (define_insn_and_split "*lea_general_2"
5237   [(set (match_operand 0 "register_operand" "=r")
5238         (plus (mult (match_operand 1 "index_register_operand" "l")
5239                     (match_operand 2 "const248_operand" "i"))
5240               (match_operand 3 "nonmemory_operand" "ri")))]
5241   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5242     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5243    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5244    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5245    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5246        || GET_MODE (operands[3]) == VOIDmode)"
5247   "#"
5248   "&& reload_completed"
5249   [(const_int 0)]
5250 {
5251   rtx pat;
5252   operands[0] = gen_lowpart (SImode, operands[0]);
5253   operands[1] = gen_lowpart (Pmode, operands[1]);
5254   operands[3] = gen_lowpart (Pmode, operands[3]);
5255   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5256                       operands[3]);
5257   if (Pmode != SImode)
5258     pat = gen_rtx_SUBREG (SImode, pat, 0);
5259   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5260   DONE;
5261 }
5262   [(set_attr "type" "lea")
5263    (set_attr "mode" "SI")])
5264
5265 (define_insn_and_split "*lea_general_2_zext"
5266   [(set (match_operand:DI 0 "register_operand" "=r")
5267         (zero_extend:DI
5268           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5269                             (match_operand:SI 2 "const248_operand" "n"))
5270                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5271   "TARGET_64BIT"
5272   "#"
5273   "&& reload_completed"
5274   [(set (match_dup 0)
5275         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5276                                                      (match_dup 2))
5277                                             (match_dup 3)) 0)))]
5278 {
5279   operands[1] = gen_lowpart (Pmode, operands[1]);
5280   operands[3] = gen_lowpart (Pmode, operands[3]);
5281 }
5282   [(set_attr "type" "lea")
5283    (set_attr "mode" "SI")])
5284
5285 (define_insn_and_split "*lea_general_3"
5286   [(set (match_operand 0 "register_operand" "=r")
5287         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5288                           (match_operand 2 "const248_operand" "i"))
5289                     (match_operand 3 "register_operand" "r"))
5290               (match_operand 4 "immediate_operand" "i")))]
5291   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5292     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5293    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5294    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5295    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5296   "#"
5297   "&& reload_completed"
5298   [(const_int 0)]
5299 {
5300   rtx pat;
5301   operands[0] = gen_lowpart (SImode, operands[0]);
5302   operands[1] = gen_lowpart (Pmode, operands[1]);
5303   operands[3] = gen_lowpart (Pmode, operands[3]);
5304   operands[4] = gen_lowpart (Pmode, operands[4]);
5305   pat = gen_rtx_PLUS (Pmode,
5306                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5307                                                          operands[2]),
5308                                     operands[3]),
5309                       operands[4]);
5310   if (Pmode != SImode)
5311     pat = gen_rtx_SUBREG (SImode, pat, 0);
5312   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5313   DONE;
5314 }
5315   [(set_attr "type" "lea")
5316    (set_attr "mode" "SI")])
5317
5318 (define_insn_and_split "*lea_general_3_zext"
5319   [(set (match_operand:DI 0 "register_operand" "=r")
5320         (zero_extend:DI
5321           (plus:SI (plus:SI (mult:SI
5322                               (match_operand:SI 1 "index_register_operand" "l")
5323                               (match_operand:SI 2 "const248_operand" "n"))
5324                             (match_operand:SI 3 "register_operand" "r"))
5325                    (match_operand:SI 4 "immediate_operand" "i"))))]
5326   "TARGET_64BIT"
5327   "#"
5328   "&& reload_completed"
5329   [(set (match_dup 0)
5330         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5331                                                               (match_dup 2))
5332                                                      (match_dup 3))
5333                                             (match_dup 4)) 0)))]
5334 {
5335   operands[1] = gen_lowpart (Pmode, operands[1]);
5336   operands[3] = gen_lowpart (Pmode, operands[3]);
5337   operands[4] = gen_lowpart (Pmode, operands[4]);
5338 }
5339   [(set_attr "type" "lea")
5340    (set_attr "mode" "SI")])
5341
5342 (define_insn "*adddi_1_rex64"
5343   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5344         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5345                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5346    (clobber (reg:CC FLAGS_REG))]
5347   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5348 {
5349   switch (get_attr_type (insn))
5350     {
5351     case TYPE_LEA:
5352       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5353       return "lea{q}\t{%a2, %0|%0, %a2}";
5354
5355     case TYPE_INCDEC:
5356       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5357       if (operands[2] == const1_rtx)
5358         return "inc{q}\t%0";
5359       else
5360         {
5361           gcc_assert (operands[2] == constm1_rtx);
5362           return "dec{q}\t%0";
5363         }
5364
5365     default:
5366       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5367
5368       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5369          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5370       if (CONST_INT_P (operands[2])
5371           /* Avoid overflows.  */
5372           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5373           && (INTVAL (operands[2]) == 128
5374               || (INTVAL (operands[2]) < 0
5375                   && INTVAL (operands[2]) != -128)))
5376         {
5377           operands[2] = GEN_INT (-INTVAL (operands[2]));
5378           return "sub{q}\t{%2, %0|%0, %2}";
5379         }
5380       return "add{q}\t{%2, %0|%0, %2}";
5381     }
5382 }
5383   [(set (attr "type")
5384      (cond [(eq_attr "alternative" "2")
5385               (const_string "lea")
5386             ; Current assemblers are broken and do not allow @GOTOFF in
5387             ; ought but a memory context.
5388             (match_operand:DI 2 "pic_symbolic_operand" "")
5389               (const_string "lea")
5390             (match_operand:DI 2 "incdec_operand" "")
5391               (const_string "incdec")
5392            ]
5393            (const_string "alu")))
5394    (set_attr "mode" "DI")])
5395
5396 ;; Convert lea to the lea pattern to avoid flags dependency.
5397 (define_split
5398   [(set (match_operand:DI 0 "register_operand" "")
5399         (plus:DI (match_operand:DI 1 "register_operand" "")
5400                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5401    (clobber (reg:CC FLAGS_REG))]
5402   "TARGET_64BIT && reload_completed
5403    && true_regnum (operands[0]) != true_regnum (operands[1])"
5404   [(set (match_dup 0)
5405         (plus:DI (match_dup 1)
5406                  (match_dup 2)))]
5407   "")
5408
5409 (define_insn "*adddi_2_rex64"
5410   [(set (reg FLAGS_REG)
5411         (compare
5412           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5413                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5414           (const_int 0)))
5415    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5416         (plus:DI (match_dup 1) (match_dup 2)))]
5417   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5418    && ix86_binary_operator_ok (PLUS, DImode, operands)
5419    /* Current assemblers are broken and do not allow @GOTOFF in
5420       ought but a memory context.  */
5421    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5422 {
5423   switch (get_attr_type (insn))
5424     {
5425     case TYPE_INCDEC:
5426       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5427       if (operands[2] == const1_rtx)
5428         return "inc{q}\t%0";
5429       else
5430         {
5431           gcc_assert (operands[2] == constm1_rtx);
5432           return "dec{q}\t%0";
5433         }
5434
5435     default:
5436       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5437       /* ???? We ought to handle there the 32bit case too
5438          - do we need new constraint?  */
5439       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5440          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5441       if (CONST_INT_P (operands[2])
5442           /* Avoid overflows.  */
5443           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5444           && (INTVAL (operands[2]) == 128
5445               || (INTVAL (operands[2]) < 0
5446                   && INTVAL (operands[2]) != -128)))
5447         {
5448           operands[2] = GEN_INT (-INTVAL (operands[2]));
5449           return "sub{q}\t{%2, %0|%0, %2}";
5450         }
5451       return "add{q}\t{%2, %0|%0, %2}";
5452     }
5453 }
5454   [(set (attr "type")
5455      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5456         (const_string "incdec")
5457         (const_string "alu")))
5458    (set_attr "mode" "DI")])
5459
5460 (define_insn "*adddi_3_rex64"
5461   [(set (reg FLAGS_REG)
5462         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5463                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5464    (clobber (match_scratch:DI 0 "=r"))]
5465   "TARGET_64BIT
5466    && ix86_match_ccmode (insn, CCZmode)
5467    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5468    /* Current assemblers are broken and do not allow @GOTOFF in
5469       ought but a memory context.  */
5470    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5471 {
5472   switch (get_attr_type (insn))
5473     {
5474     case TYPE_INCDEC:
5475       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5476       if (operands[2] == const1_rtx)
5477         return "inc{q}\t%0";
5478       else
5479         {
5480           gcc_assert (operands[2] == constm1_rtx);
5481           return "dec{q}\t%0";
5482         }
5483
5484     default:
5485       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5486       /* ???? We ought to handle there the 32bit case too
5487          - do we need new constraint?  */
5488       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5489          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5490       if (CONST_INT_P (operands[2])
5491           /* Avoid overflows.  */
5492           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5493           && (INTVAL (operands[2]) == 128
5494               || (INTVAL (operands[2]) < 0
5495                   && INTVAL (operands[2]) != -128)))
5496         {
5497           operands[2] = GEN_INT (-INTVAL (operands[2]));
5498           return "sub{q}\t{%2, %0|%0, %2}";
5499         }
5500       return "add{q}\t{%2, %0|%0, %2}";
5501     }
5502 }
5503   [(set (attr "type")
5504      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5505         (const_string "incdec")
5506         (const_string "alu")))
5507    (set_attr "mode" "DI")])
5508
5509 ; For comparisons against 1, -1 and 128, we may generate better code
5510 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5511 ; is matched then.  We can't accept general immediate, because for
5512 ; case of overflows,  the result is messed up.
5513 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5514 ; when negated.
5515 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5516 ; only for comparisons not depending on it.
5517 (define_insn "*adddi_4_rex64"
5518   [(set (reg FLAGS_REG)
5519         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5520                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5521    (clobber (match_scratch:DI 0 "=rm"))]
5522   "TARGET_64BIT
5523    &&  ix86_match_ccmode (insn, CCGCmode)"
5524 {
5525   switch (get_attr_type (insn))
5526     {
5527     case TYPE_INCDEC:
5528       if (operands[2] == constm1_rtx)
5529         return "inc{q}\t%0";
5530       else
5531         {
5532           gcc_assert (operands[2] == const1_rtx);
5533           return "dec{q}\t%0";
5534         }
5535
5536     default:
5537       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5538       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5539          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5540       if ((INTVAL (operands[2]) == -128
5541            || (INTVAL (operands[2]) > 0
5542                && INTVAL (operands[2]) != 128))
5543           /* Avoid overflows.  */
5544           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5545         return "sub{q}\t{%2, %0|%0, %2}";
5546       operands[2] = GEN_INT (-INTVAL (operands[2]));
5547       return "add{q}\t{%2, %0|%0, %2}";
5548     }
5549 }
5550   [(set (attr "type")
5551      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5552         (const_string "incdec")
5553         (const_string "alu")))
5554    (set_attr "mode" "DI")])
5555
5556 (define_insn "*adddi_5_rex64"
5557   [(set (reg FLAGS_REG)
5558         (compare
5559           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5560                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5561           (const_int 0)))
5562    (clobber (match_scratch:DI 0 "=r"))]
5563   "TARGET_64BIT
5564    && ix86_match_ccmode (insn, CCGOCmode)
5565    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5566    /* Current assemblers are broken and do not allow @GOTOFF in
5567       ought but a memory context.  */
5568    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5569 {
5570   switch (get_attr_type (insn))
5571     {
5572     case TYPE_INCDEC:
5573       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5574       if (operands[2] == const1_rtx)
5575         return "inc{q}\t%0";
5576       else
5577         {
5578           gcc_assert (operands[2] == constm1_rtx);
5579           return "dec{q}\t%0";
5580         }
5581
5582     default:
5583       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5584       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5585          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5586       if (CONST_INT_P (operands[2])
5587           /* Avoid overflows.  */
5588           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5589           && (INTVAL (operands[2]) == 128
5590               || (INTVAL (operands[2]) < 0
5591                   && INTVAL (operands[2]) != -128)))
5592         {
5593           operands[2] = GEN_INT (-INTVAL (operands[2]));
5594           return "sub{q}\t{%2, %0|%0, %2}";
5595         }
5596       return "add{q}\t{%2, %0|%0, %2}";
5597     }
5598 }
5599   [(set (attr "type")
5600      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5601         (const_string "incdec")
5602         (const_string "alu")))
5603    (set_attr "mode" "DI")])
5604
5605
5606 (define_insn "*addsi_1"
5607   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5608         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5609                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5610    (clobber (reg:CC FLAGS_REG))]
5611   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5612 {
5613   switch (get_attr_type (insn))
5614     {
5615     case TYPE_LEA:
5616       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5617       return "lea{l}\t{%a2, %0|%0, %a2}";
5618
5619     case TYPE_INCDEC:
5620       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5621       if (operands[2] == const1_rtx)
5622         return "inc{l}\t%0";
5623       else
5624         {
5625           gcc_assert (operands[2] == constm1_rtx);
5626           return "dec{l}\t%0";
5627         }
5628
5629     default:
5630       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5631
5632       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5633          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5634       if (CONST_INT_P (operands[2])
5635           && (INTVAL (operands[2]) == 128
5636               || (INTVAL (operands[2]) < 0
5637                   && INTVAL (operands[2]) != -128)))
5638         {
5639           operands[2] = GEN_INT (-INTVAL (operands[2]));
5640           return "sub{l}\t{%2, %0|%0, %2}";
5641         }
5642       return "add{l}\t{%2, %0|%0, %2}";
5643     }
5644 }
5645   [(set (attr "type")
5646      (cond [(eq_attr "alternative" "2")
5647               (const_string "lea")
5648             ; Current assemblers are broken and do not allow @GOTOFF in
5649             ; ought but a memory context.
5650             (match_operand:SI 2 "pic_symbolic_operand" "")
5651               (const_string "lea")
5652             (match_operand:SI 2 "incdec_operand" "")
5653               (const_string "incdec")
5654            ]
5655            (const_string "alu")))
5656    (set_attr "mode" "SI")])
5657
5658 ;; Convert lea to the lea pattern to avoid flags dependency.
5659 (define_split
5660   [(set (match_operand 0 "register_operand" "")
5661         (plus (match_operand 1 "register_operand" "")
5662               (match_operand 2 "nonmemory_operand" "")))
5663    (clobber (reg:CC FLAGS_REG))]
5664   "reload_completed
5665    && true_regnum (operands[0]) != true_regnum (operands[1])"
5666   [(const_int 0)]
5667 {
5668   rtx pat;
5669   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5670      may confuse gen_lowpart.  */
5671   if (GET_MODE (operands[0]) != Pmode)
5672     {
5673       operands[1] = gen_lowpart (Pmode, operands[1]);
5674       operands[2] = gen_lowpart (Pmode, operands[2]);
5675     }
5676   operands[0] = gen_lowpart (SImode, operands[0]);
5677   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5678   if (Pmode != SImode)
5679     pat = gen_rtx_SUBREG (SImode, pat, 0);
5680   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5681   DONE;
5682 })
5683
5684 ;; It may seem that nonimmediate operand is proper one for operand 1.
5685 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5686 ;; we take care in ix86_binary_operator_ok to not allow two memory
5687 ;; operands so proper swapping will be done in reload.  This allow
5688 ;; patterns constructed from addsi_1 to match.
5689 (define_insn "addsi_1_zext"
5690   [(set (match_operand:DI 0 "register_operand" "=r,r")
5691         (zero_extend:DI
5692           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5693                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5694    (clobber (reg:CC FLAGS_REG))]
5695   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5696 {
5697   switch (get_attr_type (insn))
5698     {
5699     case TYPE_LEA:
5700       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5701       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5702
5703     case TYPE_INCDEC:
5704       if (operands[2] == const1_rtx)
5705         return "inc{l}\t%k0";
5706       else
5707         {
5708           gcc_assert (operands[2] == constm1_rtx);
5709           return "dec{l}\t%k0";
5710         }
5711
5712     default:
5713       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5714          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5715       if (CONST_INT_P (operands[2])
5716           && (INTVAL (operands[2]) == 128
5717               || (INTVAL (operands[2]) < 0
5718                   && INTVAL (operands[2]) != -128)))
5719         {
5720           operands[2] = GEN_INT (-INTVAL (operands[2]));
5721           return "sub{l}\t{%2, %k0|%k0, %2}";
5722         }
5723       return "add{l}\t{%2, %k0|%k0, %2}";
5724     }
5725 }
5726   [(set (attr "type")
5727      (cond [(eq_attr "alternative" "1")
5728               (const_string "lea")
5729             ; Current assemblers are broken and do not allow @GOTOFF in
5730             ; ought but a memory context.
5731             (match_operand:SI 2 "pic_symbolic_operand" "")
5732               (const_string "lea")
5733             (match_operand:SI 2 "incdec_operand" "")
5734               (const_string "incdec")
5735            ]
5736            (const_string "alu")))
5737    (set_attr "mode" "SI")])
5738
5739 ;; Convert lea to the lea pattern to avoid flags dependency.
5740 (define_split
5741   [(set (match_operand:DI 0 "register_operand" "")
5742         (zero_extend:DI
5743           (plus:SI (match_operand:SI 1 "register_operand" "")
5744                    (match_operand:SI 2 "nonmemory_operand" ""))))
5745    (clobber (reg:CC FLAGS_REG))]
5746   "TARGET_64BIT && reload_completed
5747    && true_regnum (operands[0]) != true_regnum (operands[1])"
5748   [(set (match_dup 0)
5749         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5750 {
5751   operands[1] = gen_lowpart (Pmode, operands[1]);
5752   operands[2] = gen_lowpart (Pmode, operands[2]);
5753 })
5754
5755 (define_insn "*addsi_2"
5756   [(set (reg FLAGS_REG)
5757         (compare
5758           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5759                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5760           (const_int 0)))
5761    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5762         (plus:SI (match_dup 1) (match_dup 2)))]
5763   "ix86_match_ccmode (insn, CCGOCmode)
5764    && ix86_binary_operator_ok (PLUS, SImode, operands)
5765    /* Current assemblers are broken and do not allow @GOTOFF in
5766       ought but a memory context.  */
5767    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5768 {
5769   switch (get_attr_type (insn))
5770     {
5771     case TYPE_INCDEC:
5772       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5773       if (operands[2] == const1_rtx)
5774         return "inc{l}\t%0";
5775       else
5776         {
5777           gcc_assert (operands[2] == constm1_rtx);
5778           return "dec{l}\t%0";
5779         }
5780
5781     default:
5782       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5783       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5784          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5785       if (CONST_INT_P (operands[2])
5786           && (INTVAL (operands[2]) == 128
5787               || (INTVAL (operands[2]) < 0
5788                   && INTVAL (operands[2]) != -128)))
5789         {
5790           operands[2] = GEN_INT (-INTVAL (operands[2]));
5791           return "sub{l}\t{%2, %0|%0, %2}";
5792         }
5793       return "add{l}\t{%2, %0|%0, %2}";
5794     }
5795 }
5796   [(set (attr "type")
5797      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5798         (const_string "incdec")
5799         (const_string "alu")))
5800    (set_attr "mode" "SI")])
5801
5802 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5803 (define_insn "*addsi_2_zext"
5804   [(set (reg FLAGS_REG)
5805         (compare
5806           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5807                    (match_operand:SI 2 "general_operand" "rmni"))
5808           (const_int 0)))
5809    (set (match_operand:DI 0 "register_operand" "=r")
5810         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5811   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5812    && ix86_binary_operator_ok (PLUS, SImode, operands)
5813    /* Current assemblers are broken and do not allow @GOTOFF in
5814       ought but a memory context.  */
5815    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5816 {
5817   switch (get_attr_type (insn))
5818     {
5819     case TYPE_INCDEC:
5820       if (operands[2] == const1_rtx)
5821         return "inc{l}\t%k0";
5822       else
5823         {
5824           gcc_assert (operands[2] == constm1_rtx);
5825           return "dec{l}\t%k0";
5826         }
5827
5828     default:
5829       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5830          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5831       if (CONST_INT_P (operands[2])
5832           && (INTVAL (operands[2]) == 128
5833               || (INTVAL (operands[2]) < 0
5834                   && INTVAL (operands[2]) != -128)))
5835         {
5836           operands[2] = GEN_INT (-INTVAL (operands[2]));
5837           return "sub{l}\t{%2, %k0|%k0, %2}";
5838         }
5839       return "add{l}\t{%2, %k0|%k0, %2}";
5840     }
5841 }
5842   [(set (attr "type")
5843      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5844         (const_string "incdec")
5845         (const_string "alu")))
5846    (set_attr "mode" "SI")])
5847
5848 (define_insn "*addsi_3"
5849   [(set (reg FLAGS_REG)
5850         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5851                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5852    (clobber (match_scratch:SI 0 "=r"))]
5853   "ix86_match_ccmode (insn, CCZmode)
5854    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5855    /* Current assemblers are broken and do not allow @GOTOFF in
5856       ought but a memory context.  */
5857    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5858 {
5859   switch (get_attr_type (insn))
5860     {
5861     case TYPE_INCDEC:
5862       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5863       if (operands[2] == const1_rtx)
5864         return "inc{l}\t%0";
5865       else
5866         {
5867           gcc_assert (operands[2] == constm1_rtx);
5868           return "dec{l}\t%0";
5869         }
5870
5871     default:
5872       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5873       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5874          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5875       if (CONST_INT_P (operands[2])
5876           && (INTVAL (operands[2]) == 128
5877               || (INTVAL (operands[2]) < 0
5878                   && INTVAL (operands[2]) != -128)))
5879         {
5880           operands[2] = GEN_INT (-INTVAL (operands[2]));
5881           return "sub{l}\t{%2, %0|%0, %2}";
5882         }
5883       return "add{l}\t{%2, %0|%0, %2}";
5884     }
5885 }
5886   [(set (attr "type")
5887      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5888         (const_string "incdec")
5889         (const_string "alu")))
5890    (set_attr "mode" "SI")])
5891
5892 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5893 (define_insn "*addsi_3_zext"
5894   [(set (reg FLAGS_REG)
5895         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5896                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5897    (set (match_operand:DI 0 "register_operand" "=r")
5898         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5899   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5900    && ix86_binary_operator_ok (PLUS, SImode, operands)
5901    /* Current assemblers are broken and do not allow @GOTOFF in
5902       ought but a memory context.  */
5903    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5904 {
5905   switch (get_attr_type (insn))
5906     {
5907     case TYPE_INCDEC:
5908       if (operands[2] == const1_rtx)
5909         return "inc{l}\t%k0";
5910       else
5911         {
5912           gcc_assert (operands[2] == constm1_rtx);
5913           return "dec{l}\t%k0";
5914         }
5915
5916     default:
5917       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5918          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5919       if (CONST_INT_P (operands[2])
5920           && (INTVAL (operands[2]) == 128
5921               || (INTVAL (operands[2]) < 0
5922                   && INTVAL (operands[2]) != -128)))
5923         {
5924           operands[2] = GEN_INT (-INTVAL (operands[2]));
5925           return "sub{l}\t{%2, %k0|%k0, %2}";
5926         }
5927       return "add{l}\t{%2, %k0|%k0, %2}";
5928     }
5929 }
5930   [(set (attr "type")
5931      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5932         (const_string "incdec")
5933         (const_string "alu")))
5934    (set_attr "mode" "SI")])
5935
5936 ; For comparisons against 1, -1 and 128, we may generate better code
5937 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5938 ; is matched then.  We can't accept general immediate, because for
5939 ; case of overflows,  the result is messed up.
5940 ; This pattern also don't hold of 0x80000000, since the value overflows
5941 ; when negated.
5942 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5943 ; only for comparisons not depending on it.
5944 (define_insn "*addsi_4"
5945   [(set (reg FLAGS_REG)
5946         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5947                  (match_operand:SI 2 "const_int_operand" "n")))
5948    (clobber (match_scratch:SI 0 "=rm"))]
5949   "ix86_match_ccmode (insn, CCGCmode)
5950    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5951 {
5952   switch (get_attr_type (insn))
5953     {
5954     case TYPE_INCDEC:
5955       if (operands[2] == constm1_rtx)
5956         return "inc{l}\t%0";
5957       else
5958         {
5959           gcc_assert (operands[2] == const1_rtx);
5960           return "dec{l}\t%0";
5961         }
5962
5963     default:
5964       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5965       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5966          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5967       if ((INTVAL (operands[2]) == -128
5968            || (INTVAL (operands[2]) > 0
5969                && INTVAL (operands[2]) != 128)))
5970         return "sub{l}\t{%2, %0|%0, %2}";
5971       operands[2] = GEN_INT (-INTVAL (operands[2]));
5972       return "add{l}\t{%2, %0|%0, %2}";
5973     }
5974 }
5975   [(set (attr "type")
5976      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5977         (const_string "incdec")
5978         (const_string "alu")))
5979    (set_attr "mode" "SI")])
5980
5981 (define_insn "*addsi_5"
5982   [(set (reg FLAGS_REG)
5983         (compare
5984           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5985                    (match_operand:SI 2 "general_operand" "rmni"))
5986           (const_int 0)))
5987    (clobber (match_scratch:SI 0 "=r"))]
5988   "ix86_match_ccmode (insn, CCGOCmode)
5989    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5990    /* Current assemblers are broken and do not allow @GOTOFF in
5991       ought but a memory context.  */
5992    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5993 {
5994   switch (get_attr_type (insn))
5995     {
5996     case TYPE_INCDEC:
5997       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5998       if (operands[2] == const1_rtx)
5999         return "inc{l}\t%0";
6000       else
6001         {
6002           gcc_assert (operands[2] == constm1_rtx);
6003           return "dec{l}\t%0";
6004         }
6005
6006     default:
6007       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6008       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6009          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6010       if (CONST_INT_P (operands[2])
6011           && (INTVAL (operands[2]) == 128
6012               || (INTVAL (operands[2]) < 0
6013                   && INTVAL (operands[2]) != -128)))
6014         {
6015           operands[2] = GEN_INT (-INTVAL (operands[2]));
6016           return "sub{l}\t{%2, %0|%0, %2}";
6017         }
6018       return "add{l}\t{%2, %0|%0, %2}";
6019     }
6020 }
6021   [(set (attr "type")
6022      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6023         (const_string "incdec")
6024         (const_string "alu")))
6025    (set_attr "mode" "SI")])
6026
6027 (define_expand "addhi3"
6028   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6029                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6030                             (match_operand:HI 2 "general_operand" "")))
6031               (clobber (reg:CC FLAGS_REG))])]
6032   "TARGET_HIMODE_MATH"
6033   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6034
6035 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6036 ;; type optimizations enabled by define-splits.  This is not important
6037 ;; for PII, and in fact harmful because of partial register stalls.
6038
6039 (define_insn "*addhi_1_lea"
6040   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6041         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6042                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6043    (clobber (reg:CC FLAGS_REG))]
6044   "!TARGET_PARTIAL_REG_STALL
6045    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6046 {
6047   switch (get_attr_type (insn))
6048     {
6049     case TYPE_LEA:
6050       return "#";
6051     case TYPE_INCDEC:
6052       if (operands[2] == const1_rtx)
6053         return "inc{w}\t%0";
6054       else
6055         {
6056           gcc_assert (operands[2] == constm1_rtx);
6057           return "dec{w}\t%0";
6058         }
6059
6060     default:
6061       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6062          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6063       if (CONST_INT_P (operands[2])
6064           && (INTVAL (operands[2]) == 128
6065               || (INTVAL (operands[2]) < 0
6066                   && INTVAL (operands[2]) != -128)))
6067         {
6068           operands[2] = GEN_INT (-INTVAL (operands[2]));
6069           return "sub{w}\t{%2, %0|%0, %2}";
6070         }
6071       return "add{w}\t{%2, %0|%0, %2}";
6072     }
6073 }
6074   [(set (attr "type")
6075      (if_then_else (eq_attr "alternative" "2")
6076         (const_string "lea")
6077         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6078            (const_string "incdec")
6079            (const_string "alu"))))
6080    (set_attr "mode" "HI,HI,SI")])
6081
6082 (define_insn "*addhi_1"
6083   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6084         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6085                  (match_operand:HI 2 "general_operand" "ri,rm")))
6086    (clobber (reg:CC FLAGS_REG))]
6087   "TARGET_PARTIAL_REG_STALL
6088    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6089 {
6090   switch (get_attr_type (insn))
6091     {
6092     case TYPE_INCDEC:
6093       if (operands[2] == const1_rtx)
6094         return "inc{w}\t%0";
6095       else
6096         {
6097           gcc_assert (operands[2] == constm1_rtx);
6098           return "dec{w}\t%0";
6099         }
6100
6101     default:
6102       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6103          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6104       if (CONST_INT_P (operands[2])
6105           && (INTVAL (operands[2]) == 128
6106               || (INTVAL (operands[2]) < 0
6107                   && INTVAL (operands[2]) != -128)))
6108         {
6109           operands[2] = GEN_INT (-INTVAL (operands[2]));
6110           return "sub{w}\t{%2, %0|%0, %2}";
6111         }
6112       return "add{w}\t{%2, %0|%0, %2}";
6113     }
6114 }
6115   [(set (attr "type")
6116      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6117         (const_string "incdec")
6118         (const_string "alu")))
6119    (set_attr "mode" "HI")])
6120
6121 (define_insn "*addhi_2"
6122   [(set (reg FLAGS_REG)
6123         (compare
6124           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6125                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6126           (const_int 0)))
6127    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6128         (plus:HI (match_dup 1) (match_dup 2)))]
6129   "ix86_match_ccmode (insn, CCGOCmode)
6130    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6131 {
6132   switch (get_attr_type (insn))
6133     {
6134     case TYPE_INCDEC:
6135       if (operands[2] == const1_rtx)
6136         return "inc{w}\t%0";
6137       else
6138         {
6139           gcc_assert (operands[2] == constm1_rtx);
6140           return "dec{w}\t%0";
6141         }
6142
6143     default:
6144       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6145          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6146       if (CONST_INT_P (operands[2])
6147           && (INTVAL (operands[2]) == 128
6148               || (INTVAL (operands[2]) < 0
6149                   && INTVAL (operands[2]) != -128)))
6150         {
6151           operands[2] = GEN_INT (-INTVAL (operands[2]));
6152           return "sub{w}\t{%2, %0|%0, %2}";
6153         }
6154       return "add{w}\t{%2, %0|%0, %2}";
6155     }
6156 }
6157   [(set (attr "type")
6158      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6159         (const_string "incdec")
6160         (const_string "alu")))
6161    (set_attr "mode" "HI")])
6162
6163 (define_insn "*addhi_3"
6164   [(set (reg FLAGS_REG)
6165         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6166                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6167    (clobber (match_scratch:HI 0 "=r"))]
6168   "ix86_match_ccmode (insn, CCZmode)
6169    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6170 {
6171   switch (get_attr_type (insn))
6172     {
6173     case TYPE_INCDEC:
6174       if (operands[2] == const1_rtx)
6175         return "inc{w}\t%0";
6176       else
6177         {
6178           gcc_assert (operands[2] == constm1_rtx);
6179           return "dec{w}\t%0";
6180         }
6181
6182     default:
6183       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6184          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6185       if (CONST_INT_P (operands[2])
6186           && (INTVAL (operands[2]) == 128
6187               || (INTVAL (operands[2]) < 0
6188                   && INTVAL (operands[2]) != -128)))
6189         {
6190           operands[2] = GEN_INT (-INTVAL (operands[2]));
6191           return "sub{w}\t{%2, %0|%0, %2}";
6192         }
6193       return "add{w}\t{%2, %0|%0, %2}";
6194     }
6195 }
6196   [(set (attr "type")
6197      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6198         (const_string "incdec")
6199         (const_string "alu")))
6200    (set_attr "mode" "HI")])
6201
6202 ; See comments above addsi_4 for details.
6203 (define_insn "*addhi_4"
6204   [(set (reg FLAGS_REG)
6205         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6206                  (match_operand:HI 2 "const_int_operand" "n")))
6207    (clobber (match_scratch:HI 0 "=rm"))]
6208   "ix86_match_ccmode (insn, CCGCmode)
6209    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6210 {
6211   switch (get_attr_type (insn))
6212     {
6213     case TYPE_INCDEC:
6214       if (operands[2] == constm1_rtx)
6215         return "inc{w}\t%0";
6216       else
6217         {
6218           gcc_assert (operands[2] == const1_rtx);
6219           return "dec{w}\t%0";
6220         }
6221
6222     default:
6223       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6224       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6225          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6226       if ((INTVAL (operands[2]) == -128
6227            || (INTVAL (operands[2]) > 0
6228                && INTVAL (operands[2]) != 128)))
6229         return "sub{w}\t{%2, %0|%0, %2}";
6230       operands[2] = GEN_INT (-INTVAL (operands[2]));
6231       return "add{w}\t{%2, %0|%0, %2}";
6232     }
6233 }
6234   [(set (attr "type")
6235      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6236         (const_string "incdec")
6237         (const_string "alu")))
6238    (set_attr "mode" "SI")])
6239
6240
6241 (define_insn "*addhi_5"
6242   [(set (reg FLAGS_REG)
6243         (compare
6244           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6245                    (match_operand:HI 2 "general_operand" "rmni"))
6246           (const_int 0)))
6247    (clobber (match_scratch:HI 0 "=r"))]
6248   "ix86_match_ccmode (insn, CCGOCmode)
6249    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6250 {
6251   switch (get_attr_type (insn))
6252     {
6253     case TYPE_INCDEC:
6254       if (operands[2] == const1_rtx)
6255         return "inc{w}\t%0";
6256       else
6257         {
6258           gcc_assert (operands[2] == constm1_rtx);
6259           return "dec{w}\t%0";
6260         }
6261
6262     default:
6263       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6264          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6265       if (CONST_INT_P (operands[2])
6266           && (INTVAL (operands[2]) == 128
6267               || (INTVAL (operands[2]) < 0
6268                   && INTVAL (operands[2]) != -128)))
6269         {
6270           operands[2] = GEN_INT (-INTVAL (operands[2]));
6271           return "sub{w}\t{%2, %0|%0, %2}";
6272         }
6273       return "add{w}\t{%2, %0|%0, %2}";
6274     }
6275 }
6276   [(set (attr "type")
6277      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6278         (const_string "incdec")
6279         (const_string "alu")))
6280    (set_attr "mode" "HI")])
6281
6282 (define_expand "addqi3"
6283   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6284                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6285                             (match_operand:QI 2 "general_operand" "")))
6286               (clobber (reg:CC FLAGS_REG))])]
6287   "TARGET_QIMODE_MATH"
6288   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6289
6290 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6291 (define_insn "*addqi_1_lea"
6292   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6293         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6294                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6295    (clobber (reg:CC FLAGS_REG))]
6296   "!TARGET_PARTIAL_REG_STALL
6297    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6298 {
6299   int widen = (which_alternative == 2);
6300   switch (get_attr_type (insn))
6301     {
6302     case TYPE_LEA:
6303       return "#";
6304     case TYPE_INCDEC:
6305       if (operands[2] == const1_rtx)
6306         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6307       else
6308         {
6309           gcc_assert (operands[2] == constm1_rtx);
6310           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6311         }
6312
6313     default:
6314       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6315          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6316       if (CONST_INT_P (operands[2])
6317           && (INTVAL (operands[2]) == 128
6318               || (INTVAL (operands[2]) < 0
6319                   && INTVAL (operands[2]) != -128)))
6320         {
6321           operands[2] = GEN_INT (-INTVAL (operands[2]));
6322           if (widen)
6323             return "sub{l}\t{%2, %k0|%k0, %2}";
6324           else
6325             return "sub{b}\t{%2, %0|%0, %2}";
6326         }
6327       if (widen)
6328         return "add{l}\t{%k2, %k0|%k0, %k2}";
6329       else
6330         return "add{b}\t{%2, %0|%0, %2}";
6331     }
6332 }
6333   [(set (attr "type")
6334      (if_then_else (eq_attr "alternative" "3")
6335         (const_string "lea")
6336         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6337            (const_string "incdec")
6338            (const_string "alu"))))
6339    (set_attr "mode" "QI,QI,SI,SI")])
6340
6341 (define_insn "*addqi_1"
6342   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6343         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6344                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6345    (clobber (reg:CC FLAGS_REG))]
6346   "TARGET_PARTIAL_REG_STALL
6347    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6348 {
6349   int widen = (which_alternative == 2);
6350   switch (get_attr_type (insn))
6351     {
6352     case TYPE_INCDEC:
6353       if (operands[2] == const1_rtx)
6354         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6355       else
6356         {
6357           gcc_assert (operands[2] == constm1_rtx);
6358           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6359         }
6360
6361     default:
6362       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6363          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6364       if (CONST_INT_P (operands[2])
6365           && (INTVAL (operands[2]) == 128
6366               || (INTVAL (operands[2]) < 0
6367                   && INTVAL (operands[2]) != -128)))
6368         {
6369           operands[2] = GEN_INT (-INTVAL (operands[2]));
6370           if (widen)
6371             return "sub{l}\t{%2, %k0|%k0, %2}";
6372           else
6373             return "sub{b}\t{%2, %0|%0, %2}";
6374         }
6375       if (widen)
6376         return "add{l}\t{%k2, %k0|%k0, %k2}";
6377       else
6378         return "add{b}\t{%2, %0|%0, %2}";
6379     }
6380 }
6381   [(set (attr "type")
6382      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6383         (const_string "incdec")
6384         (const_string "alu")))
6385    (set_attr "mode" "QI,QI,SI")])
6386
6387 (define_insn "*addqi_1_slp"
6388   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6389         (plus:QI (match_dup 0)
6390                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6391    (clobber (reg:CC FLAGS_REG))]
6392   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6393    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6394 {
6395   switch (get_attr_type (insn))
6396     {
6397     case TYPE_INCDEC:
6398       if (operands[1] == const1_rtx)
6399         return "inc{b}\t%0";
6400       else
6401         {
6402           gcc_assert (operands[1] == constm1_rtx);
6403           return "dec{b}\t%0";
6404         }
6405
6406     default:
6407       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6408       if (CONST_INT_P (operands[1])
6409           && INTVAL (operands[1]) < 0)
6410         {
6411           operands[1] = GEN_INT (-INTVAL (operands[1]));
6412           return "sub{b}\t{%1, %0|%0, %1}";
6413         }
6414       return "add{b}\t{%1, %0|%0, %1}";
6415     }
6416 }
6417   [(set (attr "type")
6418      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6419         (const_string "incdec")
6420         (const_string "alu1")))
6421    (set (attr "memory")
6422      (if_then_else (match_operand 1 "memory_operand" "")
6423         (const_string "load")
6424         (const_string "none")))
6425    (set_attr "mode" "QI")])
6426
6427 (define_insn "*addqi_2"
6428   [(set (reg FLAGS_REG)
6429         (compare
6430           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6431                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6432           (const_int 0)))
6433    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6434         (plus:QI (match_dup 1) (match_dup 2)))]
6435   "ix86_match_ccmode (insn, CCGOCmode)
6436    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6437 {
6438   switch (get_attr_type (insn))
6439     {
6440     case TYPE_INCDEC:
6441       if (operands[2] == const1_rtx)
6442         return "inc{b}\t%0";
6443       else
6444         {
6445           gcc_assert (operands[2] == constm1_rtx
6446                       || (CONST_INT_P (operands[2])
6447                           && INTVAL (operands[2]) == 255));
6448           return "dec{b}\t%0";
6449         }
6450
6451     default:
6452       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6453       if (CONST_INT_P (operands[2])
6454           && INTVAL (operands[2]) < 0)
6455         {
6456           operands[2] = GEN_INT (-INTVAL (operands[2]));
6457           return "sub{b}\t{%2, %0|%0, %2}";
6458         }
6459       return "add{b}\t{%2, %0|%0, %2}";
6460     }
6461 }
6462   [(set (attr "type")
6463      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6464         (const_string "incdec")
6465         (const_string "alu")))
6466    (set_attr "mode" "QI")])
6467
6468 (define_insn "*addqi_3"
6469   [(set (reg FLAGS_REG)
6470         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6471                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6472    (clobber (match_scratch:QI 0 "=q"))]
6473   "ix86_match_ccmode (insn, CCZmode)
6474    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6475 {
6476   switch (get_attr_type (insn))
6477     {
6478     case TYPE_INCDEC:
6479       if (operands[2] == const1_rtx)
6480         return "inc{b}\t%0";
6481       else
6482         {
6483           gcc_assert (operands[2] == constm1_rtx
6484                       || (CONST_INT_P (operands[2])
6485                           && INTVAL (operands[2]) == 255));
6486           return "dec{b}\t%0";
6487         }
6488
6489     default:
6490       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6491       if (CONST_INT_P (operands[2])
6492           && INTVAL (operands[2]) < 0)
6493         {
6494           operands[2] = GEN_INT (-INTVAL (operands[2]));
6495           return "sub{b}\t{%2, %0|%0, %2}";
6496         }
6497       return "add{b}\t{%2, %0|%0, %2}";
6498     }
6499 }
6500   [(set (attr "type")
6501      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6502         (const_string "incdec")
6503         (const_string "alu")))
6504    (set_attr "mode" "QI")])
6505
6506 ; See comments above addsi_4 for details.
6507 (define_insn "*addqi_4"
6508   [(set (reg FLAGS_REG)
6509         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6510                  (match_operand:QI 2 "const_int_operand" "n")))
6511    (clobber (match_scratch:QI 0 "=qm"))]
6512   "ix86_match_ccmode (insn, CCGCmode)
6513    && (INTVAL (operands[2]) & 0xff) != 0x80"
6514 {
6515   switch (get_attr_type (insn))
6516     {
6517     case TYPE_INCDEC:
6518       if (operands[2] == constm1_rtx
6519           || (CONST_INT_P (operands[2])
6520               && INTVAL (operands[2]) == 255))
6521         return "inc{b}\t%0";
6522       else
6523         {
6524           gcc_assert (operands[2] == const1_rtx);
6525           return "dec{b}\t%0";
6526         }
6527
6528     default:
6529       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6530       if (INTVAL (operands[2]) < 0)
6531         {
6532           operands[2] = GEN_INT (-INTVAL (operands[2]));
6533           return "add{b}\t{%2, %0|%0, %2}";
6534         }
6535       return "sub{b}\t{%2, %0|%0, %2}";
6536     }
6537 }
6538   [(set (attr "type")
6539      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6540         (const_string "incdec")
6541         (const_string "alu")))
6542    (set_attr "mode" "QI")])
6543
6544
6545 (define_insn "*addqi_5"
6546   [(set (reg FLAGS_REG)
6547         (compare
6548           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6549                    (match_operand:QI 2 "general_operand" "qmni"))
6550           (const_int 0)))
6551    (clobber (match_scratch:QI 0 "=q"))]
6552   "ix86_match_ccmode (insn, CCGOCmode)
6553    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6554 {
6555   switch (get_attr_type (insn))
6556     {
6557     case TYPE_INCDEC:
6558       if (operands[2] == const1_rtx)
6559         return "inc{b}\t%0";
6560       else
6561         {
6562           gcc_assert (operands[2] == constm1_rtx
6563                       || (CONST_INT_P (operands[2])
6564                           && INTVAL (operands[2]) == 255));
6565           return "dec{b}\t%0";
6566         }
6567
6568     default:
6569       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6570       if (CONST_INT_P (operands[2])
6571           && INTVAL (operands[2]) < 0)
6572         {
6573           operands[2] = GEN_INT (-INTVAL (operands[2]));
6574           return "sub{b}\t{%2, %0|%0, %2}";
6575         }
6576       return "add{b}\t{%2, %0|%0, %2}";
6577     }
6578 }
6579   [(set (attr "type")
6580      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6581         (const_string "incdec")
6582         (const_string "alu")))
6583    (set_attr "mode" "QI")])
6584
6585
6586 (define_insn "addqi_ext_1"
6587   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6588                          (const_int 8)
6589                          (const_int 8))
6590         (plus:SI
6591           (zero_extract:SI
6592             (match_operand 1 "ext_register_operand" "0")
6593             (const_int 8)
6594             (const_int 8))
6595           (match_operand:QI 2 "general_operand" "Qmn")))
6596    (clobber (reg:CC FLAGS_REG))]
6597   "!TARGET_64BIT"
6598 {
6599   switch (get_attr_type (insn))
6600     {
6601     case TYPE_INCDEC:
6602       if (operands[2] == const1_rtx)
6603         return "inc{b}\t%h0";
6604       else
6605         {
6606           gcc_assert (operands[2] == constm1_rtx
6607                       || (CONST_INT_P (operands[2])
6608                           && INTVAL (operands[2]) == 255));
6609           return "dec{b}\t%h0";
6610         }
6611
6612     default:
6613       return "add{b}\t{%2, %h0|%h0, %2}";
6614     }
6615 }
6616   [(set (attr "type")
6617      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6618         (const_string "incdec")
6619         (const_string "alu")))
6620    (set_attr "mode" "QI")])
6621
6622 (define_insn "*addqi_ext_1_rex64"
6623   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6624                          (const_int 8)
6625                          (const_int 8))
6626         (plus:SI
6627           (zero_extract:SI
6628             (match_operand 1 "ext_register_operand" "0")
6629             (const_int 8)
6630             (const_int 8))
6631           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6632    (clobber (reg:CC FLAGS_REG))]
6633   "TARGET_64BIT"
6634 {
6635   switch (get_attr_type (insn))
6636     {
6637     case TYPE_INCDEC:
6638       if (operands[2] == const1_rtx)
6639         return "inc{b}\t%h0";
6640       else
6641         {
6642           gcc_assert (operands[2] == constm1_rtx
6643                       || (CONST_INT_P (operands[2])
6644                           && INTVAL (operands[2]) == 255));
6645           return "dec{b}\t%h0";
6646         }
6647
6648     default:
6649       return "add{b}\t{%2, %h0|%h0, %2}";
6650     }
6651 }
6652   [(set (attr "type")
6653      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6654         (const_string "incdec")
6655         (const_string "alu")))
6656    (set_attr "mode" "QI")])
6657
6658 (define_insn "*addqi_ext_2"
6659   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6660                          (const_int 8)
6661                          (const_int 8))
6662         (plus:SI
6663           (zero_extract:SI
6664             (match_operand 1 "ext_register_operand" "%0")
6665             (const_int 8)
6666             (const_int 8))
6667           (zero_extract:SI
6668             (match_operand 2 "ext_register_operand" "Q")
6669             (const_int 8)
6670             (const_int 8))))
6671    (clobber (reg:CC FLAGS_REG))]
6672   ""
6673   "add{b}\t{%h2, %h0|%h0, %h2}"
6674   [(set_attr "type" "alu")
6675    (set_attr "mode" "QI")])
6676
6677 ;; The patterns that match these are at the end of this file.
6678
6679 (define_expand "addxf3"
6680   [(set (match_operand:XF 0 "register_operand" "")
6681         (plus:XF (match_operand:XF 1 "register_operand" "")
6682                  (match_operand:XF 2 "register_operand" "")))]
6683   "TARGET_80387"
6684   "")
6685
6686 (define_expand "adddf3"
6687   [(set (match_operand:DF 0 "register_operand" "")
6688         (plus:DF (match_operand:DF 1 "register_operand" "")
6689                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6690   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6691   "")
6692
6693 (define_expand "addsf3"
6694   [(set (match_operand:SF 0 "register_operand" "")
6695         (plus:SF (match_operand:SF 1 "register_operand" "")
6696                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6697   "TARGET_80387 || TARGET_SSE_MATH"
6698   "")
6699 \f
6700 ;; Subtract instructions
6701
6702 ;; %%% splits for subditi3
6703
6704 (define_expand "subti3"
6705   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6706                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6707                              (match_operand:TI 2 "x86_64_general_operand" "")))
6708               (clobber (reg:CC FLAGS_REG))])]
6709   "TARGET_64BIT"
6710   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6711
6712 (define_insn "*subti3_1"
6713   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6714         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6715                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6716    (clobber (reg:CC FLAGS_REG))]
6717   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6718   "#")
6719
6720 (define_split
6721   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6722         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6723                   (match_operand:TI 2 "general_operand" "")))
6724    (clobber (reg:CC FLAGS_REG))]
6725   "TARGET_64BIT && reload_completed"
6726   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6727               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6728    (parallel [(set (match_dup 3)
6729                    (minus:DI (match_dup 4)
6730                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6731                                       (match_dup 5))))
6732               (clobber (reg:CC FLAGS_REG))])]
6733   "split_ti (operands+0, 1, operands+0, operands+3);
6734    split_ti (operands+1, 1, operands+1, operands+4);
6735    split_ti (operands+2, 1, operands+2, operands+5);")
6736
6737 ;; %%% splits for subsidi3
6738
6739 (define_expand "subdi3"
6740   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6741                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6742                              (match_operand:DI 2 "x86_64_general_operand" "")))
6743               (clobber (reg:CC FLAGS_REG))])]
6744   ""
6745   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6746
6747 (define_insn "*subdi3_1"
6748   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6749         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6750                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6751    (clobber (reg:CC FLAGS_REG))]
6752   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6753   "#")
6754
6755 (define_split
6756   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6757         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6758                   (match_operand:DI 2 "general_operand" "")))
6759    (clobber (reg:CC FLAGS_REG))]
6760   "!TARGET_64BIT && reload_completed"
6761   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6762               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6763    (parallel [(set (match_dup 3)
6764                    (minus:SI (match_dup 4)
6765                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6766                                       (match_dup 5))))
6767               (clobber (reg:CC FLAGS_REG))])]
6768   "split_di (operands+0, 1, operands+0, operands+3);
6769    split_di (operands+1, 1, operands+1, operands+4);
6770    split_di (operands+2, 1, operands+2, operands+5);")
6771
6772 (define_insn "subdi3_carry_rex64"
6773   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6774           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6775             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6776                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6777    (clobber (reg:CC FLAGS_REG))]
6778   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6779   "sbb{q}\t{%2, %0|%0, %2}"
6780   [(set_attr "type" "alu")
6781    (set_attr "pent_pair" "pu")
6782    (set_attr "mode" "DI")])
6783
6784 (define_insn "*subdi_1_rex64"
6785   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6786         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6787                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6788    (clobber (reg:CC FLAGS_REG))]
6789   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6790   "sub{q}\t{%2, %0|%0, %2}"
6791   [(set_attr "type" "alu")
6792    (set_attr "mode" "DI")])
6793
6794 (define_insn "*subdi_2_rex64"
6795   [(set (reg FLAGS_REG)
6796         (compare
6797           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6798                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6799           (const_int 0)))
6800    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6801         (minus:DI (match_dup 1) (match_dup 2)))]
6802   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6803    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6804   "sub{q}\t{%2, %0|%0, %2}"
6805   [(set_attr "type" "alu")
6806    (set_attr "mode" "DI")])
6807
6808 (define_insn "*subdi_3_rex63"
6809   [(set (reg FLAGS_REG)
6810         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6811                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6812    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6813         (minus:DI (match_dup 1) (match_dup 2)))]
6814   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6815    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6816   "sub{q}\t{%2, %0|%0, %2}"
6817   [(set_attr "type" "alu")
6818    (set_attr "mode" "DI")])
6819
6820 (define_insn "subqi3_carry"
6821   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6822           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6823             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6824                (match_operand:QI 2 "general_operand" "qi,qm"))))
6825    (clobber (reg:CC FLAGS_REG))]
6826   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6827   "sbb{b}\t{%2, %0|%0, %2}"
6828   [(set_attr "type" "alu")
6829    (set_attr "pent_pair" "pu")
6830    (set_attr "mode" "QI")])
6831
6832 (define_insn "subhi3_carry"
6833   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6834           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6835             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6836                (match_operand:HI 2 "general_operand" "ri,rm"))))
6837    (clobber (reg:CC FLAGS_REG))]
6838   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6839   "sbb{w}\t{%2, %0|%0, %2}"
6840   [(set_attr "type" "alu")
6841    (set_attr "pent_pair" "pu")
6842    (set_attr "mode" "HI")])
6843
6844 (define_insn "subsi3_carry"
6845   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6846           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6847             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6848                (match_operand:SI 2 "general_operand" "ri,rm"))))
6849    (clobber (reg:CC FLAGS_REG))]
6850   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6851   "sbb{l}\t{%2, %0|%0, %2}"
6852   [(set_attr "type" "alu")
6853    (set_attr "pent_pair" "pu")
6854    (set_attr "mode" "SI")])
6855
6856 (define_insn "subsi3_carry_zext"
6857   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6858           (zero_extend:DI
6859             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6860               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6861                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6862    (clobber (reg:CC FLAGS_REG))]
6863   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6864   "sbb{l}\t{%2, %k0|%k0, %2}"
6865   [(set_attr "type" "alu")
6866    (set_attr "pent_pair" "pu")
6867    (set_attr "mode" "SI")])
6868
6869 (define_expand "subsi3"
6870   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6871                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6872                              (match_operand:SI 2 "general_operand" "")))
6873               (clobber (reg:CC FLAGS_REG))])]
6874   ""
6875   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6876
6877 (define_insn "*subsi_1"
6878   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6879         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6880                   (match_operand:SI 2 "general_operand" "ri,rm")))
6881    (clobber (reg:CC FLAGS_REG))]
6882   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6883   "sub{l}\t{%2, %0|%0, %2}"
6884   [(set_attr "type" "alu")
6885    (set_attr "mode" "SI")])
6886
6887 (define_insn "*subsi_1_zext"
6888   [(set (match_operand:DI 0 "register_operand" "=r")
6889         (zero_extend:DI
6890           (minus:SI (match_operand:SI 1 "register_operand" "0")
6891                     (match_operand:SI 2 "general_operand" "rim"))))
6892    (clobber (reg:CC FLAGS_REG))]
6893   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6894   "sub{l}\t{%2, %k0|%k0, %2}"
6895   [(set_attr "type" "alu")
6896    (set_attr "mode" "SI")])
6897
6898 (define_insn "*subsi_2"
6899   [(set (reg FLAGS_REG)
6900         (compare
6901           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6902                     (match_operand:SI 2 "general_operand" "ri,rm"))
6903           (const_int 0)))
6904    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6905         (minus:SI (match_dup 1) (match_dup 2)))]
6906   "ix86_match_ccmode (insn, CCGOCmode)
6907    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6908   "sub{l}\t{%2, %0|%0, %2}"
6909   [(set_attr "type" "alu")
6910    (set_attr "mode" "SI")])
6911
6912 (define_insn "*subsi_2_zext"
6913   [(set (reg FLAGS_REG)
6914         (compare
6915           (minus:SI (match_operand:SI 1 "register_operand" "0")
6916                     (match_operand:SI 2 "general_operand" "rim"))
6917           (const_int 0)))
6918    (set (match_operand:DI 0 "register_operand" "=r")
6919         (zero_extend:DI
6920           (minus:SI (match_dup 1)
6921                     (match_dup 2))))]
6922   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6923    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6924   "sub{l}\t{%2, %k0|%k0, %2}"
6925   [(set_attr "type" "alu")
6926    (set_attr "mode" "SI")])
6927
6928 (define_insn "*subsi_3"
6929   [(set (reg FLAGS_REG)
6930         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6931                  (match_operand:SI 2 "general_operand" "ri,rm")))
6932    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6933         (minus:SI (match_dup 1) (match_dup 2)))]
6934   "ix86_match_ccmode (insn, CCmode)
6935    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6936   "sub{l}\t{%2, %0|%0, %2}"
6937   [(set_attr "type" "alu")
6938    (set_attr "mode" "SI")])
6939
6940 (define_insn "*subsi_3_zext"
6941   [(set (reg FLAGS_REG)
6942         (compare (match_operand:SI 1 "register_operand" "0")
6943                  (match_operand:SI 2 "general_operand" "rim")))
6944    (set (match_operand:DI 0 "register_operand" "=r")
6945         (zero_extend:DI
6946           (minus:SI (match_dup 1)
6947                     (match_dup 2))))]
6948   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6949    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6950   "sub{l}\t{%2, %1|%1, %2}"
6951   [(set_attr "type" "alu")
6952    (set_attr "mode" "DI")])
6953
6954 (define_expand "subhi3"
6955   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6956                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6957                              (match_operand:HI 2 "general_operand" "")))
6958               (clobber (reg:CC FLAGS_REG))])]
6959   "TARGET_HIMODE_MATH"
6960   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6961
6962 (define_insn "*subhi_1"
6963   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6964         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6965                   (match_operand:HI 2 "general_operand" "ri,rm")))
6966    (clobber (reg:CC FLAGS_REG))]
6967   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6968   "sub{w}\t{%2, %0|%0, %2}"
6969   [(set_attr "type" "alu")
6970    (set_attr "mode" "HI")])
6971
6972 (define_insn "*subhi_2"
6973   [(set (reg FLAGS_REG)
6974         (compare
6975           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6976                     (match_operand:HI 2 "general_operand" "ri,rm"))
6977           (const_int 0)))
6978    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6979         (minus:HI (match_dup 1) (match_dup 2)))]
6980   "ix86_match_ccmode (insn, CCGOCmode)
6981    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6982   "sub{w}\t{%2, %0|%0, %2}"
6983   [(set_attr "type" "alu")
6984    (set_attr "mode" "HI")])
6985
6986 (define_insn "*subhi_3"
6987   [(set (reg FLAGS_REG)
6988         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6989                  (match_operand:HI 2 "general_operand" "ri,rm")))
6990    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6991         (minus:HI (match_dup 1) (match_dup 2)))]
6992   "ix86_match_ccmode (insn, CCmode)
6993    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6994   "sub{w}\t{%2, %0|%0, %2}"
6995   [(set_attr "type" "alu")
6996    (set_attr "mode" "HI")])
6997
6998 (define_expand "subqi3"
6999   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7000                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7001                              (match_operand:QI 2 "general_operand" "")))
7002               (clobber (reg:CC FLAGS_REG))])]
7003   "TARGET_QIMODE_MATH"
7004   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7005
7006 (define_insn "*subqi_1"
7007   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7008         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7009                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7010    (clobber (reg:CC FLAGS_REG))]
7011   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7012   "sub{b}\t{%2, %0|%0, %2}"
7013   [(set_attr "type" "alu")
7014    (set_attr "mode" "QI")])
7015
7016 (define_insn "*subqi_1_slp"
7017   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7018         (minus:QI (match_dup 0)
7019                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7020    (clobber (reg:CC FLAGS_REG))]
7021   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7022    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7023   "sub{b}\t{%1, %0|%0, %1}"
7024   [(set_attr "type" "alu1")
7025    (set_attr "mode" "QI")])
7026
7027 (define_insn "*subqi_2"
7028   [(set (reg FLAGS_REG)
7029         (compare
7030           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7031                     (match_operand:QI 2 "general_operand" "qi,qm"))
7032           (const_int 0)))
7033    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7034         (minus:HI (match_dup 1) (match_dup 2)))]
7035   "ix86_match_ccmode (insn, CCGOCmode)
7036    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7037   "sub{b}\t{%2, %0|%0, %2}"
7038   [(set_attr "type" "alu")
7039    (set_attr "mode" "QI")])
7040
7041 (define_insn "*subqi_3"
7042   [(set (reg FLAGS_REG)
7043         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7044                  (match_operand:QI 2 "general_operand" "qi,qm")))
7045    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7046         (minus:HI (match_dup 1) (match_dup 2)))]
7047   "ix86_match_ccmode (insn, CCmode)
7048    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7049   "sub{b}\t{%2, %0|%0, %2}"
7050   [(set_attr "type" "alu")
7051    (set_attr "mode" "QI")])
7052
7053 ;; The patterns that match these are at the end of this file.
7054
7055 (define_expand "subxf3"
7056   [(set (match_operand:XF 0 "register_operand" "")
7057         (minus:XF (match_operand:XF 1 "register_operand" "")
7058                   (match_operand:XF 2 "register_operand" "")))]
7059   "TARGET_80387"
7060   "")
7061
7062 (define_expand "subdf3"
7063   [(set (match_operand:DF 0 "register_operand" "")
7064         (minus:DF (match_operand:DF 1 "register_operand" "")
7065                   (match_operand:DF 2 "nonimmediate_operand" "")))]
7066   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7067   "")
7068
7069 (define_expand "subsf3"
7070   [(set (match_operand:SF 0 "register_operand" "")
7071         (minus:SF (match_operand:SF 1 "register_operand" "")
7072                   (match_operand:SF 2 "nonimmediate_operand" "")))]
7073   "TARGET_80387 || TARGET_SSE_MATH"
7074   "")
7075 \f
7076 ;; Multiply instructions
7077
7078 (define_expand "muldi3"
7079   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7080                    (mult:DI (match_operand:DI 1 "register_operand" "")
7081                             (match_operand:DI 2 "x86_64_general_operand" "")))
7082               (clobber (reg:CC FLAGS_REG))])]
7083   "TARGET_64BIT"
7084   "")
7085
7086 ;; On AMDFAM10 
7087 ;; IMUL reg64, reg64, imm8      Direct
7088 ;; IMUL reg64, mem64, imm8      VectorPath
7089 ;; IMUL reg64, reg64, imm32     Direct
7090 ;; IMUL reg64, mem64, imm32     VectorPath 
7091 ;; IMUL reg64, reg64            Direct
7092 ;; IMUL reg64, mem64            Direct
7093
7094 (define_insn "*muldi3_1_rex64"
7095   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7096         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7097                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7098    (clobber (reg:CC FLAGS_REG))]
7099   "TARGET_64BIT
7100    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7101   "@
7102    imul{q}\t{%2, %1, %0|%0, %1, %2}
7103    imul{q}\t{%2, %1, %0|%0, %1, %2}
7104    imul{q}\t{%2, %0|%0, %2}"
7105   [(set_attr "type" "imul")
7106    (set_attr "prefix_0f" "0,0,1")
7107    (set (attr "athlon_decode")
7108         (cond [(eq_attr "cpu" "athlon")
7109                   (const_string "vector")
7110                (eq_attr "alternative" "1")
7111                   (const_string "vector")
7112                (and (eq_attr "alternative" "2")
7113                     (match_operand 1 "memory_operand" ""))
7114                   (const_string "vector")]
7115               (const_string "direct")))
7116    (set (attr "amdfam10_decode")
7117         (cond [(and (eq_attr "alternative" "0,1")
7118                     (match_operand 1 "memory_operand" ""))
7119                   (const_string "vector")]
7120               (const_string "direct")))       
7121    (set_attr "mode" "DI")])
7122
7123 (define_expand "mulsi3"
7124   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7125                    (mult:SI (match_operand:SI 1 "register_operand" "")
7126                             (match_operand:SI 2 "general_operand" "")))
7127               (clobber (reg:CC FLAGS_REG))])]
7128   ""
7129   "")
7130
7131 ;; On AMDFAM10 
7132 ;; IMUL reg32, reg32, imm8      Direct
7133 ;; IMUL reg32, mem32, imm8      VectorPath
7134 ;; IMUL reg32, reg32, imm32     Direct
7135 ;; IMUL reg32, mem32, imm32     VectorPath
7136 ;; IMUL reg32, reg32            Direct
7137 ;; IMUL reg32, mem32            Direct
7138
7139 (define_insn "*mulsi3_1"
7140   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7141         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7142                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7143    (clobber (reg:CC FLAGS_REG))]
7144   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7145   "@
7146    imul{l}\t{%2, %1, %0|%0, %1, %2}
7147    imul{l}\t{%2, %1, %0|%0, %1, %2}
7148    imul{l}\t{%2, %0|%0, %2}"
7149   [(set_attr "type" "imul")
7150    (set_attr "prefix_0f" "0,0,1")
7151    (set (attr "athlon_decode")
7152         (cond [(eq_attr "cpu" "athlon")
7153                   (const_string "vector")
7154                (eq_attr "alternative" "1")
7155                   (const_string "vector")
7156                (and (eq_attr "alternative" "2")
7157                     (match_operand 1 "memory_operand" ""))
7158                   (const_string "vector")]
7159               (const_string "direct")))
7160    (set (attr "amdfam10_decode")
7161         (cond [(and (eq_attr "alternative" "0,1")
7162                     (match_operand 1 "memory_operand" ""))
7163                   (const_string "vector")]
7164               (const_string "direct")))       
7165    (set_attr "mode" "SI")])
7166
7167 (define_insn "*mulsi3_1_zext"
7168   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7169         (zero_extend:DI
7170           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7171                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7172    (clobber (reg:CC FLAGS_REG))]
7173   "TARGET_64BIT
7174    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7175   "@
7176    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7177    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7178    imul{l}\t{%2, %k0|%k0, %2}"
7179   [(set_attr "type" "imul")
7180    (set_attr "prefix_0f" "0,0,1")
7181    (set (attr "athlon_decode")
7182         (cond [(eq_attr "cpu" "athlon")
7183                   (const_string "vector")
7184                (eq_attr "alternative" "1")
7185                   (const_string "vector")
7186                (and (eq_attr "alternative" "2")
7187                     (match_operand 1 "memory_operand" ""))
7188                   (const_string "vector")]
7189               (const_string "direct")))
7190    (set (attr "amdfam10_decode")
7191         (cond [(and (eq_attr "alternative" "0,1")
7192                     (match_operand 1 "memory_operand" ""))
7193                   (const_string "vector")]
7194               (const_string "direct")))       
7195    (set_attr "mode" "SI")])
7196
7197 (define_expand "mulhi3"
7198   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7199                    (mult:HI (match_operand:HI 1 "register_operand" "")
7200                             (match_operand:HI 2 "general_operand" "")))
7201               (clobber (reg:CC FLAGS_REG))])]
7202   "TARGET_HIMODE_MATH"
7203   "")
7204
7205 ;; On AMDFAM10
7206 ;; IMUL reg16, reg16, imm8      VectorPath
7207 ;; IMUL reg16, mem16, imm8      VectorPath
7208 ;; IMUL reg16, reg16, imm16     VectorPath
7209 ;; IMUL reg16, mem16, imm16     VectorPath
7210 ;; IMUL reg16, reg16            Direct
7211 ;; IMUL reg16, mem16            Direct
7212 (define_insn "*mulhi3_1"
7213   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7214         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7215                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7216    (clobber (reg:CC FLAGS_REG))]
7217   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7218   "@
7219    imul{w}\t{%2, %1, %0|%0, %1, %2}
7220    imul{w}\t{%2, %1, %0|%0, %1, %2}
7221    imul{w}\t{%2, %0|%0, %2}"
7222   [(set_attr "type" "imul")
7223    (set_attr "prefix_0f" "0,0,1")
7224    (set (attr "athlon_decode")
7225         (cond [(eq_attr "cpu" "athlon")
7226                   (const_string "vector")
7227                (eq_attr "alternative" "1,2")
7228                   (const_string "vector")]
7229               (const_string "direct")))
7230    (set (attr "amdfam10_decode")
7231         (cond [(eq_attr "alternative" "0,1")
7232                   (const_string "vector")]
7233               (const_string "direct")))
7234    (set_attr "mode" "HI")])
7235
7236 (define_expand "mulqi3"
7237   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7238                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7239                             (match_operand:QI 2 "register_operand" "")))
7240               (clobber (reg:CC FLAGS_REG))])]
7241   "TARGET_QIMODE_MATH"
7242   "")
7243
7244 ;;On AMDFAM10
7245 ;; MUL reg8     Direct
7246 ;; MUL mem8     Direct
7247
7248 (define_insn "*mulqi3_1"
7249   [(set (match_operand:QI 0 "register_operand" "=a")
7250         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7251                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7252    (clobber (reg:CC FLAGS_REG))]
7253   "TARGET_QIMODE_MATH
7254    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7255   "mul{b}\t%2"
7256   [(set_attr "type" "imul")
7257    (set_attr "length_immediate" "0")
7258    (set (attr "athlon_decode")
7259      (if_then_else (eq_attr "cpu" "athlon")
7260         (const_string "vector")
7261         (const_string "direct")))
7262    (set_attr "amdfam10_decode" "direct")        
7263    (set_attr "mode" "QI")])
7264
7265 (define_expand "umulqihi3"
7266   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7267                    (mult:HI (zero_extend:HI
7268                               (match_operand:QI 1 "nonimmediate_operand" ""))
7269                             (zero_extend:HI
7270                               (match_operand:QI 2 "register_operand" ""))))
7271               (clobber (reg:CC FLAGS_REG))])]
7272   "TARGET_QIMODE_MATH"
7273   "")
7274
7275 (define_insn "*umulqihi3_1"
7276   [(set (match_operand:HI 0 "register_operand" "=a")
7277         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7278                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7279    (clobber (reg:CC FLAGS_REG))]
7280   "TARGET_QIMODE_MATH
7281    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7282   "mul{b}\t%2"
7283   [(set_attr "type" "imul")
7284    (set_attr "length_immediate" "0")
7285    (set (attr "athlon_decode")
7286      (if_then_else (eq_attr "cpu" "athlon")
7287         (const_string "vector")
7288         (const_string "direct")))
7289    (set_attr "amdfam10_decode" "direct")        
7290    (set_attr "mode" "QI")])
7291
7292 (define_expand "mulqihi3"
7293   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7294                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7295                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7296               (clobber (reg:CC FLAGS_REG))])]
7297   "TARGET_QIMODE_MATH"
7298   "")
7299
7300 (define_insn "*mulqihi3_insn"
7301   [(set (match_operand:HI 0 "register_operand" "=a")
7302         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7303                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7304    (clobber (reg:CC FLAGS_REG))]
7305   "TARGET_QIMODE_MATH
7306    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7307   "imul{b}\t%2"
7308   [(set_attr "type" "imul")
7309    (set_attr "length_immediate" "0")
7310    (set (attr "athlon_decode")
7311      (if_then_else (eq_attr "cpu" "athlon")
7312         (const_string "vector")
7313         (const_string "direct")))
7314    (set_attr "amdfam10_decode" "direct")        
7315    (set_attr "mode" "QI")])
7316
7317 (define_expand "umulditi3"
7318   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7319                    (mult:TI (zero_extend:TI
7320                               (match_operand:DI 1 "nonimmediate_operand" ""))
7321                             (zero_extend:TI
7322                               (match_operand:DI 2 "register_operand" ""))))
7323               (clobber (reg:CC FLAGS_REG))])]
7324   "TARGET_64BIT"
7325   "")
7326
7327 (define_insn "*umulditi3_insn"
7328   [(set (match_operand:TI 0 "register_operand" "=A")
7329         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7330                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7331    (clobber (reg:CC FLAGS_REG))]
7332   "TARGET_64BIT
7333    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7334   "mul{q}\t%2"
7335   [(set_attr "type" "imul")
7336    (set_attr "length_immediate" "0")
7337    (set (attr "athlon_decode")
7338      (if_then_else (eq_attr "cpu" "athlon")
7339         (const_string "vector")
7340         (const_string "double")))
7341    (set_attr "amdfam10_decode" "double")        
7342    (set_attr "mode" "DI")])
7343
7344 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7345 (define_expand "umulsidi3"
7346   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7347                    (mult:DI (zero_extend:DI
7348                               (match_operand:SI 1 "nonimmediate_operand" ""))
7349                             (zero_extend:DI
7350                               (match_operand:SI 2 "register_operand" ""))))
7351               (clobber (reg:CC FLAGS_REG))])]
7352   "!TARGET_64BIT"
7353   "")
7354
7355 (define_insn "*umulsidi3_insn"
7356   [(set (match_operand:DI 0 "register_operand" "=A")
7357         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7358                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7359    (clobber (reg:CC FLAGS_REG))]
7360   "!TARGET_64BIT
7361    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7362   "mul{l}\t%2"
7363   [(set_attr "type" "imul")
7364    (set_attr "length_immediate" "0")
7365    (set (attr "athlon_decode")
7366      (if_then_else (eq_attr "cpu" "athlon")
7367         (const_string "vector")
7368         (const_string "double")))
7369    (set_attr "amdfam10_decode" "double")        
7370    (set_attr "mode" "SI")])
7371
7372 (define_expand "mulditi3"
7373   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7374                    (mult:TI (sign_extend:TI
7375                               (match_operand:DI 1 "nonimmediate_operand" ""))
7376                             (sign_extend:TI
7377                               (match_operand:DI 2 "register_operand" ""))))
7378               (clobber (reg:CC FLAGS_REG))])]
7379   "TARGET_64BIT"
7380   "")
7381
7382 (define_insn "*mulditi3_insn"
7383   [(set (match_operand:TI 0 "register_operand" "=A")
7384         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7385                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7386    (clobber (reg:CC FLAGS_REG))]
7387   "TARGET_64BIT
7388    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7389   "imul{q}\t%2"
7390   [(set_attr "type" "imul")
7391    (set_attr "length_immediate" "0")
7392    (set (attr "athlon_decode")
7393      (if_then_else (eq_attr "cpu" "athlon")
7394         (const_string "vector")
7395         (const_string "double")))
7396    (set_attr "amdfam10_decode" "double")
7397    (set_attr "mode" "DI")])
7398
7399 (define_expand "mulsidi3"
7400   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7401                    (mult:DI (sign_extend:DI
7402                               (match_operand:SI 1 "nonimmediate_operand" ""))
7403                             (sign_extend:DI
7404                               (match_operand:SI 2 "register_operand" ""))))
7405               (clobber (reg:CC FLAGS_REG))])]
7406   "!TARGET_64BIT"
7407   "")
7408
7409 (define_insn "*mulsidi3_insn"
7410   [(set (match_operand:DI 0 "register_operand" "=A")
7411         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7412                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7413    (clobber (reg:CC FLAGS_REG))]
7414   "!TARGET_64BIT
7415    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7416   "imul{l}\t%2"
7417   [(set_attr "type" "imul")
7418    (set_attr "length_immediate" "0")
7419    (set (attr "athlon_decode")
7420      (if_then_else (eq_attr "cpu" "athlon")
7421         (const_string "vector")
7422         (const_string "double")))
7423    (set_attr "amdfam10_decode" "double")        
7424    (set_attr "mode" "SI")])
7425
7426 (define_expand "umuldi3_highpart"
7427   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7428                    (truncate:DI
7429                      (lshiftrt:TI
7430                        (mult:TI (zero_extend:TI
7431                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7432                                 (zero_extend:TI
7433                                   (match_operand:DI 2 "register_operand" "")))
7434                        (const_int 64))))
7435               (clobber (match_scratch:DI 3 ""))
7436               (clobber (reg:CC FLAGS_REG))])]
7437   "TARGET_64BIT"
7438   "")
7439
7440 (define_insn "*umuldi3_highpart_rex64"
7441   [(set (match_operand:DI 0 "register_operand" "=d")
7442         (truncate:DI
7443           (lshiftrt:TI
7444             (mult:TI (zero_extend:TI
7445                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7446                      (zero_extend:TI
7447                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7448             (const_int 64))))
7449    (clobber (match_scratch:DI 3 "=1"))
7450    (clobber (reg:CC FLAGS_REG))]
7451   "TARGET_64BIT
7452    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7453   "mul{q}\t%2"
7454   [(set_attr "type" "imul")
7455    (set_attr "length_immediate" "0")
7456    (set (attr "athlon_decode")
7457      (if_then_else (eq_attr "cpu" "athlon")
7458         (const_string "vector")
7459         (const_string "double")))
7460    (set_attr "amdfam10_decode" "double")        
7461    (set_attr "mode" "DI")])
7462
7463 (define_expand "umulsi3_highpart"
7464   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7465                    (truncate:SI
7466                      (lshiftrt:DI
7467                        (mult:DI (zero_extend:DI
7468                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7469                                 (zero_extend:DI
7470                                   (match_operand:SI 2 "register_operand" "")))
7471                        (const_int 32))))
7472               (clobber (match_scratch:SI 3 ""))
7473               (clobber (reg:CC FLAGS_REG))])]
7474   ""
7475   "")
7476
7477 (define_insn "*umulsi3_highpart_insn"
7478   [(set (match_operand:SI 0 "register_operand" "=d")
7479         (truncate:SI
7480           (lshiftrt:DI
7481             (mult:DI (zero_extend:DI
7482                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7483                      (zero_extend:DI
7484                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7485             (const_int 32))))
7486    (clobber (match_scratch:SI 3 "=1"))
7487    (clobber (reg:CC FLAGS_REG))]
7488   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7489   "mul{l}\t%2"
7490   [(set_attr "type" "imul")
7491    (set_attr "length_immediate" "0")
7492    (set (attr "athlon_decode")
7493      (if_then_else (eq_attr "cpu" "athlon")
7494         (const_string "vector")
7495         (const_string "double")))
7496    (set_attr "amdfam10_decode" "double")
7497    (set_attr "mode" "SI")])
7498
7499 (define_insn "*umulsi3_highpart_zext"
7500   [(set (match_operand:DI 0 "register_operand" "=d")
7501         (zero_extend:DI (truncate:SI
7502           (lshiftrt:DI
7503             (mult:DI (zero_extend:DI
7504                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7505                      (zero_extend:DI
7506                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7507             (const_int 32)))))
7508    (clobber (match_scratch:SI 3 "=1"))
7509    (clobber (reg:CC FLAGS_REG))]
7510   "TARGET_64BIT
7511    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7512   "mul{l}\t%2"
7513   [(set_attr "type" "imul")
7514    (set_attr "length_immediate" "0")
7515    (set (attr "athlon_decode")
7516      (if_then_else (eq_attr "cpu" "athlon")
7517         (const_string "vector")
7518         (const_string "double")))
7519    (set_attr "amdfam10_decode" "double")
7520    (set_attr "mode" "SI")])
7521
7522 (define_expand "smuldi3_highpart"
7523   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7524                    (truncate:DI
7525                      (lshiftrt:TI
7526                        (mult:TI (sign_extend:TI
7527                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7528                                 (sign_extend:TI
7529                                   (match_operand:DI 2 "register_operand" "")))
7530                        (const_int 64))))
7531               (clobber (match_scratch:DI 3 ""))
7532               (clobber (reg:CC FLAGS_REG))])]
7533   "TARGET_64BIT"
7534   "")
7535
7536 (define_insn "*smuldi3_highpart_rex64"
7537   [(set (match_operand:DI 0 "register_operand" "=d")
7538         (truncate:DI
7539           (lshiftrt:TI
7540             (mult:TI (sign_extend:TI
7541                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7542                      (sign_extend:TI
7543                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7544             (const_int 64))))
7545    (clobber (match_scratch:DI 3 "=1"))
7546    (clobber (reg:CC FLAGS_REG))]
7547   "TARGET_64BIT
7548    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7549   "imul{q}\t%2"
7550   [(set_attr "type" "imul")
7551    (set (attr "athlon_decode")
7552      (if_then_else (eq_attr "cpu" "athlon")
7553         (const_string "vector")
7554         (const_string "double")))
7555    (set_attr "amdfam10_decode" "double")
7556    (set_attr "mode" "DI")])
7557
7558 (define_expand "smulsi3_highpart"
7559   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7560                    (truncate:SI
7561                      (lshiftrt:DI
7562                        (mult:DI (sign_extend:DI
7563                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7564                                 (sign_extend:DI
7565                                   (match_operand:SI 2 "register_operand" "")))
7566                        (const_int 32))))
7567               (clobber (match_scratch:SI 3 ""))
7568               (clobber (reg:CC FLAGS_REG))])]
7569   ""
7570   "")
7571
7572 (define_insn "*smulsi3_highpart_insn"
7573   [(set (match_operand:SI 0 "register_operand" "=d")
7574         (truncate:SI
7575           (lshiftrt:DI
7576             (mult:DI (sign_extend:DI
7577                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7578                      (sign_extend:DI
7579                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7580             (const_int 32))))
7581    (clobber (match_scratch:SI 3 "=1"))
7582    (clobber (reg:CC FLAGS_REG))]
7583   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7584   "imul{l}\t%2"
7585   [(set_attr "type" "imul")
7586    (set (attr "athlon_decode")
7587      (if_then_else (eq_attr "cpu" "athlon")
7588         (const_string "vector")
7589         (const_string "double")))
7590    (set_attr "amdfam10_decode" "double")
7591    (set_attr "mode" "SI")])
7592
7593 (define_insn "*smulsi3_highpart_zext"
7594   [(set (match_operand:DI 0 "register_operand" "=d")
7595         (zero_extend:DI (truncate:SI
7596           (lshiftrt:DI
7597             (mult:DI (sign_extend:DI
7598                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7599                      (sign_extend:DI
7600                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7601             (const_int 32)))))
7602    (clobber (match_scratch:SI 3 "=1"))
7603    (clobber (reg:CC FLAGS_REG))]
7604   "TARGET_64BIT
7605    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7606   "imul{l}\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" "SI")])
7614
7615 ;; The patterns that match these are at the end of this file.
7616
7617 (define_expand "mulxf3"
7618   [(set (match_operand:XF 0 "register_operand" "")
7619         (mult:XF (match_operand:XF 1 "register_operand" "")
7620                  (match_operand:XF 2 "register_operand" "")))]
7621   "TARGET_80387"
7622   "")
7623
7624 (define_expand "muldf3"
7625   [(set (match_operand:DF 0 "register_operand" "")
7626         (mult:DF (match_operand:DF 1 "register_operand" "")
7627                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7628   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7629   "")
7630
7631 (define_expand "mulsf3"
7632   [(set (match_operand:SF 0 "register_operand" "")
7633         (mult:SF (match_operand:SF 1 "register_operand" "")
7634                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7635   "TARGET_80387 || TARGET_SSE_MATH"
7636   "")
7637 \f
7638 ;; Divide instructions
7639
7640 (define_insn "divqi3"
7641   [(set (match_operand:QI 0 "register_operand" "=a")
7642         (div:QI (match_operand:HI 1 "register_operand" "0")
7643                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7644    (clobber (reg:CC FLAGS_REG))]
7645   "TARGET_QIMODE_MATH"
7646   "idiv{b}\t%2"
7647   [(set_attr "type" "idiv")
7648    (set_attr "mode" "QI")])
7649
7650 (define_insn "udivqi3"
7651   [(set (match_operand:QI 0 "register_operand" "=a")
7652         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7653                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7654    (clobber (reg:CC FLAGS_REG))]
7655   "TARGET_QIMODE_MATH"
7656   "div{b}\t%2"
7657   [(set_attr "type" "idiv")
7658    (set_attr "mode" "QI")])
7659
7660 ;; The patterns that match these are at the end of this file.
7661
7662 (define_expand "divxf3"
7663   [(set (match_operand:XF 0 "register_operand" "")
7664         (div:XF (match_operand:XF 1 "register_operand" "")
7665                 (match_operand:XF 2 "register_operand" "")))]
7666   "TARGET_80387"
7667   "")
7668
7669 (define_expand "divdf3"
7670   [(set (match_operand:DF 0 "register_operand" "")
7671         (div:DF (match_operand:DF 1 "register_operand" "")
7672                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7673    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7674    "")
7675
7676 (define_expand "divsf3"
7677   [(set (match_operand:SF 0 "register_operand" "")
7678         (div:SF (match_operand:SF 1 "register_operand" "")
7679                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7680   "TARGET_80387 || TARGET_SSE_MATH"
7681   "")
7682 \f
7683 ;; Remainder instructions.
7684
7685 (define_expand "divmoddi4"
7686   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7687                    (div:DI (match_operand:DI 1 "register_operand" "")
7688                            (match_operand:DI 2 "nonimmediate_operand" "")))
7689               (set (match_operand:DI 3 "register_operand" "")
7690                    (mod:DI (match_dup 1) (match_dup 2)))
7691               (clobber (reg:CC FLAGS_REG))])]
7692   "TARGET_64BIT"
7693   "")
7694
7695 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7696 ;; Penalize eax case slightly because it results in worse scheduling
7697 ;; of code.
7698 (define_insn "*divmoddi4_nocltd_rex64"
7699   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7700         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7701                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7702    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7703         (mod:DI (match_dup 2) (match_dup 3)))
7704    (clobber (reg:CC FLAGS_REG))]
7705   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7706   "#"
7707   [(set_attr "type" "multi")])
7708
7709 (define_insn "*divmoddi4_cltd_rex64"
7710   [(set (match_operand:DI 0 "register_operand" "=a")
7711         (div:DI (match_operand:DI 2 "register_operand" "a")
7712                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7713    (set (match_operand:DI 1 "register_operand" "=&d")
7714         (mod:DI (match_dup 2) (match_dup 3)))
7715    (clobber (reg:CC FLAGS_REG))]
7716   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7717   "#"
7718   [(set_attr "type" "multi")])
7719
7720 (define_insn "*divmoddi_noext_rex64"
7721   [(set (match_operand:DI 0 "register_operand" "=a")
7722         (div:DI (match_operand:DI 1 "register_operand" "0")
7723                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7724    (set (match_operand:DI 3 "register_operand" "=d")
7725         (mod:DI (match_dup 1) (match_dup 2)))
7726    (use (match_operand:DI 4 "register_operand" "3"))
7727    (clobber (reg:CC FLAGS_REG))]
7728   "TARGET_64BIT"
7729   "idiv{q}\t%2"
7730   [(set_attr "type" "idiv")
7731    (set_attr "mode" "DI")])
7732
7733 (define_split
7734   [(set (match_operand:DI 0 "register_operand" "")
7735         (div:DI (match_operand:DI 1 "register_operand" "")
7736                 (match_operand:DI 2 "nonimmediate_operand" "")))
7737    (set (match_operand:DI 3 "register_operand" "")
7738         (mod:DI (match_dup 1) (match_dup 2)))
7739    (clobber (reg:CC FLAGS_REG))]
7740   "TARGET_64BIT && reload_completed"
7741   [(parallel [(set (match_dup 3)
7742                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7743               (clobber (reg:CC FLAGS_REG))])
7744    (parallel [(set (match_dup 0)
7745                    (div:DI (reg:DI 0) (match_dup 2)))
7746               (set (match_dup 3)
7747                    (mod:DI (reg:DI 0) (match_dup 2)))
7748               (use (match_dup 3))
7749               (clobber (reg:CC FLAGS_REG))])]
7750 {
7751   /* Avoid use of cltd in favor of a mov+shift.  */
7752   if (!TARGET_USE_CLTD && !optimize_size)
7753     {
7754       if (true_regnum (operands[1]))
7755         emit_move_insn (operands[0], operands[1]);
7756       else
7757         emit_move_insn (operands[3], operands[1]);
7758       operands[4] = operands[3];
7759     }
7760   else
7761     {
7762       gcc_assert (!true_regnum (operands[1]));
7763       operands[4] = operands[1];
7764     }
7765 })
7766
7767
7768 (define_expand "divmodsi4"
7769   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7770                    (div:SI (match_operand:SI 1 "register_operand" "")
7771                            (match_operand:SI 2 "nonimmediate_operand" "")))
7772               (set (match_operand:SI 3 "register_operand" "")
7773                    (mod:SI (match_dup 1) (match_dup 2)))
7774               (clobber (reg:CC FLAGS_REG))])]
7775   ""
7776   "")
7777
7778 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7779 ;; Penalize eax case slightly because it results in worse scheduling
7780 ;; of code.
7781 (define_insn "*divmodsi4_nocltd"
7782   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7783         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7784                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7785    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7786         (mod:SI (match_dup 2) (match_dup 3)))
7787    (clobber (reg:CC FLAGS_REG))]
7788   "!optimize_size && !TARGET_USE_CLTD"
7789   "#"
7790   [(set_attr "type" "multi")])
7791
7792 (define_insn "*divmodsi4_cltd"
7793   [(set (match_operand:SI 0 "register_operand" "=a")
7794         (div:SI (match_operand:SI 2 "register_operand" "a")
7795                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7796    (set (match_operand:SI 1 "register_operand" "=&d")
7797         (mod:SI (match_dup 2) (match_dup 3)))
7798    (clobber (reg:CC FLAGS_REG))]
7799   "optimize_size || TARGET_USE_CLTD"
7800   "#"
7801   [(set_attr "type" "multi")])
7802
7803 (define_insn "*divmodsi_noext"
7804   [(set (match_operand:SI 0 "register_operand" "=a")
7805         (div:SI (match_operand:SI 1 "register_operand" "0")
7806                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7807    (set (match_operand:SI 3 "register_operand" "=d")
7808         (mod:SI (match_dup 1) (match_dup 2)))
7809    (use (match_operand:SI 4 "register_operand" "3"))
7810    (clobber (reg:CC FLAGS_REG))]
7811   ""
7812   "idiv{l}\t%2"
7813   [(set_attr "type" "idiv")
7814    (set_attr "mode" "SI")])
7815
7816 (define_split
7817   [(set (match_operand:SI 0 "register_operand" "")
7818         (div:SI (match_operand:SI 1 "register_operand" "")
7819                 (match_operand:SI 2 "nonimmediate_operand" "")))
7820    (set (match_operand:SI 3 "register_operand" "")
7821         (mod:SI (match_dup 1) (match_dup 2)))
7822    (clobber (reg:CC FLAGS_REG))]
7823   "reload_completed"
7824   [(parallel [(set (match_dup 3)
7825                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7826               (clobber (reg:CC FLAGS_REG))])
7827    (parallel [(set (match_dup 0)
7828                    (div:SI (reg:SI 0) (match_dup 2)))
7829               (set (match_dup 3)
7830                    (mod:SI (reg:SI 0) (match_dup 2)))
7831               (use (match_dup 3))
7832               (clobber (reg:CC FLAGS_REG))])]
7833 {
7834   /* Avoid use of cltd in favor of a mov+shift.  */
7835   if (!TARGET_USE_CLTD && !optimize_size)
7836     {
7837       if (true_regnum (operands[1]))
7838         emit_move_insn (operands[0], operands[1]);
7839       else
7840         emit_move_insn (operands[3], operands[1]);
7841       operands[4] = operands[3];
7842     }
7843   else
7844     {
7845       gcc_assert (!true_regnum (operands[1]));
7846       operands[4] = operands[1];
7847     }
7848 })
7849 ;; %%% Split me.
7850 (define_insn "divmodhi4"
7851   [(set (match_operand:HI 0 "register_operand" "=a")
7852         (div:HI (match_operand:HI 1 "register_operand" "0")
7853                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7854    (set (match_operand:HI 3 "register_operand" "=&d")
7855         (mod:HI (match_dup 1) (match_dup 2)))
7856    (clobber (reg:CC FLAGS_REG))]
7857   "TARGET_HIMODE_MATH"
7858   "cwtd\;idiv{w}\t%2"
7859   [(set_attr "type" "multi")
7860    (set_attr "length_immediate" "0")
7861    (set_attr "mode" "SI")])
7862
7863 (define_insn "udivmoddi4"
7864   [(set (match_operand:DI 0 "register_operand" "=a")
7865         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7866                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7867    (set (match_operand:DI 3 "register_operand" "=&d")
7868         (umod:DI (match_dup 1) (match_dup 2)))
7869    (clobber (reg:CC FLAGS_REG))]
7870   "TARGET_64BIT"
7871   "xor{q}\t%3, %3\;div{q}\t%2"
7872   [(set_attr "type" "multi")
7873    (set_attr "length_immediate" "0")
7874    (set_attr "mode" "DI")])
7875
7876 (define_insn "*udivmoddi4_noext"
7877   [(set (match_operand:DI 0 "register_operand" "=a")
7878         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7879                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7880    (set (match_operand:DI 3 "register_operand" "=d")
7881         (umod:DI (match_dup 1) (match_dup 2)))
7882    (use (match_dup 3))
7883    (clobber (reg:CC FLAGS_REG))]
7884   "TARGET_64BIT"
7885   "div{q}\t%2"
7886   [(set_attr "type" "idiv")
7887    (set_attr "mode" "DI")])
7888
7889 (define_split
7890   [(set (match_operand:DI 0 "register_operand" "")
7891         (udiv:DI (match_operand:DI 1 "register_operand" "")
7892                  (match_operand:DI 2 "nonimmediate_operand" "")))
7893    (set (match_operand:DI 3 "register_operand" "")
7894         (umod:DI (match_dup 1) (match_dup 2)))
7895    (clobber (reg:CC FLAGS_REG))]
7896   "TARGET_64BIT && reload_completed"
7897   [(set (match_dup 3) (const_int 0))
7898    (parallel [(set (match_dup 0)
7899                    (udiv:DI (match_dup 1) (match_dup 2)))
7900               (set (match_dup 3)
7901                    (umod:DI (match_dup 1) (match_dup 2)))
7902               (use (match_dup 3))
7903               (clobber (reg:CC FLAGS_REG))])]
7904   "")
7905
7906 (define_insn "udivmodsi4"
7907   [(set (match_operand:SI 0 "register_operand" "=a")
7908         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7909                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7910    (set (match_operand:SI 3 "register_operand" "=&d")
7911         (umod:SI (match_dup 1) (match_dup 2)))
7912    (clobber (reg:CC FLAGS_REG))]
7913   ""
7914   "xor{l}\t%3, %3\;div{l}\t%2"
7915   [(set_attr "type" "multi")
7916    (set_attr "length_immediate" "0")
7917    (set_attr "mode" "SI")])
7918
7919 (define_insn "*udivmodsi4_noext"
7920   [(set (match_operand:SI 0 "register_operand" "=a")
7921         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7922                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7923    (set (match_operand:SI 3 "register_operand" "=d")
7924         (umod:SI (match_dup 1) (match_dup 2)))
7925    (use (match_dup 3))
7926    (clobber (reg:CC FLAGS_REG))]
7927   ""
7928   "div{l}\t%2"
7929   [(set_attr "type" "idiv")
7930    (set_attr "mode" "SI")])
7931
7932 (define_split
7933   [(set (match_operand:SI 0 "register_operand" "")
7934         (udiv:SI (match_operand:SI 1 "register_operand" "")
7935                  (match_operand:SI 2 "nonimmediate_operand" "")))
7936    (set (match_operand:SI 3 "register_operand" "")
7937         (umod:SI (match_dup 1) (match_dup 2)))
7938    (clobber (reg:CC FLAGS_REG))]
7939   "reload_completed"
7940   [(set (match_dup 3) (const_int 0))
7941    (parallel [(set (match_dup 0)
7942                    (udiv:SI (match_dup 1) (match_dup 2)))
7943               (set (match_dup 3)
7944                    (umod:SI (match_dup 1) (match_dup 2)))
7945               (use (match_dup 3))
7946               (clobber (reg:CC FLAGS_REG))])]
7947   "")
7948
7949 (define_expand "udivmodhi4"
7950   [(set (match_dup 4) (const_int 0))
7951    (parallel [(set (match_operand:HI 0 "register_operand" "")
7952                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7953                             (match_operand:HI 2 "nonimmediate_operand" "")))
7954               (set (match_operand:HI 3 "register_operand" "")
7955                    (umod:HI (match_dup 1) (match_dup 2)))
7956               (use (match_dup 4))
7957               (clobber (reg:CC FLAGS_REG))])]
7958   "TARGET_HIMODE_MATH"
7959   "operands[4] = gen_reg_rtx (HImode);")
7960
7961 (define_insn "*udivmodhi_noext"
7962   [(set (match_operand:HI 0 "register_operand" "=a")
7963         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7964                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7965    (set (match_operand:HI 3 "register_operand" "=d")
7966         (umod:HI (match_dup 1) (match_dup 2)))
7967    (use (match_operand:HI 4 "register_operand" "3"))
7968    (clobber (reg:CC FLAGS_REG))]
7969   ""
7970   "div{w}\t%2"
7971   [(set_attr "type" "idiv")
7972    (set_attr "mode" "HI")])
7973
7974 ;; We cannot use div/idiv for double division, because it causes
7975 ;; "division by zero" on the overflow and that's not what we expect
7976 ;; from truncate.  Because true (non truncating) double division is
7977 ;; never generated, we can't create this insn anyway.
7978 ;
7979 ;(define_insn ""
7980 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7981 ;       (truncate:SI
7982 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7983 ;                  (zero_extend:DI
7984 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7985 ;   (set (match_operand:SI 3 "register_operand" "=d")
7986 ;       (truncate:SI
7987 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7988 ;   (clobber (reg:CC FLAGS_REG))]
7989 ;  ""
7990 ;  "div{l}\t{%2, %0|%0, %2}"
7991 ;  [(set_attr "type" "idiv")])
7992 \f
7993 ;;- Logical AND instructions
7994
7995 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7996 ;; Note that this excludes ah.
7997
7998 (define_insn "*testdi_1_rex64"
7999   [(set (reg FLAGS_REG)
8000         (compare
8001           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8002                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8003           (const_int 0)))]
8004   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8005    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8006   "@
8007    test{l}\t{%k1, %k0|%k0, %k1}
8008    test{l}\t{%k1, %k0|%k0, %k1}
8009    test{q}\t{%1, %0|%0, %1}
8010    test{q}\t{%1, %0|%0, %1}
8011    test{q}\t{%1, %0|%0, %1}"
8012   [(set_attr "type" "test")
8013    (set_attr "modrm" "0,1,0,1,1")
8014    (set_attr "mode" "SI,SI,DI,DI,DI")
8015    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8016
8017 (define_insn "testsi_1"
8018   [(set (reg FLAGS_REG)
8019         (compare
8020           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8021                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8022           (const_int 0)))]
8023   "ix86_match_ccmode (insn, CCNOmode)
8024    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8025   "test{l}\t{%1, %0|%0, %1}"
8026   [(set_attr "type" "test")
8027    (set_attr "modrm" "0,1,1")
8028    (set_attr "mode" "SI")
8029    (set_attr "pent_pair" "uv,np,uv")])
8030
8031 (define_expand "testsi_ccno_1"
8032   [(set (reg:CCNO FLAGS_REG)
8033         (compare:CCNO
8034           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8035                   (match_operand:SI 1 "nonmemory_operand" ""))
8036           (const_int 0)))]
8037   ""
8038   "")
8039
8040 (define_insn "*testhi_1"
8041   [(set (reg FLAGS_REG)
8042         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8043                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8044                  (const_int 0)))]
8045   "ix86_match_ccmode (insn, CCNOmode)
8046    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8047   "test{w}\t{%1, %0|%0, %1}"
8048   [(set_attr "type" "test")
8049    (set_attr "modrm" "0,1,1")
8050    (set_attr "mode" "HI")
8051    (set_attr "pent_pair" "uv,np,uv")])
8052
8053 (define_expand "testqi_ccz_1"
8054   [(set (reg:CCZ FLAGS_REG)
8055         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8056                              (match_operand:QI 1 "nonmemory_operand" ""))
8057                  (const_int 0)))]
8058   ""
8059   "")
8060
8061 (define_insn "*testqi_1_maybe_si"
8062   [(set (reg FLAGS_REG)
8063         (compare
8064           (and:QI
8065             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8066             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8067           (const_int 0)))]
8068    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8069     && ix86_match_ccmode (insn,
8070                          CONST_INT_P (operands[1])
8071                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8072 {
8073   if (which_alternative == 3)
8074     {
8075       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8076         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8077       return "test{l}\t{%1, %k0|%k0, %1}";
8078     }
8079   return "test{b}\t{%1, %0|%0, %1}";
8080 }
8081   [(set_attr "type" "test")
8082    (set_attr "modrm" "0,1,1,1")
8083    (set_attr "mode" "QI,QI,QI,SI")
8084    (set_attr "pent_pair" "uv,np,uv,np")])
8085
8086 (define_insn "*testqi_1"
8087   [(set (reg FLAGS_REG)
8088         (compare
8089           (and:QI
8090             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8091             (match_operand:QI 1 "general_operand" "n,n,qn"))
8092           (const_int 0)))]
8093   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8094    && ix86_match_ccmode (insn, CCNOmode)"
8095   "test{b}\t{%1, %0|%0, %1}"
8096   [(set_attr "type" "test")
8097    (set_attr "modrm" "0,1,1")
8098    (set_attr "mode" "QI")
8099    (set_attr "pent_pair" "uv,np,uv")])
8100
8101 (define_expand "testqi_ext_ccno_0"
8102   [(set (reg:CCNO FLAGS_REG)
8103         (compare:CCNO
8104           (and:SI
8105             (zero_extract:SI
8106               (match_operand 0 "ext_register_operand" "")
8107               (const_int 8)
8108               (const_int 8))
8109             (match_operand 1 "const_int_operand" ""))
8110           (const_int 0)))]
8111   ""
8112   "")
8113
8114 (define_insn "*testqi_ext_0"
8115   [(set (reg FLAGS_REG)
8116         (compare
8117           (and:SI
8118             (zero_extract:SI
8119               (match_operand 0 "ext_register_operand" "Q")
8120               (const_int 8)
8121               (const_int 8))
8122             (match_operand 1 "const_int_operand" "n"))
8123           (const_int 0)))]
8124   "ix86_match_ccmode (insn, CCNOmode)"
8125   "test{b}\t{%1, %h0|%h0, %1}"
8126   [(set_attr "type" "test")
8127    (set_attr "mode" "QI")
8128    (set_attr "length_immediate" "1")
8129    (set_attr "pent_pair" "np")])
8130
8131 (define_insn "*testqi_ext_1"
8132   [(set (reg FLAGS_REG)
8133         (compare
8134           (and:SI
8135             (zero_extract:SI
8136               (match_operand 0 "ext_register_operand" "Q")
8137               (const_int 8)
8138               (const_int 8))
8139             (zero_extend:SI
8140               (match_operand:QI 1 "general_operand" "Qm")))
8141           (const_int 0)))]
8142   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8143    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8144   "test{b}\t{%1, %h0|%h0, %1}"
8145   [(set_attr "type" "test")
8146    (set_attr "mode" "QI")])
8147
8148 (define_insn "*testqi_ext_1_rex64"
8149   [(set (reg FLAGS_REG)
8150         (compare
8151           (and:SI
8152             (zero_extract:SI
8153               (match_operand 0 "ext_register_operand" "Q")
8154               (const_int 8)
8155               (const_int 8))
8156             (zero_extend:SI
8157               (match_operand:QI 1 "register_operand" "Q")))
8158           (const_int 0)))]
8159   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8160   "test{b}\t{%1, %h0|%h0, %1}"
8161   [(set_attr "type" "test")
8162    (set_attr "mode" "QI")])
8163
8164 (define_insn "*testqi_ext_2"
8165   [(set (reg FLAGS_REG)
8166         (compare
8167           (and:SI
8168             (zero_extract:SI
8169               (match_operand 0 "ext_register_operand" "Q")
8170               (const_int 8)
8171               (const_int 8))
8172             (zero_extract:SI
8173               (match_operand 1 "ext_register_operand" "Q")
8174               (const_int 8)
8175               (const_int 8)))
8176           (const_int 0)))]
8177   "ix86_match_ccmode (insn, CCNOmode)"
8178   "test{b}\t{%h1, %h0|%h0, %h1}"
8179   [(set_attr "type" "test")
8180    (set_attr "mode" "QI")])
8181
8182 ;; Combine likes to form bit extractions for some tests.  Humor it.
8183 (define_insn "*testqi_ext_3"
8184   [(set (reg FLAGS_REG)
8185         (compare (zero_extract:SI
8186                    (match_operand 0 "nonimmediate_operand" "rm")
8187                    (match_operand:SI 1 "const_int_operand" "")
8188                    (match_operand:SI 2 "const_int_operand" ""))
8189                  (const_int 0)))]
8190   "ix86_match_ccmode (insn, CCNOmode)
8191    && INTVAL (operands[1]) > 0
8192    && INTVAL (operands[2]) >= 0
8193    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8194    && (GET_MODE (operands[0]) == SImode
8195        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8196        || GET_MODE (operands[0]) == HImode
8197        || GET_MODE (operands[0]) == QImode)"
8198   "#")
8199
8200 (define_insn "*testqi_ext_3_rex64"
8201   [(set (reg FLAGS_REG)
8202         (compare (zero_extract:DI
8203                    (match_operand 0 "nonimmediate_operand" "rm")
8204                    (match_operand:DI 1 "const_int_operand" "")
8205                    (match_operand:DI 2 "const_int_operand" ""))
8206                  (const_int 0)))]
8207   "TARGET_64BIT
8208    && ix86_match_ccmode (insn, CCNOmode)
8209    && INTVAL (operands[1]) > 0
8210    && INTVAL (operands[2]) >= 0
8211    /* Ensure that resulting mask is zero or sign extended operand.  */
8212    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8213        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8214            && INTVAL (operands[1]) > 32))
8215    && (GET_MODE (operands[0]) == SImode
8216        || GET_MODE (operands[0]) == DImode
8217        || GET_MODE (operands[0]) == HImode
8218        || GET_MODE (operands[0]) == QImode)"
8219   "#")
8220
8221 (define_split
8222   [(set (match_operand 0 "flags_reg_operand" "")
8223         (match_operator 1 "compare_operator"
8224           [(zero_extract
8225              (match_operand 2 "nonimmediate_operand" "")
8226              (match_operand 3 "const_int_operand" "")
8227              (match_operand 4 "const_int_operand" ""))
8228            (const_int 0)]))]
8229   "ix86_match_ccmode (insn, CCNOmode)"
8230   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8231 {
8232   rtx val = operands[2];
8233   HOST_WIDE_INT len = INTVAL (operands[3]);
8234   HOST_WIDE_INT pos = INTVAL (operands[4]);
8235   HOST_WIDE_INT mask;
8236   enum machine_mode mode, submode;
8237
8238   mode = GET_MODE (val);
8239   if (MEM_P (val))
8240     {
8241       /* ??? Combine likes to put non-volatile mem extractions in QImode
8242          no matter the size of the test.  So find a mode that works.  */
8243       if (! MEM_VOLATILE_P (val))
8244         {
8245           mode = smallest_mode_for_size (pos + len, MODE_INT);
8246           val = adjust_address (val, mode, 0);
8247         }
8248     }
8249   else if (GET_CODE (val) == SUBREG
8250            && (submode = GET_MODE (SUBREG_REG (val)),
8251                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8252            && pos + len <= GET_MODE_BITSIZE (submode))
8253     {
8254       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8255       mode = submode;
8256       val = SUBREG_REG (val);
8257     }
8258   else if (mode == HImode && pos + len <= 8)
8259     {
8260       /* Small HImode tests can be converted to QImode.  */
8261       mode = QImode;
8262       val = gen_lowpart (QImode, val);
8263     }
8264
8265   if (len == HOST_BITS_PER_WIDE_INT)
8266     mask = -1;
8267   else
8268     mask = ((HOST_WIDE_INT)1 << len) - 1;
8269   mask <<= pos;
8270
8271   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8272 })
8273
8274 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8275 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8276 ;; this is relatively important trick.
8277 ;; Do the conversion only post-reload to avoid limiting of the register class
8278 ;; to QI regs.
8279 (define_split
8280   [(set (match_operand 0 "flags_reg_operand" "")
8281         (match_operator 1 "compare_operator"
8282           [(and (match_operand 2 "register_operand" "")
8283                 (match_operand 3 "const_int_operand" ""))
8284            (const_int 0)]))]
8285    "reload_completed
8286     && QI_REG_P (operands[2])
8287     && GET_MODE (operands[2]) != QImode
8288     && ((ix86_match_ccmode (insn, CCZmode)
8289          && !(INTVAL (operands[3]) & ~(255 << 8)))
8290         || (ix86_match_ccmode (insn, CCNOmode)
8291             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8292   [(set (match_dup 0)
8293         (match_op_dup 1
8294           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8295                    (match_dup 3))
8296            (const_int 0)]))]
8297   "operands[2] = gen_lowpart (SImode, operands[2]);
8298    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8299
8300 (define_split
8301   [(set (match_operand 0 "flags_reg_operand" "")
8302         (match_operator 1 "compare_operator"
8303           [(and (match_operand 2 "nonimmediate_operand" "")
8304                 (match_operand 3 "const_int_operand" ""))
8305            (const_int 0)]))]
8306    "reload_completed
8307     && GET_MODE (operands[2]) != QImode
8308     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8309     && ((ix86_match_ccmode (insn, CCZmode)
8310          && !(INTVAL (operands[3]) & ~255))
8311         || (ix86_match_ccmode (insn, CCNOmode)
8312             && !(INTVAL (operands[3]) & ~127)))"
8313   [(set (match_dup 0)
8314         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8315                          (const_int 0)]))]
8316   "operands[2] = gen_lowpart (QImode, operands[2]);
8317    operands[3] = gen_lowpart (QImode, operands[3]);")
8318
8319
8320 ;; %%% This used to optimize known byte-wide and operations to memory,
8321 ;; and sometimes to QImode registers.  If this is considered useful,
8322 ;; it should be done with splitters.
8323
8324 (define_expand "anddi3"
8325   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8326         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8327                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8328    (clobber (reg:CC FLAGS_REG))]
8329   "TARGET_64BIT"
8330   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8331
8332 (define_insn "*anddi_1_rex64"
8333   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8334         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8335                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8336    (clobber (reg:CC FLAGS_REG))]
8337   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8338 {
8339   switch (get_attr_type (insn))
8340     {
8341     case TYPE_IMOVX:
8342       {
8343         enum machine_mode mode;
8344
8345         gcc_assert (CONST_INT_P (operands[2]));
8346         if (INTVAL (operands[2]) == 0xff)
8347           mode = QImode;
8348         else
8349           {
8350             gcc_assert (INTVAL (operands[2]) == 0xffff);
8351             mode = HImode;
8352           }
8353
8354         operands[1] = gen_lowpart (mode, operands[1]);
8355         if (mode == QImode)
8356           return "movz{bq|x}\t{%1,%0|%0, %1}";
8357         else
8358           return "movz{wq|x}\t{%1,%0|%0, %1}";
8359       }
8360
8361     default:
8362       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8363       if (get_attr_mode (insn) == MODE_SI)
8364         return "and{l}\t{%k2, %k0|%k0, %k2}";
8365       else
8366         return "and{q}\t{%2, %0|%0, %2}";
8367     }
8368 }
8369   [(set_attr "type" "alu,alu,alu,imovx")
8370    (set_attr "length_immediate" "*,*,*,0")
8371    (set_attr "mode" "SI,DI,DI,DI")])
8372
8373 (define_insn "*anddi_2"
8374   [(set (reg FLAGS_REG)
8375         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8376                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8377                  (const_int 0)))
8378    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8379         (and:DI (match_dup 1) (match_dup 2)))]
8380   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8381    && ix86_binary_operator_ok (AND, DImode, operands)"
8382   "@
8383    and{l}\t{%k2, %k0|%k0, %k2}
8384    and{q}\t{%2, %0|%0, %2}
8385    and{q}\t{%2, %0|%0, %2}"
8386   [(set_attr "type" "alu")
8387    (set_attr "mode" "SI,DI,DI")])
8388
8389 (define_expand "andsi3"
8390   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8391         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8392                 (match_operand:SI 2 "general_operand" "")))
8393    (clobber (reg:CC FLAGS_REG))]
8394   ""
8395   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8396
8397 (define_insn "*andsi_1"
8398   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8399         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8400                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8401    (clobber (reg:CC FLAGS_REG))]
8402   "ix86_binary_operator_ok (AND, SImode, operands)"
8403 {
8404   switch (get_attr_type (insn))
8405     {
8406     case TYPE_IMOVX:
8407       {
8408         enum machine_mode mode;
8409
8410         gcc_assert (CONST_INT_P (operands[2]));
8411         if (INTVAL (operands[2]) == 0xff)
8412           mode = QImode;
8413         else
8414           {
8415             gcc_assert (INTVAL (operands[2]) == 0xffff);
8416             mode = HImode;
8417           }
8418
8419         operands[1] = gen_lowpart (mode, operands[1]);
8420         if (mode == QImode)
8421           return "movz{bl|x}\t{%1,%0|%0, %1}";
8422         else
8423           return "movz{wl|x}\t{%1,%0|%0, %1}";
8424       }
8425
8426     default:
8427       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8428       return "and{l}\t{%2, %0|%0, %2}";
8429     }
8430 }
8431   [(set_attr "type" "alu,alu,imovx")
8432    (set_attr "length_immediate" "*,*,0")
8433    (set_attr "mode" "SI")])
8434
8435 (define_split
8436   [(set (match_operand 0 "register_operand" "")
8437         (and (match_dup 0)
8438              (const_int -65536)))
8439    (clobber (reg:CC FLAGS_REG))]
8440   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8441   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8442   "operands[1] = gen_lowpart (HImode, operands[0]);")
8443
8444 (define_split
8445   [(set (match_operand 0 "ext_register_operand" "")
8446         (and (match_dup 0)
8447              (const_int -256)))
8448    (clobber (reg:CC FLAGS_REG))]
8449   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8450   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8451   "operands[1] = gen_lowpart (QImode, operands[0]);")
8452
8453 (define_split
8454   [(set (match_operand 0 "ext_register_operand" "")
8455         (and (match_dup 0)
8456              (const_int -65281)))
8457    (clobber (reg:CC FLAGS_REG))]
8458   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8459   [(parallel [(set (zero_extract:SI (match_dup 0)
8460                                     (const_int 8)
8461                                     (const_int 8))
8462                    (xor:SI
8463                      (zero_extract:SI (match_dup 0)
8464                                       (const_int 8)
8465                                       (const_int 8))
8466                      (zero_extract:SI (match_dup 0)
8467                                       (const_int 8)
8468                                       (const_int 8))))
8469               (clobber (reg:CC FLAGS_REG))])]
8470   "operands[0] = gen_lowpart (SImode, operands[0]);")
8471
8472 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8473 (define_insn "*andsi_1_zext"
8474   [(set (match_operand:DI 0 "register_operand" "=r")
8475         (zero_extend:DI
8476           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8477                   (match_operand:SI 2 "general_operand" "rim"))))
8478    (clobber (reg:CC FLAGS_REG))]
8479   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8480   "and{l}\t{%2, %k0|%k0, %2}"
8481   [(set_attr "type" "alu")
8482    (set_attr "mode" "SI")])
8483
8484 (define_insn "*andsi_2"
8485   [(set (reg FLAGS_REG)
8486         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8487                          (match_operand:SI 2 "general_operand" "rim,ri"))
8488                  (const_int 0)))
8489    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8490         (and:SI (match_dup 1) (match_dup 2)))]
8491   "ix86_match_ccmode (insn, CCNOmode)
8492    && ix86_binary_operator_ok (AND, SImode, operands)"
8493   "and{l}\t{%2, %0|%0, %2}"
8494   [(set_attr "type" "alu")
8495    (set_attr "mode" "SI")])
8496
8497 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8498 (define_insn "*andsi_2_zext"
8499   [(set (reg FLAGS_REG)
8500         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8501                          (match_operand:SI 2 "general_operand" "rim"))
8502                  (const_int 0)))
8503    (set (match_operand:DI 0 "register_operand" "=r")
8504         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8505   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8506    && ix86_binary_operator_ok (AND, SImode, operands)"
8507   "and{l}\t{%2, %k0|%k0, %2}"
8508   [(set_attr "type" "alu")
8509    (set_attr "mode" "SI")])
8510
8511 (define_expand "andhi3"
8512   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8513         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8514                 (match_operand:HI 2 "general_operand" "")))
8515    (clobber (reg:CC FLAGS_REG))]
8516   "TARGET_HIMODE_MATH"
8517   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8518
8519 (define_insn "*andhi_1"
8520   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8521         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8522                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8523    (clobber (reg:CC FLAGS_REG))]
8524   "ix86_binary_operator_ok (AND, HImode, operands)"
8525 {
8526   switch (get_attr_type (insn))
8527     {
8528     case TYPE_IMOVX:
8529       gcc_assert (CONST_INT_P (operands[2]));
8530       gcc_assert (INTVAL (operands[2]) == 0xff);
8531       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8532
8533     default:
8534       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8535
8536       return "and{w}\t{%2, %0|%0, %2}";
8537     }
8538 }
8539   [(set_attr "type" "alu,alu,imovx")
8540    (set_attr "length_immediate" "*,*,0")
8541    (set_attr "mode" "HI,HI,SI")])
8542
8543 (define_insn "*andhi_2"
8544   [(set (reg FLAGS_REG)
8545         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8546                          (match_operand:HI 2 "general_operand" "rim,ri"))
8547                  (const_int 0)))
8548    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8549         (and:HI (match_dup 1) (match_dup 2)))]
8550   "ix86_match_ccmode (insn, CCNOmode)
8551    && ix86_binary_operator_ok (AND, HImode, operands)"
8552   "and{w}\t{%2, %0|%0, %2}"
8553   [(set_attr "type" "alu")
8554    (set_attr "mode" "HI")])
8555
8556 (define_expand "andqi3"
8557   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8558         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8559                 (match_operand:QI 2 "general_operand" "")))
8560    (clobber (reg:CC FLAGS_REG))]
8561   "TARGET_QIMODE_MATH"
8562   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8563
8564 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8565 (define_insn "*andqi_1"
8566   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8567         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8568                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8569    (clobber (reg:CC FLAGS_REG))]
8570   "ix86_binary_operator_ok (AND, QImode, operands)"
8571   "@
8572    and{b}\t{%2, %0|%0, %2}
8573    and{b}\t{%2, %0|%0, %2}
8574    and{l}\t{%k2, %k0|%k0, %k2}"
8575   [(set_attr "type" "alu")
8576    (set_attr "mode" "QI,QI,SI")])
8577
8578 (define_insn "*andqi_1_slp"
8579   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8580         (and:QI (match_dup 0)
8581                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8582    (clobber (reg:CC FLAGS_REG))]
8583   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8584    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8585   "and{b}\t{%1, %0|%0, %1}"
8586   [(set_attr "type" "alu1")
8587    (set_attr "mode" "QI")])
8588
8589 (define_insn "*andqi_2_maybe_si"
8590   [(set (reg FLAGS_REG)
8591         (compare (and:QI
8592                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8593                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8594                  (const_int 0)))
8595    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8596         (and:QI (match_dup 1) (match_dup 2)))]
8597   "ix86_binary_operator_ok (AND, QImode, operands)
8598    && ix86_match_ccmode (insn,
8599                          CONST_INT_P (operands[2])
8600                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8601 {
8602   if (which_alternative == 2)
8603     {
8604       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8605         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8606       return "and{l}\t{%2, %k0|%k0, %2}";
8607     }
8608   return "and{b}\t{%2, %0|%0, %2}";
8609 }
8610   [(set_attr "type" "alu")
8611    (set_attr "mode" "QI,QI,SI")])
8612
8613 (define_insn "*andqi_2"
8614   [(set (reg FLAGS_REG)
8615         (compare (and:QI
8616                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8617                    (match_operand:QI 2 "general_operand" "qim,qi"))
8618                  (const_int 0)))
8619    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8620         (and:QI (match_dup 1) (match_dup 2)))]
8621   "ix86_match_ccmode (insn, CCNOmode)
8622    && ix86_binary_operator_ok (AND, QImode, operands)"
8623   "and{b}\t{%2, %0|%0, %2}"
8624   [(set_attr "type" "alu")
8625    (set_attr "mode" "QI")])
8626
8627 (define_insn "*andqi_2_slp"
8628   [(set (reg FLAGS_REG)
8629         (compare (and:QI
8630                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8631                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8632                  (const_int 0)))
8633    (set (strict_low_part (match_dup 0))
8634         (and:QI (match_dup 0) (match_dup 1)))]
8635   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8636    && ix86_match_ccmode (insn, CCNOmode)
8637    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8638   "and{b}\t{%1, %0|%0, %1}"
8639   [(set_attr "type" "alu1")
8640    (set_attr "mode" "QI")])
8641
8642 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8643 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8644 ;; for a QImode operand, which of course failed.
8645
8646 (define_insn "andqi_ext_0"
8647   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8648                          (const_int 8)
8649                          (const_int 8))
8650         (and:SI
8651           (zero_extract:SI
8652             (match_operand 1 "ext_register_operand" "0")
8653             (const_int 8)
8654             (const_int 8))
8655           (match_operand 2 "const_int_operand" "n")))
8656    (clobber (reg:CC FLAGS_REG))]
8657   ""
8658   "and{b}\t{%2, %h0|%h0, %2}"
8659   [(set_attr "type" "alu")
8660    (set_attr "length_immediate" "1")
8661    (set_attr "mode" "QI")])
8662
8663 ;; Generated by peephole translating test to and.  This shows up
8664 ;; often in fp comparisons.
8665
8666 (define_insn "*andqi_ext_0_cc"
8667   [(set (reg FLAGS_REG)
8668         (compare
8669           (and:SI
8670             (zero_extract:SI
8671               (match_operand 1 "ext_register_operand" "0")
8672               (const_int 8)
8673               (const_int 8))
8674             (match_operand 2 "const_int_operand" "n"))
8675           (const_int 0)))
8676    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8677                          (const_int 8)
8678                          (const_int 8))
8679         (and:SI
8680           (zero_extract:SI
8681             (match_dup 1)
8682             (const_int 8)
8683             (const_int 8))
8684           (match_dup 2)))]
8685   "ix86_match_ccmode (insn, CCNOmode)"
8686   "and{b}\t{%2, %h0|%h0, %2}"
8687   [(set_attr "type" "alu")
8688    (set_attr "length_immediate" "1")
8689    (set_attr "mode" "QI")])
8690
8691 (define_insn "*andqi_ext_1"
8692   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8693                          (const_int 8)
8694                          (const_int 8))
8695         (and:SI
8696           (zero_extract:SI
8697             (match_operand 1 "ext_register_operand" "0")
8698             (const_int 8)
8699             (const_int 8))
8700           (zero_extend:SI
8701             (match_operand:QI 2 "general_operand" "Qm"))))
8702    (clobber (reg:CC FLAGS_REG))]
8703   "!TARGET_64BIT"
8704   "and{b}\t{%2, %h0|%h0, %2}"
8705   [(set_attr "type" "alu")
8706    (set_attr "length_immediate" "0")
8707    (set_attr "mode" "QI")])
8708
8709 (define_insn "*andqi_ext_1_rex64"
8710   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8711                          (const_int 8)
8712                          (const_int 8))
8713         (and:SI
8714           (zero_extract:SI
8715             (match_operand 1 "ext_register_operand" "0")
8716             (const_int 8)
8717             (const_int 8))
8718           (zero_extend:SI
8719             (match_operand 2 "ext_register_operand" "Q"))))
8720    (clobber (reg:CC FLAGS_REG))]
8721   "TARGET_64BIT"
8722   "and{b}\t{%2, %h0|%h0, %2}"
8723   [(set_attr "type" "alu")
8724    (set_attr "length_immediate" "0")
8725    (set_attr "mode" "QI")])
8726
8727 (define_insn "*andqi_ext_2"
8728   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8729                          (const_int 8)
8730                          (const_int 8))
8731         (and:SI
8732           (zero_extract:SI
8733             (match_operand 1 "ext_register_operand" "%0")
8734             (const_int 8)
8735             (const_int 8))
8736           (zero_extract:SI
8737             (match_operand 2 "ext_register_operand" "Q")
8738             (const_int 8)
8739             (const_int 8))))
8740    (clobber (reg:CC FLAGS_REG))]
8741   ""
8742   "and{b}\t{%h2, %h0|%h0, %h2}"
8743   [(set_attr "type" "alu")
8744    (set_attr "length_immediate" "0")
8745    (set_attr "mode" "QI")])
8746
8747 ;; Convert wide AND instructions with immediate operand to shorter QImode
8748 ;; equivalents when possible.
8749 ;; Don't do the splitting with memory operands, since it introduces risk
8750 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8751 ;; for size, but that can (should?) be handled by generic code instead.
8752 (define_split
8753   [(set (match_operand 0 "register_operand" "")
8754         (and (match_operand 1 "register_operand" "")
8755              (match_operand 2 "const_int_operand" "")))
8756    (clobber (reg:CC FLAGS_REG))]
8757    "reload_completed
8758     && QI_REG_P (operands[0])
8759     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8760     && !(~INTVAL (operands[2]) & ~(255 << 8))
8761     && GET_MODE (operands[0]) != QImode"
8762   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8763                    (and:SI (zero_extract:SI (match_dup 1)
8764                                             (const_int 8) (const_int 8))
8765                            (match_dup 2)))
8766               (clobber (reg:CC FLAGS_REG))])]
8767   "operands[0] = gen_lowpart (SImode, operands[0]);
8768    operands[1] = gen_lowpart (SImode, operands[1]);
8769    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8770
8771 ;; Since AND can be encoded with sign extended immediate, this is only
8772 ;; profitable when 7th bit is not set.
8773 (define_split
8774   [(set (match_operand 0 "register_operand" "")
8775         (and (match_operand 1 "general_operand" "")
8776              (match_operand 2 "const_int_operand" "")))
8777    (clobber (reg:CC FLAGS_REG))]
8778    "reload_completed
8779     && ANY_QI_REG_P (operands[0])
8780     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8781     && !(~INTVAL (operands[2]) & ~255)
8782     && !(INTVAL (operands[2]) & 128)
8783     && GET_MODE (operands[0]) != QImode"
8784   [(parallel [(set (strict_low_part (match_dup 0))
8785                    (and:QI (match_dup 1)
8786                            (match_dup 2)))
8787               (clobber (reg:CC FLAGS_REG))])]
8788   "operands[0] = gen_lowpart (QImode, operands[0]);
8789    operands[1] = gen_lowpart (QImode, operands[1]);
8790    operands[2] = gen_lowpart (QImode, operands[2]);")
8791 \f
8792 ;; Logical inclusive OR instructions
8793
8794 ;; %%% This used to optimize known byte-wide and operations to memory.
8795 ;; If this is considered useful, it should be done with splitters.
8796
8797 (define_expand "iordi3"
8798   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8799         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8800                 (match_operand:DI 2 "x86_64_general_operand" "")))
8801    (clobber (reg:CC FLAGS_REG))]
8802   "TARGET_64BIT"
8803   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8804
8805 (define_insn "*iordi_1_rex64"
8806   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8807         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8808                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8809    (clobber (reg:CC FLAGS_REG))]
8810   "TARGET_64BIT
8811    && ix86_binary_operator_ok (IOR, DImode, operands)"
8812   "or{q}\t{%2, %0|%0, %2}"
8813   [(set_attr "type" "alu")
8814    (set_attr "mode" "DI")])
8815
8816 (define_insn "*iordi_2_rex64"
8817   [(set (reg FLAGS_REG)
8818         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8819                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8820                  (const_int 0)))
8821    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8822         (ior:DI (match_dup 1) (match_dup 2)))]
8823   "TARGET_64BIT
8824    && ix86_match_ccmode (insn, CCNOmode)
8825    && ix86_binary_operator_ok (IOR, DImode, operands)"
8826   "or{q}\t{%2, %0|%0, %2}"
8827   [(set_attr "type" "alu")
8828    (set_attr "mode" "DI")])
8829
8830 (define_insn "*iordi_3_rex64"
8831   [(set (reg FLAGS_REG)
8832         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8833                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8834                  (const_int 0)))
8835    (clobber (match_scratch:DI 0 "=r"))]
8836   "TARGET_64BIT
8837    && ix86_match_ccmode (insn, CCNOmode)
8838    && ix86_binary_operator_ok (IOR, DImode, operands)"
8839   "or{q}\t{%2, %0|%0, %2}"
8840   [(set_attr "type" "alu")
8841    (set_attr "mode" "DI")])
8842
8843
8844 (define_expand "iorsi3"
8845   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8846         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8847                 (match_operand:SI 2 "general_operand" "")))
8848    (clobber (reg:CC FLAGS_REG))]
8849   ""
8850   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8851
8852 (define_insn "*iorsi_1"
8853   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8854         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8855                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8856    (clobber (reg:CC FLAGS_REG))]
8857   "ix86_binary_operator_ok (IOR, SImode, operands)"
8858   "or{l}\t{%2, %0|%0, %2}"
8859   [(set_attr "type" "alu")
8860    (set_attr "mode" "SI")])
8861
8862 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8863 (define_insn "*iorsi_1_zext"
8864   [(set (match_operand:DI 0 "register_operand" "=rm")
8865         (zero_extend:DI
8866           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8867                   (match_operand:SI 2 "general_operand" "rim"))))
8868    (clobber (reg:CC FLAGS_REG))]
8869   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8870   "or{l}\t{%2, %k0|%k0, %2}"
8871   [(set_attr "type" "alu")
8872    (set_attr "mode" "SI")])
8873
8874 (define_insn "*iorsi_1_zext_imm"
8875   [(set (match_operand:DI 0 "register_operand" "=rm")
8876         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8877                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8878    (clobber (reg:CC FLAGS_REG))]
8879   "TARGET_64BIT"
8880   "or{l}\t{%2, %k0|%k0, %2}"
8881   [(set_attr "type" "alu")
8882    (set_attr "mode" "SI")])
8883
8884 (define_insn "*iorsi_2"
8885   [(set (reg FLAGS_REG)
8886         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8887                          (match_operand:SI 2 "general_operand" "rim,ri"))
8888                  (const_int 0)))
8889    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8890         (ior:SI (match_dup 1) (match_dup 2)))]
8891   "ix86_match_ccmode (insn, CCNOmode)
8892    && ix86_binary_operator_ok (IOR, SImode, operands)"
8893   "or{l}\t{%2, %0|%0, %2}"
8894   [(set_attr "type" "alu")
8895    (set_attr "mode" "SI")])
8896
8897 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8898 ;; ??? Special case for immediate operand is missing - it is tricky.
8899 (define_insn "*iorsi_2_zext"
8900   [(set (reg FLAGS_REG)
8901         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8902                          (match_operand:SI 2 "general_operand" "rim"))
8903                  (const_int 0)))
8904    (set (match_operand:DI 0 "register_operand" "=r")
8905         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8906   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8907    && ix86_binary_operator_ok (IOR, SImode, operands)"
8908   "or{l}\t{%2, %k0|%k0, %2}"
8909   [(set_attr "type" "alu")
8910    (set_attr "mode" "SI")])
8911
8912 (define_insn "*iorsi_2_zext_imm"
8913   [(set (reg FLAGS_REG)
8914         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8915                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8916                  (const_int 0)))
8917    (set (match_operand:DI 0 "register_operand" "=r")
8918         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8919   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8920    && ix86_binary_operator_ok (IOR, SImode, operands)"
8921   "or{l}\t{%2, %k0|%k0, %2}"
8922   [(set_attr "type" "alu")
8923    (set_attr "mode" "SI")])
8924
8925 (define_insn "*iorsi_3"
8926   [(set (reg FLAGS_REG)
8927         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8928                          (match_operand:SI 2 "general_operand" "rim"))
8929                  (const_int 0)))
8930    (clobber (match_scratch:SI 0 "=r"))]
8931   "ix86_match_ccmode (insn, CCNOmode)
8932    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8933   "or{l}\t{%2, %0|%0, %2}"
8934   [(set_attr "type" "alu")
8935    (set_attr "mode" "SI")])
8936
8937 (define_expand "iorhi3"
8938   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8939         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8940                 (match_operand:HI 2 "general_operand" "")))
8941    (clobber (reg:CC FLAGS_REG))]
8942   "TARGET_HIMODE_MATH"
8943   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8944
8945 (define_insn "*iorhi_1"
8946   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8947         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8948                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8949    (clobber (reg:CC FLAGS_REG))]
8950   "ix86_binary_operator_ok (IOR, HImode, operands)"
8951   "or{w}\t{%2, %0|%0, %2}"
8952   [(set_attr "type" "alu")
8953    (set_attr "mode" "HI")])
8954
8955 (define_insn "*iorhi_2"
8956   [(set (reg FLAGS_REG)
8957         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8958                          (match_operand:HI 2 "general_operand" "rim,ri"))
8959                  (const_int 0)))
8960    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8961         (ior:HI (match_dup 1) (match_dup 2)))]
8962   "ix86_match_ccmode (insn, CCNOmode)
8963    && ix86_binary_operator_ok (IOR, HImode, operands)"
8964   "or{w}\t{%2, %0|%0, %2}"
8965   [(set_attr "type" "alu")
8966    (set_attr "mode" "HI")])
8967
8968 (define_insn "*iorhi_3"
8969   [(set (reg FLAGS_REG)
8970         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8971                          (match_operand:HI 2 "general_operand" "rim"))
8972                  (const_int 0)))
8973    (clobber (match_scratch:HI 0 "=r"))]
8974   "ix86_match_ccmode (insn, CCNOmode)
8975    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8976   "or{w}\t{%2, %0|%0, %2}"
8977   [(set_attr "type" "alu")
8978    (set_attr "mode" "HI")])
8979
8980 (define_expand "iorqi3"
8981   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8982         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8983                 (match_operand:QI 2 "general_operand" "")))
8984    (clobber (reg:CC FLAGS_REG))]
8985   "TARGET_QIMODE_MATH"
8986   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8987
8988 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8989 (define_insn "*iorqi_1"
8990   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8991         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8992                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8993    (clobber (reg:CC FLAGS_REG))]
8994   "ix86_binary_operator_ok (IOR, QImode, operands)"
8995   "@
8996    or{b}\t{%2, %0|%0, %2}
8997    or{b}\t{%2, %0|%0, %2}
8998    or{l}\t{%k2, %k0|%k0, %k2}"
8999   [(set_attr "type" "alu")
9000    (set_attr "mode" "QI,QI,SI")])
9001
9002 (define_insn "*iorqi_1_slp"
9003   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9004         (ior:QI (match_dup 0)
9005                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9006    (clobber (reg:CC FLAGS_REG))]
9007   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9008    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9009   "or{b}\t{%1, %0|%0, %1}"
9010   [(set_attr "type" "alu1")
9011    (set_attr "mode" "QI")])
9012
9013 (define_insn "*iorqi_2"
9014   [(set (reg FLAGS_REG)
9015         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9016                          (match_operand:QI 2 "general_operand" "qim,qi"))
9017                  (const_int 0)))
9018    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9019         (ior:QI (match_dup 1) (match_dup 2)))]
9020   "ix86_match_ccmode (insn, CCNOmode)
9021    && ix86_binary_operator_ok (IOR, QImode, operands)"
9022   "or{b}\t{%2, %0|%0, %2}"
9023   [(set_attr "type" "alu")
9024    (set_attr "mode" "QI")])
9025
9026 (define_insn "*iorqi_2_slp"
9027   [(set (reg FLAGS_REG)
9028         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9029                          (match_operand:QI 1 "general_operand" "qim,qi"))
9030                  (const_int 0)))
9031    (set (strict_low_part (match_dup 0))
9032         (ior:QI (match_dup 0) (match_dup 1)))]
9033   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9034    && ix86_match_ccmode (insn, CCNOmode)
9035    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9036   "or{b}\t{%1, %0|%0, %1}"
9037   [(set_attr "type" "alu1")
9038    (set_attr "mode" "QI")])
9039
9040 (define_insn "*iorqi_3"
9041   [(set (reg FLAGS_REG)
9042         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9043                          (match_operand:QI 2 "general_operand" "qim"))
9044                  (const_int 0)))
9045    (clobber (match_scratch:QI 0 "=q"))]
9046   "ix86_match_ccmode (insn, CCNOmode)
9047    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9048   "or{b}\t{%2, %0|%0, %2}"
9049   [(set_attr "type" "alu")
9050    (set_attr "mode" "QI")])
9051
9052 (define_insn "iorqi_ext_0"
9053   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9054                          (const_int 8)
9055                          (const_int 8))
9056         (ior:SI
9057           (zero_extract:SI
9058             (match_operand 1 "ext_register_operand" "0")
9059             (const_int 8)
9060             (const_int 8))
9061           (match_operand 2 "const_int_operand" "n")))
9062    (clobber (reg:CC FLAGS_REG))]
9063   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9064   "or{b}\t{%2, %h0|%h0, %2}"
9065   [(set_attr "type" "alu")
9066    (set_attr "length_immediate" "1")
9067    (set_attr "mode" "QI")])
9068
9069 (define_insn "*iorqi_ext_1"
9070   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9071                          (const_int 8)
9072                          (const_int 8))
9073         (ior:SI
9074           (zero_extract:SI
9075             (match_operand 1 "ext_register_operand" "0")
9076             (const_int 8)
9077             (const_int 8))
9078           (zero_extend:SI
9079             (match_operand:QI 2 "general_operand" "Qm"))))
9080    (clobber (reg:CC FLAGS_REG))]
9081   "!TARGET_64BIT
9082    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9083   "or{b}\t{%2, %h0|%h0, %2}"
9084   [(set_attr "type" "alu")
9085    (set_attr "length_immediate" "0")
9086    (set_attr "mode" "QI")])
9087
9088 (define_insn "*iorqi_ext_1_rex64"
9089   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9090                          (const_int 8)
9091                          (const_int 8))
9092         (ior:SI
9093           (zero_extract:SI
9094             (match_operand 1 "ext_register_operand" "0")
9095             (const_int 8)
9096             (const_int 8))
9097           (zero_extend:SI
9098             (match_operand 2 "ext_register_operand" "Q"))))
9099    (clobber (reg:CC FLAGS_REG))]
9100   "TARGET_64BIT
9101    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9102   "or{b}\t{%2, %h0|%h0, %2}"
9103   [(set_attr "type" "alu")
9104    (set_attr "length_immediate" "0")
9105    (set_attr "mode" "QI")])
9106
9107 (define_insn "*iorqi_ext_2"
9108   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9109                          (const_int 8)
9110                          (const_int 8))
9111         (ior:SI
9112           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9113                            (const_int 8)
9114                            (const_int 8))
9115           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9116                            (const_int 8)
9117                            (const_int 8))))
9118    (clobber (reg:CC FLAGS_REG))]
9119   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9120   "ior{b}\t{%h2, %h0|%h0, %h2}"
9121   [(set_attr "type" "alu")
9122    (set_attr "length_immediate" "0")
9123    (set_attr "mode" "QI")])
9124
9125 (define_split
9126   [(set (match_operand 0 "register_operand" "")
9127         (ior (match_operand 1 "register_operand" "")
9128              (match_operand 2 "const_int_operand" "")))
9129    (clobber (reg:CC FLAGS_REG))]
9130    "reload_completed
9131     && QI_REG_P (operands[0])
9132     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9133     && !(INTVAL (operands[2]) & ~(255 << 8))
9134     && GET_MODE (operands[0]) != QImode"
9135   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9136                    (ior:SI (zero_extract:SI (match_dup 1)
9137                                             (const_int 8) (const_int 8))
9138                            (match_dup 2)))
9139               (clobber (reg:CC FLAGS_REG))])]
9140   "operands[0] = gen_lowpart (SImode, operands[0]);
9141    operands[1] = gen_lowpart (SImode, operands[1]);
9142    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9143
9144 ;; Since OR can be encoded with sign extended immediate, this is only
9145 ;; profitable when 7th bit is set.
9146 (define_split
9147   [(set (match_operand 0 "register_operand" "")
9148         (ior (match_operand 1 "general_operand" "")
9149              (match_operand 2 "const_int_operand" "")))
9150    (clobber (reg:CC FLAGS_REG))]
9151    "reload_completed
9152     && ANY_QI_REG_P (operands[0])
9153     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9154     && !(INTVAL (operands[2]) & ~255)
9155     && (INTVAL (operands[2]) & 128)
9156     && GET_MODE (operands[0]) != QImode"
9157   [(parallel [(set (strict_low_part (match_dup 0))
9158                    (ior:QI (match_dup 1)
9159                            (match_dup 2)))
9160               (clobber (reg:CC FLAGS_REG))])]
9161   "operands[0] = gen_lowpart (QImode, operands[0]);
9162    operands[1] = gen_lowpart (QImode, operands[1]);
9163    operands[2] = gen_lowpart (QImode, operands[2]);")
9164 \f
9165 ;; Logical XOR instructions
9166
9167 ;; %%% This used to optimize known byte-wide and operations to memory.
9168 ;; If this is considered useful, it should be done with splitters.
9169
9170 (define_expand "xordi3"
9171   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9172         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9173                 (match_operand:DI 2 "x86_64_general_operand" "")))
9174    (clobber (reg:CC FLAGS_REG))]
9175   "TARGET_64BIT"
9176   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9177
9178 (define_insn "*xordi_1_rex64"
9179   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9180         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9181                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9182    (clobber (reg:CC FLAGS_REG))]
9183   "TARGET_64BIT
9184    && ix86_binary_operator_ok (XOR, DImode, operands)"
9185   "@
9186    xor{q}\t{%2, %0|%0, %2}
9187    xor{q}\t{%2, %0|%0, %2}"
9188   [(set_attr "type" "alu")
9189    (set_attr "mode" "DI,DI")])
9190
9191 (define_insn "*xordi_2_rex64"
9192   [(set (reg FLAGS_REG)
9193         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9194                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9195                  (const_int 0)))
9196    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9197         (xor:DI (match_dup 1) (match_dup 2)))]
9198   "TARGET_64BIT
9199    && ix86_match_ccmode (insn, CCNOmode)
9200    && ix86_binary_operator_ok (XOR, DImode, operands)"
9201   "@
9202    xor{q}\t{%2, %0|%0, %2}
9203    xor{q}\t{%2, %0|%0, %2}"
9204   [(set_attr "type" "alu")
9205    (set_attr "mode" "DI,DI")])
9206
9207 (define_insn "*xordi_3_rex64"
9208   [(set (reg FLAGS_REG)
9209         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9210                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9211                  (const_int 0)))
9212    (clobber (match_scratch:DI 0 "=r"))]
9213   "TARGET_64BIT
9214    && ix86_match_ccmode (insn, CCNOmode)
9215    && ix86_binary_operator_ok (XOR, DImode, operands)"
9216   "xor{q}\t{%2, %0|%0, %2}"
9217   [(set_attr "type" "alu")
9218    (set_attr "mode" "DI")])
9219
9220 (define_expand "xorsi3"
9221   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9222         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9223                 (match_operand:SI 2 "general_operand" "")))
9224    (clobber (reg:CC FLAGS_REG))]
9225   ""
9226   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9227
9228 (define_insn "*xorsi_1"
9229   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9230         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9231                 (match_operand:SI 2 "general_operand" "ri,rm")))
9232    (clobber (reg:CC FLAGS_REG))]
9233   "ix86_binary_operator_ok (XOR, SImode, operands)"
9234   "xor{l}\t{%2, %0|%0, %2}"
9235   [(set_attr "type" "alu")
9236    (set_attr "mode" "SI")])
9237
9238 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9239 ;; Add speccase for immediates
9240 (define_insn "*xorsi_1_zext"
9241   [(set (match_operand:DI 0 "register_operand" "=r")
9242         (zero_extend:DI
9243           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9244                   (match_operand:SI 2 "general_operand" "rim"))))
9245    (clobber (reg:CC FLAGS_REG))]
9246   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9247   "xor{l}\t{%2, %k0|%k0, %2}"
9248   [(set_attr "type" "alu")
9249    (set_attr "mode" "SI")])
9250
9251 (define_insn "*xorsi_1_zext_imm"
9252   [(set (match_operand:DI 0 "register_operand" "=r")
9253         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9254                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9255    (clobber (reg:CC FLAGS_REG))]
9256   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9257   "xor{l}\t{%2, %k0|%k0, %2}"
9258   [(set_attr "type" "alu")
9259    (set_attr "mode" "SI")])
9260
9261 (define_insn "*xorsi_2"
9262   [(set (reg FLAGS_REG)
9263         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9264                          (match_operand:SI 2 "general_operand" "rim,ri"))
9265                  (const_int 0)))
9266    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9267         (xor:SI (match_dup 1) (match_dup 2)))]
9268   "ix86_match_ccmode (insn, CCNOmode)
9269    && ix86_binary_operator_ok (XOR, SImode, operands)"
9270   "xor{l}\t{%2, %0|%0, %2}"
9271   [(set_attr "type" "alu")
9272    (set_attr "mode" "SI")])
9273
9274 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9275 ;; ??? Special case for immediate operand is missing - it is tricky.
9276 (define_insn "*xorsi_2_zext"
9277   [(set (reg FLAGS_REG)
9278         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9279                          (match_operand:SI 2 "general_operand" "rim"))
9280                  (const_int 0)))
9281    (set (match_operand:DI 0 "register_operand" "=r")
9282         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9283   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9284    && ix86_binary_operator_ok (XOR, SImode, operands)"
9285   "xor{l}\t{%2, %k0|%k0, %2}"
9286   [(set_attr "type" "alu")
9287    (set_attr "mode" "SI")])
9288
9289 (define_insn "*xorsi_2_zext_imm"
9290   [(set (reg FLAGS_REG)
9291         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9292                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9293                  (const_int 0)))
9294    (set (match_operand:DI 0 "register_operand" "=r")
9295         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9296   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9297    && ix86_binary_operator_ok (XOR, SImode, operands)"
9298   "xor{l}\t{%2, %k0|%k0, %2}"
9299   [(set_attr "type" "alu")
9300    (set_attr "mode" "SI")])
9301
9302 (define_insn "*xorsi_3"
9303   [(set (reg FLAGS_REG)
9304         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9305                          (match_operand:SI 2 "general_operand" "rim"))
9306                  (const_int 0)))
9307    (clobber (match_scratch:SI 0 "=r"))]
9308   "ix86_match_ccmode (insn, CCNOmode)
9309    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9310   "xor{l}\t{%2, %0|%0, %2}"
9311   [(set_attr "type" "alu")
9312    (set_attr "mode" "SI")])
9313
9314 (define_expand "xorhi3"
9315   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9316         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9317                 (match_operand:HI 2 "general_operand" "")))
9318    (clobber (reg:CC FLAGS_REG))]
9319   "TARGET_HIMODE_MATH"
9320   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9321
9322 (define_insn "*xorhi_1"
9323   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9324         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9325                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9326    (clobber (reg:CC FLAGS_REG))]
9327   "ix86_binary_operator_ok (XOR, HImode, operands)"
9328   "xor{w}\t{%2, %0|%0, %2}"
9329   [(set_attr "type" "alu")
9330    (set_attr "mode" "HI")])
9331
9332 (define_insn "*xorhi_2"
9333   [(set (reg FLAGS_REG)
9334         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9335                          (match_operand:HI 2 "general_operand" "rim,ri"))
9336                  (const_int 0)))
9337    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9338         (xor:HI (match_dup 1) (match_dup 2)))]
9339   "ix86_match_ccmode (insn, CCNOmode)
9340    && ix86_binary_operator_ok (XOR, HImode, operands)"
9341   "xor{w}\t{%2, %0|%0, %2}"
9342   [(set_attr "type" "alu")
9343    (set_attr "mode" "HI")])
9344
9345 (define_insn "*xorhi_3"
9346   [(set (reg FLAGS_REG)
9347         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9348                          (match_operand:HI 2 "general_operand" "rim"))
9349                  (const_int 0)))
9350    (clobber (match_scratch:HI 0 "=r"))]
9351   "ix86_match_ccmode (insn, CCNOmode)
9352    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9353   "xor{w}\t{%2, %0|%0, %2}"
9354   [(set_attr "type" "alu")
9355    (set_attr "mode" "HI")])
9356
9357 (define_expand "xorqi3"
9358   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9359         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9360                 (match_operand:QI 2 "general_operand" "")))
9361    (clobber (reg:CC FLAGS_REG))]
9362   "TARGET_QIMODE_MATH"
9363   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9364
9365 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9366 (define_insn "*xorqi_1"
9367   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9368         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9369                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9370    (clobber (reg:CC FLAGS_REG))]
9371   "ix86_binary_operator_ok (XOR, QImode, operands)"
9372   "@
9373    xor{b}\t{%2, %0|%0, %2}
9374    xor{b}\t{%2, %0|%0, %2}
9375    xor{l}\t{%k2, %k0|%k0, %k2}"
9376   [(set_attr "type" "alu")
9377    (set_attr "mode" "QI,QI,SI")])
9378
9379 (define_insn "*xorqi_1_slp"
9380   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9381         (xor:QI (match_dup 0)
9382                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9383    (clobber (reg:CC FLAGS_REG))]
9384   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9385    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9386   "xor{b}\t{%1, %0|%0, %1}"
9387   [(set_attr "type" "alu1")
9388    (set_attr "mode" "QI")])
9389
9390 (define_insn "xorqi_ext_0"
9391   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9392                          (const_int 8)
9393                          (const_int 8))
9394         (xor:SI
9395           (zero_extract:SI
9396             (match_operand 1 "ext_register_operand" "0")
9397             (const_int 8)
9398             (const_int 8))
9399           (match_operand 2 "const_int_operand" "n")))
9400    (clobber (reg:CC FLAGS_REG))]
9401   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9402   "xor{b}\t{%2, %h0|%h0, %2}"
9403   [(set_attr "type" "alu")
9404    (set_attr "length_immediate" "1")
9405    (set_attr "mode" "QI")])
9406
9407 (define_insn "*xorqi_ext_1"
9408   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9409                          (const_int 8)
9410                          (const_int 8))
9411         (xor:SI
9412           (zero_extract:SI
9413             (match_operand 1 "ext_register_operand" "0")
9414             (const_int 8)
9415             (const_int 8))
9416           (zero_extend:SI
9417             (match_operand:QI 2 "general_operand" "Qm"))))
9418    (clobber (reg:CC FLAGS_REG))]
9419   "!TARGET_64BIT
9420    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9421   "xor{b}\t{%2, %h0|%h0, %2}"
9422   [(set_attr "type" "alu")
9423    (set_attr "length_immediate" "0")
9424    (set_attr "mode" "QI")])
9425
9426 (define_insn "*xorqi_ext_1_rex64"
9427   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9428                          (const_int 8)
9429                          (const_int 8))
9430         (xor:SI
9431           (zero_extract:SI
9432             (match_operand 1 "ext_register_operand" "0")
9433             (const_int 8)
9434             (const_int 8))
9435           (zero_extend:SI
9436             (match_operand 2 "ext_register_operand" "Q"))))
9437    (clobber (reg:CC FLAGS_REG))]
9438   "TARGET_64BIT
9439    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9440   "xor{b}\t{%2, %h0|%h0, %2}"
9441   [(set_attr "type" "alu")
9442    (set_attr "length_immediate" "0")
9443    (set_attr "mode" "QI")])
9444
9445 (define_insn "*xorqi_ext_2"
9446   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9447                          (const_int 8)
9448                          (const_int 8))
9449         (xor:SI
9450           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9451                            (const_int 8)
9452                            (const_int 8))
9453           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9454                            (const_int 8)
9455                            (const_int 8))))
9456    (clobber (reg:CC FLAGS_REG))]
9457   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9458   "xor{b}\t{%h2, %h0|%h0, %h2}"
9459   [(set_attr "type" "alu")
9460    (set_attr "length_immediate" "0")
9461    (set_attr "mode" "QI")])
9462
9463 (define_insn "*xorqi_cc_1"
9464   [(set (reg FLAGS_REG)
9465         (compare
9466           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9467                   (match_operand:QI 2 "general_operand" "qim,qi"))
9468           (const_int 0)))
9469    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9470         (xor:QI (match_dup 1) (match_dup 2)))]
9471   "ix86_match_ccmode (insn, CCNOmode)
9472    && ix86_binary_operator_ok (XOR, QImode, operands)"
9473   "xor{b}\t{%2, %0|%0, %2}"
9474   [(set_attr "type" "alu")
9475    (set_attr "mode" "QI")])
9476
9477 (define_insn "*xorqi_2_slp"
9478   [(set (reg FLAGS_REG)
9479         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9480                          (match_operand:QI 1 "general_operand" "qim,qi"))
9481                  (const_int 0)))
9482    (set (strict_low_part (match_dup 0))
9483         (xor:QI (match_dup 0) (match_dup 1)))]
9484   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9485    && ix86_match_ccmode (insn, CCNOmode)
9486    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9487   "xor{b}\t{%1, %0|%0, %1}"
9488   [(set_attr "type" "alu1")
9489    (set_attr "mode" "QI")])
9490
9491 (define_insn "*xorqi_cc_2"
9492   [(set (reg FLAGS_REG)
9493         (compare
9494           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9495                   (match_operand:QI 2 "general_operand" "qim"))
9496           (const_int 0)))
9497    (clobber (match_scratch:QI 0 "=q"))]
9498   "ix86_match_ccmode (insn, CCNOmode)
9499    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9500   "xor{b}\t{%2, %0|%0, %2}"
9501   [(set_attr "type" "alu")
9502    (set_attr "mode" "QI")])
9503
9504 (define_insn "*xorqi_cc_ext_1"
9505   [(set (reg FLAGS_REG)
9506         (compare
9507           (xor:SI
9508             (zero_extract:SI
9509               (match_operand 1 "ext_register_operand" "0")
9510               (const_int 8)
9511               (const_int 8))
9512             (match_operand:QI 2 "general_operand" "qmn"))
9513           (const_int 0)))
9514    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9515                          (const_int 8)
9516                          (const_int 8))
9517         (xor:SI
9518           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9519           (match_dup 2)))]
9520   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9521   "xor{b}\t{%2, %h0|%h0, %2}"
9522   [(set_attr "type" "alu")
9523    (set_attr "mode" "QI")])
9524
9525 (define_insn "*xorqi_cc_ext_1_rex64"
9526   [(set (reg FLAGS_REG)
9527         (compare
9528           (xor:SI
9529             (zero_extract:SI
9530               (match_operand 1 "ext_register_operand" "0")
9531               (const_int 8)
9532               (const_int 8))
9533             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9534           (const_int 0)))
9535    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9536                          (const_int 8)
9537                          (const_int 8))
9538         (xor:SI
9539           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9540           (match_dup 2)))]
9541   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9542   "xor{b}\t{%2, %h0|%h0, %2}"
9543   [(set_attr "type" "alu")
9544    (set_attr "mode" "QI")])
9545
9546 (define_expand "xorqi_cc_ext_1"
9547   [(parallel [
9548      (set (reg:CCNO FLAGS_REG)
9549           (compare:CCNO
9550             (xor:SI
9551               (zero_extract:SI
9552                 (match_operand 1 "ext_register_operand" "")
9553                 (const_int 8)
9554                 (const_int 8))
9555               (match_operand:QI 2 "general_operand" ""))
9556             (const_int 0)))
9557      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9558                            (const_int 8)
9559                            (const_int 8))
9560           (xor:SI
9561             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9562             (match_dup 2)))])]
9563   ""
9564   "")
9565
9566 (define_split
9567   [(set (match_operand 0 "register_operand" "")
9568         (xor (match_operand 1 "register_operand" "")
9569              (match_operand 2 "const_int_operand" "")))
9570    (clobber (reg:CC FLAGS_REG))]
9571    "reload_completed
9572     && QI_REG_P (operands[0])
9573     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9574     && !(INTVAL (operands[2]) & ~(255 << 8))
9575     && GET_MODE (operands[0]) != QImode"
9576   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9577                    (xor:SI (zero_extract:SI (match_dup 1)
9578                                             (const_int 8) (const_int 8))
9579                            (match_dup 2)))
9580               (clobber (reg:CC FLAGS_REG))])]
9581   "operands[0] = gen_lowpart (SImode, operands[0]);
9582    operands[1] = gen_lowpart (SImode, operands[1]);
9583    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9584
9585 ;; Since XOR can be encoded with sign extended immediate, this is only
9586 ;; profitable when 7th bit is set.
9587 (define_split
9588   [(set (match_operand 0 "register_operand" "")
9589         (xor (match_operand 1 "general_operand" "")
9590              (match_operand 2 "const_int_operand" "")))
9591    (clobber (reg:CC FLAGS_REG))]
9592    "reload_completed
9593     && ANY_QI_REG_P (operands[0])
9594     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9595     && !(INTVAL (operands[2]) & ~255)
9596     && (INTVAL (operands[2]) & 128)
9597     && GET_MODE (operands[0]) != QImode"
9598   [(parallel [(set (strict_low_part (match_dup 0))
9599                    (xor:QI (match_dup 1)
9600                            (match_dup 2)))
9601               (clobber (reg:CC FLAGS_REG))])]
9602   "operands[0] = gen_lowpart (QImode, operands[0]);
9603    operands[1] = gen_lowpart (QImode, operands[1]);
9604    operands[2] = gen_lowpart (QImode, operands[2]);")
9605 \f
9606 ;; Negation instructions
9607
9608 (define_expand "negti2"
9609   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9610                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9611               (clobber (reg:CC FLAGS_REG))])]
9612   "TARGET_64BIT"
9613   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9614
9615 (define_insn "*negti2_1"
9616   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9617         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9618    (clobber (reg:CC FLAGS_REG))]
9619   "TARGET_64BIT
9620    && ix86_unary_operator_ok (NEG, TImode, operands)"
9621   "#")
9622
9623 (define_split
9624   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9625         (neg:TI (match_operand:TI 1 "general_operand" "")))
9626    (clobber (reg:CC FLAGS_REG))]
9627   "TARGET_64BIT && reload_completed"
9628   [(parallel
9629     [(set (reg:CCZ FLAGS_REG)
9630           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9631      (set (match_dup 0) (neg:DI (match_dup 2)))])
9632    (parallel
9633     [(set (match_dup 1)
9634           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9635                             (match_dup 3))
9636                    (const_int 0)))
9637      (clobber (reg:CC FLAGS_REG))])
9638    (parallel
9639     [(set (match_dup 1)
9640           (neg:DI (match_dup 1)))
9641      (clobber (reg:CC FLAGS_REG))])]
9642   "split_ti (operands+1, 1, operands+2, operands+3);
9643    split_ti (operands+0, 1, operands+0, operands+1);")
9644
9645 (define_expand "negdi2"
9646   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9647                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9648               (clobber (reg:CC FLAGS_REG))])]
9649   ""
9650   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9651
9652 (define_insn "*negdi2_1"
9653   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9654         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9655    (clobber (reg:CC FLAGS_REG))]
9656   "!TARGET_64BIT
9657    && ix86_unary_operator_ok (NEG, DImode, operands)"
9658   "#")
9659
9660 (define_split
9661   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9662         (neg:DI (match_operand:DI 1 "general_operand" "")))
9663    (clobber (reg:CC FLAGS_REG))]
9664   "!TARGET_64BIT && reload_completed"
9665   [(parallel
9666     [(set (reg:CCZ FLAGS_REG)
9667           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9668      (set (match_dup 0) (neg:SI (match_dup 2)))])
9669    (parallel
9670     [(set (match_dup 1)
9671           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9672                             (match_dup 3))
9673                    (const_int 0)))
9674      (clobber (reg:CC FLAGS_REG))])
9675    (parallel
9676     [(set (match_dup 1)
9677           (neg:SI (match_dup 1)))
9678      (clobber (reg:CC FLAGS_REG))])]
9679   "split_di (operands+1, 1, operands+2, operands+3);
9680    split_di (operands+0, 1, operands+0, operands+1);")
9681
9682 (define_insn "*negdi2_1_rex64"
9683   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9684         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9685    (clobber (reg:CC FLAGS_REG))]
9686   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9687   "neg{q}\t%0"
9688   [(set_attr "type" "negnot")
9689    (set_attr "mode" "DI")])
9690
9691 ;; The problem with neg is that it does not perform (compare x 0),
9692 ;; it really performs (compare 0 x), which leaves us with the zero
9693 ;; flag being the only useful item.
9694
9695 (define_insn "*negdi2_cmpz_rex64"
9696   [(set (reg:CCZ FLAGS_REG)
9697         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9698                      (const_int 0)))
9699    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9700         (neg:DI (match_dup 1)))]
9701   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9702   "neg{q}\t%0"
9703   [(set_attr "type" "negnot")
9704    (set_attr "mode" "DI")])
9705
9706
9707 (define_expand "negsi2"
9708   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9709                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9710               (clobber (reg:CC FLAGS_REG))])]
9711   ""
9712   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9713
9714 (define_insn "*negsi2_1"
9715   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9716         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9717    (clobber (reg:CC FLAGS_REG))]
9718   "ix86_unary_operator_ok (NEG, SImode, operands)"
9719   "neg{l}\t%0"
9720   [(set_attr "type" "negnot")
9721    (set_attr "mode" "SI")])
9722
9723 ;; Combine is quite creative about this pattern.
9724 (define_insn "*negsi2_1_zext"
9725   [(set (match_operand:DI 0 "register_operand" "=r")
9726         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9727                                         (const_int 32)))
9728                      (const_int 32)))
9729    (clobber (reg:CC FLAGS_REG))]
9730   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9731   "neg{l}\t%k0"
9732   [(set_attr "type" "negnot")
9733    (set_attr "mode" "SI")])
9734
9735 ;; The problem with neg is that it does not perform (compare x 0),
9736 ;; it really performs (compare 0 x), which leaves us with the zero
9737 ;; flag being the only useful item.
9738
9739 (define_insn "*negsi2_cmpz"
9740   [(set (reg:CCZ FLAGS_REG)
9741         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9742                      (const_int 0)))
9743    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9744         (neg:SI (match_dup 1)))]
9745   "ix86_unary_operator_ok (NEG, SImode, operands)"
9746   "neg{l}\t%0"
9747   [(set_attr "type" "negnot")
9748    (set_attr "mode" "SI")])
9749
9750 (define_insn "*negsi2_cmpz_zext"
9751   [(set (reg:CCZ FLAGS_REG)
9752         (compare:CCZ (lshiftrt:DI
9753                        (neg:DI (ashift:DI
9754                                  (match_operand:DI 1 "register_operand" "0")
9755                                  (const_int 32)))
9756                        (const_int 32))
9757                      (const_int 0)))
9758    (set (match_operand:DI 0 "register_operand" "=r")
9759         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9760                                         (const_int 32)))
9761                      (const_int 32)))]
9762   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9763   "neg{l}\t%k0"
9764   [(set_attr "type" "negnot")
9765    (set_attr "mode" "SI")])
9766
9767 (define_expand "neghi2"
9768   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9769                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9770               (clobber (reg:CC FLAGS_REG))])]
9771   "TARGET_HIMODE_MATH"
9772   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9773
9774 (define_insn "*neghi2_1"
9775   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9776         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9777    (clobber (reg:CC FLAGS_REG))]
9778   "ix86_unary_operator_ok (NEG, HImode, operands)"
9779   "neg{w}\t%0"
9780   [(set_attr "type" "negnot")
9781    (set_attr "mode" "HI")])
9782
9783 (define_insn "*neghi2_cmpz"
9784   [(set (reg:CCZ FLAGS_REG)
9785         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9786                      (const_int 0)))
9787    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9788         (neg:HI (match_dup 1)))]
9789   "ix86_unary_operator_ok (NEG, HImode, operands)"
9790   "neg{w}\t%0"
9791   [(set_attr "type" "negnot")
9792    (set_attr "mode" "HI")])
9793
9794 (define_expand "negqi2"
9795   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9796                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9797               (clobber (reg:CC FLAGS_REG))])]
9798   "TARGET_QIMODE_MATH"
9799   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9800
9801 (define_insn "*negqi2_1"
9802   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9803         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9804    (clobber (reg:CC FLAGS_REG))]
9805   "ix86_unary_operator_ok (NEG, QImode, operands)"
9806   "neg{b}\t%0"
9807   [(set_attr "type" "negnot")
9808    (set_attr "mode" "QI")])
9809
9810 (define_insn "*negqi2_cmpz"
9811   [(set (reg:CCZ FLAGS_REG)
9812         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9813                      (const_int 0)))
9814    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9815         (neg:QI (match_dup 1)))]
9816   "ix86_unary_operator_ok (NEG, QImode, operands)"
9817   "neg{b}\t%0"
9818   [(set_attr "type" "negnot")
9819    (set_attr "mode" "QI")])
9820
9821 ;; Changing of sign for FP values is doable using integer unit too.
9822
9823 (define_expand "negsf2"
9824   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9825         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9826   "TARGET_80387 || TARGET_SSE_MATH"
9827   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9828
9829 (define_expand "abssf2"
9830   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9831         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9832   "TARGET_80387 || TARGET_SSE_MATH"
9833   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9834
9835 (define_insn "*absnegsf2_mixed"
9836   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9837         (match_operator:SF 3 "absneg_operator"
9838           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9839    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9840    (clobber (reg:CC FLAGS_REG))]
9841   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9842    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9843   "#")
9844
9845 (define_insn "*absnegsf2_sse"
9846   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9847         (match_operator:SF 3 "absneg_operator"
9848           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9849    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9850    (clobber (reg:CC FLAGS_REG))]
9851   "TARGET_SSE_MATH
9852    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9853   "#")
9854
9855 (define_insn "*absnegsf2_i387"
9856   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9857         (match_operator:SF 3 "absneg_operator"
9858           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9859    (use (match_operand 2 "" ""))
9860    (clobber (reg:CC FLAGS_REG))]
9861   "TARGET_80387 && !TARGET_SSE_MATH
9862    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9863   "#")
9864
9865 (define_expand "copysignsf3"
9866   [(match_operand:SF 0 "register_operand" "")
9867    (match_operand:SF 1 "nonmemory_operand" "")
9868    (match_operand:SF 2 "register_operand" "")]
9869   "TARGET_SSE_MATH"
9870 {
9871   ix86_expand_copysign (operands);
9872   DONE;
9873 })
9874
9875 (define_insn_and_split "copysignsf3_const"
9876   [(set (match_operand:SF 0 "register_operand"          "=x")
9877         (unspec:SF
9878           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9879            (match_operand:SF 2 "register_operand"       "0")
9880            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9881           UNSPEC_COPYSIGN))]
9882   "TARGET_SSE_MATH"
9883   "#"
9884   "&& reload_completed"
9885   [(const_int 0)]
9886 {
9887   ix86_split_copysign_const (operands);
9888   DONE;
9889 })
9890
9891 (define_insn "copysignsf3_var"
9892   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9893         (unspec:SF
9894           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9895            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9896            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9897            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9898           UNSPEC_COPYSIGN))
9899    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9900   "TARGET_SSE_MATH"
9901   "#")
9902
9903 (define_split
9904   [(set (match_operand:SF 0 "register_operand" "")
9905         (unspec:SF
9906           [(match_operand:SF 2 "register_operand" "")
9907            (match_operand:SF 3 "register_operand" "")
9908            (match_operand:V4SF 4 "" "")
9909            (match_operand:V4SF 5 "" "")]
9910           UNSPEC_COPYSIGN))
9911    (clobber (match_scratch:V4SF 1 ""))]
9912   "TARGET_SSE_MATH && reload_completed"
9913   [(const_int 0)]
9914 {
9915   ix86_split_copysign_var (operands);
9916   DONE;
9917 })
9918
9919 (define_expand "negdf2"
9920   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9921         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9922   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9923   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9924
9925 (define_expand "absdf2"
9926   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9927         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9928   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9929   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9930
9931 (define_insn "*absnegdf2_mixed"
9932   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
9933         (match_operator:DF 3 "absneg_operator"
9934           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9935    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
9936    (clobber (reg:CC FLAGS_REG))]
9937   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9938    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9939   "#")
9940
9941 (define_insn "*absnegdf2_sse"
9942   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
9943         (match_operator:DF 3 "absneg_operator"
9944           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
9945    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
9946    (clobber (reg:CC FLAGS_REG))]
9947   "TARGET_SSE2 && TARGET_SSE_MATH
9948    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9949   "#")
9950
9951 (define_insn "*absnegdf2_i387"
9952   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9953         (match_operator:DF 3 "absneg_operator"
9954           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9955    (use (match_operand 2 "" ""))
9956    (clobber (reg:CC FLAGS_REG))]
9957   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9958    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9959   "#")
9960
9961 (define_expand "copysigndf3"
9962   [(match_operand:DF 0 "register_operand" "")
9963    (match_operand:DF 1 "nonmemory_operand" "")
9964    (match_operand:DF 2 "register_operand" "")]
9965   "TARGET_SSE2 && TARGET_SSE_MATH"
9966 {
9967   ix86_expand_copysign (operands);
9968   DONE;
9969 })
9970
9971 (define_insn_and_split "copysigndf3_const"
9972   [(set (match_operand:DF 0 "register_operand"          "=x")
9973         (unspec:DF
9974           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9975            (match_operand:DF 2 "register_operand"       "0")
9976            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9977           UNSPEC_COPYSIGN))]
9978   "TARGET_SSE2 && TARGET_SSE_MATH"
9979   "#"
9980   "&& reload_completed"
9981   [(const_int 0)]
9982 {
9983   ix86_split_copysign_const (operands);
9984   DONE;
9985 })
9986
9987 (define_insn "copysigndf3_var"
9988   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9989         (unspec:DF
9990           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9991            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9992            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9993            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9994           UNSPEC_COPYSIGN))
9995    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9996   "TARGET_SSE2 && TARGET_SSE_MATH"
9997   "#")
9998
9999 (define_split
10000   [(set (match_operand:DF 0 "register_operand" "")
10001         (unspec:DF
10002           [(match_operand:DF 2 "register_operand" "")
10003            (match_operand:DF 3 "register_operand" "")
10004            (match_operand:V2DF 4 "" "")
10005            (match_operand:V2DF 5 "" "")]
10006           UNSPEC_COPYSIGN))
10007    (clobber (match_scratch:V2DF 1 ""))]
10008   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10009   [(const_int 0)]
10010 {
10011   ix86_split_copysign_var (operands);
10012   DONE;
10013 })
10014
10015 (define_expand "negxf2"
10016   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10017         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10018   "TARGET_80387"
10019   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10020
10021 (define_expand "absxf2"
10022   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10023         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10024   "TARGET_80387"
10025   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10026
10027 (define_insn "*absnegxf2_i387"
10028   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10029         (match_operator:XF 3 "absneg_operator"
10030           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10031    (use (match_operand 2 "" ""))
10032    (clobber (reg:CC FLAGS_REG))]
10033   "TARGET_80387
10034    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10035   "#")
10036
10037 ;; Splitters for fp abs and neg.
10038
10039 (define_split
10040   [(set (match_operand 0 "fp_register_operand" "")
10041         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10042    (use (match_operand 2 "" ""))
10043    (clobber (reg:CC FLAGS_REG))]
10044   "reload_completed"
10045   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10046
10047 (define_split
10048   [(set (match_operand 0 "register_operand" "")
10049         (match_operator 3 "absneg_operator"
10050           [(match_operand 1 "register_operand" "")]))
10051    (use (match_operand 2 "nonimmediate_operand" ""))
10052    (clobber (reg:CC FLAGS_REG))]
10053   "reload_completed && SSE_REG_P (operands[0])"
10054   [(set (match_dup 0) (match_dup 3))]
10055 {
10056   enum machine_mode mode = GET_MODE (operands[0]);
10057   enum machine_mode vmode = GET_MODE (operands[2]);
10058   rtx tmp;
10059
10060   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10061   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10062   if (operands_match_p (operands[0], operands[2]))
10063     {
10064       tmp = operands[1];
10065       operands[1] = operands[2];
10066       operands[2] = tmp;
10067     }
10068   if (GET_CODE (operands[3]) == ABS)
10069     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10070   else
10071     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10072   operands[3] = tmp;
10073 })
10074
10075 (define_split
10076   [(set (match_operand:SF 0 "register_operand" "")
10077         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10078    (use (match_operand:V4SF 2 "" ""))
10079    (clobber (reg:CC FLAGS_REG))]
10080   "reload_completed"
10081   [(parallel [(set (match_dup 0) (match_dup 1))
10082               (clobber (reg:CC FLAGS_REG))])]
10083 {
10084   rtx tmp;
10085   operands[0] = gen_lowpart (SImode, operands[0]);
10086   if (GET_CODE (operands[1]) == ABS)
10087     {
10088       tmp = gen_int_mode (0x7fffffff, SImode);
10089       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10090     }
10091   else
10092     {
10093       tmp = gen_int_mode (0x80000000, SImode);
10094       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10095     }
10096   operands[1] = tmp;
10097 })
10098
10099 (define_split
10100   [(set (match_operand:DF 0 "register_operand" "")
10101         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10102    (use (match_operand 2 "" ""))
10103    (clobber (reg:CC FLAGS_REG))]
10104   "reload_completed"
10105   [(parallel [(set (match_dup 0) (match_dup 1))
10106               (clobber (reg:CC FLAGS_REG))])]
10107 {
10108   rtx tmp;
10109   if (TARGET_64BIT)
10110     {
10111       tmp = gen_lowpart (DImode, operands[0]);
10112       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10113       operands[0] = tmp;
10114
10115       if (GET_CODE (operands[1]) == ABS)
10116         tmp = const0_rtx;
10117       else
10118         tmp = gen_rtx_NOT (DImode, tmp);
10119     }
10120   else
10121     {
10122       operands[0] = gen_highpart (SImode, operands[0]);
10123       if (GET_CODE (operands[1]) == ABS)
10124         {
10125           tmp = gen_int_mode (0x7fffffff, SImode);
10126           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10127         }
10128       else
10129         {
10130           tmp = gen_int_mode (0x80000000, SImode);
10131           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10132         }
10133     }
10134   operands[1] = tmp;
10135 })
10136
10137 (define_split
10138   [(set (match_operand:XF 0 "register_operand" "")
10139         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10140    (use (match_operand 2 "" ""))
10141    (clobber (reg:CC FLAGS_REG))]
10142   "reload_completed"
10143   [(parallel [(set (match_dup 0) (match_dup 1))
10144               (clobber (reg:CC FLAGS_REG))])]
10145 {
10146   rtx tmp;
10147   operands[0] = gen_rtx_REG (SImode,
10148                              true_regnum (operands[0])
10149                              + (TARGET_64BIT ? 1 : 2));
10150   if (GET_CODE (operands[1]) == ABS)
10151     {
10152       tmp = GEN_INT (0x7fff);
10153       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10154     }
10155   else
10156     {
10157       tmp = GEN_INT (0x8000);
10158       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10159     }
10160   operands[1] = tmp;
10161 })
10162
10163 (define_split
10164   [(set (match_operand 0 "memory_operand" "")
10165         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10166    (use (match_operand 2 "" ""))
10167    (clobber (reg:CC FLAGS_REG))]
10168   "reload_completed"
10169   [(parallel [(set (match_dup 0) (match_dup 1))
10170               (clobber (reg:CC FLAGS_REG))])]
10171 {
10172   enum machine_mode mode = GET_MODE (operands[0]);
10173   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10174   rtx tmp;
10175
10176   operands[0] = adjust_address (operands[0], QImode, size - 1);
10177   if (GET_CODE (operands[1]) == ABS)
10178     {
10179       tmp = gen_int_mode (0x7f, QImode);
10180       tmp = gen_rtx_AND (QImode, operands[0], tmp);
10181     }
10182   else
10183     {
10184       tmp = gen_int_mode (0x80, QImode);
10185       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10186     }
10187   operands[1] = tmp;
10188 })
10189
10190 ;; Conditionalize these after reload. If they match before reload, we
10191 ;; lose the clobber and ability to use integer instructions.
10192
10193 (define_insn "*negsf2_1"
10194   [(set (match_operand:SF 0 "register_operand" "=f")
10195         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10196   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10197   "fchs"
10198   [(set_attr "type" "fsgn")
10199    (set_attr "mode" "SF")])
10200
10201 (define_insn "*negdf2_1"
10202   [(set (match_operand:DF 0 "register_operand" "=f")
10203         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10204   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10205   "fchs"
10206   [(set_attr "type" "fsgn")
10207    (set_attr "mode" "DF")])
10208
10209 (define_insn "*negxf2_1"
10210   [(set (match_operand:XF 0 "register_operand" "=f")
10211         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10212   "TARGET_80387"
10213   "fchs"
10214   [(set_attr "type" "fsgn")
10215    (set_attr "mode" "XF")])
10216
10217 (define_insn "*abssf2_1"
10218   [(set (match_operand:SF 0 "register_operand" "=f")
10219         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10220   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10221   "fabs"
10222   [(set_attr "type" "fsgn")
10223    (set_attr "mode" "SF")])
10224
10225 (define_insn "*absdf2_1"
10226   [(set (match_operand:DF 0 "register_operand" "=f")
10227         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10228   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10229   "fabs"
10230   [(set_attr "type" "fsgn")
10231    (set_attr "mode" "DF")])
10232
10233 (define_insn "*absxf2_1"
10234   [(set (match_operand:XF 0 "register_operand" "=f")
10235         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10236   "TARGET_80387"
10237   "fabs"
10238   [(set_attr "type" "fsgn")
10239    (set_attr "mode" "DF")])
10240
10241 (define_insn "*negextendsfdf2"
10242   [(set (match_operand:DF 0 "register_operand" "=f")
10243         (neg:DF (float_extend:DF
10244                   (match_operand:SF 1 "register_operand" "0"))))]
10245   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10246   "fchs"
10247   [(set_attr "type" "fsgn")
10248    (set_attr "mode" "DF")])
10249
10250 (define_insn "*negextenddfxf2"
10251   [(set (match_operand:XF 0 "register_operand" "=f")
10252         (neg:XF (float_extend:XF
10253                   (match_operand:DF 1 "register_operand" "0"))))]
10254   "TARGET_80387"
10255   "fchs"
10256   [(set_attr "type" "fsgn")
10257    (set_attr "mode" "XF")])
10258
10259 (define_insn "*negextendsfxf2"
10260   [(set (match_operand:XF 0 "register_operand" "=f")
10261         (neg:XF (float_extend:XF
10262                   (match_operand:SF 1 "register_operand" "0"))))]
10263   "TARGET_80387"
10264   "fchs"
10265   [(set_attr "type" "fsgn")
10266    (set_attr "mode" "XF")])
10267
10268 (define_insn "*absextendsfdf2"
10269   [(set (match_operand:DF 0 "register_operand" "=f")
10270         (abs:DF (float_extend:DF
10271                   (match_operand:SF 1 "register_operand" "0"))))]
10272   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10273   "fabs"
10274   [(set_attr "type" "fsgn")
10275    (set_attr "mode" "DF")])
10276
10277 (define_insn "*absextenddfxf2"
10278   [(set (match_operand:XF 0 "register_operand" "=f")
10279         (abs:XF (float_extend:XF
10280           (match_operand:DF 1 "register_operand" "0"))))]
10281   "TARGET_80387"
10282   "fabs"
10283   [(set_attr "type" "fsgn")
10284    (set_attr "mode" "XF")])
10285
10286 (define_insn "*absextendsfxf2"
10287   [(set (match_operand:XF 0 "register_operand" "=f")
10288         (abs:XF (float_extend:XF
10289           (match_operand:SF 1 "register_operand" "0"))))]
10290   "TARGET_80387"
10291   "fabs"
10292   [(set_attr "type" "fsgn")
10293    (set_attr "mode" "XF")])
10294 \f
10295 ;; One complement instructions
10296
10297 (define_expand "one_cmpldi2"
10298   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10299         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10300   "TARGET_64BIT"
10301   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10302
10303 (define_insn "*one_cmpldi2_1_rex64"
10304   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10305         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10306   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10307   "not{q}\t%0"
10308   [(set_attr "type" "negnot")
10309    (set_attr "mode" "DI")])
10310
10311 (define_insn "*one_cmpldi2_2_rex64"
10312   [(set (reg FLAGS_REG)
10313         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10314                  (const_int 0)))
10315    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10316         (not:DI (match_dup 1)))]
10317   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10318    && ix86_unary_operator_ok (NOT, DImode, operands)"
10319   "#"
10320   [(set_attr "type" "alu1")
10321    (set_attr "mode" "DI")])
10322
10323 (define_split
10324   [(set (match_operand 0 "flags_reg_operand" "")
10325         (match_operator 2 "compare_operator"
10326           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10327            (const_int 0)]))
10328    (set (match_operand:DI 1 "nonimmediate_operand" "")
10329         (not:DI (match_dup 3)))]
10330   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10331   [(parallel [(set (match_dup 0)
10332                    (match_op_dup 2
10333                      [(xor:DI (match_dup 3) (const_int -1))
10334                       (const_int 0)]))
10335               (set (match_dup 1)
10336                    (xor:DI (match_dup 3) (const_int -1)))])]
10337   "")
10338
10339 (define_expand "one_cmplsi2"
10340   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10341         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10342   ""
10343   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10344
10345 (define_insn "*one_cmplsi2_1"
10346   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10347         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10348   "ix86_unary_operator_ok (NOT, SImode, operands)"
10349   "not{l}\t%0"
10350   [(set_attr "type" "negnot")
10351    (set_attr "mode" "SI")])
10352
10353 ;; ??? Currently never generated - xor is used instead.
10354 (define_insn "*one_cmplsi2_1_zext"
10355   [(set (match_operand:DI 0 "register_operand" "=r")
10356         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10357   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10358   "not{l}\t%k0"
10359   [(set_attr "type" "negnot")
10360    (set_attr "mode" "SI")])
10361
10362 (define_insn "*one_cmplsi2_2"
10363   [(set (reg FLAGS_REG)
10364         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10365                  (const_int 0)))
10366    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10367         (not:SI (match_dup 1)))]
10368   "ix86_match_ccmode (insn, CCNOmode)
10369    && ix86_unary_operator_ok (NOT, SImode, operands)"
10370   "#"
10371   [(set_attr "type" "alu1")
10372    (set_attr "mode" "SI")])
10373
10374 (define_split
10375   [(set (match_operand 0 "flags_reg_operand" "")
10376         (match_operator 2 "compare_operator"
10377           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10378            (const_int 0)]))
10379    (set (match_operand:SI 1 "nonimmediate_operand" "")
10380         (not:SI (match_dup 3)))]
10381   "ix86_match_ccmode (insn, CCNOmode)"
10382   [(parallel [(set (match_dup 0)
10383                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10384                                     (const_int 0)]))
10385               (set (match_dup 1)
10386                    (xor:SI (match_dup 3) (const_int -1)))])]
10387   "")
10388
10389 ;; ??? Currently never generated - xor is used instead.
10390 (define_insn "*one_cmplsi2_2_zext"
10391   [(set (reg FLAGS_REG)
10392         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10393                  (const_int 0)))
10394    (set (match_operand:DI 0 "register_operand" "=r")
10395         (zero_extend:DI (not:SI (match_dup 1))))]
10396   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10397    && ix86_unary_operator_ok (NOT, SImode, operands)"
10398   "#"
10399   [(set_attr "type" "alu1")
10400    (set_attr "mode" "SI")])
10401
10402 (define_split
10403   [(set (match_operand 0 "flags_reg_operand" "")
10404         (match_operator 2 "compare_operator"
10405           [(not:SI (match_operand:SI 3 "register_operand" ""))
10406            (const_int 0)]))
10407    (set (match_operand:DI 1 "register_operand" "")
10408         (zero_extend:DI (not:SI (match_dup 3))))]
10409   "ix86_match_ccmode (insn, CCNOmode)"
10410   [(parallel [(set (match_dup 0)
10411                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10412                                     (const_int 0)]))
10413               (set (match_dup 1)
10414                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10415   "")
10416
10417 (define_expand "one_cmplhi2"
10418   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10419         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10420   "TARGET_HIMODE_MATH"
10421   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10422
10423 (define_insn "*one_cmplhi2_1"
10424   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10425         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10426   "ix86_unary_operator_ok (NOT, HImode, operands)"
10427   "not{w}\t%0"
10428   [(set_attr "type" "negnot")
10429    (set_attr "mode" "HI")])
10430
10431 (define_insn "*one_cmplhi2_2"
10432   [(set (reg FLAGS_REG)
10433         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10434                  (const_int 0)))
10435    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10436         (not:HI (match_dup 1)))]
10437   "ix86_match_ccmode (insn, CCNOmode)
10438    && ix86_unary_operator_ok (NEG, HImode, operands)"
10439   "#"
10440   [(set_attr "type" "alu1")
10441    (set_attr "mode" "HI")])
10442
10443 (define_split
10444   [(set (match_operand 0 "flags_reg_operand" "")
10445         (match_operator 2 "compare_operator"
10446           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10447            (const_int 0)]))
10448    (set (match_operand:HI 1 "nonimmediate_operand" "")
10449         (not:HI (match_dup 3)))]
10450   "ix86_match_ccmode (insn, CCNOmode)"
10451   [(parallel [(set (match_dup 0)
10452                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10453                                     (const_int 0)]))
10454               (set (match_dup 1)
10455                    (xor:HI (match_dup 3) (const_int -1)))])]
10456   "")
10457
10458 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10459 (define_expand "one_cmplqi2"
10460   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10461         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10462   "TARGET_QIMODE_MATH"
10463   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10464
10465 (define_insn "*one_cmplqi2_1"
10466   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10467         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10468   "ix86_unary_operator_ok (NOT, QImode, operands)"
10469   "@
10470    not{b}\t%0
10471    not{l}\t%k0"
10472   [(set_attr "type" "negnot")
10473    (set_attr "mode" "QI,SI")])
10474
10475 (define_insn "*one_cmplqi2_2"
10476   [(set (reg FLAGS_REG)
10477         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10478                  (const_int 0)))
10479    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10480         (not:QI (match_dup 1)))]
10481   "ix86_match_ccmode (insn, CCNOmode)
10482    && ix86_unary_operator_ok (NOT, QImode, operands)"
10483   "#"
10484   [(set_attr "type" "alu1")
10485    (set_attr "mode" "QI")])
10486
10487 (define_split
10488   [(set (match_operand 0 "flags_reg_operand" "")
10489         (match_operator 2 "compare_operator"
10490           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10491            (const_int 0)]))
10492    (set (match_operand:QI 1 "nonimmediate_operand" "")
10493         (not:QI (match_dup 3)))]
10494   "ix86_match_ccmode (insn, CCNOmode)"
10495   [(parallel [(set (match_dup 0)
10496                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10497                                     (const_int 0)]))
10498               (set (match_dup 1)
10499                    (xor:QI (match_dup 3) (const_int -1)))])]
10500   "")
10501 \f
10502 ;; Arithmetic shift instructions
10503
10504 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10505 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10506 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10507 ;; from the assembler input.
10508 ;;
10509 ;; This instruction shifts the target reg/mem as usual, but instead of
10510 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10511 ;; is a left shift double, bits are taken from the high order bits of
10512 ;; reg, else if the insn is a shift right double, bits are taken from the
10513 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10514 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10515 ;;
10516 ;; Since sh[lr]d does not change the `reg' operand, that is done
10517 ;; separately, making all shifts emit pairs of shift double and normal
10518 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10519 ;; support a 63 bit shift, each shift where the count is in a reg expands
10520 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10521 ;;
10522 ;; If the shift count is a constant, we need never emit more than one
10523 ;; shift pair, instead using moves and sign extension for counts greater
10524 ;; than 31.
10525
10526 (define_expand "ashlti3"
10527   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10528                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10529                               (match_operand:QI 2 "nonmemory_operand" "")))
10530               (clobber (reg:CC FLAGS_REG))])]
10531   "TARGET_64BIT"
10532 {
10533   if (! immediate_operand (operands[2], QImode))
10534     {
10535       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10536       DONE;
10537     }
10538   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10539   DONE;
10540 })
10541
10542 (define_insn "ashlti3_1"
10543   [(set (match_operand:TI 0 "register_operand" "=r")
10544         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10545                    (match_operand:QI 2 "register_operand" "c")))
10546    (clobber (match_scratch:DI 3 "=&r"))
10547    (clobber (reg:CC FLAGS_REG))]
10548   "TARGET_64BIT"
10549   "#"
10550   [(set_attr "type" "multi")])
10551
10552 (define_insn "*ashlti3_2"
10553   [(set (match_operand:TI 0 "register_operand" "=r")
10554         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10555                    (match_operand:QI 2 "immediate_operand" "O")))
10556    (clobber (reg:CC FLAGS_REG))]
10557   "TARGET_64BIT"
10558   "#"
10559   [(set_attr "type" "multi")])
10560
10561 (define_split
10562   [(set (match_operand:TI 0 "register_operand" "")
10563         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10564                    (match_operand:QI 2 "register_operand" "")))
10565    (clobber (match_scratch:DI 3 ""))
10566    (clobber (reg:CC FLAGS_REG))]
10567   "TARGET_64BIT && reload_completed"
10568   [(const_int 0)]
10569   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10570
10571 (define_split
10572   [(set (match_operand:TI 0 "register_operand" "")
10573         (ashift:TI (match_operand:TI 1 "register_operand" "")
10574                    (match_operand:QI 2 "immediate_operand" "")))
10575    (clobber (reg:CC FLAGS_REG))]
10576   "TARGET_64BIT && reload_completed"
10577   [(const_int 0)]
10578   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10579
10580 (define_insn "x86_64_shld"
10581   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10582         (ior:DI (ashift:DI (match_dup 0)
10583                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10584                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10585                   (minus:QI (const_int 64) (match_dup 2)))))
10586    (clobber (reg:CC FLAGS_REG))]
10587   "TARGET_64BIT"
10588   "@
10589    shld{q}\t{%2, %1, %0|%0, %1, %2}
10590    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10591   [(set_attr "type" "ishift")
10592    (set_attr "prefix_0f" "1")
10593    (set_attr "mode" "DI")
10594    (set_attr "athlon_decode" "vector")
10595    (set_attr "amdfam10_decode" "vector")])   
10596
10597 (define_expand "x86_64_shift_adj"
10598   [(set (reg:CCZ FLAGS_REG)
10599         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10600                              (const_int 64))
10601                      (const_int 0)))
10602    (set (match_operand:DI 0 "register_operand" "")
10603         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10604                          (match_operand:DI 1 "register_operand" "")
10605                          (match_dup 0)))
10606    (set (match_dup 1)
10607         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10608                          (match_operand:DI 3 "register_operand" "r")
10609                          (match_dup 1)))]
10610   "TARGET_64BIT"
10611   "")
10612
10613 (define_expand "ashldi3"
10614   [(set (match_operand:DI 0 "shiftdi_operand" "")
10615         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10616                    (match_operand:QI 2 "nonmemory_operand" "")))]
10617   ""
10618   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10619
10620 (define_insn "*ashldi3_1_rex64"
10621   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10622         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10623                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10624    (clobber (reg:CC FLAGS_REG))]
10625   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10626 {
10627   switch (get_attr_type (insn))
10628     {
10629     case TYPE_ALU:
10630       gcc_assert (operands[2] == const1_rtx);
10631       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10632       return "add{q}\t{%0, %0|%0, %0}";
10633
10634     case TYPE_LEA:
10635       gcc_assert (CONST_INT_P (operands[2]));
10636       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10637       operands[1] = gen_rtx_MULT (DImode, operands[1],
10638                                   GEN_INT (1 << INTVAL (operands[2])));
10639       return "lea{q}\t{%a1, %0|%0, %a1}";
10640
10641     default:
10642       if (REG_P (operands[2]))
10643         return "sal{q}\t{%b2, %0|%0, %b2}";
10644       else if (operands[2] == const1_rtx
10645                && (TARGET_SHIFT1 || optimize_size))
10646         return "sal{q}\t%0";
10647       else
10648         return "sal{q}\t{%2, %0|%0, %2}";
10649     }
10650 }
10651   [(set (attr "type")
10652      (cond [(eq_attr "alternative" "1")
10653               (const_string "lea")
10654             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10655                           (const_int 0))
10656                       (match_operand 0 "register_operand" ""))
10657                  (match_operand 2 "const1_operand" ""))
10658               (const_string "alu")
10659            ]
10660            (const_string "ishift")))
10661    (set_attr "mode" "DI")])
10662
10663 ;; Convert lea to the lea pattern to avoid flags dependency.
10664 (define_split
10665   [(set (match_operand:DI 0 "register_operand" "")
10666         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10667                    (match_operand:QI 2 "immediate_operand" "")))
10668    (clobber (reg:CC FLAGS_REG))]
10669   "TARGET_64BIT && reload_completed
10670    && true_regnum (operands[0]) != true_regnum (operands[1])"
10671   [(set (match_dup 0)
10672         (mult:DI (match_dup 1)
10673                  (match_dup 2)))]
10674   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10675
10676 ;; This pattern can't accept a variable shift count, since shifts by
10677 ;; zero don't affect the flags.  We assume that shifts by constant
10678 ;; zero are optimized away.
10679 (define_insn "*ashldi3_cmp_rex64"
10680   [(set (reg FLAGS_REG)
10681         (compare
10682           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10683                      (match_operand:QI 2 "immediate_operand" "e"))
10684           (const_int 0)))
10685    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10686         (ashift:DI (match_dup 1) (match_dup 2)))]
10687   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10688    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10689    && (optimize_size
10690        || !TARGET_PARTIAL_FLAG_REG_STALL
10691        || (operands[2] == const1_rtx
10692            && (TARGET_SHIFT1
10693                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10694 {
10695   switch (get_attr_type (insn))
10696     {
10697     case TYPE_ALU:
10698       gcc_assert (operands[2] == const1_rtx);
10699       return "add{q}\t{%0, %0|%0, %0}";
10700
10701     default:
10702       if (REG_P (operands[2]))
10703         return "sal{q}\t{%b2, %0|%0, %b2}";
10704       else if (operands[2] == const1_rtx
10705                && (TARGET_SHIFT1 || optimize_size))
10706         return "sal{q}\t%0";
10707       else
10708         return "sal{q}\t{%2, %0|%0, %2}";
10709     }
10710 }
10711   [(set (attr "type")
10712      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10713                           (const_int 0))
10714                       (match_operand 0 "register_operand" ""))
10715                  (match_operand 2 "const1_operand" ""))
10716               (const_string "alu")
10717            ]
10718            (const_string "ishift")))
10719    (set_attr "mode" "DI")])
10720
10721 (define_insn "*ashldi3_cconly_rex64"
10722   [(set (reg FLAGS_REG)
10723         (compare
10724           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10725                      (match_operand:QI 2 "immediate_operand" "e"))
10726           (const_int 0)))
10727    (clobber (match_scratch:DI 0 "=r"))]
10728   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10729    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10730    && (optimize_size
10731        || !TARGET_PARTIAL_FLAG_REG_STALL
10732        || (operands[2] == const1_rtx
10733            && (TARGET_SHIFT1
10734                || TARGET_DOUBLE_WITH_ADD)))"
10735 {
10736   switch (get_attr_type (insn))
10737     {
10738     case TYPE_ALU:
10739       gcc_assert (operands[2] == const1_rtx);
10740       return "add{q}\t{%0, %0|%0, %0}";
10741
10742     default:
10743       if (REG_P (operands[2]))
10744         return "sal{q}\t{%b2, %0|%0, %b2}";
10745       else if (operands[2] == const1_rtx
10746                && (TARGET_SHIFT1 || optimize_size))
10747         return "sal{q}\t%0";
10748       else
10749         return "sal{q}\t{%2, %0|%0, %2}";
10750     }
10751 }
10752   [(set (attr "type")
10753      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10754                           (const_int 0))
10755                       (match_operand 0 "register_operand" ""))
10756                  (match_operand 2 "const1_operand" ""))
10757               (const_string "alu")
10758            ]
10759            (const_string "ishift")))
10760    (set_attr "mode" "DI")])
10761
10762 (define_insn "*ashldi3_1"
10763   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10764         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10765                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10766    (clobber (reg:CC FLAGS_REG))]
10767   "!TARGET_64BIT"
10768   "#"
10769   [(set_attr "type" "multi")])
10770
10771 ;; By default we don't ask for a scratch register, because when DImode
10772 ;; values are manipulated, registers are already at a premium.  But if
10773 ;; we have one handy, we won't turn it away.
10774 (define_peephole2
10775   [(match_scratch:SI 3 "r")
10776    (parallel [(set (match_operand:DI 0 "register_operand" "")
10777                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10778                               (match_operand:QI 2 "nonmemory_operand" "")))
10779               (clobber (reg:CC FLAGS_REG))])
10780    (match_dup 3)]
10781   "!TARGET_64BIT && TARGET_CMOVE"
10782   [(const_int 0)]
10783   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10784
10785 (define_split
10786   [(set (match_operand:DI 0 "register_operand" "")
10787         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10788                    (match_operand:QI 2 "nonmemory_operand" "")))
10789    (clobber (reg:CC FLAGS_REG))]
10790   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10791                      ? flow2_completed : reload_completed)"
10792   [(const_int 0)]
10793   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10794
10795 (define_insn "x86_shld_1"
10796   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10797         (ior:SI (ashift:SI (match_dup 0)
10798                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10799                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10800                   (minus:QI (const_int 32) (match_dup 2)))))
10801    (clobber (reg:CC FLAGS_REG))]
10802   ""
10803   "@
10804    shld{l}\t{%2, %1, %0|%0, %1, %2}
10805    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10806   [(set_attr "type" "ishift")
10807    (set_attr "prefix_0f" "1")
10808    (set_attr "mode" "SI")
10809    (set_attr "pent_pair" "np")
10810    (set_attr "athlon_decode" "vector")
10811    (set_attr "amdfam10_decode" "vector")])   
10812
10813 (define_expand "x86_shift_adj_1"
10814   [(set (reg:CCZ FLAGS_REG)
10815         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10816                              (const_int 32))
10817                      (const_int 0)))
10818    (set (match_operand:SI 0 "register_operand" "")
10819         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10820                          (match_operand:SI 1 "register_operand" "")
10821                          (match_dup 0)))
10822    (set (match_dup 1)
10823         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10824                          (match_operand:SI 3 "register_operand" "r")
10825                          (match_dup 1)))]
10826   "TARGET_CMOVE"
10827   "")
10828
10829 (define_expand "x86_shift_adj_2"
10830   [(use (match_operand:SI 0 "register_operand" ""))
10831    (use (match_operand:SI 1 "register_operand" ""))
10832    (use (match_operand:QI 2 "register_operand" ""))]
10833   ""
10834 {
10835   rtx label = gen_label_rtx ();
10836   rtx tmp;
10837
10838   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10839
10840   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10841   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10842   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10843                               gen_rtx_LABEL_REF (VOIDmode, label),
10844                               pc_rtx);
10845   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10846   JUMP_LABEL (tmp) = label;
10847
10848   emit_move_insn (operands[0], operands[1]);
10849   ix86_expand_clear (operands[1]);
10850
10851   emit_label (label);
10852   LABEL_NUSES (label) = 1;
10853
10854   DONE;
10855 })
10856
10857 (define_expand "ashlsi3"
10858   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10859         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10860                    (match_operand:QI 2 "nonmemory_operand" "")))
10861    (clobber (reg:CC FLAGS_REG))]
10862   ""
10863   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10864
10865 (define_insn "*ashlsi3_1"
10866   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10867         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10868                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10869    (clobber (reg:CC FLAGS_REG))]
10870   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10871 {
10872   switch (get_attr_type (insn))
10873     {
10874     case TYPE_ALU:
10875       gcc_assert (operands[2] == const1_rtx);
10876       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10877       return "add{l}\t{%0, %0|%0, %0}";
10878
10879     case TYPE_LEA:
10880       return "#";
10881
10882     default:
10883       if (REG_P (operands[2]))
10884         return "sal{l}\t{%b2, %0|%0, %b2}";
10885       else if (operands[2] == const1_rtx
10886                && (TARGET_SHIFT1 || optimize_size))
10887         return "sal{l}\t%0";
10888       else
10889         return "sal{l}\t{%2, %0|%0, %2}";
10890     }
10891 }
10892   [(set (attr "type")
10893      (cond [(eq_attr "alternative" "1")
10894               (const_string "lea")
10895             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10896                           (const_int 0))
10897                       (match_operand 0 "register_operand" ""))
10898                  (match_operand 2 "const1_operand" ""))
10899               (const_string "alu")
10900            ]
10901            (const_string "ishift")))
10902    (set_attr "mode" "SI")])
10903
10904 ;; Convert lea to the lea pattern to avoid flags dependency.
10905 (define_split
10906   [(set (match_operand 0 "register_operand" "")
10907         (ashift (match_operand 1 "index_register_operand" "")
10908                 (match_operand:QI 2 "const_int_operand" "")))
10909    (clobber (reg:CC FLAGS_REG))]
10910   "reload_completed
10911    && true_regnum (operands[0]) != true_regnum (operands[1])
10912    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10913   [(const_int 0)]
10914 {
10915   rtx pat;
10916   enum machine_mode mode = GET_MODE (operands[0]);
10917
10918   if (GET_MODE_SIZE (mode) < 4)
10919     operands[0] = gen_lowpart (SImode, operands[0]);
10920   if (mode != Pmode)
10921     operands[1] = gen_lowpart (Pmode, operands[1]);
10922   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10923
10924   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10925   if (Pmode != SImode)
10926     pat = gen_rtx_SUBREG (SImode, pat, 0);
10927   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10928   DONE;
10929 })
10930
10931 ;; Rare case of shifting RSP is handled by generating move and shift
10932 (define_split
10933   [(set (match_operand 0 "register_operand" "")
10934         (ashift (match_operand 1 "register_operand" "")
10935                 (match_operand:QI 2 "const_int_operand" "")))
10936    (clobber (reg:CC FLAGS_REG))]
10937   "reload_completed
10938    && true_regnum (operands[0]) != true_regnum (operands[1])"
10939   [(const_int 0)]
10940 {
10941   rtx pat, clob;
10942   emit_move_insn (operands[0], operands[1]);
10943   pat = gen_rtx_SET (VOIDmode, operands[0],
10944                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10945                                      operands[0], operands[2]));
10946   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10947   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10948   DONE;
10949 })
10950
10951 (define_insn "*ashlsi3_1_zext"
10952   [(set (match_operand:DI 0 "register_operand" "=r,r")
10953         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10954                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10955    (clobber (reg:CC FLAGS_REG))]
10956   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10957 {
10958   switch (get_attr_type (insn))
10959     {
10960     case TYPE_ALU:
10961       gcc_assert (operands[2] == const1_rtx);
10962       return "add{l}\t{%k0, %k0|%k0, %k0}";
10963
10964     case TYPE_LEA:
10965       return "#";
10966
10967     default:
10968       if (REG_P (operands[2]))
10969         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10970       else if (operands[2] == const1_rtx
10971                && (TARGET_SHIFT1 || optimize_size))
10972         return "sal{l}\t%k0";
10973       else
10974         return "sal{l}\t{%2, %k0|%k0, %2}";
10975     }
10976 }
10977   [(set (attr "type")
10978      (cond [(eq_attr "alternative" "1")
10979               (const_string "lea")
10980             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10981                      (const_int 0))
10982                  (match_operand 2 "const1_operand" ""))
10983               (const_string "alu")
10984            ]
10985            (const_string "ishift")))
10986    (set_attr "mode" "SI")])
10987
10988 ;; Convert lea to the lea pattern to avoid flags dependency.
10989 (define_split
10990   [(set (match_operand:DI 0 "register_operand" "")
10991         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10992                                 (match_operand:QI 2 "const_int_operand" ""))))
10993    (clobber (reg:CC FLAGS_REG))]
10994   "TARGET_64BIT && reload_completed
10995    && true_regnum (operands[0]) != true_regnum (operands[1])"
10996   [(set (match_dup 0) (zero_extend:DI
10997                         (subreg:SI (mult:SI (match_dup 1)
10998                                             (match_dup 2)) 0)))]
10999 {
11000   operands[1] = gen_lowpart (Pmode, operands[1]);
11001   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11002 })
11003
11004 ;; This pattern can't accept a variable shift count, since shifts by
11005 ;; zero don't affect the flags.  We assume that shifts by constant
11006 ;; zero are optimized away.
11007 (define_insn "*ashlsi3_cmp"
11008   [(set (reg FLAGS_REG)
11009         (compare
11010           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11011                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11012           (const_int 0)))
11013    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11014         (ashift:SI (match_dup 1) (match_dup 2)))]
11015   "ix86_match_ccmode (insn, CCGOCmode)
11016    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11017    && (optimize_size
11018        || !TARGET_PARTIAL_FLAG_REG_STALL
11019        || (operands[2] == const1_rtx
11020            && (TARGET_SHIFT1
11021                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11022 {
11023   switch (get_attr_type (insn))
11024     {
11025     case TYPE_ALU:
11026       gcc_assert (operands[2] == const1_rtx);
11027       return "add{l}\t{%0, %0|%0, %0}";
11028
11029     default:
11030       if (REG_P (operands[2]))
11031         return "sal{l}\t{%b2, %0|%0, %b2}";
11032       else if (operands[2] == const1_rtx
11033                && (TARGET_SHIFT1 || optimize_size))
11034         return "sal{l}\t%0";
11035       else
11036         return "sal{l}\t{%2, %0|%0, %2}";
11037     }
11038 }
11039   [(set (attr "type")
11040      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11041                           (const_int 0))
11042                       (match_operand 0 "register_operand" ""))
11043                  (match_operand 2 "const1_operand" ""))
11044               (const_string "alu")
11045            ]
11046            (const_string "ishift")))
11047    (set_attr "mode" "SI")])
11048
11049 (define_insn "*ashlsi3_cconly"
11050   [(set (reg FLAGS_REG)
11051         (compare
11052           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11053                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11054           (const_int 0)))
11055    (clobber (match_scratch:SI 0 "=r"))]
11056   "ix86_match_ccmode (insn, CCGOCmode)
11057    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11058    && (optimize_size
11059        || !TARGET_PARTIAL_FLAG_REG_STALL
11060        || (operands[2] == const1_rtx
11061            && (TARGET_SHIFT1
11062                || TARGET_DOUBLE_WITH_ADD)))"
11063 {
11064   switch (get_attr_type (insn))
11065     {
11066     case TYPE_ALU:
11067       gcc_assert (operands[2] == const1_rtx);
11068       return "add{l}\t{%0, %0|%0, %0}";
11069
11070     default:
11071       if (REG_P (operands[2]))
11072         return "sal{l}\t{%b2, %0|%0, %b2}";
11073       else if (operands[2] == const1_rtx
11074                && (TARGET_SHIFT1 || optimize_size))
11075         return "sal{l}\t%0";
11076       else
11077         return "sal{l}\t{%2, %0|%0, %2}";
11078     }
11079 }
11080   [(set (attr "type")
11081      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11082                           (const_int 0))
11083                       (match_operand 0 "register_operand" ""))
11084                  (match_operand 2 "const1_operand" ""))
11085               (const_string "alu")
11086            ]
11087            (const_string "ishift")))
11088    (set_attr "mode" "SI")])
11089
11090 (define_insn "*ashlsi3_cmp_zext"
11091   [(set (reg FLAGS_REG)
11092         (compare
11093           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11094                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11095           (const_int 0)))
11096    (set (match_operand:DI 0 "register_operand" "=r")
11097         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11098   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11099    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11100    && (optimize_size
11101        || !TARGET_PARTIAL_FLAG_REG_STALL
11102        || (operands[2] == const1_rtx
11103            && (TARGET_SHIFT1
11104                || TARGET_DOUBLE_WITH_ADD)))"
11105 {
11106   switch (get_attr_type (insn))
11107     {
11108     case TYPE_ALU:
11109       gcc_assert (operands[2] == const1_rtx);
11110       return "add{l}\t{%k0, %k0|%k0, %k0}";
11111
11112     default:
11113       if (REG_P (operands[2]))
11114         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11115       else if (operands[2] == const1_rtx
11116                && (TARGET_SHIFT1 || optimize_size))
11117         return "sal{l}\t%k0";
11118       else
11119         return "sal{l}\t{%2, %k0|%k0, %2}";
11120     }
11121 }
11122   [(set (attr "type")
11123      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11124                      (const_int 0))
11125                  (match_operand 2 "const1_operand" ""))
11126               (const_string "alu")
11127            ]
11128            (const_string "ishift")))
11129    (set_attr "mode" "SI")])
11130
11131 (define_expand "ashlhi3"
11132   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11133         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11134                    (match_operand:QI 2 "nonmemory_operand" "")))
11135    (clobber (reg:CC FLAGS_REG))]
11136   "TARGET_HIMODE_MATH"
11137   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11138
11139 (define_insn "*ashlhi3_1_lea"
11140   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11141         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11142                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11143    (clobber (reg:CC FLAGS_REG))]
11144   "!TARGET_PARTIAL_REG_STALL
11145    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11146 {
11147   switch (get_attr_type (insn))
11148     {
11149     case TYPE_LEA:
11150       return "#";
11151     case TYPE_ALU:
11152       gcc_assert (operands[2] == const1_rtx);
11153       return "add{w}\t{%0, %0|%0, %0}";
11154
11155     default:
11156       if (REG_P (operands[2]))
11157         return "sal{w}\t{%b2, %0|%0, %b2}";
11158       else if (operands[2] == const1_rtx
11159                && (TARGET_SHIFT1 || optimize_size))
11160         return "sal{w}\t%0";
11161       else
11162         return "sal{w}\t{%2, %0|%0, %2}";
11163     }
11164 }
11165   [(set (attr "type")
11166      (cond [(eq_attr "alternative" "1")
11167               (const_string "lea")
11168             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11169                           (const_int 0))
11170                       (match_operand 0 "register_operand" ""))
11171                  (match_operand 2 "const1_operand" ""))
11172               (const_string "alu")
11173            ]
11174            (const_string "ishift")))
11175    (set_attr "mode" "HI,SI")])
11176
11177 (define_insn "*ashlhi3_1"
11178   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11179         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11180                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11181    (clobber (reg:CC FLAGS_REG))]
11182   "TARGET_PARTIAL_REG_STALL
11183    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11184 {
11185   switch (get_attr_type (insn))
11186     {
11187     case TYPE_ALU:
11188       gcc_assert (operands[2] == const1_rtx);
11189       return "add{w}\t{%0, %0|%0, %0}";
11190
11191     default:
11192       if (REG_P (operands[2]))
11193         return "sal{w}\t{%b2, %0|%0, %b2}";
11194       else if (operands[2] == const1_rtx
11195                && (TARGET_SHIFT1 || optimize_size))
11196         return "sal{w}\t%0";
11197       else
11198         return "sal{w}\t{%2, %0|%0, %2}";
11199     }
11200 }
11201   [(set (attr "type")
11202      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11203                           (const_int 0))
11204                       (match_operand 0 "register_operand" ""))
11205                  (match_operand 2 "const1_operand" ""))
11206               (const_string "alu")
11207            ]
11208            (const_string "ishift")))
11209    (set_attr "mode" "HI")])
11210
11211 ;; This pattern can't accept a variable shift count, since shifts by
11212 ;; zero don't affect the flags.  We assume that shifts by constant
11213 ;; zero are optimized away.
11214 (define_insn "*ashlhi3_cmp"
11215   [(set (reg FLAGS_REG)
11216         (compare
11217           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11218                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11219           (const_int 0)))
11220    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11221         (ashift:HI (match_dup 1) (match_dup 2)))]
11222   "ix86_match_ccmode (insn, CCGOCmode)
11223    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11224    && (optimize_size
11225        || !TARGET_PARTIAL_FLAG_REG_STALL
11226        || (operands[2] == const1_rtx
11227            && (TARGET_SHIFT1
11228                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11229 {
11230   switch (get_attr_type (insn))
11231     {
11232     case TYPE_ALU:
11233       gcc_assert (operands[2] == const1_rtx);
11234       return "add{w}\t{%0, %0|%0, %0}";
11235
11236     default:
11237       if (REG_P (operands[2]))
11238         return "sal{w}\t{%b2, %0|%0, %b2}";
11239       else if (operands[2] == const1_rtx
11240                && (TARGET_SHIFT1 || optimize_size))
11241         return "sal{w}\t%0";
11242       else
11243         return "sal{w}\t{%2, %0|%0, %2}";
11244     }
11245 }
11246   [(set (attr "type")
11247      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11248                           (const_int 0))
11249                       (match_operand 0 "register_operand" ""))
11250                  (match_operand 2 "const1_operand" ""))
11251               (const_string "alu")
11252            ]
11253            (const_string "ishift")))
11254    (set_attr "mode" "HI")])
11255
11256 (define_insn "*ashlhi3_cconly"
11257   [(set (reg FLAGS_REG)
11258         (compare
11259           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11260                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11261           (const_int 0)))
11262    (clobber (match_scratch:HI 0 "=r"))]
11263   "ix86_match_ccmode (insn, CCGOCmode)
11264    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11265    && (optimize_size
11266        || !TARGET_PARTIAL_FLAG_REG_STALL
11267        || (operands[2] == const1_rtx
11268            && (TARGET_SHIFT1
11269                || TARGET_DOUBLE_WITH_ADD)))"
11270 {
11271   switch (get_attr_type (insn))
11272     {
11273     case TYPE_ALU:
11274       gcc_assert (operands[2] == const1_rtx);
11275       return "add{w}\t{%0, %0|%0, %0}";
11276
11277     default:
11278       if (REG_P (operands[2]))
11279         return "sal{w}\t{%b2, %0|%0, %b2}";
11280       else if (operands[2] == const1_rtx
11281                && (TARGET_SHIFT1 || optimize_size))
11282         return "sal{w}\t%0";
11283       else
11284         return "sal{w}\t{%2, %0|%0, %2}";
11285     }
11286 }
11287   [(set (attr "type")
11288      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11289                           (const_int 0))
11290                       (match_operand 0 "register_operand" ""))
11291                  (match_operand 2 "const1_operand" ""))
11292               (const_string "alu")
11293            ]
11294            (const_string "ishift")))
11295    (set_attr "mode" "HI")])
11296
11297 (define_expand "ashlqi3"
11298   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11299         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11300                    (match_operand:QI 2 "nonmemory_operand" "")))
11301    (clobber (reg:CC FLAGS_REG))]
11302   "TARGET_QIMODE_MATH"
11303   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11304
11305 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11306
11307 (define_insn "*ashlqi3_1_lea"
11308   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11309         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11310                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11311    (clobber (reg:CC FLAGS_REG))]
11312   "!TARGET_PARTIAL_REG_STALL
11313    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11314 {
11315   switch (get_attr_type (insn))
11316     {
11317     case TYPE_LEA:
11318       return "#";
11319     case TYPE_ALU:
11320       gcc_assert (operands[2] == const1_rtx);
11321       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11322         return "add{l}\t{%k0, %k0|%k0, %k0}";
11323       else
11324         return "add{b}\t{%0, %0|%0, %0}";
11325
11326     default:
11327       if (REG_P (operands[2]))
11328         {
11329           if (get_attr_mode (insn) == MODE_SI)
11330             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11331           else
11332             return "sal{b}\t{%b2, %0|%0, %b2}";
11333         }
11334       else if (operands[2] == const1_rtx
11335                && (TARGET_SHIFT1 || optimize_size))
11336         {
11337           if (get_attr_mode (insn) == MODE_SI)
11338             return "sal{l}\t%0";
11339           else
11340             return "sal{b}\t%0";
11341         }
11342       else
11343         {
11344           if (get_attr_mode (insn) == MODE_SI)
11345             return "sal{l}\t{%2, %k0|%k0, %2}";
11346           else
11347             return "sal{b}\t{%2, %0|%0, %2}";
11348         }
11349     }
11350 }
11351   [(set (attr "type")
11352      (cond [(eq_attr "alternative" "2")
11353               (const_string "lea")
11354             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11355                           (const_int 0))
11356                       (match_operand 0 "register_operand" ""))
11357                  (match_operand 2 "const1_operand" ""))
11358               (const_string "alu")
11359            ]
11360            (const_string "ishift")))
11361    (set_attr "mode" "QI,SI,SI")])
11362
11363 (define_insn "*ashlqi3_1"
11364   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11365         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11366                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11367    (clobber (reg:CC FLAGS_REG))]
11368   "TARGET_PARTIAL_REG_STALL
11369    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11370 {
11371   switch (get_attr_type (insn))
11372     {
11373     case TYPE_ALU:
11374       gcc_assert (operands[2] == const1_rtx);
11375       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11376         return "add{l}\t{%k0, %k0|%k0, %k0}";
11377       else
11378         return "add{b}\t{%0, %0|%0, %0}";
11379
11380     default:
11381       if (REG_P (operands[2]))
11382         {
11383           if (get_attr_mode (insn) == MODE_SI)
11384             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11385           else
11386             return "sal{b}\t{%b2, %0|%0, %b2}";
11387         }
11388       else if (operands[2] == const1_rtx
11389                && (TARGET_SHIFT1 || optimize_size))
11390         {
11391           if (get_attr_mode (insn) == MODE_SI)
11392             return "sal{l}\t%0";
11393           else
11394             return "sal{b}\t%0";
11395         }
11396       else
11397         {
11398           if (get_attr_mode (insn) == MODE_SI)
11399             return "sal{l}\t{%2, %k0|%k0, %2}";
11400           else
11401             return "sal{b}\t{%2, %0|%0, %2}";
11402         }
11403     }
11404 }
11405   [(set (attr "type")
11406      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11407                           (const_int 0))
11408                       (match_operand 0 "register_operand" ""))
11409                  (match_operand 2 "const1_operand" ""))
11410               (const_string "alu")
11411            ]
11412            (const_string "ishift")))
11413    (set_attr "mode" "QI,SI")])
11414
11415 ;; This pattern can't accept a variable shift count, since shifts by
11416 ;; zero don't affect the flags.  We assume that shifts by constant
11417 ;; zero are optimized away.
11418 (define_insn "*ashlqi3_cmp"
11419   [(set (reg FLAGS_REG)
11420         (compare
11421           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11422                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11423           (const_int 0)))
11424    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11425         (ashift:QI (match_dup 1) (match_dup 2)))]
11426   "ix86_match_ccmode (insn, CCGOCmode)
11427    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11428    && (optimize_size
11429        || !TARGET_PARTIAL_FLAG_REG_STALL
11430        || (operands[2] == const1_rtx
11431            && (TARGET_SHIFT1
11432                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11433 {
11434   switch (get_attr_type (insn))
11435     {
11436     case TYPE_ALU:
11437       gcc_assert (operands[2] == const1_rtx);
11438       return "add{b}\t{%0, %0|%0, %0}";
11439
11440     default:
11441       if (REG_P (operands[2]))
11442         return "sal{b}\t{%b2, %0|%0, %b2}";
11443       else if (operands[2] == const1_rtx
11444                && (TARGET_SHIFT1 || optimize_size))
11445         return "sal{b}\t%0";
11446       else
11447         return "sal{b}\t{%2, %0|%0, %2}";
11448     }
11449 }
11450   [(set (attr "type")
11451      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11452                           (const_int 0))
11453                       (match_operand 0 "register_operand" ""))
11454                  (match_operand 2 "const1_operand" ""))
11455               (const_string "alu")
11456            ]
11457            (const_string "ishift")))
11458    (set_attr "mode" "QI")])
11459
11460 (define_insn "*ashlqi3_cconly"
11461   [(set (reg FLAGS_REG)
11462         (compare
11463           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11464                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11465           (const_int 0)))
11466    (clobber (match_scratch:QI 0 "=q"))]
11467   "ix86_match_ccmode (insn, CCGOCmode)
11468    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11469    && (optimize_size
11470        || !TARGET_PARTIAL_FLAG_REG_STALL
11471        || (operands[2] == const1_rtx
11472            && (TARGET_SHIFT1
11473                || TARGET_DOUBLE_WITH_ADD)))"
11474 {
11475   switch (get_attr_type (insn))
11476     {
11477     case TYPE_ALU:
11478       gcc_assert (operands[2] == const1_rtx);
11479       return "add{b}\t{%0, %0|%0, %0}";
11480
11481     default:
11482       if (REG_P (operands[2]))
11483         return "sal{b}\t{%b2, %0|%0, %b2}";
11484       else if (operands[2] == const1_rtx
11485                && (TARGET_SHIFT1 || optimize_size))
11486         return "sal{b}\t%0";
11487       else
11488         return "sal{b}\t{%2, %0|%0, %2}";
11489     }
11490 }
11491   [(set (attr "type")
11492      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11493                           (const_int 0))
11494                       (match_operand 0 "register_operand" ""))
11495                  (match_operand 2 "const1_operand" ""))
11496               (const_string "alu")
11497            ]
11498            (const_string "ishift")))
11499    (set_attr "mode" "QI")])
11500
11501 ;; See comment above `ashldi3' about how this works.
11502
11503 (define_expand "ashrti3"
11504   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11505                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11506                                 (match_operand:QI 2 "nonmemory_operand" "")))
11507               (clobber (reg:CC FLAGS_REG))])]
11508   "TARGET_64BIT"
11509 {
11510   if (! immediate_operand (operands[2], QImode))
11511     {
11512       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11513       DONE;
11514     }
11515   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11516   DONE;
11517 })
11518
11519 (define_insn "ashrti3_1"
11520   [(set (match_operand:TI 0 "register_operand" "=r")
11521         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11522                      (match_operand:QI 2 "register_operand" "c")))
11523    (clobber (match_scratch:DI 3 "=&r"))
11524    (clobber (reg:CC FLAGS_REG))]
11525   "TARGET_64BIT"
11526   "#"
11527   [(set_attr "type" "multi")])
11528
11529 (define_insn "*ashrti3_2"
11530   [(set (match_operand:TI 0 "register_operand" "=r")
11531         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11532                      (match_operand:QI 2 "immediate_operand" "O")))
11533    (clobber (reg:CC FLAGS_REG))]
11534   "TARGET_64BIT"
11535   "#"
11536   [(set_attr "type" "multi")])
11537
11538 (define_split
11539   [(set (match_operand:TI 0 "register_operand" "")
11540         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11541                      (match_operand:QI 2 "register_operand" "")))
11542    (clobber (match_scratch:DI 3 ""))
11543    (clobber (reg:CC FLAGS_REG))]
11544   "TARGET_64BIT && reload_completed"
11545   [(const_int 0)]
11546   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11547
11548 (define_split
11549   [(set (match_operand:TI 0 "register_operand" "")
11550         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11551                      (match_operand:QI 2 "immediate_operand" "")))
11552    (clobber (reg:CC FLAGS_REG))]
11553   "TARGET_64BIT && reload_completed"
11554   [(const_int 0)]
11555   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11556
11557 (define_insn "x86_64_shrd"
11558   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11559         (ior:DI (ashiftrt:DI (match_dup 0)
11560                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11561                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11562                   (minus:QI (const_int 64) (match_dup 2)))))
11563    (clobber (reg:CC FLAGS_REG))]
11564   "TARGET_64BIT"
11565   "@
11566    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11567    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11568   [(set_attr "type" "ishift")
11569    (set_attr "prefix_0f" "1")
11570    (set_attr "mode" "DI")
11571    (set_attr "athlon_decode" "vector")
11572    (set_attr "amdfam10_decode" "vector")])   
11573
11574 (define_expand "ashrdi3"
11575   [(set (match_operand:DI 0 "shiftdi_operand" "")
11576         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11577                      (match_operand:QI 2 "nonmemory_operand" "")))]
11578   ""
11579   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11580
11581 (define_insn "*ashrdi3_63_rex64"
11582   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11583         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11584                      (match_operand:DI 2 "const_int_operand" "i,i")))
11585    (clobber (reg:CC FLAGS_REG))]
11586   "TARGET_64BIT && INTVAL (operands[2]) == 63
11587    && (TARGET_USE_CLTD || optimize_size)
11588    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11589   "@
11590    {cqto|cqo}
11591    sar{q}\t{%2, %0|%0, %2}"
11592   [(set_attr "type" "imovx,ishift")
11593    (set_attr "prefix_0f" "0,*")
11594    (set_attr "length_immediate" "0,*")
11595    (set_attr "modrm" "0,1")
11596    (set_attr "mode" "DI")])
11597
11598 (define_insn "*ashrdi3_1_one_bit_rex64"
11599   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11600         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11601                      (match_operand:QI 2 "const1_operand" "")))
11602    (clobber (reg:CC FLAGS_REG))]
11603   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11604    && (TARGET_SHIFT1 || optimize_size)"
11605   "sar{q}\t%0"
11606   [(set_attr "type" "ishift")
11607    (set (attr "length")
11608      (if_then_else (match_operand:DI 0 "register_operand" "")
11609         (const_string "2")
11610         (const_string "*")))])
11611
11612 (define_insn "*ashrdi3_1_rex64"
11613   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11614         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11615                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11616    (clobber (reg:CC FLAGS_REG))]
11617   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11618   "@
11619    sar{q}\t{%2, %0|%0, %2}
11620    sar{q}\t{%b2, %0|%0, %b2}"
11621   [(set_attr "type" "ishift")
11622    (set_attr "mode" "DI")])
11623
11624 ;; This pattern can't accept a variable shift count, since shifts by
11625 ;; zero don't affect the flags.  We assume that shifts by constant
11626 ;; zero are optimized away.
11627 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11628   [(set (reg FLAGS_REG)
11629         (compare
11630           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11631                        (match_operand:QI 2 "const1_operand" ""))
11632           (const_int 0)))
11633    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11634         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11635   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11636    && (TARGET_SHIFT1 || optimize_size)
11637    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11638   "sar{q}\t%0"
11639   [(set_attr "type" "ishift")
11640    (set (attr "length")
11641      (if_then_else (match_operand:DI 0 "register_operand" "")
11642         (const_string "2")
11643         (const_string "*")))])
11644
11645 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11646   [(set (reg FLAGS_REG)
11647         (compare
11648           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11649                        (match_operand:QI 2 "const1_operand" ""))
11650           (const_int 0)))
11651    (clobber (match_scratch:DI 0 "=r"))]
11652   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11653    && (TARGET_SHIFT1 || optimize_size)
11654    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11655   "sar{q}\t%0"
11656   [(set_attr "type" "ishift")
11657    (set_attr "length" "2")])
11658
11659 ;; This pattern can't accept a variable shift count, since shifts by
11660 ;; zero don't affect the flags.  We assume that shifts by constant
11661 ;; zero are optimized away.
11662 (define_insn "*ashrdi3_cmp_rex64"
11663   [(set (reg FLAGS_REG)
11664         (compare
11665           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11666                        (match_operand:QI 2 "const_int_operand" "n"))
11667           (const_int 0)))
11668    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11669         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11670   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11671    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11672    && (optimize_size
11673        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11674   "sar{q}\t{%2, %0|%0, %2}"
11675   [(set_attr "type" "ishift")
11676    (set_attr "mode" "DI")])
11677
11678 (define_insn "*ashrdi3_cconly_rex64"
11679   [(set (reg FLAGS_REG)
11680         (compare
11681           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11682                        (match_operand:QI 2 "const_int_operand" "n"))
11683           (const_int 0)))
11684    (clobber (match_scratch:DI 0 "=r"))]
11685   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11686    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11687    && (optimize_size
11688        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11689   "sar{q}\t{%2, %0|%0, %2}"
11690   [(set_attr "type" "ishift")
11691    (set_attr "mode" "DI")])
11692
11693 (define_insn "*ashrdi3_1"
11694   [(set (match_operand:DI 0 "register_operand" "=r")
11695         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11696                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11697    (clobber (reg:CC FLAGS_REG))]
11698   "!TARGET_64BIT"
11699   "#"
11700   [(set_attr "type" "multi")])
11701
11702 ;; By default we don't ask for a scratch register, because when DImode
11703 ;; values are manipulated, registers are already at a premium.  But if
11704 ;; we have one handy, we won't turn it away.
11705 (define_peephole2
11706   [(match_scratch:SI 3 "r")
11707    (parallel [(set (match_operand:DI 0 "register_operand" "")
11708                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11709                                 (match_operand:QI 2 "nonmemory_operand" "")))
11710               (clobber (reg:CC FLAGS_REG))])
11711    (match_dup 3)]
11712   "!TARGET_64BIT && TARGET_CMOVE"
11713   [(const_int 0)]
11714   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11715
11716 (define_split
11717   [(set (match_operand:DI 0 "register_operand" "")
11718         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11719                      (match_operand:QI 2 "nonmemory_operand" "")))
11720    (clobber (reg:CC FLAGS_REG))]
11721   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11722                      ? flow2_completed : reload_completed)"
11723   [(const_int 0)]
11724   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11725
11726 (define_insn "x86_shrd_1"
11727   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11728         (ior:SI (ashiftrt:SI (match_dup 0)
11729                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11730                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11731                   (minus:QI (const_int 32) (match_dup 2)))))
11732    (clobber (reg:CC FLAGS_REG))]
11733   ""
11734   "@
11735    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11736    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11737   [(set_attr "type" "ishift")
11738    (set_attr "prefix_0f" "1")
11739    (set_attr "pent_pair" "np")
11740    (set_attr "mode" "SI")])
11741
11742 (define_expand "x86_shift_adj_3"
11743   [(use (match_operand:SI 0 "register_operand" ""))
11744    (use (match_operand:SI 1 "register_operand" ""))
11745    (use (match_operand:QI 2 "register_operand" ""))]
11746   ""
11747 {
11748   rtx label = gen_label_rtx ();
11749   rtx tmp;
11750
11751   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11752
11753   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11754   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11755   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11756                               gen_rtx_LABEL_REF (VOIDmode, label),
11757                               pc_rtx);
11758   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11759   JUMP_LABEL (tmp) = label;
11760
11761   emit_move_insn (operands[0], operands[1]);
11762   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11763
11764   emit_label (label);
11765   LABEL_NUSES (label) = 1;
11766
11767   DONE;
11768 })
11769
11770 (define_insn "ashrsi3_31"
11771   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11772         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11773                      (match_operand:SI 2 "const_int_operand" "i,i")))
11774    (clobber (reg:CC FLAGS_REG))]
11775   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11776    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11777   "@
11778    {cltd|cdq}
11779    sar{l}\t{%2, %0|%0, %2}"
11780   [(set_attr "type" "imovx,ishift")
11781    (set_attr "prefix_0f" "0,*")
11782    (set_attr "length_immediate" "0,*")
11783    (set_attr "modrm" "0,1")
11784    (set_attr "mode" "SI")])
11785
11786 (define_insn "*ashrsi3_31_zext"
11787   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11788         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11789                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11790    (clobber (reg:CC FLAGS_REG))]
11791   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11792    && INTVAL (operands[2]) == 31
11793    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11794   "@
11795    {cltd|cdq}
11796    sar{l}\t{%2, %k0|%k0, %2}"
11797   [(set_attr "type" "imovx,ishift")
11798    (set_attr "prefix_0f" "0,*")
11799    (set_attr "length_immediate" "0,*")
11800    (set_attr "modrm" "0,1")
11801    (set_attr "mode" "SI")])
11802
11803 (define_expand "ashrsi3"
11804   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11805         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11806                      (match_operand:QI 2 "nonmemory_operand" "")))
11807    (clobber (reg:CC FLAGS_REG))]
11808   ""
11809   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11810
11811 (define_insn "*ashrsi3_1_one_bit"
11812   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11813         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11814                      (match_operand:QI 2 "const1_operand" "")))
11815    (clobber (reg:CC FLAGS_REG))]
11816   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11817    && (TARGET_SHIFT1 || optimize_size)"
11818   "sar{l}\t%0"
11819   [(set_attr "type" "ishift")
11820    (set (attr "length")
11821      (if_then_else (match_operand:SI 0 "register_operand" "")
11822         (const_string "2")
11823         (const_string "*")))])
11824
11825 (define_insn "*ashrsi3_1_one_bit_zext"
11826   [(set (match_operand:DI 0 "register_operand" "=r")
11827         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11828                                      (match_operand:QI 2 "const1_operand" ""))))
11829    (clobber (reg:CC FLAGS_REG))]
11830   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11831    && (TARGET_SHIFT1 || optimize_size)"
11832   "sar{l}\t%k0"
11833   [(set_attr "type" "ishift")
11834    (set_attr "length" "2")])
11835
11836 (define_insn "*ashrsi3_1"
11837   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11838         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11839                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11840    (clobber (reg:CC FLAGS_REG))]
11841   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11842   "@
11843    sar{l}\t{%2, %0|%0, %2}
11844    sar{l}\t{%b2, %0|%0, %b2}"
11845   [(set_attr "type" "ishift")
11846    (set_attr "mode" "SI")])
11847
11848 (define_insn "*ashrsi3_1_zext"
11849   [(set (match_operand:DI 0 "register_operand" "=r,r")
11850         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11851                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11852    (clobber (reg:CC FLAGS_REG))]
11853   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11854   "@
11855    sar{l}\t{%2, %k0|%k0, %2}
11856    sar{l}\t{%b2, %k0|%k0, %b2}"
11857   [(set_attr "type" "ishift")
11858    (set_attr "mode" "SI")])
11859
11860 ;; This pattern can't accept a variable shift count, since shifts by
11861 ;; zero don't affect the flags.  We assume that shifts by constant
11862 ;; zero are optimized away.
11863 (define_insn "*ashrsi3_one_bit_cmp"
11864   [(set (reg FLAGS_REG)
11865         (compare
11866           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11867                        (match_operand:QI 2 "const1_operand" ""))
11868           (const_int 0)))
11869    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11870         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11871   "ix86_match_ccmode (insn, CCGOCmode)
11872    && (TARGET_SHIFT1 || optimize_size)
11873    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11874   "sar{l}\t%0"
11875   [(set_attr "type" "ishift")
11876    (set (attr "length")
11877      (if_then_else (match_operand:SI 0 "register_operand" "")
11878         (const_string "2")
11879         (const_string "*")))])
11880
11881 (define_insn "*ashrsi3_one_bit_cconly"
11882   [(set (reg FLAGS_REG)
11883         (compare
11884           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11885                        (match_operand:QI 2 "const1_operand" ""))
11886           (const_int 0)))
11887    (clobber (match_scratch:SI 0 "=r"))]
11888   "ix86_match_ccmode (insn, CCGOCmode)
11889    && (TARGET_SHIFT1 || optimize_size)
11890    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11891   "sar{l}\t%0"
11892   [(set_attr "type" "ishift")
11893    (set_attr "length" "2")])
11894
11895 (define_insn "*ashrsi3_one_bit_cmp_zext"
11896   [(set (reg FLAGS_REG)
11897         (compare
11898           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11899                        (match_operand:QI 2 "const1_operand" ""))
11900           (const_int 0)))
11901    (set (match_operand:DI 0 "register_operand" "=r")
11902         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11903   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11904    && (TARGET_SHIFT1 || optimize_size)
11905    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11906   "sar{l}\t%k0"
11907   [(set_attr "type" "ishift")
11908    (set_attr "length" "2")])
11909
11910 ;; This pattern can't accept a variable shift count, since shifts by
11911 ;; zero don't affect the flags.  We assume that shifts by constant
11912 ;; zero are optimized away.
11913 (define_insn "*ashrsi3_cmp"
11914   [(set (reg FLAGS_REG)
11915         (compare
11916           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11917                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11918           (const_int 0)))
11919    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11920         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11921   "ix86_match_ccmode (insn, CCGOCmode)
11922    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11923    && (optimize_size
11924        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11925   "sar{l}\t{%2, %0|%0, %2}"
11926   [(set_attr "type" "ishift")
11927    (set_attr "mode" "SI")])
11928
11929 (define_insn "*ashrsi3_cconly"
11930   [(set (reg FLAGS_REG)
11931         (compare
11932           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11933                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11934           (const_int 0)))
11935    (clobber (match_scratch:SI 0 "=r"))]
11936   "ix86_match_ccmode (insn, CCGOCmode)
11937    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11938    && (optimize_size
11939        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11940   "sar{l}\t{%2, %0|%0, %2}"
11941   [(set_attr "type" "ishift")
11942    (set_attr "mode" "SI")])
11943
11944 (define_insn "*ashrsi3_cmp_zext"
11945   [(set (reg FLAGS_REG)
11946         (compare
11947           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11948                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11949           (const_int 0)))
11950    (set (match_operand:DI 0 "register_operand" "=r")
11951         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11952   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11953    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11954    && (optimize_size
11955        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11956   "sar{l}\t{%2, %k0|%k0, %2}"
11957   [(set_attr "type" "ishift")
11958    (set_attr "mode" "SI")])
11959
11960 (define_expand "ashrhi3"
11961   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11962         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11963                      (match_operand:QI 2 "nonmemory_operand" "")))
11964    (clobber (reg:CC FLAGS_REG))]
11965   "TARGET_HIMODE_MATH"
11966   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11967
11968 (define_insn "*ashrhi3_1_one_bit"
11969   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11970         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11971                      (match_operand:QI 2 "const1_operand" "")))
11972    (clobber (reg:CC FLAGS_REG))]
11973   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11974    && (TARGET_SHIFT1 || optimize_size)"
11975   "sar{w}\t%0"
11976   [(set_attr "type" "ishift")
11977    (set (attr "length")
11978      (if_then_else (match_operand 0 "register_operand" "")
11979         (const_string "2")
11980         (const_string "*")))])
11981
11982 (define_insn "*ashrhi3_1"
11983   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11984         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11985                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11986    (clobber (reg:CC FLAGS_REG))]
11987   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11988   "@
11989    sar{w}\t{%2, %0|%0, %2}
11990    sar{w}\t{%b2, %0|%0, %b2}"
11991   [(set_attr "type" "ishift")
11992    (set_attr "mode" "HI")])
11993
11994 ;; This pattern can't accept a variable shift count, since shifts by
11995 ;; zero don't affect the flags.  We assume that shifts by constant
11996 ;; zero are optimized away.
11997 (define_insn "*ashrhi3_one_bit_cmp"
11998   [(set (reg FLAGS_REG)
11999         (compare
12000           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12001                        (match_operand:QI 2 "const1_operand" ""))
12002           (const_int 0)))
12003    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12004         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12005   "ix86_match_ccmode (insn, CCGOCmode)
12006    && (TARGET_SHIFT1 || optimize_size)
12007    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12008   "sar{w}\t%0"
12009   [(set_attr "type" "ishift")
12010    (set (attr "length")
12011      (if_then_else (match_operand 0 "register_operand" "")
12012         (const_string "2")
12013         (const_string "*")))])
12014
12015 (define_insn "*ashrhi3_one_bit_cconly"
12016   [(set (reg FLAGS_REG)
12017         (compare
12018           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12019                        (match_operand:QI 2 "const1_operand" ""))
12020           (const_int 0)))
12021    (clobber (match_scratch:HI 0 "=r"))]
12022   "ix86_match_ccmode (insn, CCGOCmode)
12023    && (TARGET_SHIFT1 || optimize_size)
12024    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12025   "sar{w}\t%0"
12026   [(set_attr "type" "ishift")
12027    (set_attr "length" "2")])
12028
12029 ;; This pattern can't accept a variable shift count, since shifts by
12030 ;; zero don't affect the flags.  We assume that shifts by constant
12031 ;; zero are optimized away.
12032 (define_insn "*ashrhi3_cmp"
12033   [(set (reg FLAGS_REG)
12034         (compare
12035           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12036                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12037           (const_int 0)))
12038    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12039         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12040   "ix86_match_ccmode (insn, CCGOCmode)
12041    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12042    && (optimize_size
12043        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12044   "sar{w}\t{%2, %0|%0, %2}"
12045   [(set_attr "type" "ishift")
12046    (set_attr "mode" "HI")])
12047
12048 (define_insn "*ashrhi3_cconly"
12049   [(set (reg FLAGS_REG)
12050         (compare
12051           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12052                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12053           (const_int 0)))
12054    (clobber (match_scratch:HI 0 "=r"))]
12055   "ix86_match_ccmode (insn, CCGOCmode)
12056    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12057    && (optimize_size
12058        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12059   "sar{w}\t{%2, %0|%0, %2}"
12060   [(set_attr "type" "ishift")
12061    (set_attr "mode" "HI")])
12062
12063 (define_expand "ashrqi3"
12064   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12065         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12066                      (match_operand:QI 2 "nonmemory_operand" "")))
12067    (clobber (reg:CC FLAGS_REG))]
12068   "TARGET_QIMODE_MATH"
12069   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12070
12071 (define_insn "*ashrqi3_1_one_bit"
12072   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12073         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12074                      (match_operand:QI 2 "const1_operand" "")))
12075    (clobber (reg:CC FLAGS_REG))]
12076   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12077    && (TARGET_SHIFT1 || optimize_size)"
12078   "sar{b}\t%0"
12079   [(set_attr "type" "ishift")
12080    (set (attr "length")
12081      (if_then_else (match_operand 0 "register_operand" "")
12082         (const_string "2")
12083         (const_string "*")))])
12084
12085 (define_insn "*ashrqi3_1_one_bit_slp"
12086   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12087         (ashiftrt:QI (match_dup 0)
12088                      (match_operand:QI 1 "const1_operand" "")))
12089    (clobber (reg:CC FLAGS_REG))]
12090   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12091    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12092    && (TARGET_SHIFT1 || optimize_size)"
12093   "sar{b}\t%0"
12094   [(set_attr "type" "ishift1")
12095    (set (attr "length")
12096      (if_then_else (match_operand 0 "register_operand" "")
12097         (const_string "2")
12098         (const_string "*")))])
12099
12100 (define_insn "*ashrqi3_1"
12101   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12102         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12103                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12104    (clobber (reg:CC FLAGS_REG))]
12105   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12106   "@
12107    sar{b}\t{%2, %0|%0, %2}
12108    sar{b}\t{%b2, %0|%0, %b2}"
12109   [(set_attr "type" "ishift")
12110    (set_attr "mode" "QI")])
12111
12112 (define_insn "*ashrqi3_1_slp"
12113   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12114         (ashiftrt:QI (match_dup 0)
12115                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12116    (clobber (reg:CC FLAGS_REG))]
12117   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12118    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12119   "@
12120    sar{b}\t{%1, %0|%0, %1}
12121    sar{b}\t{%b1, %0|%0, %b1}"
12122   [(set_attr "type" "ishift1")
12123    (set_attr "mode" "QI")])
12124
12125 ;; This pattern can't accept a variable shift count, since shifts by
12126 ;; zero don't affect the flags.  We assume that shifts by constant
12127 ;; zero are optimized away.
12128 (define_insn "*ashrqi3_one_bit_cmp"
12129   [(set (reg FLAGS_REG)
12130         (compare
12131           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12132                        (match_operand:QI 2 "const1_operand" "I"))
12133           (const_int 0)))
12134    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12135         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12136   "ix86_match_ccmode (insn, CCGOCmode)
12137    && (TARGET_SHIFT1 || optimize_size)
12138    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12139   "sar{b}\t%0"
12140   [(set_attr "type" "ishift")
12141    (set (attr "length")
12142      (if_then_else (match_operand 0 "register_operand" "")
12143         (const_string "2")
12144         (const_string "*")))])
12145
12146 (define_insn "*ashrqi3_one_bit_cconly"
12147   [(set (reg FLAGS_REG)
12148         (compare
12149           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12150                        (match_operand:QI 2 "const1_operand" "I"))
12151           (const_int 0)))
12152    (clobber (match_scratch:QI 0 "=q"))]
12153   "ix86_match_ccmode (insn, CCGOCmode)
12154    && (TARGET_SHIFT1 || optimize_size)
12155    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12156   "sar{b}\t%0"
12157   [(set_attr "type" "ishift")
12158    (set_attr "length" "2")])
12159
12160 ;; This pattern can't accept a variable shift count, since shifts by
12161 ;; zero don't affect the flags.  We assume that shifts by constant
12162 ;; zero are optimized away.
12163 (define_insn "*ashrqi3_cmp"
12164   [(set (reg FLAGS_REG)
12165         (compare
12166           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12167                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12168           (const_int 0)))
12169    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12170         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12171   "ix86_match_ccmode (insn, CCGOCmode)
12172    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12173    && (optimize_size
12174        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12175   "sar{b}\t{%2, %0|%0, %2}"
12176   [(set_attr "type" "ishift")
12177    (set_attr "mode" "QI")])
12178
12179 (define_insn "*ashrqi3_cconly"
12180   [(set (reg FLAGS_REG)
12181         (compare
12182           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12183                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12184           (const_int 0)))
12185    (clobber (match_scratch:QI 0 "=q"))]
12186   "ix86_match_ccmode (insn, CCGOCmode)
12187    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12188    && (optimize_size
12189        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12190   "sar{b}\t{%2, %0|%0, %2}"
12191   [(set_attr "type" "ishift")
12192    (set_attr "mode" "QI")])
12193
12194 \f
12195 ;; Logical shift instructions
12196
12197 ;; See comment above `ashldi3' about how this works.
12198
12199 (define_expand "lshrti3"
12200   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12201                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12202                                 (match_operand:QI 2 "nonmemory_operand" "")))
12203               (clobber (reg:CC FLAGS_REG))])]
12204   "TARGET_64BIT"
12205 {
12206   if (! immediate_operand (operands[2], QImode))
12207     {
12208       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12209       DONE;
12210     }
12211   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12212   DONE;
12213 })
12214
12215 (define_insn "lshrti3_1"
12216   [(set (match_operand:TI 0 "register_operand" "=r")
12217         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12218                      (match_operand:QI 2 "register_operand" "c")))
12219    (clobber (match_scratch:DI 3 "=&r"))
12220    (clobber (reg:CC FLAGS_REG))]
12221   "TARGET_64BIT"
12222   "#"
12223   [(set_attr "type" "multi")])
12224
12225 (define_insn "*lshrti3_2"
12226   [(set (match_operand:TI 0 "register_operand" "=r")
12227         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12228                      (match_operand:QI 2 "immediate_operand" "O")))
12229    (clobber (reg:CC FLAGS_REG))]
12230   "TARGET_64BIT"
12231   "#"
12232   [(set_attr "type" "multi")])
12233
12234 (define_split
12235   [(set (match_operand:TI 0 "register_operand" "")
12236         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12237                      (match_operand:QI 2 "register_operand" "")))
12238    (clobber (match_scratch:DI 3 ""))
12239    (clobber (reg:CC FLAGS_REG))]
12240   "TARGET_64BIT && reload_completed"
12241   [(const_int 0)]
12242   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12243
12244 (define_split
12245   [(set (match_operand:TI 0 "register_operand" "")
12246         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12247                      (match_operand:QI 2 "immediate_operand" "")))
12248    (clobber (reg:CC FLAGS_REG))]
12249   "TARGET_64BIT && reload_completed"
12250   [(const_int 0)]
12251   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12252
12253 (define_expand "lshrdi3"
12254   [(set (match_operand:DI 0 "shiftdi_operand" "")
12255         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12256                      (match_operand:QI 2 "nonmemory_operand" "")))]
12257   ""
12258   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12259
12260 (define_insn "*lshrdi3_1_one_bit_rex64"
12261   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12262         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12263                      (match_operand:QI 2 "const1_operand" "")))
12264    (clobber (reg:CC FLAGS_REG))]
12265   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12266    && (TARGET_SHIFT1 || optimize_size)"
12267   "shr{q}\t%0"
12268   [(set_attr "type" "ishift")
12269    (set (attr "length")
12270      (if_then_else (match_operand:DI 0 "register_operand" "")
12271         (const_string "2")
12272         (const_string "*")))])
12273
12274 (define_insn "*lshrdi3_1_rex64"
12275   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12276         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12277                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12278    (clobber (reg:CC FLAGS_REG))]
12279   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12280   "@
12281    shr{q}\t{%2, %0|%0, %2}
12282    shr{q}\t{%b2, %0|%0, %b2}"
12283   [(set_attr "type" "ishift")
12284    (set_attr "mode" "DI")])
12285
12286 ;; This pattern can't accept a variable shift count, since shifts by
12287 ;; zero don't affect the flags.  We assume that shifts by constant
12288 ;; zero are optimized away.
12289 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12290   [(set (reg FLAGS_REG)
12291         (compare
12292           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12293                        (match_operand:QI 2 "const1_operand" ""))
12294           (const_int 0)))
12295    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12296         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12297   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12298    && (TARGET_SHIFT1 || optimize_size)
12299    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12300   "shr{q}\t%0"
12301   [(set_attr "type" "ishift")
12302    (set (attr "length")
12303      (if_then_else (match_operand:DI 0 "register_operand" "")
12304         (const_string "2")
12305         (const_string "*")))])
12306
12307 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12308   [(set (reg FLAGS_REG)
12309         (compare
12310           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12311                        (match_operand:QI 2 "const1_operand" ""))
12312           (const_int 0)))
12313    (clobber (match_scratch:DI 0 "=r"))]
12314   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12315    && (TARGET_SHIFT1 || optimize_size)
12316    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12317   "shr{q}\t%0"
12318   [(set_attr "type" "ishift")
12319    (set_attr "length" "2")])
12320
12321 ;; This pattern can't accept a variable shift count, since shifts by
12322 ;; zero don't affect the flags.  We assume that shifts by constant
12323 ;; zero are optimized away.
12324 (define_insn "*lshrdi3_cmp_rex64"
12325   [(set (reg FLAGS_REG)
12326         (compare
12327           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12328                        (match_operand:QI 2 "const_int_operand" "e"))
12329           (const_int 0)))
12330    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12331         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12332   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12333    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12334    && (optimize_size
12335        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12336   "shr{q}\t{%2, %0|%0, %2}"
12337   [(set_attr "type" "ishift")
12338    (set_attr "mode" "DI")])
12339
12340 (define_insn "*lshrdi3_cconly_rex64"
12341   [(set (reg FLAGS_REG)
12342         (compare
12343           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12344                        (match_operand:QI 2 "const_int_operand" "e"))
12345           (const_int 0)))
12346    (clobber (match_scratch:DI 0 "=r"))]
12347   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12348    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12349    && (optimize_size
12350        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12351   "shr{q}\t{%2, %0|%0, %2}"
12352   [(set_attr "type" "ishift")
12353    (set_attr "mode" "DI")])
12354
12355 (define_insn "*lshrdi3_1"
12356   [(set (match_operand:DI 0 "register_operand" "=r")
12357         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12358                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12359    (clobber (reg:CC FLAGS_REG))]
12360   "!TARGET_64BIT"
12361   "#"
12362   [(set_attr "type" "multi")])
12363
12364 ;; By default we don't ask for a scratch register, because when DImode
12365 ;; values are manipulated, registers are already at a premium.  But if
12366 ;; we have one handy, we won't turn it away.
12367 (define_peephole2
12368   [(match_scratch:SI 3 "r")
12369    (parallel [(set (match_operand:DI 0 "register_operand" "")
12370                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12371                                 (match_operand:QI 2 "nonmemory_operand" "")))
12372               (clobber (reg:CC FLAGS_REG))])
12373    (match_dup 3)]
12374   "!TARGET_64BIT && TARGET_CMOVE"
12375   [(const_int 0)]
12376   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12377
12378 (define_split
12379   [(set (match_operand:DI 0 "register_operand" "")
12380         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12381                      (match_operand:QI 2 "nonmemory_operand" "")))
12382    (clobber (reg:CC FLAGS_REG))]
12383   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12384                      ? flow2_completed : reload_completed)"
12385   [(const_int 0)]
12386   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12387
12388 (define_expand "lshrsi3"
12389   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12390         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12391                      (match_operand:QI 2 "nonmemory_operand" "")))
12392    (clobber (reg:CC FLAGS_REG))]
12393   ""
12394   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12395
12396 (define_insn "*lshrsi3_1_one_bit"
12397   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12398         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12399                      (match_operand:QI 2 "const1_operand" "")))
12400    (clobber (reg:CC FLAGS_REG))]
12401   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12402    && (TARGET_SHIFT1 || optimize_size)"
12403   "shr{l}\t%0"
12404   [(set_attr "type" "ishift")
12405    (set (attr "length")
12406      (if_then_else (match_operand:SI 0 "register_operand" "")
12407         (const_string "2")
12408         (const_string "*")))])
12409
12410 (define_insn "*lshrsi3_1_one_bit_zext"
12411   [(set (match_operand:DI 0 "register_operand" "=r")
12412         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12413                      (match_operand:QI 2 "const1_operand" "")))
12414    (clobber (reg:CC FLAGS_REG))]
12415   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12416    && (TARGET_SHIFT1 || optimize_size)"
12417   "shr{l}\t%k0"
12418   [(set_attr "type" "ishift")
12419    (set_attr "length" "2")])
12420
12421 (define_insn "*lshrsi3_1"
12422   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12423         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12424                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12425    (clobber (reg:CC FLAGS_REG))]
12426   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12427   "@
12428    shr{l}\t{%2, %0|%0, %2}
12429    shr{l}\t{%b2, %0|%0, %b2}"
12430   [(set_attr "type" "ishift")
12431    (set_attr "mode" "SI")])
12432
12433 (define_insn "*lshrsi3_1_zext"
12434   [(set (match_operand:DI 0 "register_operand" "=r,r")
12435         (zero_extend:DI
12436           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12437                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12438    (clobber (reg:CC FLAGS_REG))]
12439   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12440   "@
12441    shr{l}\t{%2, %k0|%k0, %2}
12442    shr{l}\t{%b2, %k0|%k0, %b2}"
12443   [(set_attr "type" "ishift")
12444    (set_attr "mode" "SI")])
12445
12446 ;; This pattern can't accept a variable shift count, since shifts by
12447 ;; zero don't affect the flags.  We assume that shifts by constant
12448 ;; zero are optimized away.
12449 (define_insn "*lshrsi3_one_bit_cmp"
12450   [(set (reg FLAGS_REG)
12451         (compare
12452           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12453                        (match_operand:QI 2 "const1_operand" ""))
12454           (const_int 0)))
12455    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12456         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12457   "ix86_match_ccmode (insn, CCGOCmode)
12458    && (TARGET_SHIFT1 || optimize_size)
12459    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
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_one_bit_cconly"
12468   [(set (reg FLAGS_REG)
12469         (compare
12470           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12471                        (match_operand:QI 2 "const1_operand" ""))
12472           (const_int 0)))
12473    (clobber (match_scratch:SI 0 "=r"))]
12474   "ix86_match_ccmode (insn, CCGOCmode)
12475    && (TARGET_SHIFT1 || optimize_size)
12476    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12477   "shr{l}\t%0"
12478   [(set_attr "type" "ishift")
12479    (set_attr "length" "2")])
12480
12481 (define_insn "*lshrsi3_cmp_one_bit_zext"
12482   [(set (reg FLAGS_REG)
12483         (compare
12484           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12485                        (match_operand:QI 2 "const1_operand" ""))
12486           (const_int 0)))
12487    (set (match_operand:DI 0 "register_operand" "=r")
12488         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12489   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12490    && (TARGET_SHIFT1 || optimize_size)
12491    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12492   "shr{l}\t%k0"
12493   [(set_attr "type" "ishift")
12494    (set_attr "length" "2")])
12495
12496 ;; This pattern can't accept a variable shift count, since shifts by
12497 ;; zero don't affect the flags.  We assume that shifts by constant
12498 ;; zero are optimized away.
12499 (define_insn "*lshrsi3_cmp"
12500   [(set (reg FLAGS_REG)
12501         (compare
12502           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12503                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12504           (const_int 0)))
12505    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12506         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12507   "ix86_match_ccmode (insn, CCGOCmode)
12508    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12509    && (optimize_size
12510        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12511   "shr{l}\t{%2, %0|%0, %2}"
12512   [(set_attr "type" "ishift")
12513    (set_attr "mode" "SI")])
12514
12515 (define_insn "*lshrsi3_cconly"
12516   [(set (reg FLAGS_REG)
12517       (compare
12518         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12519                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12520         (const_int 0)))
12521    (clobber (match_scratch:SI 0 "=r"))]
12522   "ix86_match_ccmode (insn, CCGOCmode)
12523    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12524    && (optimize_size
12525        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12526   "shr{l}\t{%2, %0|%0, %2}"
12527   [(set_attr "type" "ishift")
12528    (set_attr "mode" "SI")])
12529
12530 (define_insn "*lshrsi3_cmp_zext"
12531   [(set (reg FLAGS_REG)
12532         (compare
12533           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12534                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12535           (const_int 0)))
12536    (set (match_operand:DI 0 "register_operand" "=r")
12537         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12538   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12539    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12540    && (optimize_size
12541        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12542   "shr{l}\t{%2, %k0|%k0, %2}"
12543   [(set_attr "type" "ishift")
12544    (set_attr "mode" "SI")])
12545
12546 (define_expand "lshrhi3"
12547   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12548         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12549                      (match_operand:QI 2 "nonmemory_operand" "")))
12550    (clobber (reg:CC FLAGS_REG))]
12551   "TARGET_HIMODE_MATH"
12552   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12553
12554 (define_insn "*lshrhi3_1_one_bit"
12555   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12556         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12557                      (match_operand:QI 2 "const1_operand" "")))
12558    (clobber (reg:CC FLAGS_REG))]
12559   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12560    && (TARGET_SHIFT1 || optimize_size)"
12561   "shr{w}\t%0"
12562   [(set_attr "type" "ishift")
12563    (set (attr "length")
12564      (if_then_else (match_operand 0 "register_operand" "")
12565         (const_string "2")
12566         (const_string "*")))])
12567
12568 (define_insn "*lshrhi3_1"
12569   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12570         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12571                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12572    (clobber (reg:CC FLAGS_REG))]
12573   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12574   "@
12575    shr{w}\t{%2, %0|%0, %2}
12576    shr{w}\t{%b2, %0|%0, %b2}"
12577   [(set_attr "type" "ishift")
12578    (set_attr "mode" "HI")])
12579
12580 ;; This pattern can't accept a variable shift count, since shifts by
12581 ;; zero don't affect the flags.  We assume that shifts by constant
12582 ;; zero are optimized away.
12583 (define_insn "*lshrhi3_one_bit_cmp"
12584   [(set (reg FLAGS_REG)
12585         (compare
12586           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12587                        (match_operand:QI 2 "const1_operand" ""))
12588           (const_int 0)))
12589    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12590         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12591   "ix86_match_ccmode (insn, CCGOCmode)
12592    && (TARGET_SHIFT1 || optimize_size)
12593    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12594   "shr{w}\t%0"
12595   [(set_attr "type" "ishift")
12596    (set (attr "length")
12597      (if_then_else (match_operand:SI 0 "register_operand" "")
12598         (const_string "2")
12599         (const_string "*")))])
12600
12601 (define_insn "*lshrhi3_one_bit_cconly"
12602   [(set (reg FLAGS_REG)
12603         (compare
12604           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12605                        (match_operand:QI 2 "const1_operand" ""))
12606           (const_int 0)))
12607    (clobber (match_scratch:HI 0 "=r"))]
12608   "ix86_match_ccmode (insn, CCGOCmode)
12609    && (TARGET_SHIFT1 || optimize_size)
12610    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12611   "shr{w}\t%0"
12612   [(set_attr "type" "ishift")
12613    (set_attr "length" "2")])
12614
12615 ;; This pattern can't accept a variable shift count, since shifts by
12616 ;; zero don't affect the flags.  We assume that shifts by constant
12617 ;; zero are optimized away.
12618 (define_insn "*lshrhi3_cmp"
12619   [(set (reg FLAGS_REG)
12620         (compare
12621           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12622                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12623           (const_int 0)))
12624    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12625         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12626   "ix86_match_ccmode (insn, CCGOCmode)
12627    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12628    && (optimize_size
12629        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12630   "shr{w}\t{%2, %0|%0, %2}"
12631   [(set_attr "type" "ishift")
12632    (set_attr "mode" "HI")])
12633
12634 (define_insn "*lshrhi3_cconly"
12635   [(set (reg FLAGS_REG)
12636         (compare
12637           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12638                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12639           (const_int 0)))
12640    (clobber (match_scratch:HI 0 "=r"))]
12641   "ix86_match_ccmode (insn, CCGOCmode)
12642    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12643    && (optimize_size
12644        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12645   "shr{w}\t{%2, %0|%0, %2}"
12646   [(set_attr "type" "ishift")
12647    (set_attr "mode" "HI")])
12648
12649 (define_expand "lshrqi3"
12650   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12651         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12652                      (match_operand:QI 2 "nonmemory_operand" "")))
12653    (clobber (reg:CC FLAGS_REG))]
12654   "TARGET_QIMODE_MATH"
12655   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12656
12657 (define_insn "*lshrqi3_1_one_bit"
12658   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12659         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12660                      (match_operand:QI 2 "const1_operand" "")))
12661    (clobber (reg:CC FLAGS_REG))]
12662   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12663    && (TARGET_SHIFT1 || optimize_size)"
12664   "shr{b}\t%0"
12665   [(set_attr "type" "ishift")
12666    (set (attr "length")
12667      (if_then_else (match_operand 0 "register_operand" "")
12668         (const_string "2")
12669         (const_string "*")))])
12670
12671 (define_insn "*lshrqi3_1_one_bit_slp"
12672   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12673         (lshiftrt:QI (match_dup 0)
12674                      (match_operand:QI 1 "const1_operand" "")))
12675    (clobber (reg:CC FLAGS_REG))]
12676   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12677    && (TARGET_SHIFT1 || optimize_size)"
12678   "shr{b}\t%0"
12679   [(set_attr "type" "ishift1")
12680    (set (attr "length")
12681      (if_then_else (match_operand 0 "register_operand" "")
12682         (const_string "2")
12683         (const_string "*")))])
12684
12685 (define_insn "*lshrqi3_1"
12686   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12687         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12688                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12689    (clobber (reg:CC FLAGS_REG))]
12690   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12691   "@
12692    shr{b}\t{%2, %0|%0, %2}
12693    shr{b}\t{%b2, %0|%0, %b2}"
12694   [(set_attr "type" "ishift")
12695    (set_attr "mode" "QI")])
12696
12697 (define_insn "*lshrqi3_1_slp"
12698   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12699         (lshiftrt:QI (match_dup 0)
12700                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12701    (clobber (reg:CC FLAGS_REG))]
12702   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12703    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12704   "@
12705    shr{b}\t{%1, %0|%0, %1}
12706    shr{b}\t{%b1, %0|%0, %b1}"
12707   [(set_attr "type" "ishift1")
12708    (set_attr "mode" "QI")])
12709
12710 ;; This pattern can't accept a variable shift count, since shifts by
12711 ;; zero don't affect the flags.  We assume that shifts by constant
12712 ;; zero are optimized away.
12713 (define_insn "*lshrqi2_one_bit_cmp"
12714   [(set (reg FLAGS_REG)
12715         (compare
12716           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12717                        (match_operand:QI 2 "const1_operand" ""))
12718           (const_int 0)))
12719    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12720         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12721   "ix86_match_ccmode (insn, CCGOCmode)
12722    && (TARGET_SHIFT1 || optimize_size)
12723    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12724   "shr{b}\t%0"
12725   [(set_attr "type" "ishift")
12726    (set (attr "length")
12727      (if_then_else (match_operand:SI 0 "register_operand" "")
12728         (const_string "2")
12729         (const_string "*")))])
12730
12731 (define_insn "*lshrqi2_one_bit_cconly"
12732   [(set (reg FLAGS_REG)
12733         (compare
12734           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12735                        (match_operand:QI 2 "const1_operand" ""))
12736           (const_int 0)))
12737    (clobber (match_scratch:QI 0 "=q"))]
12738   "ix86_match_ccmode (insn, CCGOCmode)
12739    && (TARGET_SHIFT1 || optimize_size)
12740    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12741   "shr{b}\t%0"
12742   [(set_attr "type" "ishift")
12743    (set_attr "length" "2")])
12744
12745 ;; This pattern can't accept a variable shift count, since shifts by
12746 ;; zero don't affect the flags.  We assume that shifts by constant
12747 ;; zero are optimized away.
12748 (define_insn "*lshrqi2_cmp"
12749   [(set (reg FLAGS_REG)
12750         (compare
12751           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12752                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12753           (const_int 0)))
12754    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12755         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12756   "ix86_match_ccmode (insn, CCGOCmode)
12757    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12758    && (optimize_size
12759        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12760   "shr{b}\t{%2, %0|%0, %2}"
12761   [(set_attr "type" "ishift")
12762    (set_attr "mode" "QI")])
12763
12764 (define_insn "*lshrqi2_cconly"
12765   [(set (reg FLAGS_REG)
12766         (compare
12767           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12768                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12769           (const_int 0)))
12770    (clobber (match_scratch:QI 0 "=q"))]
12771   "ix86_match_ccmode (insn, CCGOCmode)
12772    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12773    && (optimize_size
12774        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12775   "shr{b}\t{%2, %0|%0, %2}"
12776   [(set_attr "type" "ishift")
12777    (set_attr "mode" "QI")])
12778 \f
12779 ;; Rotate instructions
12780
12781 (define_expand "rotldi3"
12782   [(set (match_operand:DI 0 "shiftdi_operand" "")
12783         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12784                    (match_operand:QI 2 "nonmemory_operand" "")))
12785    (clobber (reg:CC FLAGS_REG))]
12786  ""
12787 {
12788   if (TARGET_64BIT)
12789     {
12790       ix86_expand_binary_operator (ROTATE, DImode, operands);
12791       DONE;
12792     }
12793   if (!const_1_to_31_operand (operands[2], VOIDmode))
12794     FAIL;
12795   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12796   DONE;
12797 })
12798
12799 ;; Implement rotation using two double-precision shift instructions
12800 ;; and a scratch register.
12801 (define_insn_and_split "ix86_rotldi3"
12802  [(set (match_operand:DI 0 "register_operand" "=r")
12803        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12804                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12805   (clobber (reg:CC FLAGS_REG))
12806   (clobber (match_scratch:SI 3 "=&r"))]
12807  "!TARGET_64BIT"
12808  ""
12809  "&& reload_completed"
12810  [(set (match_dup 3) (match_dup 4))
12811   (parallel
12812    [(set (match_dup 4)
12813          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12814                  (lshiftrt:SI (match_dup 5)
12815                               (minus:QI (const_int 32) (match_dup 2)))))
12816     (clobber (reg:CC FLAGS_REG))])
12817   (parallel
12818    [(set (match_dup 5)
12819          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12820                  (lshiftrt:SI (match_dup 3)
12821                               (minus:QI (const_int 32) (match_dup 2)))))
12822     (clobber (reg:CC FLAGS_REG))])]
12823  "split_di (operands, 1, operands + 4, operands + 5);")
12824
12825 (define_insn "*rotlsi3_1_one_bit_rex64"
12826   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12827         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12828                    (match_operand:QI 2 "const1_operand" "")))
12829    (clobber (reg:CC FLAGS_REG))]
12830   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12831    && (TARGET_SHIFT1 || optimize_size)"
12832   "rol{q}\t%0"
12833   [(set_attr "type" "rotate")
12834    (set (attr "length")
12835      (if_then_else (match_operand:DI 0 "register_operand" "")
12836         (const_string "2")
12837         (const_string "*")))])
12838
12839 (define_insn "*rotldi3_1_rex64"
12840   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12841         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12842                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12843    (clobber (reg:CC FLAGS_REG))]
12844   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12845   "@
12846    rol{q}\t{%2, %0|%0, %2}
12847    rol{q}\t{%b2, %0|%0, %b2}"
12848   [(set_attr "type" "rotate")
12849    (set_attr "mode" "DI")])
12850
12851 (define_expand "rotlsi3"
12852   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12853         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12854                    (match_operand:QI 2 "nonmemory_operand" "")))
12855    (clobber (reg:CC FLAGS_REG))]
12856   ""
12857   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12858
12859 (define_insn "*rotlsi3_1_one_bit"
12860   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12861         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12862                    (match_operand:QI 2 "const1_operand" "")))
12863    (clobber (reg:CC FLAGS_REG))]
12864   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12865    && (TARGET_SHIFT1 || optimize_size)"
12866   "rol{l}\t%0"
12867   [(set_attr "type" "rotate")
12868    (set (attr "length")
12869      (if_then_else (match_operand:SI 0 "register_operand" "")
12870         (const_string "2")
12871         (const_string "*")))])
12872
12873 (define_insn "*rotlsi3_1_one_bit_zext"
12874   [(set (match_operand:DI 0 "register_operand" "=r")
12875         (zero_extend:DI
12876           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12877                      (match_operand:QI 2 "const1_operand" ""))))
12878    (clobber (reg:CC FLAGS_REG))]
12879   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12880    && (TARGET_SHIFT1 || optimize_size)"
12881   "rol{l}\t%k0"
12882   [(set_attr "type" "rotate")
12883    (set_attr "length" "2")])
12884
12885 (define_insn "*rotlsi3_1"
12886   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12887         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12888                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12889    (clobber (reg:CC FLAGS_REG))]
12890   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12891   "@
12892    rol{l}\t{%2, %0|%0, %2}
12893    rol{l}\t{%b2, %0|%0, %b2}"
12894   [(set_attr "type" "rotate")
12895    (set_attr "mode" "SI")])
12896
12897 (define_insn "*rotlsi3_1_zext"
12898   [(set (match_operand:DI 0 "register_operand" "=r,r")
12899         (zero_extend:DI
12900           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12901                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12902    (clobber (reg:CC FLAGS_REG))]
12903   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12904   "@
12905    rol{l}\t{%2, %k0|%k0, %2}
12906    rol{l}\t{%b2, %k0|%k0, %b2}"
12907   [(set_attr "type" "rotate")
12908    (set_attr "mode" "SI")])
12909
12910 (define_expand "rotlhi3"
12911   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12912         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12913                    (match_operand:QI 2 "nonmemory_operand" "")))
12914    (clobber (reg:CC FLAGS_REG))]
12915   "TARGET_HIMODE_MATH"
12916   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12917
12918 (define_insn "*rotlhi3_1_one_bit"
12919   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12920         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12921                    (match_operand:QI 2 "const1_operand" "")))
12922    (clobber (reg:CC FLAGS_REG))]
12923   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12924    && (TARGET_SHIFT1 || optimize_size)"
12925   "rol{w}\t%0"
12926   [(set_attr "type" "rotate")
12927    (set (attr "length")
12928      (if_then_else (match_operand 0 "register_operand" "")
12929         (const_string "2")
12930         (const_string "*")))])
12931
12932 (define_insn "*rotlhi3_1"
12933   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12934         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12935                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12936    (clobber (reg:CC FLAGS_REG))]
12937   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12938   "@
12939    rol{w}\t{%2, %0|%0, %2}
12940    rol{w}\t{%b2, %0|%0, %b2}"
12941   [(set_attr "type" "rotate")
12942    (set_attr "mode" "HI")])
12943
12944 (define_expand "rotlqi3"
12945   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12946         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12947                    (match_operand:QI 2 "nonmemory_operand" "")))
12948    (clobber (reg:CC FLAGS_REG))]
12949   "TARGET_QIMODE_MATH"
12950   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12951
12952 (define_insn "*rotlqi3_1_one_bit_slp"
12953   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12954         (rotate:QI (match_dup 0)
12955                    (match_operand:QI 1 "const1_operand" "")))
12956    (clobber (reg:CC FLAGS_REG))]
12957   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12958    && (TARGET_SHIFT1 || optimize_size)"
12959   "rol{b}\t%0"
12960   [(set_attr "type" "rotate1")
12961    (set (attr "length")
12962      (if_then_else (match_operand 0 "register_operand" "")
12963         (const_string "2")
12964         (const_string "*")))])
12965
12966 (define_insn "*rotlqi3_1_one_bit"
12967   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12968         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12969                    (match_operand:QI 2 "const1_operand" "")))
12970    (clobber (reg:CC FLAGS_REG))]
12971   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12972    && (TARGET_SHIFT1 || optimize_size)"
12973   "rol{b}\t%0"
12974   [(set_attr "type" "rotate")
12975    (set (attr "length")
12976      (if_then_else (match_operand 0 "register_operand" "")
12977         (const_string "2")
12978         (const_string "*")))])
12979
12980 (define_insn "*rotlqi3_1_slp"
12981   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12982         (rotate:QI (match_dup 0)
12983                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12984    (clobber (reg:CC FLAGS_REG))]
12985   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12986    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12987   "@
12988    rol{b}\t{%1, %0|%0, %1}
12989    rol{b}\t{%b1, %0|%0, %b1}"
12990   [(set_attr "type" "rotate1")
12991    (set_attr "mode" "QI")])
12992
12993 (define_insn "*rotlqi3_1"
12994   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12995         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12996                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12997    (clobber (reg:CC FLAGS_REG))]
12998   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12999   "@
13000    rol{b}\t{%2, %0|%0, %2}
13001    rol{b}\t{%b2, %0|%0, %b2}"
13002   [(set_attr "type" "rotate")
13003    (set_attr "mode" "QI")])
13004
13005 (define_expand "rotrdi3"
13006   [(set (match_operand:DI 0 "shiftdi_operand" "")
13007         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13008                    (match_operand:QI 2 "nonmemory_operand" "")))
13009    (clobber (reg:CC FLAGS_REG))]
13010  ""
13011 {
13012   if (TARGET_64BIT)
13013     {
13014       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13015       DONE;
13016     }
13017   if (!const_1_to_31_operand (operands[2], VOIDmode))
13018     FAIL;
13019   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13020   DONE;
13021 })
13022
13023 ;; Implement rotation using two double-precision shift instructions
13024 ;; and a scratch register.
13025 (define_insn_and_split "ix86_rotrdi3"
13026  [(set (match_operand:DI 0 "register_operand" "=r")
13027        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13028                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13029   (clobber (reg:CC FLAGS_REG))
13030   (clobber (match_scratch:SI 3 "=&r"))]
13031  "!TARGET_64BIT"
13032  ""
13033  "&& reload_completed"
13034  [(set (match_dup 3) (match_dup 4))
13035   (parallel
13036    [(set (match_dup 4)
13037          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13038                  (ashift:SI (match_dup 5)
13039                             (minus:QI (const_int 32) (match_dup 2)))))
13040     (clobber (reg:CC FLAGS_REG))])
13041   (parallel
13042    [(set (match_dup 5)
13043          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13044                  (ashift:SI (match_dup 3)
13045                             (minus:QI (const_int 32) (match_dup 2)))))
13046     (clobber (reg:CC FLAGS_REG))])]
13047  "split_di (operands, 1, operands + 4, operands + 5);")
13048
13049 (define_insn "*rotrdi3_1_one_bit_rex64"
13050   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13051         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13052                      (match_operand:QI 2 "const1_operand" "")))
13053    (clobber (reg:CC FLAGS_REG))]
13054   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13055    && (TARGET_SHIFT1 || optimize_size)"
13056   "ror{q}\t%0"
13057   [(set_attr "type" "rotate")
13058    (set (attr "length")
13059      (if_then_else (match_operand:DI 0 "register_operand" "")
13060         (const_string "2")
13061         (const_string "*")))])
13062
13063 (define_insn "*rotrdi3_1_rex64"
13064   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13065         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13066                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13067    (clobber (reg:CC FLAGS_REG))]
13068   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13069   "@
13070    ror{q}\t{%2, %0|%0, %2}
13071    ror{q}\t{%b2, %0|%0, %b2}"
13072   [(set_attr "type" "rotate")
13073    (set_attr "mode" "DI")])
13074
13075 (define_expand "rotrsi3"
13076   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13077         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13078                      (match_operand:QI 2 "nonmemory_operand" "")))
13079    (clobber (reg:CC FLAGS_REG))]
13080   ""
13081   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13082
13083 (define_insn "*rotrsi3_1_one_bit"
13084   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13085         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13086                      (match_operand:QI 2 "const1_operand" "")))
13087    (clobber (reg:CC FLAGS_REG))]
13088   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13089    && (TARGET_SHIFT1 || optimize_size)"
13090   "ror{l}\t%0"
13091   [(set_attr "type" "rotate")
13092    (set (attr "length")
13093      (if_then_else (match_operand:SI 0 "register_operand" "")
13094         (const_string "2")
13095         (const_string "*")))])
13096
13097 (define_insn "*rotrsi3_1_one_bit_zext"
13098   [(set (match_operand:DI 0 "register_operand" "=r")
13099         (zero_extend:DI
13100           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13101                        (match_operand:QI 2 "const1_operand" ""))))
13102    (clobber (reg:CC FLAGS_REG))]
13103   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13104    && (TARGET_SHIFT1 || optimize_size)"
13105   "ror{l}\t%k0"
13106   [(set_attr "type" "rotate")
13107    (set (attr "length")
13108      (if_then_else (match_operand:SI 0 "register_operand" "")
13109         (const_string "2")
13110         (const_string "*")))])
13111
13112 (define_insn "*rotrsi3_1"
13113   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13114         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13115                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13116    (clobber (reg:CC FLAGS_REG))]
13117   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13118   "@
13119    ror{l}\t{%2, %0|%0, %2}
13120    ror{l}\t{%b2, %0|%0, %b2}"
13121   [(set_attr "type" "rotate")
13122    (set_attr "mode" "SI")])
13123
13124 (define_insn "*rotrsi3_1_zext"
13125   [(set (match_operand:DI 0 "register_operand" "=r,r")
13126         (zero_extend:DI
13127           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13128                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13129    (clobber (reg:CC FLAGS_REG))]
13130   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13131   "@
13132    ror{l}\t{%2, %k0|%k0, %2}
13133    ror{l}\t{%b2, %k0|%k0, %b2}"
13134   [(set_attr "type" "rotate")
13135    (set_attr "mode" "SI")])
13136
13137 (define_expand "rotrhi3"
13138   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13139         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13140                      (match_operand:QI 2 "nonmemory_operand" "")))
13141    (clobber (reg:CC FLAGS_REG))]
13142   "TARGET_HIMODE_MATH"
13143   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13144
13145 (define_insn "*rotrhi3_one_bit"
13146   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13147         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13148                      (match_operand:QI 2 "const1_operand" "")))
13149    (clobber (reg:CC FLAGS_REG))]
13150   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13151    && (TARGET_SHIFT1 || optimize_size)"
13152   "ror{w}\t%0"
13153   [(set_attr "type" "rotate")
13154    (set (attr "length")
13155      (if_then_else (match_operand 0 "register_operand" "")
13156         (const_string "2")
13157         (const_string "*")))])
13158
13159 (define_insn "*rotrhi3"
13160   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13161         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13162                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13163    (clobber (reg:CC FLAGS_REG))]
13164   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13165   "@
13166    ror{w}\t{%2, %0|%0, %2}
13167    ror{w}\t{%b2, %0|%0, %b2}"
13168   [(set_attr "type" "rotate")
13169    (set_attr "mode" "HI")])
13170
13171 (define_expand "rotrqi3"
13172   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13173         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13174                      (match_operand:QI 2 "nonmemory_operand" "")))
13175    (clobber (reg:CC FLAGS_REG))]
13176   "TARGET_QIMODE_MATH"
13177   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13178
13179 (define_insn "*rotrqi3_1_one_bit"
13180   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13181         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13182                      (match_operand:QI 2 "const1_operand" "")))
13183    (clobber (reg:CC FLAGS_REG))]
13184   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13185    && (TARGET_SHIFT1 || optimize_size)"
13186   "ror{b}\t%0"
13187   [(set_attr "type" "rotate")
13188    (set (attr "length")
13189      (if_then_else (match_operand 0 "register_operand" "")
13190         (const_string "2")
13191         (const_string "*")))])
13192
13193 (define_insn "*rotrqi3_1_one_bit_slp"
13194   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13195         (rotatert:QI (match_dup 0)
13196                      (match_operand:QI 1 "const1_operand" "")))
13197    (clobber (reg:CC FLAGS_REG))]
13198   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13199    && (TARGET_SHIFT1 || optimize_size)"
13200   "ror{b}\t%0"
13201   [(set_attr "type" "rotate1")
13202    (set (attr "length")
13203      (if_then_else (match_operand 0 "register_operand" "")
13204         (const_string "2")
13205         (const_string "*")))])
13206
13207 (define_insn "*rotrqi3_1"
13208   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13209         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13210                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13211    (clobber (reg:CC FLAGS_REG))]
13212   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13213   "@
13214    ror{b}\t{%2, %0|%0, %2}
13215    ror{b}\t{%b2, %0|%0, %b2}"
13216   [(set_attr "type" "rotate")
13217    (set_attr "mode" "QI")])
13218
13219 (define_insn "*rotrqi3_1_slp"
13220   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13221         (rotatert:QI (match_dup 0)
13222                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13223    (clobber (reg:CC FLAGS_REG))]
13224   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13225    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13226   "@
13227    ror{b}\t{%1, %0|%0, %1}
13228    ror{b}\t{%b1, %0|%0, %b1}"
13229   [(set_attr "type" "rotate1")
13230    (set_attr "mode" "QI")])
13231 \f
13232 ;; Bit set / bit test instructions
13233
13234 (define_expand "extv"
13235   [(set (match_operand:SI 0 "register_operand" "")
13236         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13237                          (match_operand:SI 2 "const8_operand" "")
13238                          (match_operand:SI 3 "const8_operand" "")))]
13239   ""
13240 {
13241   /* Handle extractions from %ah et al.  */
13242   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13243     FAIL;
13244
13245   /* From mips.md: extract_bit_field doesn't verify that our source
13246      matches the predicate, so check it again here.  */
13247   if (! ext_register_operand (operands[1], VOIDmode))
13248     FAIL;
13249 })
13250
13251 (define_expand "extzv"
13252   [(set (match_operand:SI 0 "register_operand" "")
13253         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13254                          (match_operand:SI 2 "const8_operand" "")
13255                          (match_operand:SI 3 "const8_operand" "")))]
13256   ""
13257 {
13258   /* Handle extractions from %ah et al.  */
13259   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13260     FAIL;
13261
13262   /* From mips.md: extract_bit_field doesn't verify that our source
13263      matches the predicate, so check it again here.  */
13264   if (! ext_register_operand (operands[1], VOIDmode))
13265     FAIL;
13266 })
13267
13268 (define_expand "insv"
13269   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13270                       (match_operand 1 "const8_operand" "")
13271                       (match_operand 2 "const8_operand" ""))
13272         (match_operand 3 "register_operand" ""))]
13273   ""
13274 {
13275   /* Handle insertions to %ah et al.  */
13276   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13277     FAIL;
13278
13279   /* From mips.md: insert_bit_field doesn't verify that our source
13280      matches the predicate, so check it again here.  */
13281   if (! ext_register_operand (operands[0], VOIDmode))
13282     FAIL;
13283
13284   if (TARGET_64BIT)
13285     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13286   else
13287     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13288
13289   DONE;
13290 })
13291
13292 ;; %%% bts, btr, btc, bt.
13293 ;; In general these instructions are *slow* when applied to memory,
13294 ;; since they enforce atomic operation.  When applied to registers,
13295 ;; it depends on the cpu implementation.  They're never faster than
13296 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13297 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13298 ;; within the instruction itself, so operating on bits in the high
13299 ;; 32-bits of a register becomes easier.
13300 ;;
13301 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13302 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13303 ;; negdf respectively, so they can never be disabled entirely.
13304
13305 (define_insn "*btsq"
13306   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13307                          (const_int 1)
13308                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13309         (const_int 1))
13310    (clobber (reg:CC FLAGS_REG))]
13311   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13312   "bts{q} %1,%0"
13313   [(set_attr "type" "alu1")])
13314
13315 (define_insn "*btrq"
13316   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13317                          (const_int 1)
13318                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13319         (const_int 0))
13320    (clobber (reg:CC FLAGS_REG))]
13321   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13322   "btr{q} %1,%0"
13323   [(set_attr "type" "alu1")])
13324
13325 (define_insn "*btcq"
13326   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13327                          (const_int 1)
13328                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13329         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13330    (clobber (reg:CC FLAGS_REG))]
13331   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13332   "btc{q} %1,%0"
13333   [(set_attr "type" "alu1")])
13334
13335 ;; Allow Nocona to avoid these instructions if a register is available.
13336
13337 (define_peephole2
13338   [(match_scratch:DI 2 "r")
13339    (parallel [(set (zero_extract:DI
13340                      (match_operand:DI 0 "register_operand" "")
13341                      (const_int 1)
13342                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13343                    (const_int 1))
13344               (clobber (reg:CC FLAGS_REG))])]
13345   "TARGET_64BIT && !TARGET_USE_BT"
13346   [(const_int 0)]
13347 {
13348   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13349   rtx op1;
13350
13351   if (HOST_BITS_PER_WIDE_INT >= 64)
13352     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13353   else if (i < HOST_BITS_PER_WIDE_INT)
13354     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13355   else
13356     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13357
13358   op1 = immed_double_const (lo, hi, DImode);
13359   if (i >= 31)
13360     {
13361       emit_move_insn (operands[2], op1);
13362       op1 = operands[2];
13363     }
13364
13365   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13366   DONE;
13367 })
13368
13369 (define_peephole2
13370   [(match_scratch:DI 2 "r")
13371    (parallel [(set (zero_extract:DI
13372                      (match_operand:DI 0 "register_operand" "")
13373                      (const_int 1)
13374                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13375                    (const_int 0))
13376               (clobber (reg:CC FLAGS_REG))])]
13377   "TARGET_64BIT && !TARGET_USE_BT"
13378   [(const_int 0)]
13379 {
13380   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13381   rtx op1;
13382
13383   if (HOST_BITS_PER_WIDE_INT >= 64)
13384     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13385   else if (i < HOST_BITS_PER_WIDE_INT)
13386     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13387   else
13388     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13389
13390   op1 = immed_double_const (~lo, ~hi, DImode);
13391   if (i >= 32)
13392     {
13393       emit_move_insn (operands[2], op1);
13394       op1 = operands[2];
13395     }
13396
13397   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13398   DONE;
13399 })
13400
13401 (define_peephole2
13402   [(match_scratch:DI 2 "r")
13403    (parallel [(set (zero_extract:DI
13404                      (match_operand:DI 0 "register_operand" "")
13405                      (const_int 1)
13406                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13407               (not:DI (zero_extract:DI
13408                         (match_dup 0) (const_int 1) (match_dup 1))))
13409               (clobber (reg:CC FLAGS_REG))])]
13410   "TARGET_64BIT && !TARGET_USE_BT"
13411   [(const_int 0)]
13412 {
13413   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13414   rtx op1;
13415
13416   if (HOST_BITS_PER_WIDE_INT >= 64)
13417     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13418   else if (i < HOST_BITS_PER_WIDE_INT)
13419     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13420   else
13421     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13422
13423   op1 = immed_double_const (lo, hi, DImode);
13424   if (i >= 31)
13425     {
13426       emit_move_insn (operands[2], op1);
13427       op1 = operands[2];
13428     }
13429
13430   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13431   DONE;
13432 })
13433 \f
13434 ;; Store-flag instructions.
13435
13436 ;; For all sCOND expanders, also expand the compare or test insn that
13437 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13438
13439 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13440 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13441 ;; way, which can later delete the movzx if only QImode is needed.
13442
13443 (define_expand "seq"
13444   [(set (match_operand:QI 0 "register_operand" "")
13445         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13446   ""
13447   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13448
13449 (define_expand "sne"
13450   [(set (match_operand:QI 0 "register_operand" "")
13451         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13452   ""
13453   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13454
13455 (define_expand "sgt"
13456   [(set (match_operand:QI 0 "register_operand" "")
13457         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13458   ""
13459   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13460
13461 (define_expand "sgtu"
13462   [(set (match_operand:QI 0 "register_operand" "")
13463         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13464   ""
13465   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13466
13467 (define_expand "slt"
13468   [(set (match_operand:QI 0 "register_operand" "")
13469         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13470   ""
13471   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13472
13473 (define_expand "sltu"
13474   [(set (match_operand:QI 0 "register_operand" "")
13475         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13476   ""
13477   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13478
13479 (define_expand "sge"
13480   [(set (match_operand:QI 0 "register_operand" "")
13481         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13482   ""
13483   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13484
13485 (define_expand "sgeu"
13486   [(set (match_operand:QI 0 "register_operand" "")
13487         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13488   ""
13489   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13490
13491 (define_expand "sle"
13492   [(set (match_operand:QI 0 "register_operand" "")
13493         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13494   ""
13495   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13496
13497 (define_expand "sleu"
13498   [(set (match_operand:QI 0 "register_operand" "")
13499         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13500   ""
13501   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13502
13503 (define_expand "sunordered"
13504   [(set (match_operand:QI 0 "register_operand" "")
13505         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13506   "TARGET_80387 || TARGET_SSE"
13507   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13508
13509 (define_expand "sordered"
13510   [(set (match_operand:QI 0 "register_operand" "")
13511         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13512   "TARGET_80387"
13513   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13514
13515 (define_expand "suneq"
13516   [(set (match_operand:QI 0 "register_operand" "")
13517         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13518   "TARGET_80387 || TARGET_SSE"
13519   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13520
13521 (define_expand "sunge"
13522   [(set (match_operand:QI 0 "register_operand" "")
13523         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13524   "TARGET_80387 || TARGET_SSE"
13525   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13526
13527 (define_expand "sungt"
13528   [(set (match_operand:QI 0 "register_operand" "")
13529         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13530   "TARGET_80387 || TARGET_SSE"
13531   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13532
13533 (define_expand "sunle"
13534   [(set (match_operand:QI 0 "register_operand" "")
13535         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13536   "TARGET_80387 || TARGET_SSE"
13537   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13538
13539 (define_expand "sunlt"
13540   [(set (match_operand:QI 0 "register_operand" "")
13541         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13542   "TARGET_80387 || TARGET_SSE"
13543   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13544
13545 (define_expand "sltgt"
13546   [(set (match_operand:QI 0 "register_operand" "")
13547         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13548   "TARGET_80387 || TARGET_SSE"
13549   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13550
13551 (define_insn "*setcc_1"
13552   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13553         (match_operator:QI 1 "ix86_comparison_operator"
13554           [(reg FLAGS_REG) (const_int 0)]))]
13555   ""
13556   "set%C1\t%0"
13557   [(set_attr "type" "setcc")
13558    (set_attr "mode" "QI")])
13559
13560 (define_insn "*setcc_2"
13561   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13562         (match_operator:QI 1 "ix86_comparison_operator"
13563           [(reg FLAGS_REG) (const_int 0)]))]
13564   ""
13565   "set%C1\t%0"
13566   [(set_attr "type" "setcc")
13567    (set_attr "mode" "QI")])
13568
13569 ;; In general it is not safe to assume too much about CCmode registers,
13570 ;; so simplify-rtx stops when it sees a second one.  Under certain
13571 ;; conditions this is safe on x86, so help combine not create
13572 ;;
13573 ;;      seta    %al
13574 ;;      testb   %al, %al
13575 ;;      sete    %al
13576
13577 (define_split
13578   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13579         (ne:QI (match_operator 1 "ix86_comparison_operator"
13580                  [(reg FLAGS_REG) (const_int 0)])
13581             (const_int 0)))]
13582   ""
13583   [(set (match_dup 0) (match_dup 1))]
13584 {
13585   PUT_MODE (operands[1], QImode);
13586 })
13587
13588 (define_split
13589   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13590         (ne:QI (match_operator 1 "ix86_comparison_operator"
13591                  [(reg FLAGS_REG) (const_int 0)])
13592             (const_int 0)))]
13593   ""
13594   [(set (match_dup 0) (match_dup 1))]
13595 {
13596   PUT_MODE (operands[1], QImode);
13597 })
13598
13599 (define_split
13600   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13601         (eq:QI (match_operator 1 "ix86_comparison_operator"
13602                  [(reg FLAGS_REG) (const_int 0)])
13603             (const_int 0)))]
13604   ""
13605   [(set (match_dup 0) (match_dup 1))]
13606 {
13607   rtx new_op1 = copy_rtx (operands[1]);
13608   operands[1] = new_op1;
13609   PUT_MODE (new_op1, QImode);
13610   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13611                                              GET_MODE (XEXP (new_op1, 0))));
13612
13613   /* Make sure that (a) the CCmode we have for the flags is strong
13614      enough for the reversed compare or (b) we have a valid FP compare.  */
13615   if (! ix86_comparison_operator (new_op1, VOIDmode))
13616     FAIL;
13617 })
13618
13619 (define_split
13620   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13621         (eq:QI (match_operator 1 "ix86_comparison_operator"
13622                  [(reg FLAGS_REG) (const_int 0)])
13623             (const_int 0)))]
13624   ""
13625   [(set (match_dup 0) (match_dup 1))]
13626 {
13627   rtx new_op1 = copy_rtx (operands[1]);
13628   operands[1] = new_op1;
13629   PUT_MODE (new_op1, QImode);
13630   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13631                                              GET_MODE (XEXP (new_op1, 0))));
13632
13633   /* Make sure that (a) the CCmode we have for the flags is strong
13634      enough for the reversed compare or (b) we have a valid FP compare.  */
13635   if (! ix86_comparison_operator (new_op1, VOIDmode))
13636     FAIL;
13637 })
13638
13639 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13640 ;; subsequent logical operations are used to imitate conditional moves.
13641 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13642 ;; it directly.
13643
13644 (define_insn "*sse_setccsf"
13645   [(set (match_operand:SF 0 "register_operand" "=x")
13646         (match_operator:SF 1 "sse_comparison_operator"
13647           [(match_operand:SF 2 "register_operand" "0")
13648            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13649   "TARGET_SSE"
13650   "cmp%D1ss\t{%3, %0|%0, %3}"
13651   [(set_attr "type" "ssecmp")
13652    (set_attr "mode" "SF")])
13653
13654 (define_insn "*sse_setccdf"
13655   [(set (match_operand:DF 0 "register_operand" "=x")
13656         (match_operator:DF 1 "sse_comparison_operator"
13657           [(match_operand:DF 2 "register_operand" "0")
13658            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13659   "TARGET_SSE2"
13660   "cmp%D1sd\t{%3, %0|%0, %3}"
13661   [(set_attr "type" "ssecmp")
13662    (set_attr "mode" "DF")])
13663 \f
13664 ;; Basic conditional jump instructions.
13665 ;; We ignore the overflow flag for signed branch instructions.
13666
13667 ;; For all bCOND expanders, also expand the compare or test insn that
13668 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13669
13670 (define_expand "beq"
13671   [(set (pc)
13672         (if_then_else (match_dup 1)
13673                       (label_ref (match_operand 0 "" ""))
13674                       (pc)))]
13675   ""
13676   "ix86_expand_branch (EQ, operands[0]); DONE;")
13677
13678 (define_expand "bne"
13679   [(set (pc)
13680         (if_then_else (match_dup 1)
13681                       (label_ref (match_operand 0 "" ""))
13682                       (pc)))]
13683   ""
13684   "ix86_expand_branch (NE, operands[0]); DONE;")
13685
13686 (define_expand "bgt"
13687   [(set (pc)
13688         (if_then_else (match_dup 1)
13689                       (label_ref (match_operand 0 "" ""))
13690                       (pc)))]
13691   ""
13692   "ix86_expand_branch (GT, operands[0]); DONE;")
13693
13694 (define_expand "bgtu"
13695   [(set (pc)
13696         (if_then_else (match_dup 1)
13697                       (label_ref (match_operand 0 "" ""))
13698                       (pc)))]
13699   ""
13700   "ix86_expand_branch (GTU, operands[0]); DONE;")
13701
13702 (define_expand "blt"
13703   [(set (pc)
13704         (if_then_else (match_dup 1)
13705                       (label_ref (match_operand 0 "" ""))
13706                       (pc)))]
13707   ""
13708   "ix86_expand_branch (LT, operands[0]); DONE;")
13709
13710 (define_expand "bltu"
13711   [(set (pc)
13712         (if_then_else (match_dup 1)
13713                       (label_ref (match_operand 0 "" ""))
13714                       (pc)))]
13715   ""
13716   "ix86_expand_branch (LTU, operands[0]); DONE;")
13717
13718 (define_expand "bge"
13719   [(set (pc)
13720         (if_then_else (match_dup 1)
13721                       (label_ref (match_operand 0 "" ""))
13722                       (pc)))]
13723   ""
13724   "ix86_expand_branch (GE, operands[0]); DONE;")
13725
13726 (define_expand "bgeu"
13727   [(set (pc)
13728         (if_then_else (match_dup 1)
13729                       (label_ref (match_operand 0 "" ""))
13730                       (pc)))]
13731   ""
13732   "ix86_expand_branch (GEU, operands[0]); DONE;")
13733
13734 (define_expand "ble"
13735   [(set (pc)
13736         (if_then_else (match_dup 1)
13737                       (label_ref (match_operand 0 "" ""))
13738                       (pc)))]
13739   ""
13740   "ix86_expand_branch (LE, operands[0]); DONE;")
13741
13742 (define_expand "bleu"
13743   [(set (pc)
13744         (if_then_else (match_dup 1)
13745                       (label_ref (match_operand 0 "" ""))
13746                       (pc)))]
13747   ""
13748   "ix86_expand_branch (LEU, operands[0]); DONE;")
13749
13750 (define_expand "bunordered"
13751   [(set (pc)
13752         (if_then_else (match_dup 1)
13753                       (label_ref (match_operand 0 "" ""))
13754                       (pc)))]
13755   "TARGET_80387 || TARGET_SSE_MATH"
13756   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13757
13758 (define_expand "bordered"
13759   [(set (pc)
13760         (if_then_else (match_dup 1)
13761                       (label_ref (match_operand 0 "" ""))
13762                       (pc)))]
13763   "TARGET_80387 || TARGET_SSE_MATH"
13764   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13765
13766 (define_expand "buneq"
13767   [(set (pc)
13768         (if_then_else (match_dup 1)
13769                       (label_ref (match_operand 0 "" ""))
13770                       (pc)))]
13771   "TARGET_80387 || TARGET_SSE_MATH"
13772   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13773
13774 (define_expand "bunge"
13775   [(set (pc)
13776         (if_then_else (match_dup 1)
13777                       (label_ref (match_operand 0 "" ""))
13778                       (pc)))]
13779   "TARGET_80387 || TARGET_SSE_MATH"
13780   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13781
13782 (define_expand "bungt"
13783   [(set (pc)
13784         (if_then_else (match_dup 1)
13785                       (label_ref (match_operand 0 "" ""))
13786                       (pc)))]
13787   "TARGET_80387 || TARGET_SSE_MATH"
13788   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13789
13790 (define_expand "bunle"
13791   [(set (pc)
13792         (if_then_else (match_dup 1)
13793                       (label_ref (match_operand 0 "" ""))
13794                       (pc)))]
13795   "TARGET_80387 || TARGET_SSE_MATH"
13796   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13797
13798 (define_expand "bunlt"
13799   [(set (pc)
13800         (if_then_else (match_dup 1)
13801                       (label_ref (match_operand 0 "" ""))
13802                       (pc)))]
13803   "TARGET_80387 || TARGET_SSE_MATH"
13804   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13805
13806 (define_expand "bltgt"
13807   [(set (pc)
13808         (if_then_else (match_dup 1)
13809                       (label_ref (match_operand 0 "" ""))
13810                       (pc)))]
13811   "TARGET_80387 || TARGET_SSE_MATH"
13812   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13813
13814 (define_insn "*jcc_1"
13815   [(set (pc)
13816         (if_then_else (match_operator 1 "ix86_comparison_operator"
13817                                       [(reg FLAGS_REG) (const_int 0)])
13818                       (label_ref (match_operand 0 "" ""))
13819                       (pc)))]
13820   ""
13821   "%+j%C1\t%l0"
13822   [(set_attr "type" "ibr")
13823    (set_attr "modrm" "0")
13824    (set (attr "length")
13825            (if_then_else (and (ge (minus (match_dup 0) (pc))
13826                                   (const_int -126))
13827                               (lt (minus (match_dup 0) (pc))
13828                                   (const_int 128)))
13829              (const_int 2)
13830              (const_int 6)))])
13831
13832 (define_insn "*jcc_2"
13833   [(set (pc)
13834         (if_then_else (match_operator 1 "ix86_comparison_operator"
13835                                       [(reg FLAGS_REG) (const_int 0)])
13836                       (pc)
13837                       (label_ref (match_operand 0 "" ""))))]
13838   ""
13839   "%+j%c1\t%l0"
13840   [(set_attr "type" "ibr")
13841    (set_attr "modrm" "0")
13842    (set (attr "length")
13843            (if_then_else (and (ge (minus (match_dup 0) (pc))
13844                                   (const_int -126))
13845                               (lt (minus (match_dup 0) (pc))
13846                                   (const_int 128)))
13847              (const_int 2)
13848              (const_int 6)))])
13849
13850 ;; In general it is not safe to assume too much about CCmode registers,
13851 ;; so simplify-rtx stops when it sees a second one.  Under certain
13852 ;; conditions this is safe on x86, so help combine not create
13853 ;;
13854 ;;      seta    %al
13855 ;;      testb   %al, %al
13856 ;;      je      Lfoo
13857
13858 (define_split
13859   [(set (pc)
13860         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13861                                       [(reg FLAGS_REG) (const_int 0)])
13862                           (const_int 0))
13863                       (label_ref (match_operand 1 "" ""))
13864                       (pc)))]
13865   ""
13866   [(set (pc)
13867         (if_then_else (match_dup 0)
13868                       (label_ref (match_dup 1))
13869                       (pc)))]
13870 {
13871   PUT_MODE (operands[0], VOIDmode);
13872 })
13873
13874 (define_split
13875   [(set (pc)
13876         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13877                                       [(reg FLAGS_REG) (const_int 0)])
13878                           (const_int 0))
13879                       (label_ref (match_operand 1 "" ""))
13880                       (pc)))]
13881   ""
13882   [(set (pc)
13883         (if_then_else (match_dup 0)
13884                       (label_ref (match_dup 1))
13885                       (pc)))]
13886 {
13887   rtx new_op0 = copy_rtx (operands[0]);
13888   operands[0] = new_op0;
13889   PUT_MODE (new_op0, VOIDmode);
13890   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13891                                              GET_MODE (XEXP (new_op0, 0))));
13892
13893   /* Make sure that (a) the CCmode we have for the flags is strong
13894      enough for the reversed compare or (b) we have a valid FP compare.  */
13895   if (! ix86_comparison_operator (new_op0, VOIDmode))
13896     FAIL;
13897 })
13898
13899 ;; Define combination compare-and-branch fp compare instructions to use
13900 ;; during early optimization.  Splitting the operation apart early makes
13901 ;; for bad code when we want to reverse the operation.
13902
13903 (define_insn "*fp_jcc_1_mixed"
13904   [(set (pc)
13905         (if_then_else (match_operator 0 "comparison_operator"
13906                         [(match_operand 1 "register_operand" "f,x")
13907                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13908           (label_ref (match_operand 3 "" ""))
13909           (pc)))
13910    (clobber (reg:CCFP FPSR_REG))
13911    (clobber (reg:CCFP FLAGS_REG))]
13912   "TARGET_MIX_SSE_I387
13913    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13914    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13915    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13916   "#")
13917
13918 (define_insn "*fp_jcc_1_sse"
13919   [(set (pc)
13920         (if_then_else (match_operator 0 "comparison_operator"
13921                         [(match_operand 1 "register_operand" "x")
13922                          (match_operand 2 "nonimmediate_operand" "xm")])
13923           (label_ref (match_operand 3 "" ""))
13924           (pc)))
13925    (clobber (reg:CCFP FPSR_REG))
13926    (clobber (reg:CCFP FLAGS_REG))]
13927   "TARGET_SSE_MATH
13928    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13929    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13930    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13931   "#")
13932
13933 (define_insn "*fp_jcc_1_387"
13934   [(set (pc)
13935         (if_then_else (match_operator 0 "comparison_operator"
13936                         [(match_operand 1 "register_operand" "f")
13937                          (match_operand 2 "register_operand" "f")])
13938           (label_ref (match_operand 3 "" ""))
13939           (pc)))
13940    (clobber (reg:CCFP FPSR_REG))
13941    (clobber (reg:CCFP FLAGS_REG))]
13942   "TARGET_CMOVE && TARGET_80387
13943    && FLOAT_MODE_P (GET_MODE (operands[1]))
13944    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13945    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13946   "#")
13947
13948 (define_insn "*fp_jcc_2_mixed"
13949   [(set (pc)
13950         (if_then_else (match_operator 0 "comparison_operator"
13951                         [(match_operand 1 "register_operand" "f,x")
13952                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13953           (pc)
13954           (label_ref (match_operand 3 "" ""))))
13955    (clobber (reg:CCFP FPSR_REG))
13956    (clobber (reg:CCFP FLAGS_REG))]
13957   "TARGET_MIX_SSE_I387
13958    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13959    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13960    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13961   "#")
13962
13963 (define_insn "*fp_jcc_2_sse"
13964   [(set (pc)
13965         (if_then_else (match_operator 0 "comparison_operator"
13966                         [(match_operand 1 "register_operand" "x")
13967                          (match_operand 2 "nonimmediate_operand" "xm")])
13968           (pc)
13969           (label_ref (match_operand 3 "" ""))))
13970    (clobber (reg:CCFP FPSR_REG))
13971    (clobber (reg:CCFP FLAGS_REG))]
13972   "TARGET_SSE_MATH
13973    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13974    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13975    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13976   "#")
13977
13978 (define_insn "*fp_jcc_2_387"
13979   [(set (pc)
13980         (if_then_else (match_operator 0 "comparison_operator"
13981                         [(match_operand 1 "register_operand" "f")
13982                          (match_operand 2 "register_operand" "f")])
13983           (pc)
13984           (label_ref (match_operand 3 "" ""))))
13985    (clobber (reg:CCFP FPSR_REG))
13986    (clobber (reg:CCFP FLAGS_REG))]
13987   "TARGET_CMOVE && TARGET_80387
13988    && FLOAT_MODE_P (GET_MODE (operands[1]))
13989    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13990    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13991   "#")
13992
13993 (define_insn "*fp_jcc_3_387"
13994   [(set (pc)
13995         (if_then_else (match_operator 0 "comparison_operator"
13996                         [(match_operand 1 "register_operand" "f")
13997                          (match_operand 2 "nonimmediate_operand" "fm")])
13998           (label_ref (match_operand 3 "" ""))
13999           (pc)))
14000    (clobber (reg:CCFP FPSR_REG))
14001    (clobber (reg:CCFP FLAGS_REG))
14002    (clobber (match_scratch:HI 4 "=a"))]
14003   "TARGET_80387
14004    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14005    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14006    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14007    && SELECT_CC_MODE (GET_CODE (operands[0]),
14008                       operands[1], operands[2]) == CCFPmode
14009    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14010   "#")
14011
14012 (define_insn "*fp_jcc_4_387"
14013   [(set (pc)
14014         (if_then_else (match_operator 0 "comparison_operator"
14015                         [(match_operand 1 "register_operand" "f")
14016                          (match_operand 2 "nonimmediate_operand" "fm")])
14017           (pc)
14018           (label_ref (match_operand 3 "" ""))))
14019    (clobber (reg:CCFP FPSR_REG))
14020    (clobber (reg:CCFP FLAGS_REG))
14021    (clobber (match_scratch:HI 4 "=a"))]
14022   "TARGET_80387
14023    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14024    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14025    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14026    && SELECT_CC_MODE (GET_CODE (operands[0]),
14027                       operands[1], operands[2]) == CCFPmode
14028    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14029   "#")
14030
14031 (define_insn "*fp_jcc_5_387"
14032   [(set (pc)
14033         (if_then_else (match_operator 0 "comparison_operator"
14034                         [(match_operand 1 "register_operand" "f")
14035                          (match_operand 2 "register_operand" "f")])
14036           (label_ref (match_operand 3 "" ""))
14037           (pc)))
14038    (clobber (reg:CCFP FPSR_REG))
14039    (clobber (reg:CCFP FLAGS_REG))
14040    (clobber (match_scratch:HI 4 "=a"))]
14041   "TARGET_80387
14042    && FLOAT_MODE_P (GET_MODE (operands[1]))
14043    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14044    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14045   "#")
14046
14047 (define_insn "*fp_jcc_6_387"
14048   [(set (pc)
14049         (if_then_else (match_operator 0 "comparison_operator"
14050                         [(match_operand 1 "register_operand" "f")
14051                          (match_operand 2 "register_operand" "f")])
14052           (pc)
14053           (label_ref (match_operand 3 "" ""))))
14054    (clobber (reg:CCFP FPSR_REG))
14055    (clobber (reg:CCFP FLAGS_REG))
14056    (clobber (match_scratch:HI 4 "=a"))]
14057   "TARGET_80387
14058    && FLOAT_MODE_P (GET_MODE (operands[1]))
14059    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14060    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14061   "#")
14062
14063 (define_insn "*fp_jcc_7_387"
14064   [(set (pc)
14065         (if_then_else (match_operator 0 "comparison_operator"
14066                         [(match_operand 1 "register_operand" "f")
14067                          (match_operand 2 "const0_operand" "X")])
14068           (label_ref (match_operand 3 "" ""))
14069           (pc)))
14070    (clobber (reg:CCFP FPSR_REG))
14071    (clobber (reg:CCFP FLAGS_REG))
14072    (clobber (match_scratch:HI 4 "=a"))]
14073   "TARGET_80387
14074    && FLOAT_MODE_P (GET_MODE (operands[1]))
14075    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14076    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14077    && SELECT_CC_MODE (GET_CODE (operands[0]),
14078                       operands[1], operands[2]) == CCFPmode
14079    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14080   "#")
14081
14082 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14083 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14084 ;; with a precedence over other operators and is always put in the first
14085 ;; place. Swap condition and operands to match ficom instruction.
14086
14087 (define_insn "*fp_jcc_8<mode>_387"
14088   [(set (pc)
14089         (if_then_else (match_operator 0 "comparison_operator"
14090                         [(match_operator 1 "float_operator"
14091                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14092                            (match_operand 3 "register_operand" "f,f")])
14093           (label_ref (match_operand 4 "" ""))
14094           (pc)))
14095    (clobber (reg:CCFP FPSR_REG))
14096    (clobber (reg:CCFP FLAGS_REG))
14097    (clobber (match_scratch:HI 5 "=a,a"))]
14098   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14099    && FLOAT_MODE_P (GET_MODE (operands[3]))
14100    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14101    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14102    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14103    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14104   "#")
14105
14106 (define_split
14107   [(set (pc)
14108         (if_then_else (match_operator 0 "comparison_operator"
14109                         [(match_operand 1 "register_operand" "")
14110                          (match_operand 2 "nonimmediate_operand" "")])
14111           (match_operand 3 "" "")
14112           (match_operand 4 "" "")))
14113    (clobber (reg:CCFP FPSR_REG))
14114    (clobber (reg:CCFP FLAGS_REG))]
14115   "reload_completed"
14116   [(const_int 0)]
14117 {
14118   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14119                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14120   DONE;
14121 })
14122
14123 (define_split
14124   [(set (pc)
14125         (if_then_else (match_operator 0 "comparison_operator"
14126                         [(match_operand 1 "register_operand" "")
14127                          (match_operand 2 "general_operand" "")])
14128           (match_operand 3 "" "")
14129           (match_operand 4 "" "")))
14130    (clobber (reg:CCFP FPSR_REG))
14131    (clobber (reg:CCFP FLAGS_REG))
14132    (clobber (match_scratch:HI 5 "=a"))]
14133   "reload_completed"
14134   [(const_int 0)]
14135 {
14136   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14137                         operands[3], operands[4], operands[5], NULL_RTX);
14138   DONE;
14139 })
14140
14141 (define_split
14142   [(set (pc)
14143         (if_then_else (match_operator 0 "comparison_operator"
14144                         [(match_operator 1 "float_operator"
14145                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14146                            (match_operand 3 "register_operand" "")])
14147           (match_operand 4 "" "")
14148           (match_operand 5 "" "")))
14149    (clobber (reg:CCFP FPSR_REG))
14150    (clobber (reg:CCFP FLAGS_REG))
14151    (clobber (match_scratch:HI 6 "=a"))]
14152   "reload_completed"
14153   [(const_int 0)]
14154 {
14155   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14156   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14157                         operands[3], operands[7],
14158                         operands[4], operands[5], operands[6], NULL_RTX);
14159   DONE;
14160 })
14161
14162 ;; %%% Kill this when reload knows how to do it.
14163 (define_split
14164   [(set (pc)
14165         (if_then_else (match_operator 0 "comparison_operator"
14166                         [(match_operator 1 "float_operator"
14167                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14168                            (match_operand 3 "register_operand" "")])
14169           (match_operand 4 "" "")
14170           (match_operand 5 "" "")))
14171    (clobber (reg:CCFP FPSR_REG))
14172    (clobber (reg:CCFP FLAGS_REG))
14173    (clobber (match_scratch:HI 6 "=a"))]
14174   "reload_completed"
14175   [(const_int 0)]
14176 {
14177   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14178   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14179   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14180                         operands[3], operands[7],
14181                         operands[4], operands[5], operands[6], operands[2]);
14182   DONE;
14183 })
14184 \f
14185 ;; Unconditional and other jump instructions
14186
14187 (define_insn "jump"
14188   [(set (pc)
14189         (label_ref (match_operand 0 "" "")))]
14190   ""
14191   "jmp\t%l0"
14192   [(set_attr "type" "ibr")
14193    (set (attr "length")
14194            (if_then_else (and (ge (minus (match_dup 0) (pc))
14195                                   (const_int -126))
14196                               (lt (minus (match_dup 0) (pc))
14197                                   (const_int 128)))
14198              (const_int 2)
14199              (const_int 5)))
14200    (set_attr "modrm" "0")])
14201
14202 (define_expand "indirect_jump"
14203   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14204   ""
14205   "")
14206
14207 (define_insn "*indirect_jump"
14208   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14209   "!TARGET_64BIT"
14210   "jmp\t%A0"
14211   [(set_attr "type" "ibr")
14212    (set_attr "length_immediate" "0")])
14213
14214 (define_insn "*indirect_jump_rtx64"
14215   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14216   "TARGET_64BIT"
14217   "jmp\t%A0"
14218   [(set_attr "type" "ibr")
14219    (set_attr "length_immediate" "0")])
14220
14221 (define_expand "tablejump"
14222   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14223               (use (label_ref (match_operand 1 "" "")))])]
14224   ""
14225 {
14226   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14227      relative.  Convert the relative address to an absolute address.  */
14228   if (flag_pic)
14229     {
14230       rtx op0, op1;
14231       enum rtx_code code;
14232
14233       if (TARGET_64BIT)
14234         {
14235           code = PLUS;
14236           op0 = operands[0];
14237           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14238         }
14239       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14240         {
14241           code = PLUS;
14242           op0 = operands[0];
14243           op1 = pic_offset_table_rtx;
14244         }
14245       else
14246         {
14247           code = MINUS;
14248           op0 = pic_offset_table_rtx;
14249           op1 = operands[0];
14250         }
14251
14252       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14253                                          OPTAB_DIRECT);
14254     }
14255 })
14256
14257 (define_insn "*tablejump_1"
14258   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14259    (use (label_ref (match_operand 1 "" "")))]
14260   "!TARGET_64BIT"
14261   "jmp\t%A0"
14262   [(set_attr "type" "ibr")
14263    (set_attr "length_immediate" "0")])
14264
14265 (define_insn "*tablejump_1_rtx64"
14266   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14267    (use (label_ref (match_operand 1 "" "")))]
14268   "TARGET_64BIT"
14269   "jmp\t%A0"
14270   [(set_attr "type" "ibr")
14271    (set_attr "length_immediate" "0")])
14272 \f
14273 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14274
14275 (define_peephole2
14276   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14277    (set (match_operand:QI 1 "register_operand" "")
14278         (match_operator:QI 2 "ix86_comparison_operator"
14279           [(reg FLAGS_REG) (const_int 0)]))
14280    (set (match_operand 3 "q_regs_operand" "")
14281         (zero_extend (match_dup 1)))]
14282   "(peep2_reg_dead_p (3, operands[1])
14283     || operands_match_p (operands[1], operands[3]))
14284    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14285   [(set (match_dup 4) (match_dup 0))
14286    (set (strict_low_part (match_dup 5))
14287         (match_dup 2))]
14288 {
14289   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14290   operands[5] = gen_lowpart (QImode, operands[3]);
14291   ix86_expand_clear (operands[3]);
14292 })
14293
14294 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14295
14296 (define_peephole2
14297   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14298    (set (match_operand:QI 1 "register_operand" "")
14299         (match_operator:QI 2 "ix86_comparison_operator"
14300           [(reg FLAGS_REG) (const_int 0)]))
14301    (parallel [(set (match_operand 3 "q_regs_operand" "")
14302                    (zero_extend (match_dup 1)))
14303               (clobber (reg:CC FLAGS_REG))])]
14304   "(peep2_reg_dead_p (3, operands[1])
14305     || operands_match_p (operands[1], operands[3]))
14306    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14307   [(set (match_dup 4) (match_dup 0))
14308    (set (strict_low_part (match_dup 5))
14309         (match_dup 2))]
14310 {
14311   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14312   operands[5] = gen_lowpart (QImode, operands[3]);
14313   ix86_expand_clear (operands[3]);
14314 })
14315 \f
14316 ;; Call instructions.
14317
14318 ;; The predicates normally associated with named expanders are not properly
14319 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14320 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14321
14322 ;; Call subroutine returning no value.
14323
14324 (define_expand "call_pop"
14325   [(parallel [(call (match_operand:QI 0 "" "")
14326                     (match_operand:SI 1 "" ""))
14327               (set (reg:SI SP_REG)
14328                    (plus:SI (reg:SI SP_REG)
14329                             (match_operand:SI 3 "" "")))])]
14330   "!TARGET_64BIT"
14331 {
14332   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14333   DONE;
14334 })
14335
14336 (define_insn "*call_pop_0"
14337   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14338          (match_operand:SI 1 "" ""))
14339    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14340                             (match_operand:SI 2 "immediate_operand" "")))]
14341   "!TARGET_64BIT"
14342 {
14343   if (SIBLING_CALL_P (insn))
14344     return "jmp\t%P0";
14345   else
14346     return "call\t%P0";
14347 }
14348   [(set_attr "type" "call")])
14349
14350 (define_insn "*call_pop_1"
14351   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14352          (match_operand:SI 1 "" ""))
14353    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14354                             (match_operand:SI 2 "immediate_operand" "i")))]
14355   "!TARGET_64BIT"
14356 {
14357   if (constant_call_address_operand (operands[0], Pmode))
14358     {
14359       if (SIBLING_CALL_P (insn))
14360         return "jmp\t%P0";
14361       else
14362         return "call\t%P0";
14363     }
14364   if (SIBLING_CALL_P (insn))
14365     return "jmp\t%A0";
14366   else
14367     return "call\t%A0";
14368 }
14369   [(set_attr "type" "call")])
14370
14371 (define_expand "call"
14372   [(call (match_operand:QI 0 "" "")
14373          (match_operand 1 "" ""))
14374    (use (match_operand 2 "" ""))]
14375   ""
14376 {
14377   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14378   DONE;
14379 })
14380
14381 (define_expand "sibcall"
14382   [(call (match_operand:QI 0 "" "")
14383          (match_operand 1 "" ""))
14384    (use (match_operand 2 "" ""))]
14385   ""
14386 {
14387   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14388   DONE;
14389 })
14390
14391 (define_insn "*call_0"
14392   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14393          (match_operand 1 "" ""))]
14394   ""
14395 {
14396   if (SIBLING_CALL_P (insn))
14397     return "jmp\t%P0";
14398   else
14399     return "call\t%P0";
14400 }
14401   [(set_attr "type" "call")])
14402
14403 (define_insn "*call_1"
14404   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14405          (match_operand 1 "" ""))]
14406   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14407 {
14408   if (constant_call_address_operand (operands[0], Pmode))
14409     return "call\t%P0";
14410   return "call\t%A0";
14411 }
14412   [(set_attr "type" "call")])
14413
14414 (define_insn "*sibcall_1"
14415   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14416          (match_operand 1 "" ""))]
14417   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14418 {
14419   if (constant_call_address_operand (operands[0], Pmode))
14420     return "jmp\t%P0";
14421   return "jmp\t%A0";
14422 }
14423   [(set_attr "type" "call")])
14424
14425 (define_insn "*call_1_rex64"
14426   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14427          (match_operand 1 "" ""))]
14428   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14429 {
14430   if (constant_call_address_operand (operands[0], Pmode))
14431     return "call\t%P0";
14432   return "call\t%A0";
14433 }
14434   [(set_attr "type" "call")])
14435
14436 (define_insn "*sibcall_1_rex64"
14437   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14438          (match_operand 1 "" ""))]
14439   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14440   "jmp\t%P0"
14441   [(set_attr "type" "call")])
14442
14443 (define_insn "*sibcall_1_rex64_v"
14444   [(call (mem:QI (reg:DI R11_REG))
14445          (match_operand 0 "" ""))]
14446   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14447   "jmp\t*%%r11"
14448   [(set_attr "type" "call")])
14449
14450
14451 ;; Call subroutine, returning value in operand 0
14452
14453 (define_expand "call_value_pop"
14454   [(parallel [(set (match_operand 0 "" "")
14455                    (call (match_operand:QI 1 "" "")
14456                          (match_operand:SI 2 "" "")))
14457               (set (reg:SI SP_REG)
14458                    (plus:SI (reg:SI SP_REG)
14459                             (match_operand:SI 4 "" "")))])]
14460   "!TARGET_64BIT"
14461 {
14462   ix86_expand_call (operands[0], operands[1], operands[2],
14463                     operands[3], operands[4], 0);
14464   DONE;
14465 })
14466
14467 (define_expand "call_value"
14468   [(set (match_operand 0 "" "")
14469         (call (match_operand:QI 1 "" "")
14470               (match_operand:SI 2 "" "")))
14471    (use (match_operand:SI 3 "" ""))]
14472   ;; Operand 2 not used on the i386.
14473   ""
14474 {
14475   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14476   DONE;
14477 })
14478
14479 (define_expand "sibcall_value"
14480   [(set (match_operand 0 "" "")
14481         (call (match_operand:QI 1 "" "")
14482               (match_operand:SI 2 "" "")))
14483    (use (match_operand:SI 3 "" ""))]
14484   ;; Operand 2 not used on the i386.
14485   ""
14486 {
14487   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14488   DONE;
14489 })
14490
14491 ;; Call subroutine returning any type.
14492
14493 (define_expand "untyped_call"
14494   [(parallel [(call (match_operand 0 "" "")
14495                     (const_int 0))
14496               (match_operand 1 "" "")
14497               (match_operand 2 "" "")])]
14498   ""
14499 {
14500   int i;
14501
14502   /* In order to give reg-stack an easier job in validating two
14503      coprocessor registers as containing a possible return value,
14504      simply pretend the untyped call returns a complex long double
14505      value.  */
14506
14507   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14508                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14509                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14510                     NULL, 0);
14511
14512   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14513     {
14514       rtx set = XVECEXP (operands[2], 0, i);
14515       emit_move_insn (SET_DEST (set), SET_SRC (set));
14516     }
14517
14518   /* The optimizer does not know that the call sets the function value
14519      registers we stored in the result block.  We avoid problems by
14520      claiming that all hard registers are used and clobbered at this
14521      point.  */
14522   emit_insn (gen_blockage (const0_rtx));
14523
14524   DONE;
14525 })
14526 \f
14527 ;; Prologue and epilogue instructions
14528
14529 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14530 ;; all of memory.  This blocks insns from being moved across this point.
14531
14532 (define_insn "blockage"
14533   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14534   ""
14535   ""
14536   [(set_attr "length" "0")])
14537
14538 ;; Insn emitted into the body of a function to return from a function.
14539 ;; This is only done if the function's epilogue is known to be simple.
14540 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14541
14542 (define_expand "return"
14543   [(return)]
14544   "ix86_can_use_return_insn_p ()"
14545 {
14546   if (current_function_pops_args)
14547     {
14548       rtx popc = GEN_INT (current_function_pops_args);
14549       emit_jump_insn (gen_return_pop_internal (popc));
14550       DONE;
14551     }
14552 })
14553
14554 (define_insn "return_internal"
14555   [(return)]
14556   "reload_completed"
14557   "ret"
14558   [(set_attr "length" "1")
14559    (set_attr "length_immediate" "0")
14560    (set_attr "modrm" "0")])
14561
14562 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14563 ;; instruction Athlon and K8 have.
14564
14565 (define_insn "return_internal_long"
14566   [(return)
14567    (unspec [(const_int 0)] UNSPEC_REP)]
14568   "reload_completed"
14569   "rep {;} ret"
14570   [(set_attr "length" "1")
14571    (set_attr "length_immediate" "0")
14572    (set_attr "prefix_rep" "1")
14573    (set_attr "modrm" "0")])
14574
14575 (define_insn "return_pop_internal"
14576   [(return)
14577    (use (match_operand:SI 0 "const_int_operand" ""))]
14578   "reload_completed"
14579   "ret\t%0"
14580   [(set_attr "length" "3")
14581    (set_attr "length_immediate" "2")
14582    (set_attr "modrm" "0")])
14583
14584 (define_insn "return_indirect_internal"
14585   [(return)
14586    (use (match_operand:SI 0 "register_operand" "r"))]
14587   "reload_completed"
14588   "jmp\t%A0"
14589   [(set_attr "type" "ibr")
14590    (set_attr "length_immediate" "0")])
14591
14592 (define_insn "nop"
14593   [(const_int 0)]
14594   ""
14595   "nop"
14596   [(set_attr "length" "1")
14597    (set_attr "length_immediate" "0")
14598    (set_attr "modrm" "0")])
14599
14600 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14601 ;; branch prediction penalty for the third jump in a 16-byte
14602 ;; block on K8.
14603
14604 (define_insn "align"
14605   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14606   ""
14607 {
14608 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14609   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14610 #else
14611   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14612      The align insn is used to avoid 3 jump instructions in the row to improve
14613      branch prediction and the benefits hardly outweigh the cost of extra 8
14614      nops on the average inserted by full alignment pseudo operation.  */
14615 #endif
14616   return "";
14617 }
14618   [(set_attr "length" "16")])
14619
14620 (define_expand "prologue"
14621   [(const_int 1)]
14622   ""
14623   "ix86_expand_prologue (); DONE;")
14624
14625 (define_insn "set_got"
14626   [(set (match_operand:SI 0 "register_operand" "=r")
14627         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14628    (clobber (reg:CC FLAGS_REG))]
14629   "!TARGET_64BIT"
14630   { return output_set_got (operands[0], NULL_RTX); }
14631   [(set_attr "type" "multi")
14632    (set_attr "length" "12")])
14633
14634 (define_insn "set_got_labelled"
14635   [(set (match_operand:SI 0 "register_operand" "=r")
14636         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14637          UNSPEC_SET_GOT))
14638    (clobber (reg:CC FLAGS_REG))]
14639   "!TARGET_64BIT"
14640   { return output_set_got (operands[0], operands[1]); }
14641   [(set_attr "type" "multi")
14642    (set_attr "length" "12")])
14643
14644 (define_insn "set_got_rex64"
14645   [(set (match_operand:DI 0 "register_operand" "=r")
14646         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14647   "TARGET_64BIT"
14648   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14649   [(set_attr "type" "lea")
14650    (set_attr "length" "6")])
14651
14652 (define_expand "epilogue"
14653   [(const_int 1)]
14654   ""
14655   "ix86_expand_epilogue (1); DONE;")
14656
14657 (define_expand "sibcall_epilogue"
14658   [(const_int 1)]
14659   ""
14660   "ix86_expand_epilogue (0); DONE;")
14661
14662 (define_expand "eh_return"
14663   [(use (match_operand 0 "register_operand" ""))]
14664   ""
14665 {
14666   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14667
14668   /* Tricky bit: we write the address of the handler to which we will
14669      be returning into someone else's stack frame, one word below the
14670      stack address we wish to restore.  */
14671   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14672   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14673   tmp = gen_rtx_MEM (Pmode, tmp);
14674   emit_move_insn (tmp, ra);
14675
14676   if (Pmode == SImode)
14677     emit_jump_insn (gen_eh_return_si (sa));
14678   else
14679     emit_jump_insn (gen_eh_return_di (sa));
14680   emit_barrier ();
14681   DONE;
14682 })
14683
14684 (define_insn_and_split "eh_return_si"
14685   [(set (pc)
14686         (unspec [(match_operand:SI 0 "register_operand" "c")]
14687                  UNSPEC_EH_RETURN))]
14688   "!TARGET_64BIT"
14689   "#"
14690   "reload_completed"
14691   [(const_int 1)]
14692   "ix86_expand_epilogue (2); DONE;")
14693
14694 (define_insn_and_split "eh_return_di"
14695   [(set (pc)
14696         (unspec [(match_operand:DI 0 "register_operand" "c")]
14697                  UNSPEC_EH_RETURN))]
14698   "TARGET_64BIT"
14699   "#"
14700   "reload_completed"
14701   [(const_int 1)]
14702   "ix86_expand_epilogue (2); DONE;")
14703
14704 (define_insn "leave"
14705   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14706    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14707    (clobber (mem:BLK (scratch)))]
14708   "!TARGET_64BIT"
14709   "leave"
14710   [(set_attr "type" "leave")])
14711
14712 (define_insn "leave_rex64"
14713   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14714    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14715    (clobber (mem:BLK (scratch)))]
14716   "TARGET_64BIT"
14717   "leave"
14718   [(set_attr "type" "leave")])
14719 \f
14720 (define_expand "ffssi2"
14721   [(parallel
14722      [(set (match_operand:SI 0 "register_operand" "")
14723            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14724       (clobber (match_scratch:SI 2 ""))
14725       (clobber (reg:CC FLAGS_REG))])]
14726   ""
14727   "")
14728
14729 (define_insn_and_split "*ffs_cmove"
14730   [(set (match_operand:SI 0 "register_operand" "=r")
14731         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14732    (clobber (match_scratch:SI 2 "=&r"))
14733    (clobber (reg:CC FLAGS_REG))]
14734   "TARGET_CMOVE"
14735   "#"
14736   "&& reload_completed"
14737   [(set (match_dup 2) (const_int -1))
14738    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14739               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14740    (set (match_dup 0) (if_then_else:SI
14741                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14742                         (match_dup 2)
14743                         (match_dup 0)))
14744    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14745               (clobber (reg:CC FLAGS_REG))])]
14746   "")
14747
14748 (define_insn_and_split "*ffs_no_cmove"
14749   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14750         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14751    (clobber (match_scratch:SI 2 "=&q"))
14752    (clobber (reg:CC FLAGS_REG))]
14753   ""
14754   "#"
14755   "reload_completed"
14756   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14757               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14758    (set (strict_low_part (match_dup 3))
14759         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14760    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14761               (clobber (reg:CC FLAGS_REG))])
14762    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14763               (clobber (reg:CC FLAGS_REG))])
14764    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14765               (clobber (reg:CC FLAGS_REG))])]
14766 {
14767   operands[3] = gen_lowpart (QImode, operands[2]);
14768   ix86_expand_clear (operands[2]);
14769 })
14770
14771 (define_insn "*ffssi_1"
14772   [(set (reg:CCZ FLAGS_REG)
14773         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14774                      (const_int 0)))
14775    (set (match_operand:SI 0 "register_operand" "=r")
14776         (ctz:SI (match_dup 1)))]
14777   ""
14778   "bsf{l}\t{%1, %0|%0, %1}"
14779   [(set_attr "prefix_0f" "1")])
14780
14781 (define_expand "ffsdi2"
14782   [(parallel
14783      [(set (match_operand:DI 0 "register_operand" "")
14784            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14785       (clobber (match_scratch:DI 2 ""))
14786       (clobber (reg:CC FLAGS_REG))])]
14787   "TARGET_64BIT && TARGET_CMOVE"
14788   "")
14789
14790 (define_insn_and_split "*ffs_rex64"
14791   [(set (match_operand:DI 0 "register_operand" "=r")
14792         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14793    (clobber (match_scratch:DI 2 "=&r"))
14794    (clobber (reg:CC FLAGS_REG))]
14795   "TARGET_64BIT && TARGET_CMOVE"
14796   "#"
14797   "&& reload_completed"
14798   [(set (match_dup 2) (const_int -1))
14799    (parallel [(set (reg:CCZ FLAGS_REG)
14800                    (compare:CCZ (match_dup 1) (const_int 0)))
14801               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14802    (set (match_dup 0) (if_then_else:DI
14803                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14804                         (match_dup 2)
14805                         (match_dup 0)))
14806    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14807               (clobber (reg:CC FLAGS_REG))])]
14808   "")
14809
14810 (define_insn "*ffsdi_1"
14811   [(set (reg:CCZ FLAGS_REG)
14812         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14813                      (const_int 0)))
14814    (set (match_operand:DI 0 "register_operand" "=r")
14815         (ctz:DI (match_dup 1)))]
14816   "TARGET_64BIT"
14817   "bsf{q}\t{%1, %0|%0, %1}"
14818   [(set_attr "prefix_0f" "1")])
14819
14820 (define_insn "ctzsi2"
14821   [(set (match_operand:SI 0 "register_operand" "=r")
14822         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14823    (clobber (reg:CC FLAGS_REG))]
14824   ""
14825   "bsf{l}\t{%1, %0|%0, %1}"
14826   [(set_attr "prefix_0f" "1")])
14827
14828 (define_insn "ctzdi2"
14829   [(set (match_operand:DI 0 "register_operand" "=r")
14830         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14831    (clobber (reg:CC FLAGS_REG))]
14832   "TARGET_64BIT"
14833   "bsf{q}\t{%1, %0|%0, %1}"
14834   [(set_attr "prefix_0f" "1")])
14835
14836 (define_expand "clzsi2"
14837   [(parallel
14838      [(set (match_operand:SI 0 "register_operand" "")
14839            (minus:SI (const_int 31)
14840                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14841       (clobber (reg:CC FLAGS_REG))])
14842    (parallel
14843      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14844       (clobber (reg:CC FLAGS_REG))])]
14845   ""
14846 {
14847   if (TARGET_ABM)
14848     {
14849       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14850       DONE;
14851     }
14852 })
14853
14854 (define_insn "clzsi2_abm"
14855   [(set (match_operand:SI 0 "register_operand" "=r")
14856         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14857    (clobber (reg:CC FLAGS_REG))]
14858   "TARGET_ABM"
14859   "lzcnt{l}\t{%1, %0|%0, %1}"
14860   [(set_attr "prefix_rep" "1")
14861    (set_attr "type" "bitmanip")
14862    (set_attr "mode" "SI")])
14863
14864 (define_insn "*bsr"
14865   [(set (match_operand:SI 0 "register_operand" "=r")
14866         (minus:SI (const_int 31)
14867                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14868    (clobber (reg:CC FLAGS_REG))]
14869   ""
14870   "bsr{l}\t{%1, %0|%0, %1}"
14871   [(set_attr "prefix_0f" "1")
14872    (set_attr "mode" "SI")])
14873
14874 (define_insn "popcountsi2"
14875   [(set (match_operand:SI 0 "register_operand" "=r")
14876         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14877    (clobber (reg:CC FLAGS_REG))]
14878   "TARGET_POPCNT"
14879   "popcnt{l}\t{%1, %0|%0, %1}"
14880   [(set_attr "prefix_rep" "1")
14881    (set_attr "type" "bitmanip")
14882    (set_attr "mode" "SI")])
14883
14884 (define_insn "*popcountsi2_cmp"
14885   [(set (reg FLAGS_REG)
14886         (compare
14887           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14888           (const_int 0)))
14889    (set (match_operand:SI 0 "register_operand" "=r")
14890         (popcount:SI (match_dup 1)))]
14891   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14892   "popcnt{l}\t{%1, %0|%0, %1}"
14893   [(set_attr "prefix_rep" "1")
14894    (set_attr "type" "bitmanip")
14895    (set_attr "mode" "SI")])
14896
14897 (define_insn "*popcountsi2_cmp_zext"
14898   [(set (reg FLAGS_REG)
14899         (compare
14900           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14901           (const_int 0)))
14902    (set (match_operand:DI 0 "register_operand" "=r")
14903         (zero_extend:DI(popcount:SI (match_dup 1))))]
14904   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14905   "popcnt{l}\t{%1, %0|%0, %1}"
14906   [(set_attr "prefix_rep" "1")
14907    (set_attr "type" "bitmanip")
14908    (set_attr "mode" "SI")])
14909
14910 (define_insn "bswapsi2"
14911   [(set (match_operand:SI 0 "register_operand" "=r")
14912         (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14913    (clobber (reg:CC FLAGS_REG))]
14914   "TARGET_BSWAP"
14915   "bswap\t%k0"
14916   [(set_attr "prefix_0f" "1")
14917    (set_attr "length" "2")])
14918
14919 (define_insn "bswapdi2"
14920   [(set (match_operand:DI 0 "register_operand" "=r")
14921         (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14922    (clobber (reg:CC FLAGS_REG))]
14923   "TARGET_64BIT && TARGET_BSWAP"
14924   "bswap\t%0"
14925   [(set_attr "prefix_0f" "1")
14926    (set_attr "length" "3")])
14927
14928 (define_expand "clzdi2"
14929   [(parallel
14930      [(set (match_operand:DI 0 "register_operand" "")
14931            (minus:DI (const_int 63)
14932                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14933       (clobber (reg:CC FLAGS_REG))])
14934    (parallel
14935      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14936       (clobber (reg:CC FLAGS_REG))])]
14937   "TARGET_64BIT"
14938 {
14939   if (TARGET_ABM)
14940     {
14941       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14942       DONE;
14943     }
14944 })
14945
14946 (define_insn "clzdi2_abm"
14947   [(set (match_operand:DI 0 "register_operand" "=r")
14948         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14949    (clobber (reg:CC FLAGS_REG))]
14950   "TARGET_64BIT && TARGET_ABM"
14951   "lzcnt{q}\t{%1, %0|%0, %1}"
14952   [(set_attr "prefix_rep" "1")
14953    (set_attr "type" "bitmanip")
14954    (set_attr "mode" "DI")])
14955
14956 (define_insn "*bsr_rex64"
14957   [(set (match_operand:DI 0 "register_operand" "=r")
14958         (minus:DI (const_int 63)
14959                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14960    (clobber (reg:CC FLAGS_REG))]
14961   "TARGET_64BIT"
14962   "bsr{q}\t{%1, %0|%0, %1}"
14963   [(set_attr "prefix_0f" "1")
14964    (set_attr "mode" "DI")])
14965
14966 (define_insn "popcountdi2"
14967   [(set (match_operand:DI 0 "register_operand" "=r")
14968         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14969    (clobber (reg:CC FLAGS_REG))]
14970   "TARGET_64BIT && TARGET_POPCNT"
14971   "popcnt{q}\t{%1, %0|%0, %1}"
14972   [(set_attr "prefix_rep" "1")
14973    (set_attr "type" "bitmanip")
14974    (set_attr "mode" "DI")])
14975
14976 (define_insn "*popcountdi2_cmp"
14977   [(set (reg FLAGS_REG)
14978         (compare
14979           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14980           (const_int 0)))
14981    (set (match_operand:DI 0 "register_operand" "=r")
14982         (popcount:DI (match_dup 1)))]
14983   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14984   "popcnt{q}\t{%1, %0|%0, %1}"
14985   [(set_attr "prefix_rep" "1")
14986    (set_attr "type" "bitmanip")
14987    (set_attr "mode" "DI")])
14988
14989 (define_expand "clzhi2"
14990   [(parallel
14991      [(set (match_operand:HI 0 "register_operand" "")
14992            (minus:HI (const_int 15)
14993                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14994       (clobber (reg:CC FLAGS_REG))])
14995    (parallel
14996      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14997       (clobber (reg:CC FLAGS_REG))])]
14998   ""
14999 {
15000   if (TARGET_ABM)
15001     {
15002       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15003       DONE;
15004     }
15005 })
15006
15007 (define_insn "clzhi2_abm"
15008   [(set (match_operand:HI 0 "register_operand" "=r")
15009         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15010    (clobber (reg:CC FLAGS_REG))]
15011   "TARGET_ABM"
15012   "lzcnt{w}\t{%1, %0|%0, %1}"
15013   [(set_attr "prefix_rep" "1")
15014    (set_attr "type" "bitmanip")
15015    (set_attr "mode" "HI")])
15016
15017 (define_insn "*bsrhi"
15018   [(set (match_operand:HI 0 "register_operand" "=r")
15019         (minus:HI (const_int 15)
15020                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15021    (clobber (reg:CC FLAGS_REG))]
15022   ""
15023   "bsr{w}\t{%1, %0|%0, %1}"
15024   [(set_attr "prefix_0f" "1")
15025    (set_attr "mode" "HI")])
15026
15027 (define_insn "popcounthi2"
15028   [(set (match_operand:HI 0 "register_operand" "=r")
15029         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15030    (clobber (reg:CC FLAGS_REG))]
15031   "TARGET_POPCNT"
15032   "popcnt{w}\t{%1, %0|%0, %1}"
15033   [(set_attr "prefix_rep" "1")
15034    (set_attr "type" "bitmanip")
15035    (set_attr "mode" "HI")])
15036
15037 (define_insn "*popcounthi2_cmp"
15038   [(set (reg FLAGS_REG)
15039         (compare
15040           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15041           (const_int 0)))
15042    (set (match_operand:HI 0 "register_operand" "=r")
15043         (popcount:HI (match_dup 1)))]
15044   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15045   "popcnt{w}\t{%1, %0|%0, %1}"
15046   [(set_attr "prefix_rep" "1")
15047    (set_attr "type" "bitmanip")
15048    (set_attr "mode" "HI")])
15049 \f
15050 ;; Thread-local storage patterns for ELF.
15051 ;;
15052 ;; Note that these code sequences must appear exactly as shown
15053 ;; in order to allow linker relaxation.
15054
15055 (define_insn "*tls_global_dynamic_32_gnu"
15056   [(set (match_operand:SI 0 "register_operand" "=a")
15057         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15058                     (match_operand:SI 2 "tls_symbolic_operand" "")
15059                     (match_operand:SI 3 "call_insn_operand" "")]
15060                     UNSPEC_TLS_GD))
15061    (clobber (match_scratch:SI 4 "=d"))
15062    (clobber (match_scratch:SI 5 "=c"))
15063    (clobber (reg:CC FLAGS_REG))]
15064   "!TARGET_64BIT && TARGET_GNU_TLS"
15065   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15066   [(set_attr "type" "multi")
15067    (set_attr "length" "12")])
15068
15069 (define_insn "*tls_global_dynamic_32_sun"
15070   [(set (match_operand:SI 0 "register_operand" "=a")
15071         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15072                     (match_operand:SI 2 "tls_symbolic_operand" "")
15073                     (match_operand:SI 3 "call_insn_operand" "")]
15074                     UNSPEC_TLS_GD))
15075    (clobber (match_scratch:SI 4 "=d"))
15076    (clobber (match_scratch:SI 5 "=c"))
15077    (clobber (reg:CC FLAGS_REG))]
15078   "!TARGET_64BIT && TARGET_SUN_TLS"
15079   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15080         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15081   [(set_attr "type" "multi")
15082    (set_attr "length" "14")])
15083
15084 (define_expand "tls_global_dynamic_32"
15085   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15086                    (unspec:SI
15087                     [(match_dup 2)
15088                      (match_operand:SI 1 "tls_symbolic_operand" "")
15089                      (match_dup 3)]
15090                     UNSPEC_TLS_GD))
15091               (clobber (match_scratch:SI 4 ""))
15092               (clobber (match_scratch:SI 5 ""))
15093               (clobber (reg:CC FLAGS_REG))])]
15094   ""
15095 {
15096   if (flag_pic)
15097     operands[2] = pic_offset_table_rtx;
15098   else
15099     {
15100       operands[2] = gen_reg_rtx (Pmode);
15101       emit_insn (gen_set_got (operands[2]));
15102     }
15103   if (TARGET_GNU2_TLS)
15104     {
15105        emit_insn (gen_tls_dynamic_gnu2_32
15106                   (operands[0], operands[1], operands[2]));
15107        DONE;
15108     }
15109   operands[3] = ix86_tls_get_addr ();
15110 })
15111
15112 (define_insn "*tls_global_dynamic_64"
15113   [(set (match_operand:DI 0 "register_operand" "=a")
15114         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15115                  (match_operand:DI 3 "" "")))
15116    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15117               UNSPEC_TLS_GD)]
15118   "TARGET_64BIT"
15119   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15120   [(set_attr "type" "multi")
15121    (set_attr "length" "16")])
15122
15123 (define_expand "tls_global_dynamic_64"
15124   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15125                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15126               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15127                          UNSPEC_TLS_GD)])]
15128   ""
15129 {
15130   if (TARGET_GNU2_TLS)
15131     {
15132        emit_insn (gen_tls_dynamic_gnu2_64
15133                   (operands[0], operands[1]));
15134        DONE;
15135     }
15136   operands[2] = ix86_tls_get_addr ();
15137 })
15138
15139 (define_insn "*tls_local_dynamic_base_32_gnu"
15140   [(set (match_operand:SI 0 "register_operand" "=a")
15141         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15142                     (match_operand:SI 2 "call_insn_operand" "")]
15143                    UNSPEC_TLS_LD_BASE))
15144    (clobber (match_scratch:SI 3 "=d"))
15145    (clobber (match_scratch:SI 4 "=c"))
15146    (clobber (reg:CC FLAGS_REG))]
15147   "!TARGET_64BIT && TARGET_GNU_TLS"
15148   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15149   [(set_attr "type" "multi")
15150    (set_attr "length" "11")])
15151
15152 (define_insn "*tls_local_dynamic_base_32_sun"
15153   [(set (match_operand:SI 0 "register_operand" "=a")
15154         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15155                     (match_operand:SI 2 "call_insn_operand" "")]
15156                    UNSPEC_TLS_LD_BASE))
15157    (clobber (match_scratch:SI 3 "=d"))
15158    (clobber (match_scratch:SI 4 "=c"))
15159    (clobber (reg:CC FLAGS_REG))]
15160   "!TARGET_64BIT && TARGET_SUN_TLS"
15161   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15162         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15163   [(set_attr "type" "multi")
15164    (set_attr "length" "13")])
15165
15166 (define_expand "tls_local_dynamic_base_32"
15167   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15168                    (unspec:SI [(match_dup 1) (match_dup 2)]
15169                               UNSPEC_TLS_LD_BASE))
15170               (clobber (match_scratch:SI 3 ""))
15171               (clobber (match_scratch:SI 4 ""))
15172               (clobber (reg:CC FLAGS_REG))])]
15173   ""
15174 {
15175   if (flag_pic)
15176     operands[1] = pic_offset_table_rtx;
15177   else
15178     {
15179       operands[1] = gen_reg_rtx (Pmode);
15180       emit_insn (gen_set_got (operands[1]));
15181     }
15182   if (TARGET_GNU2_TLS)
15183     {
15184        emit_insn (gen_tls_dynamic_gnu2_32
15185                   (operands[0], ix86_tls_module_base (), operands[1]));
15186        DONE;
15187     }
15188   operands[2] = ix86_tls_get_addr ();
15189 })
15190
15191 (define_insn "*tls_local_dynamic_base_64"
15192   [(set (match_operand:DI 0 "register_operand" "=a")
15193         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15194                  (match_operand:DI 2 "" "")))
15195    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15196   "TARGET_64BIT"
15197   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15198   [(set_attr "type" "multi")
15199    (set_attr "length" "12")])
15200
15201 (define_expand "tls_local_dynamic_base_64"
15202   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15203                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15204               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15205   ""
15206 {
15207   if (TARGET_GNU2_TLS)
15208     {
15209        emit_insn (gen_tls_dynamic_gnu2_64
15210                   (operands[0], ix86_tls_module_base ()));
15211        DONE;
15212     }
15213   operands[1] = ix86_tls_get_addr ();
15214 })
15215
15216 ;; Local dynamic of a single variable is a lose.  Show combine how
15217 ;; to convert that back to global dynamic.
15218
15219 (define_insn_and_split "*tls_local_dynamic_32_once"
15220   [(set (match_operand:SI 0 "register_operand" "=a")
15221         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15222                              (match_operand:SI 2 "call_insn_operand" "")]
15223                             UNSPEC_TLS_LD_BASE)
15224                  (const:SI (unspec:SI
15225                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15226                             UNSPEC_DTPOFF))))
15227    (clobber (match_scratch:SI 4 "=d"))
15228    (clobber (match_scratch:SI 5 "=c"))
15229    (clobber (reg:CC FLAGS_REG))]
15230   ""
15231   "#"
15232   ""
15233   [(parallel [(set (match_dup 0)
15234                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15235                               UNSPEC_TLS_GD))
15236               (clobber (match_dup 4))
15237               (clobber (match_dup 5))
15238               (clobber (reg:CC FLAGS_REG))])]
15239   "")
15240
15241 ;; Load and add the thread base pointer from %gs:0.
15242
15243 (define_insn "*load_tp_si"
15244   [(set (match_operand:SI 0 "register_operand" "=r")
15245         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15246   "!TARGET_64BIT"
15247   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15248   [(set_attr "type" "imov")
15249    (set_attr "modrm" "0")
15250    (set_attr "length" "7")
15251    (set_attr "memory" "load")
15252    (set_attr "imm_disp" "false")])
15253
15254 (define_insn "*add_tp_si"
15255   [(set (match_operand:SI 0 "register_operand" "=r")
15256         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15257                  (match_operand:SI 1 "register_operand" "0")))
15258    (clobber (reg:CC FLAGS_REG))]
15259   "!TARGET_64BIT"
15260   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15261   [(set_attr "type" "alu")
15262    (set_attr "modrm" "0")
15263    (set_attr "length" "7")
15264    (set_attr "memory" "load")
15265    (set_attr "imm_disp" "false")])
15266
15267 (define_insn "*load_tp_di"
15268   [(set (match_operand:DI 0 "register_operand" "=r")
15269         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15270   "TARGET_64BIT"
15271   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15272   [(set_attr "type" "imov")
15273    (set_attr "modrm" "0")
15274    (set_attr "length" "7")
15275    (set_attr "memory" "load")
15276    (set_attr "imm_disp" "false")])
15277
15278 (define_insn "*add_tp_di"
15279   [(set (match_operand:DI 0 "register_operand" "=r")
15280         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15281                  (match_operand:DI 1 "register_operand" "0")))
15282    (clobber (reg:CC FLAGS_REG))]
15283   "TARGET_64BIT"
15284   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15285   [(set_attr "type" "alu")
15286    (set_attr "modrm" "0")
15287    (set_attr "length" "7")
15288    (set_attr "memory" "load")
15289    (set_attr "imm_disp" "false")])
15290
15291 ;; GNU2 TLS patterns can be split.
15292
15293 (define_expand "tls_dynamic_gnu2_32"
15294   [(set (match_dup 3)
15295         (plus:SI (match_operand:SI 2 "register_operand" "")
15296                  (const:SI
15297                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15298                              UNSPEC_TLSDESC))))
15299    (parallel
15300     [(set (match_operand:SI 0 "register_operand" "")
15301           (unspec:SI [(match_dup 1) (match_dup 3)
15302                       (match_dup 2) (reg:SI SP_REG)]
15303                       UNSPEC_TLSDESC))
15304      (clobber (reg:CC FLAGS_REG))])]
15305   "!TARGET_64BIT && TARGET_GNU2_TLS"
15306 {
15307   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15308   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15309 })
15310
15311 (define_insn "*tls_dynamic_lea_32"
15312   [(set (match_operand:SI 0 "register_operand" "=r")
15313         (plus:SI (match_operand:SI 1 "register_operand" "b")
15314                  (const:SI
15315                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15316                               UNSPEC_TLSDESC))))]
15317   "!TARGET_64BIT && TARGET_GNU2_TLS"
15318   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15319   [(set_attr "type" "lea")
15320    (set_attr "mode" "SI")
15321    (set_attr "length" "6")
15322    (set_attr "length_address" "4")])
15323
15324 (define_insn "*tls_dynamic_call_32"
15325   [(set (match_operand:SI 0 "register_operand" "=a")
15326         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15327                     (match_operand:SI 2 "register_operand" "0")
15328                     ;; we have to make sure %ebx still points to the GOT
15329                     (match_operand:SI 3 "register_operand" "b")
15330                     (reg:SI SP_REG)]
15331                    UNSPEC_TLSDESC))
15332    (clobber (reg:CC FLAGS_REG))]
15333   "!TARGET_64BIT && TARGET_GNU2_TLS"
15334   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15335   [(set_attr "type" "call")
15336    (set_attr "length" "2")
15337    (set_attr "length_address" "0")])
15338
15339 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15340   [(set (match_operand:SI 0 "register_operand" "=&a")
15341         (plus:SI
15342          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15343                      (match_operand:SI 4 "" "")
15344                      (match_operand:SI 2 "register_operand" "b")
15345                      (reg:SI SP_REG)]
15346                     UNSPEC_TLSDESC)
15347          (const:SI (unspec:SI
15348                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15349                     UNSPEC_DTPOFF))))
15350    (clobber (reg:CC FLAGS_REG))]
15351   "!TARGET_64BIT && TARGET_GNU2_TLS"
15352   "#"
15353   ""
15354   [(set (match_dup 0) (match_dup 5))]
15355 {
15356   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15357   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15358 })
15359
15360 (define_expand "tls_dynamic_gnu2_64"
15361   [(set (match_dup 2)
15362         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15363                    UNSPEC_TLSDESC))
15364    (parallel
15365     [(set (match_operand:DI 0 "register_operand" "")
15366           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15367                      UNSPEC_TLSDESC))
15368      (clobber (reg:CC FLAGS_REG))])]
15369   "TARGET_64BIT && TARGET_GNU2_TLS"
15370 {
15371   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15372   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15373 })
15374
15375 (define_insn "*tls_dynamic_lea_64"
15376   [(set (match_operand:DI 0 "register_operand" "=r")
15377         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15378                    UNSPEC_TLSDESC))]
15379   "TARGET_64BIT && TARGET_GNU2_TLS"
15380   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15381   [(set_attr "type" "lea")
15382    (set_attr "mode" "DI")
15383    (set_attr "length" "7")
15384    (set_attr "length_address" "4")])
15385
15386 (define_insn "*tls_dynamic_call_64"
15387   [(set (match_operand:DI 0 "register_operand" "=a")
15388         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15389                     (match_operand:DI 2 "register_operand" "0")
15390                     (reg:DI SP_REG)]
15391                    UNSPEC_TLSDESC))
15392    (clobber (reg:CC FLAGS_REG))]
15393   "TARGET_64BIT && TARGET_GNU2_TLS"
15394   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15395   [(set_attr "type" "call")
15396    (set_attr "length" "2")
15397    (set_attr "length_address" "0")])
15398
15399 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15400   [(set (match_operand:DI 0 "register_operand" "=&a")
15401         (plus:DI
15402          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15403                      (match_operand:DI 3 "" "")
15404                      (reg:DI SP_REG)]
15405                     UNSPEC_TLSDESC)
15406          (const:DI (unspec:DI
15407                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15408                     UNSPEC_DTPOFF))))
15409    (clobber (reg:CC FLAGS_REG))]
15410   "TARGET_64BIT && TARGET_GNU2_TLS"
15411   "#"
15412   ""
15413   [(set (match_dup 0) (match_dup 4))]
15414 {
15415   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15416   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15417 })
15418
15419 ;;
15420 \f
15421 ;; These patterns match the binary 387 instructions for addM3, subM3,
15422 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15423 ;; SFmode.  The first is the normal insn, the second the same insn but
15424 ;; with one operand a conversion, and the third the same insn but with
15425 ;; the other operand a conversion.  The conversion may be SFmode or
15426 ;; SImode if the target mode DFmode, but only SImode if the target mode
15427 ;; is SFmode.
15428
15429 ;; Gcc is slightly more smart about handling normal two address instructions
15430 ;; so use special patterns for add and mull.
15431
15432 (define_insn "*fop_sf_comm_mixed"
15433   [(set (match_operand:SF 0 "register_operand" "=f,x")
15434         (match_operator:SF 3 "binary_fp_operator"
15435                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15436                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15437   "TARGET_MIX_SSE_I387
15438    && COMMUTATIVE_ARITH_P (operands[3])
15439    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15440   "* return output_387_binary_op (insn, operands);"
15441   [(set (attr "type")
15442         (if_then_else (eq_attr "alternative" "1")
15443            (if_then_else (match_operand:SF 3 "mult_operator" "")
15444               (const_string "ssemul")
15445               (const_string "sseadd"))
15446            (if_then_else (match_operand:SF 3 "mult_operator" "")
15447               (const_string "fmul")
15448               (const_string "fop"))))
15449    (set_attr "mode" "SF")])
15450
15451 (define_insn "*fop_sf_comm_sse"
15452   [(set (match_operand:SF 0 "register_operand" "=x")
15453         (match_operator:SF 3 "binary_fp_operator"
15454                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15455                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15456   "TARGET_SSE_MATH
15457    && COMMUTATIVE_ARITH_P (operands[3])
15458    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15459   "* return output_387_binary_op (insn, operands);"
15460   [(set (attr "type")
15461         (if_then_else (match_operand:SF 3 "mult_operator" "")
15462            (const_string "ssemul")
15463            (const_string "sseadd")))
15464    (set_attr "mode" "SF")])
15465
15466 (define_insn "*fop_sf_comm_i387"
15467   [(set (match_operand:SF 0 "register_operand" "=f")
15468         (match_operator:SF 3 "binary_fp_operator"
15469                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15470                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15471   "TARGET_80387
15472    && COMMUTATIVE_ARITH_P (operands[3])
15473    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15474   "* return output_387_binary_op (insn, operands);"
15475   [(set (attr "type")
15476         (if_then_else (match_operand:SF 3 "mult_operator" "")
15477            (const_string "fmul")
15478            (const_string "fop")))
15479    (set_attr "mode" "SF")])
15480
15481 (define_insn "*fop_sf_1_mixed"
15482   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15483         (match_operator:SF 3 "binary_fp_operator"
15484                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15485                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15486   "TARGET_MIX_SSE_I387
15487    && !COMMUTATIVE_ARITH_P (operands[3])
15488    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15489   "* return output_387_binary_op (insn, operands);"
15490   [(set (attr "type")
15491         (cond [(and (eq_attr "alternative" "2")
15492                     (match_operand:SF 3 "mult_operator" ""))
15493                  (const_string "ssemul")
15494                (and (eq_attr "alternative" "2")
15495                     (match_operand:SF 3 "div_operator" ""))
15496                  (const_string "ssediv")
15497                (eq_attr "alternative" "2")
15498                  (const_string "sseadd")
15499                (match_operand:SF 3 "mult_operator" "")
15500                  (const_string "fmul")
15501                (match_operand:SF 3 "div_operator" "")
15502                  (const_string "fdiv")
15503               ]
15504               (const_string "fop")))
15505    (set_attr "mode" "SF")])
15506
15507 (define_insn "*fop_sf_1_sse"
15508   [(set (match_operand:SF 0 "register_operand" "=x")
15509         (match_operator:SF 3 "binary_fp_operator"
15510                         [(match_operand:SF 1 "register_operand" "0")
15511                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15512   "TARGET_SSE_MATH
15513    && !COMMUTATIVE_ARITH_P (operands[3])"
15514   "* return output_387_binary_op (insn, operands);"
15515   [(set (attr "type")
15516         (cond [(match_operand:SF 3 "mult_operator" "")
15517                  (const_string "ssemul")
15518                (match_operand:SF 3 "div_operator" "")
15519                  (const_string "ssediv")
15520               ]
15521               (const_string "sseadd")))
15522    (set_attr "mode" "SF")])
15523
15524 ;; This pattern is not fully shadowed by the pattern above.
15525 (define_insn "*fop_sf_1_i387"
15526   [(set (match_operand:SF 0 "register_operand" "=f,f")
15527         (match_operator:SF 3 "binary_fp_operator"
15528                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15529                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15530   "TARGET_80387 && !TARGET_SSE_MATH
15531    && !COMMUTATIVE_ARITH_P (operands[3])
15532    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15533   "* return output_387_binary_op (insn, operands);"
15534   [(set (attr "type")
15535         (cond [(match_operand:SF 3 "mult_operator" "")
15536                  (const_string "fmul")
15537                (match_operand:SF 3 "div_operator" "")
15538                  (const_string "fdiv")
15539               ]
15540               (const_string "fop")))
15541    (set_attr "mode" "SF")])
15542
15543 ;; ??? Add SSE splitters for these!
15544 (define_insn "*fop_sf_2<mode>_i387"
15545   [(set (match_operand:SF 0 "register_operand" "=f,f")
15546         (match_operator:SF 3 "binary_fp_operator"
15547           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15548            (match_operand:SF 2 "register_operand" "0,0")]))]
15549   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15550   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15551   [(set (attr "type")
15552         (cond [(match_operand:SF 3 "mult_operator" "")
15553                  (const_string "fmul")
15554                (match_operand:SF 3 "div_operator" "")
15555                  (const_string "fdiv")
15556               ]
15557               (const_string "fop")))
15558    (set_attr "fp_int_src" "true")
15559    (set_attr "mode" "<MODE>")])
15560
15561 (define_insn "*fop_sf_3<mode>_i387"
15562   [(set (match_operand:SF 0 "register_operand" "=f,f")
15563         (match_operator:SF 3 "binary_fp_operator"
15564           [(match_operand:SF 1 "register_operand" "0,0")
15565            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15566   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15567   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15568   [(set (attr "type")
15569         (cond [(match_operand:SF 3 "mult_operator" "")
15570                  (const_string "fmul")
15571                (match_operand:SF 3 "div_operator" "")
15572                  (const_string "fdiv")
15573               ]
15574               (const_string "fop")))
15575    (set_attr "fp_int_src" "true")
15576    (set_attr "mode" "<MODE>")])
15577
15578 (define_insn "*fop_df_comm_mixed"
15579   [(set (match_operand:DF 0 "register_operand" "=f,x")
15580         (match_operator:DF 3 "binary_fp_operator"
15581           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15582            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15583   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15584    && COMMUTATIVE_ARITH_P (operands[3])
15585    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15586   "* return output_387_binary_op (insn, operands);"
15587   [(set (attr "type")
15588         (if_then_else (eq_attr "alternative" "1")
15589            (if_then_else (match_operand:DF 3 "mult_operator" "")
15590               (const_string "ssemul")
15591               (const_string "sseadd"))
15592            (if_then_else (match_operand:DF 3 "mult_operator" "")
15593               (const_string "fmul")
15594               (const_string "fop"))))
15595    (set_attr "mode" "DF")])
15596
15597 (define_insn "*fop_df_comm_sse"
15598   [(set (match_operand:DF 0 "register_operand" "=x")
15599         (match_operator:DF 3 "binary_fp_operator"
15600           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15601            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15602   "TARGET_SSE2 && TARGET_SSE_MATH
15603    && COMMUTATIVE_ARITH_P (operands[3])
15604    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15605   "* return output_387_binary_op (insn, operands);"
15606   [(set (attr "type")
15607         (if_then_else (match_operand:DF 3 "mult_operator" "")
15608            (const_string "ssemul")
15609            (const_string "sseadd")))
15610    (set_attr "mode" "DF")])
15611
15612 (define_insn "*fop_df_comm_i387"
15613   [(set (match_operand:DF 0 "register_operand" "=f")
15614         (match_operator:DF 3 "binary_fp_operator"
15615                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15616                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15617   "TARGET_80387
15618    && COMMUTATIVE_ARITH_P (operands[3])
15619    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15620   "* return output_387_binary_op (insn, operands);"
15621   [(set (attr "type")
15622         (if_then_else (match_operand:DF 3 "mult_operator" "")
15623            (const_string "fmul")
15624            (const_string "fop")))
15625    (set_attr "mode" "DF")])
15626
15627 (define_insn "*fop_df_1_mixed"
15628   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15629         (match_operator:DF 3 "binary_fp_operator"
15630           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15631            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15632   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15633    && !COMMUTATIVE_ARITH_P (operands[3])
15634    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15635   "* return output_387_binary_op (insn, operands);"
15636   [(set (attr "type")
15637         (cond [(and (eq_attr "alternative" "2")
15638                     (match_operand:DF 3 "mult_operator" ""))
15639                  (const_string "ssemul")
15640                (and (eq_attr "alternative" "2")
15641                     (match_operand:DF 3 "div_operator" ""))
15642                  (const_string "ssediv")
15643                (eq_attr "alternative" "2")
15644                  (const_string "sseadd")
15645                (match_operand:DF 3 "mult_operator" "")
15646                  (const_string "fmul")
15647                (match_operand:DF 3 "div_operator" "")
15648                  (const_string "fdiv")
15649               ]
15650               (const_string "fop")))
15651    (set_attr "mode" "DF")])
15652
15653 (define_insn "*fop_df_1_sse"
15654   [(set (match_operand:DF 0 "register_operand" "=x")
15655         (match_operator:DF 3 "binary_fp_operator"
15656           [(match_operand:DF 1 "register_operand" "0")
15657            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15658   "TARGET_SSE2 && TARGET_SSE_MATH
15659    && !COMMUTATIVE_ARITH_P (operands[3])"
15660   "* return output_387_binary_op (insn, operands);"
15661   [(set_attr "mode" "DF")
15662    (set (attr "type")
15663         (cond [(match_operand:DF 3 "mult_operator" "")
15664                  (const_string "ssemul")
15665                (match_operand:DF 3 "div_operator" "")
15666                  (const_string "ssediv")
15667               ]
15668               (const_string "sseadd")))])
15669
15670 ;; This pattern is not fully shadowed by the pattern above.
15671 (define_insn "*fop_df_1_i387"
15672   [(set (match_operand:DF 0 "register_operand" "=f,f")
15673         (match_operator:DF 3 "binary_fp_operator"
15674                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15675                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15676   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15677    && !COMMUTATIVE_ARITH_P (operands[3])
15678    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15679   "* return output_387_binary_op (insn, operands);"
15680   [(set (attr "type")
15681         (cond [(match_operand:DF 3 "mult_operator" "")
15682                  (const_string "fmul")
15683                (match_operand:DF 3 "div_operator" "")
15684                  (const_string "fdiv")
15685               ]
15686               (const_string "fop")))
15687    (set_attr "mode" "DF")])
15688
15689 ;; ??? Add SSE splitters for these!
15690 (define_insn "*fop_df_2<mode>_i387"
15691   [(set (match_operand:DF 0 "register_operand" "=f,f")
15692         (match_operator:DF 3 "binary_fp_operator"
15693            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15694             (match_operand:DF 2 "register_operand" "0,0")]))]
15695   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15696    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15697   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15698   [(set (attr "type")
15699         (cond [(match_operand:DF 3 "mult_operator" "")
15700                  (const_string "fmul")
15701                (match_operand:DF 3 "div_operator" "")
15702                  (const_string "fdiv")
15703               ]
15704               (const_string "fop")))
15705    (set_attr "fp_int_src" "true")
15706    (set_attr "mode" "<MODE>")])
15707
15708 (define_insn "*fop_df_3<mode>_i387"
15709   [(set (match_operand:DF 0 "register_operand" "=f,f")
15710         (match_operator:DF 3 "binary_fp_operator"
15711            [(match_operand:DF 1 "register_operand" "0,0")
15712             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15713   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15714    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15715   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15716   [(set (attr "type")
15717         (cond [(match_operand:DF 3 "mult_operator" "")
15718                  (const_string "fmul")
15719                (match_operand:DF 3 "div_operator" "")
15720                  (const_string "fdiv")
15721               ]
15722               (const_string "fop")))
15723    (set_attr "fp_int_src" "true")
15724    (set_attr "mode" "<MODE>")])
15725
15726 (define_insn "*fop_df_4_i387"
15727   [(set (match_operand:DF 0 "register_operand" "=f,f")
15728         (match_operator:DF 3 "binary_fp_operator"
15729            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15730             (match_operand:DF 2 "register_operand" "0,f")]))]
15731   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15732    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15733   "* return output_387_binary_op (insn, operands);"
15734   [(set (attr "type")
15735         (cond [(match_operand:DF 3 "mult_operator" "")
15736                  (const_string "fmul")
15737                (match_operand:DF 3 "div_operator" "")
15738                  (const_string "fdiv")
15739               ]
15740               (const_string "fop")))
15741    (set_attr "mode" "SF")])
15742
15743 (define_insn "*fop_df_5_i387"
15744   [(set (match_operand:DF 0 "register_operand" "=f,f")
15745         (match_operator:DF 3 "binary_fp_operator"
15746           [(match_operand:DF 1 "register_operand" "0,f")
15747            (float_extend:DF
15748             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15749   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15750   "* return output_387_binary_op (insn, operands);"
15751   [(set (attr "type")
15752         (cond [(match_operand:DF 3 "mult_operator" "")
15753                  (const_string "fmul")
15754                (match_operand:DF 3 "div_operator" "")
15755                  (const_string "fdiv")
15756               ]
15757               (const_string "fop")))
15758    (set_attr "mode" "SF")])
15759
15760 (define_insn "*fop_df_6_i387"
15761   [(set (match_operand:DF 0 "register_operand" "=f,f")
15762         (match_operator:DF 3 "binary_fp_operator"
15763           [(float_extend:DF
15764             (match_operand:SF 1 "register_operand" "0,f"))
15765            (float_extend:DF
15766             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15767   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15768   "* return output_387_binary_op (insn, operands);"
15769   [(set (attr "type")
15770         (cond [(match_operand:DF 3 "mult_operator" "")
15771                  (const_string "fmul")
15772                (match_operand:DF 3 "div_operator" "")
15773                  (const_string "fdiv")
15774               ]
15775               (const_string "fop")))
15776    (set_attr "mode" "SF")])
15777
15778 (define_insn "*fop_xf_comm_i387"
15779   [(set (match_operand:XF 0 "register_operand" "=f")
15780         (match_operator:XF 3 "binary_fp_operator"
15781                         [(match_operand:XF 1 "register_operand" "%0")
15782                          (match_operand:XF 2 "register_operand" "f")]))]
15783   "TARGET_80387
15784    && COMMUTATIVE_ARITH_P (operands[3])"
15785   "* return output_387_binary_op (insn, operands);"
15786   [(set (attr "type")
15787         (if_then_else (match_operand:XF 3 "mult_operator" "")
15788            (const_string "fmul")
15789            (const_string "fop")))
15790    (set_attr "mode" "XF")])
15791
15792 (define_insn "*fop_xf_1_i387"
15793   [(set (match_operand:XF 0 "register_operand" "=f,f")
15794         (match_operator:XF 3 "binary_fp_operator"
15795                         [(match_operand:XF 1 "register_operand" "0,f")
15796                          (match_operand:XF 2 "register_operand" "f,0")]))]
15797   "TARGET_80387
15798    && !COMMUTATIVE_ARITH_P (operands[3])"
15799   "* return output_387_binary_op (insn, operands);"
15800   [(set (attr "type")
15801         (cond [(match_operand:XF 3 "mult_operator" "")
15802                  (const_string "fmul")
15803                (match_operand:XF 3 "div_operator" "")
15804                  (const_string "fdiv")
15805               ]
15806               (const_string "fop")))
15807    (set_attr "mode" "XF")])
15808
15809 (define_insn "*fop_xf_2<mode>_i387"
15810   [(set (match_operand:XF 0 "register_operand" "=f,f")
15811         (match_operator:XF 3 "binary_fp_operator"
15812            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15813             (match_operand:XF 2 "register_operand" "0,0")]))]
15814   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15815   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15816   [(set (attr "type")
15817         (cond [(match_operand:XF 3 "mult_operator" "")
15818                  (const_string "fmul")
15819                (match_operand:XF 3 "div_operator" "")
15820                  (const_string "fdiv")
15821               ]
15822               (const_string "fop")))
15823    (set_attr "fp_int_src" "true")
15824    (set_attr "mode" "<MODE>")])
15825
15826 (define_insn "*fop_xf_3<mode>_i387"
15827   [(set (match_operand:XF 0 "register_operand" "=f,f")
15828         (match_operator:XF 3 "binary_fp_operator"
15829           [(match_operand:XF 1 "register_operand" "0,0")
15830            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15831   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15832   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15833   [(set (attr "type")
15834         (cond [(match_operand:XF 3 "mult_operator" "")
15835                  (const_string "fmul")
15836                (match_operand:XF 3 "div_operator" "")
15837                  (const_string "fdiv")
15838               ]
15839               (const_string "fop")))
15840    (set_attr "fp_int_src" "true")
15841    (set_attr "mode" "<MODE>")])
15842
15843 (define_insn "*fop_xf_4_i387"
15844   [(set (match_operand:XF 0 "register_operand" "=f,f")
15845         (match_operator:XF 3 "binary_fp_operator"
15846            [(float_extend:XF
15847               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15848             (match_operand:XF 2 "register_operand" "0,f")]))]
15849   "TARGET_80387"
15850   "* return output_387_binary_op (insn, operands);"
15851   [(set (attr "type")
15852         (cond [(match_operand:XF 3 "mult_operator" "")
15853                  (const_string "fmul")
15854                (match_operand:XF 3 "div_operator" "")
15855                  (const_string "fdiv")
15856               ]
15857               (const_string "fop")))
15858    (set_attr "mode" "SF")])
15859
15860 (define_insn "*fop_xf_5_i387"
15861   [(set (match_operand:XF 0 "register_operand" "=f,f")
15862         (match_operator:XF 3 "binary_fp_operator"
15863           [(match_operand:XF 1 "register_operand" "0,f")
15864            (float_extend:XF
15865              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15866   "TARGET_80387"
15867   "* return output_387_binary_op (insn, operands);"
15868   [(set (attr "type")
15869         (cond [(match_operand:XF 3 "mult_operator" "")
15870                  (const_string "fmul")
15871                (match_operand:XF 3 "div_operator" "")
15872                  (const_string "fdiv")
15873               ]
15874               (const_string "fop")))
15875    (set_attr "mode" "SF")])
15876
15877 (define_insn "*fop_xf_6_i387"
15878   [(set (match_operand:XF 0 "register_operand" "=f,f")
15879         (match_operator:XF 3 "binary_fp_operator"
15880           [(float_extend:XF
15881              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15882            (float_extend:XF
15883              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15884   "TARGET_80387"
15885   "* return output_387_binary_op (insn, operands);"
15886   [(set (attr "type")
15887         (cond [(match_operand:XF 3 "mult_operator" "")
15888                  (const_string "fmul")
15889                (match_operand:XF 3 "div_operator" "")
15890                  (const_string "fdiv")
15891               ]
15892               (const_string "fop")))
15893    (set_attr "mode" "SF")])
15894
15895 (define_split
15896   [(set (match_operand 0 "register_operand" "")
15897         (match_operator 3 "binary_fp_operator"
15898            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15899             (match_operand 2 "register_operand" "")]))]
15900   "TARGET_80387 && reload_completed
15901    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15902   [(const_int 0)]
15903 {
15904   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15905   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15906   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15907                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15908                                           GET_MODE (operands[3]),
15909                                           operands[4],
15910                                           operands[2])));
15911   ix86_free_from_memory (GET_MODE (operands[1]));
15912   DONE;
15913 })
15914
15915 (define_split
15916   [(set (match_operand 0 "register_operand" "")
15917         (match_operator 3 "binary_fp_operator"
15918            [(match_operand 1 "register_operand" "")
15919             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15920   "TARGET_80387 && reload_completed
15921    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15922   [(const_int 0)]
15923 {
15924   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15925   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15926   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15927                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15928                                           GET_MODE (operands[3]),
15929                                           operands[1],
15930                                           operands[4])));
15931   ix86_free_from_memory (GET_MODE (operands[2]));
15932   DONE;
15933 })
15934 \f
15935 ;; FPU special functions.
15936
15937 ;; This pattern implements a no-op XFmode truncation for
15938 ;; all fancy i386 XFmode math functions.
15939
15940 (define_insn "truncxf<mode>2_i387_noop_unspec"
15941   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15942         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15943         UNSPEC_TRUNC_NOOP))]
15944   "TARGET_USE_FANCY_MATH_387"
15945   "* return output_387_reg_move (insn, operands);"
15946   [(set_attr "type" "fmov")
15947    (set_attr "mode" "<MODE>")])
15948
15949 (define_insn "sqrtxf2"
15950   [(set (match_operand:XF 0 "register_operand" "=f")
15951         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15952   "TARGET_USE_FANCY_MATH_387"
15953   "fsqrt"
15954   [(set_attr "type" "fpspc")
15955    (set_attr "mode" "XF")
15956    (set_attr "athlon_decode" "direct")
15957    (set_attr "amdfam10_decode" "direct")])
15958
15959 (define_insn "sqrt_extend<mode>xf2_i387"
15960   [(set (match_operand:XF 0 "register_operand" "=f")
15961         (sqrt:XF
15962           (float_extend:XF
15963             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15964   "TARGET_USE_FANCY_MATH_387"
15965   "fsqrt"
15966   [(set_attr "type" "fpspc")
15967    (set_attr "mode" "XF")
15968    (set_attr "athlon_decode" "direct")   
15969    (set_attr "amdfam10_decode" "direct")])
15970
15971 (define_insn "*sqrt<mode>2_sse"
15972   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15973         (sqrt:SSEMODEF
15974           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15975   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15976   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15977   [(set_attr "type" "sse")
15978    (set_attr "mode" "<MODE>")
15979    (set_attr "athlon_decode" "*")
15980    (set_attr "amdfam10_decode" "*")])
15981
15982 (define_expand "sqrt<mode>2"
15983   [(set (match_operand:X87MODEF12 0 "register_operand" "")
15984         (sqrt:X87MODEF12
15985           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15986   "TARGET_USE_FANCY_MATH_387
15987    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15988 {
15989   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15990     {
15991       rtx op0 = gen_reg_rtx (XFmode);
15992       rtx op1 = force_reg (<MODE>mode, operands[1]);
15993
15994       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15995       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15996       DONE;
15997    }
15998 })
15999
16000 (define_insn "fpremxf4_i387"
16001   [(set (match_operand:XF 0 "register_operand" "=f")
16002         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16003                     (match_operand:XF 3 "register_operand" "1")]
16004                    UNSPEC_FPREM_F))
16005    (set (match_operand:XF 1 "register_operand" "=u")
16006         (unspec:XF [(match_dup 2) (match_dup 3)]
16007                    UNSPEC_FPREM_U))
16008    (set (reg:CCFP FPSR_REG)
16009         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16010   "TARGET_USE_FANCY_MATH_387"
16011   "fprem"
16012   [(set_attr "type" "fpspc")
16013    (set_attr "mode" "XF")])
16014
16015 (define_expand "fmodxf3"
16016   [(use (match_operand:XF 0 "register_operand" ""))
16017    (use (match_operand:XF 1 "register_operand" ""))
16018    (use (match_operand:XF 2 "register_operand" ""))]
16019   "TARGET_USE_FANCY_MATH_387"
16020 {
16021   rtx label = gen_label_rtx ();
16022
16023   emit_label (label);
16024
16025   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16026                                 operands[1], operands[2]));
16027   ix86_emit_fp_unordered_jump (label);
16028
16029   emit_move_insn (operands[0], operands[1]);
16030   DONE;
16031 })
16032
16033 (define_expand "fmod<mode>3"
16034   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16035    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16036    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16037   "TARGET_USE_FANCY_MATH_387"
16038 {
16039   rtx label = gen_label_rtx ();
16040
16041   rtx op1 = gen_reg_rtx (XFmode);
16042   rtx op2 = gen_reg_rtx (XFmode);
16043
16044   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16045   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16046
16047   emit_label (label);
16048   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16049   ix86_emit_fp_unordered_jump (label);
16050
16051   /* Truncate the result properly for strict SSE math.  */
16052   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16053       && !TARGET_MIX_SSE_I387)
16054     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16055   else
16056     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16057
16058   DONE;
16059 })
16060
16061 (define_insn "fprem1xf4_i387"
16062   [(set (match_operand:XF 0 "register_operand" "=f")
16063         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16064                     (match_operand:XF 3 "register_operand" "1")]
16065                    UNSPEC_FPREM1_F))
16066    (set (match_operand:XF 1 "register_operand" "=u")
16067         (unspec:XF [(match_dup 2) (match_dup 3)]
16068                    UNSPEC_FPREM1_U))
16069    (set (reg:CCFP FPSR_REG)
16070         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16071   "TARGET_USE_FANCY_MATH_387"
16072   "fprem1"
16073   [(set_attr "type" "fpspc")
16074    (set_attr "mode" "XF")])
16075
16076 (define_expand "remainderxf3"
16077   [(use (match_operand:XF 0 "register_operand" ""))
16078    (use (match_operand:XF 1 "register_operand" ""))
16079    (use (match_operand:XF 2 "register_operand" ""))]
16080   "TARGET_USE_FANCY_MATH_387"
16081 {
16082   rtx label = gen_label_rtx ();
16083
16084   emit_label (label);
16085
16086   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16087                                  operands[1], operands[2]));
16088   ix86_emit_fp_unordered_jump (label);
16089
16090   emit_move_insn (operands[0], operands[1]);
16091   DONE;
16092 })
16093
16094 (define_expand "remainder<mode>3"
16095   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16096    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16097    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16098   "TARGET_USE_FANCY_MATH_387"
16099 {
16100   rtx label = gen_label_rtx ();
16101
16102   rtx op1 = gen_reg_rtx (XFmode);
16103   rtx op2 = gen_reg_rtx (XFmode);
16104
16105   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16106   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16107
16108   emit_label (label);
16109
16110   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16111   ix86_emit_fp_unordered_jump (label);
16112
16113   /* Truncate the result properly for strict SSE math.  */
16114   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16115       && !TARGET_MIX_SSE_I387)
16116     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16117   else
16118     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16119
16120   DONE;
16121 })
16122
16123 (define_insn "*sinxf2_i387"
16124   [(set (match_operand:XF 0 "register_operand" "=f")
16125         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16126   "TARGET_USE_FANCY_MATH_387
16127    && flag_unsafe_math_optimizations"
16128   "fsin"
16129   [(set_attr "type" "fpspc")
16130    (set_attr "mode" "XF")])
16131
16132 (define_insn "*sin_extend<mode>xf2_i387"
16133   [(set (match_operand:XF 0 "register_operand" "=f")
16134         (unspec:XF [(float_extend:XF
16135                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16136                    UNSPEC_SIN))]
16137   "TARGET_USE_FANCY_MATH_387
16138    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16139        || TARGET_MIX_SSE_I387)
16140    && flag_unsafe_math_optimizations"
16141   "fsin"
16142   [(set_attr "type" "fpspc")
16143    (set_attr "mode" "XF")])
16144
16145 (define_insn "*cosxf2_i387"
16146   [(set (match_operand:XF 0 "register_operand" "=f")
16147         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16148   "TARGET_USE_FANCY_MATH_387
16149    && flag_unsafe_math_optimizations"
16150   "fcos"
16151   [(set_attr "type" "fpspc")
16152    (set_attr "mode" "XF")])
16153
16154 (define_insn "*cos_extend<mode>xf2_i387"
16155   [(set (match_operand:XF 0 "register_operand" "=f")
16156         (unspec:XF [(float_extend:XF
16157                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16158                    UNSPEC_COS))]
16159   "TARGET_USE_FANCY_MATH_387
16160    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16161        || TARGET_MIX_SSE_I387)
16162    && flag_unsafe_math_optimizations"
16163   "fcos"
16164   [(set_attr "type" "fpspc")
16165    (set_attr "mode" "XF")])
16166
16167 ;; When sincos pattern is defined, sin and cos builtin functions will be
16168 ;; expanded to sincos pattern with one of its outputs left unused.
16169 ;; CSE pass will figure out if two sincos patterns can be combined,
16170 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16171 ;; depending on the unused output.
16172
16173 (define_insn "sincosxf3"
16174   [(set (match_operand:XF 0 "register_operand" "=f")
16175         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16176                    UNSPEC_SINCOS_COS))
16177    (set (match_operand:XF 1 "register_operand" "=u")
16178         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16179   "TARGET_USE_FANCY_MATH_387
16180    && flag_unsafe_math_optimizations"
16181   "fsincos"
16182   [(set_attr "type" "fpspc")
16183    (set_attr "mode" "XF")])
16184
16185 (define_split
16186   [(set (match_operand:XF 0 "register_operand" "")
16187         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16188                    UNSPEC_SINCOS_COS))
16189    (set (match_operand:XF 1 "register_operand" "")
16190         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16191   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16192    && !reload_completed && !reload_in_progress"
16193   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16194   "")
16195
16196 (define_split
16197   [(set (match_operand:XF 0 "register_operand" "")
16198         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16199                    UNSPEC_SINCOS_COS))
16200    (set (match_operand:XF 1 "register_operand" "")
16201         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16202   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16203    && !reload_completed && !reload_in_progress"
16204   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16205   "")
16206
16207 (define_insn "sincos_extend<mode>xf3_i387"
16208   [(set (match_operand:XF 0 "register_operand" "=f")
16209         (unspec:XF [(float_extend:XF
16210                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16211                    UNSPEC_SINCOS_COS))
16212    (set (match_operand:XF 1 "register_operand" "=u")
16213         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16214   "TARGET_USE_FANCY_MATH_387
16215    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16216        || TARGET_MIX_SSE_I387)
16217    && flag_unsafe_math_optimizations"
16218   "fsincos"
16219   [(set_attr "type" "fpspc")
16220    (set_attr "mode" "XF")])
16221
16222 (define_split
16223   [(set (match_operand:XF 0 "register_operand" "")
16224         (unspec:XF [(float_extend:XF
16225                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16226                    UNSPEC_SINCOS_COS))
16227    (set (match_operand:XF 1 "register_operand" "")
16228         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16229   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16230    && !reload_completed && !reload_in_progress"
16231   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16232   "")
16233
16234 (define_split
16235   [(set (match_operand:XF 0 "register_operand" "")
16236         (unspec:XF [(float_extend:XF
16237                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16238                    UNSPEC_SINCOS_COS))
16239    (set (match_operand:XF 1 "register_operand" "")
16240         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16241   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16242    && !reload_completed && !reload_in_progress"
16243   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16244   "")
16245
16246 (define_expand "sincos<mode>3"
16247   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16248    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16249    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16250   "TARGET_USE_FANCY_MATH_387
16251    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16252        || TARGET_MIX_SSE_I387)
16253    && flag_unsafe_math_optimizations"
16254 {
16255   rtx op0 = gen_reg_rtx (XFmode);
16256   rtx op1 = gen_reg_rtx (XFmode);
16257
16258   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16259   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16260   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16261   DONE;
16262 })
16263
16264 (define_insn "fptanxf4_i387"
16265   [(set (match_operand:XF 0 "register_operand" "=f")
16266         (match_operand:XF 3 "const_double_operand" "F"))
16267    (set (match_operand:XF 1 "register_operand" "=u")
16268         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16269                    UNSPEC_TAN))]
16270   "TARGET_USE_FANCY_MATH_387
16271    && flag_unsafe_math_optimizations
16272    && standard_80387_constant_p (operands[3]) == 2"
16273   "fptan"
16274   [(set_attr "type" "fpspc")
16275    (set_attr "mode" "XF")])
16276
16277 (define_insn "fptan_extend<mode>xf4_i387"
16278   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16279         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16280    (set (match_operand:XF 1 "register_operand" "=u")
16281         (unspec:XF [(float_extend:XF
16282                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16283                    UNSPEC_TAN))]
16284   "TARGET_USE_FANCY_MATH_387
16285    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16286        || TARGET_MIX_SSE_I387)
16287    && flag_unsafe_math_optimizations
16288    && standard_80387_constant_p (operands[3]) == 2"
16289   "fptan"
16290   [(set_attr "type" "fpspc")
16291    (set_attr "mode" "XF")])
16292
16293 (define_expand "tanxf2"
16294   [(use (match_operand:XF 0 "register_operand" ""))
16295    (use (match_operand:XF 1 "register_operand" ""))]
16296   "TARGET_USE_FANCY_MATH_387
16297    && flag_unsafe_math_optimizations"
16298 {
16299   rtx one = gen_reg_rtx (XFmode);
16300   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16301
16302   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16303   DONE;
16304 })
16305
16306 (define_expand "tan<mode>2"
16307   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16308    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16309   "TARGET_USE_FANCY_MATH_387
16310    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16311        || TARGET_MIX_SSE_I387)
16312    && flag_unsafe_math_optimizations"
16313 {
16314   rtx op0 = gen_reg_rtx (XFmode);
16315
16316   rtx one = gen_reg_rtx (<MODE>mode);
16317   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16318
16319   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16320                                              operands[1], op2));
16321   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16322   DONE;
16323 })
16324
16325 (define_insn "*fpatanxf3_i387"
16326   [(set (match_operand:XF 0 "register_operand" "=f")
16327         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16328                     (match_operand:XF 2 "register_operand" "u")]
16329                    UNSPEC_FPATAN))
16330    (clobber (match_scratch:XF 3 "=2"))]
16331   "TARGET_USE_FANCY_MATH_387
16332    && flag_unsafe_math_optimizations"
16333   "fpatan"
16334   [(set_attr "type" "fpspc")
16335    (set_attr "mode" "XF")])
16336
16337 (define_insn "fpatan_extend<mode>xf3_i387"
16338   [(set (match_operand:XF 0 "register_operand" "=f")
16339         (unspec:XF [(float_extend:XF
16340                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16341                     (float_extend:XF
16342                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
16343                    UNSPEC_FPATAN))
16344    (clobber (match_scratch:XF 3 "=2"))]
16345   "TARGET_USE_FANCY_MATH_387
16346    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16347        || TARGET_MIX_SSE_I387)
16348    && flag_unsafe_math_optimizations"
16349   "fpatan"
16350   [(set_attr "type" "fpspc")
16351    (set_attr "mode" "XF")])
16352
16353 (define_expand "atan2xf3"
16354   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16355                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16356                                (match_operand:XF 1 "register_operand" "")]
16357                               UNSPEC_FPATAN))
16358               (clobber (match_scratch:XF 3 ""))])]
16359   "TARGET_USE_FANCY_MATH_387
16360    && flag_unsafe_math_optimizations"
16361   "")
16362
16363 (define_expand "atan2<mode>3"
16364   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16365    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16366    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16367   "TARGET_USE_FANCY_MATH_387
16368    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16369        || TARGET_MIX_SSE_I387)
16370    && flag_unsafe_math_optimizations"
16371 {
16372   rtx op0 = gen_reg_rtx (XFmode);
16373
16374   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16375   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16376   DONE;
16377 })
16378
16379 (define_expand "atanxf2"
16380   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16381                    (unspec:XF [(match_dup 2)
16382                                (match_operand:XF 1 "register_operand" "")]
16383                               UNSPEC_FPATAN))
16384               (clobber (match_scratch:XF 3 ""))])]
16385   "TARGET_USE_FANCY_MATH_387
16386    && flag_unsafe_math_optimizations"
16387 {
16388   operands[2] = gen_reg_rtx (XFmode);
16389   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16390 })
16391
16392 (define_expand "atan<mode>2"
16393   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16394    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16395   "TARGET_USE_FANCY_MATH_387
16396    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16397        || TARGET_MIX_SSE_I387)
16398    && flag_unsafe_math_optimizations"
16399 {
16400   rtx op0 = gen_reg_rtx (XFmode);
16401
16402   rtx op2 = gen_reg_rtx (<MODE>mode);
16403   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16404
16405   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16406   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16407   DONE;
16408 })
16409
16410 (define_expand "asinxf2"
16411   [(set (match_dup 2)
16412         (mult:XF (match_operand:XF 1 "register_operand" "")
16413                  (match_dup 1)))
16414    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16415    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16416    (parallel [(set (match_operand:XF 0 "register_operand" "")
16417                    (unspec:XF [(match_dup 5) (match_dup 1)]
16418                               UNSPEC_FPATAN))
16419               (clobber (match_scratch:XF 6 ""))])]
16420   "TARGET_USE_FANCY_MATH_387
16421    && flag_unsafe_math_optimizations && !optimize_size"
16422 {
16423   int i;
16424
16425   for (i = 2; i < 6; i++)
16426     operands[i] = gen_reg_rtx (XFmode);
16427
16428   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16429 })
16430
16431 (define_expand "asin<mode>2"
16432   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16433    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16434  "TARGET_USE_FANCY_MATH_387
16435    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16436        || TARGET_MIX_SSE_I387)
16437    && flag_unsafe_math_optimizations && !optimize_size"
16438 {
16439   rtx op0 = gen_reg_rtx (XFmode);
16440   rtx op1 = gen_reg_rtx (XFmode);
16441
16442   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16443   emit_insn (gen_asinxf2 (op0, op1));
16444   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16445   DONE;
16446 })
16447
16448 (define_expand "acosxf2"
16449   [(set (match_dup 2)
16450         (mult:XF (match_operand:XF 1 "register_operand" "")
16451                  (match_dup 1)))
16452    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16453    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16454    (parallel [(set (match_operand:XF 0 "register_operand" "")
16455                    (unspec:XF [(match_dup 1) (match_dup 5)]
16456                               UNSPEC_FPATAN))
16457               (clobber (match_scratch:XF 6 ""))])]
16458   "TARGET_USE_FANCY_MATH_387
16459    && flag_unsafe_math_optimizations && !optimize_size"
16460 {
16461   int i;
16462
16463   for (i = 2; i < 6; i++)
16464     operands[i] = gen_reg_rtx (XFmode);
16465
16466   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16467 })
16468
16469 (define_expand "acos<mode>2"
16470   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16471    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16472  "TARGET_USE_FANCY_MATH_387
16473    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16474        || TARGET_MIX_SSE_I387)
16475    && flag_unsafe_math_optimizations && !optimize_size"
16476 {
16477   rtx op0 = gen_reg_rtx (XFmode);
16478   rtx op1 = gen_reg_rtx (XFmode);
16479
16480   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16481   emit_insn (gen_acosxf2 (op0, op1));
16482   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16483   DONE;
16484 })
16485
16486 (define_insn "fyl2xxf3_i387"
16487   [(set (match_operand:XF 0 "register_operand" "=f")
16488         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16489                     (match_operand:XF 2 "register_operand" "u")]
16490                    UNSPEC_FYL2X))
16491    (clobber (match_scratch:XF 3 "=2"))]
16492   "TARGET_USE_FANCY_MATH_387
16493    && flag_unsafe_math_optimizations"
16494   "fyl2x"
16495   [(set_attr "type" "fpspc")
16496    (set_attr "mode" "XF")])
16497
16498 (define_insn "fyl2x_extend<mode>xf3_i387"
16499   [(set (match_operand:XF 0 "register_operand" "=f")
16500         (unspec:XF [(float_extend:XF
16501                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16502                     (match_operand:XF 2 "register_operand" "u")]
16503                    UNSPEC_FYL2X))
16504    (clobber (match_scratch:XF 3 "=2"))]
16505   "TARGET_USE_FANCY_MATH_387
16506    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16507        || TARGET_MIX_SSE_I387)
16508    && flag_unsafe_math_optimizations"
16509   "fyl2x"
16510   [(set_attr "type" "fpspc")
16511    (set_attr "mode" "XF")])
16512
16513 (define_expand "logxf2"
16514   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16515                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16516                                (match_dup 2)] UNSPEC_FYL2X))
16517               (clobber (match_scratch:XF 3 ""))])]
16518   "TARGET_USE_FANCY_MATH_387
16519    && flag_unsafe_math_optimizations"
16520 {
16521   operands[2] = gen_reg_rtx (XFmode);
16522   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16523 })
16524
16525 (define_expand "log<mode>2"
16526   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16527    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16528   "TARGET_USE_FANCY_MATH_387
16529    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16530        || TARGET_MIX_SSE_I387)
16531    && flag_unsafe_math_optimizations"
16532 {
16533   rtx op0 = gen_reg_rtx (XFmode);
16534
16535   rtx op2 = gen_reg_rtx (XFmode);
16536   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16537
16538   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16539   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16540   DONE;
16541 })
16542
16543 (define_expand "log10xf2"
16544   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16545                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16546                                (match_dup 2)] UNSPEC_FYL2X))
16547               (clobber (match_scratch:XF 3 ""))])]
16548   "TARGET_USE_FANCY_MATH_387
16549    && flag_unsafe_math_optimizations"
16550 {
16551   operands[2] = gen_reg_rtx (XFmode);
16552   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16553 })
16554
16555 (define_expand "log10<mode>2"
16556   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16557    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16558   "TARGET_USE_FANCY_MATH_387
16559    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16560        || TARGET_MIX_SSE_I387)
16561    && flag_unsafe_math_optimizations"
16562 {
16563   rtx op0 = gen_reg_rtx (XFmode);
16564
16565   rtx op2 = gen_reg_rtx (XFmode);
16566   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16567
16568   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16569   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16570   DONE;
16571 })
16572
16573 (define_expand "log2xf2"
16574   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16575                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16576                                (match_dup 2)] UNSPEC_FYL2X))
16577               (clobber (match_scratch:XF 3 ""))])]
16578   "TARGET_USE_FANCY_MATH_387
16579    && flag_unsafe_math_optimizations"
16580 {
16581   operands[2] = gen_reg_rtx (XFmode);
16582   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16583 })
16584
16585 (define_expand "log2<mode>2"
16586   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16587    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16588   "TARGET_USE_FANCY_MATH_387
16589    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16590        || TARGET_MIX_SSE_I387)
16591    && flag_unsafe_math_optimizations"
16592 {
16593   rtx op0 = gen_reg_rtx (XFmode);
16594
16595   rtx op2 = gen_reg_rtx (XFmode);
16596   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16597
16598   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16599   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16600   DONE;
16601 })
16602
16603 (define_insn "fyl2xp1xf3_i387"
16604   [(set (match_operand:XF 0 "register_operand" "=f")
16605         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16606                     (match_operand:XF 2 "register_operand" "u")]
16607                    UNSPEC_FYL2XP1))
16608    (clobber (match_scratch:XF 3 "=2"))]
16609   "TARGET_USE_FANCY_MATH_387
16610    && flag_unsafe_math_optimizations"
16611   "fyl2xp1"
16612   [(set_attr "type" "fpspc")
16613    (set_attr "mode" "XF")])
16614
16615 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16616   [(set (match_operand:XF 0 "register_operand" "=f")
16617         (unspec:XF [(float_extend:XF
16618                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16619                     (match_operand:XF 2 "register_operand" "u")]
16620                    UNSPEC_FYL2XP1))
16621    (clobber (match_scratch:XF 3 "=2"))]
16622   "TARGET_USE_FANCY_MATH_387
16623    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16624        || TARGET_MIX_SSE_I387)
16625    && flag_unsafe_math_optimizations"
16626   "fyl2xp1"
16627   [(set_attr "type" "fpspc")
16628    (set_attr "mode" "XF")])
16629
16630 (define_expand "log1pxf2"
16631   [(use (match_operand:XF 0 "register_operand" ""))
16632    (use (match_operand:XF 1 "register_operand" ""))]
16633   "TARGET_USE_FANCY_MATH_387
16634    && flag_unsafe_math_optimizations && !optimize_size"
16635 {
16636   ix86_emit_i387_log1p (operands[0], operands[1]);
16637   DONE;
16638 })
16639
16640 (define_expand "log1p<mode>2"
16641   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16642    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16643   "TARGET_USE_FANCY_MATH_387
16644    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16645        || TARGET_MIX_SSE_I387)
16646    && flag_unsafe_math_optimizations && !optimize_size"
16647 {
16648   rtx op0 = gen_reg_rtx (XFmode);
16649
16650   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16651
16652   ix86_emit_i387_log1p (op0, operands[1]);
16653   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16654   DONE;
16655 })
16656
16657 (define_insn "fxtractxf3_i387"
16658   [(set (match_operand:XF 0 "register_operand" "=f")
16659         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16660                    UNSPEC_XTRACT_FRACT))
16661    (set (match_operand:XF 1 "register_operand" "=u")
16662         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16663   "TARGET_USE_FANCY_MATH_387
16664    && flag_unsafe_math_optimizations"
16665   "fxtract"
16666   [(set_attr "type" "fpspc")
16667    (set_attr "mode" "XF")])
16668
16669 (define_insn "fxtract_extend<mode>xf3_i387"
16670   [(set (match_operand:XF 0 "register_operand" "=f")
16671         (unspec:XF [(float_extend:XF
16672                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16673                    UNSPEC_XTRACT_FRACT))
16674    (set (match_operand:XF 1 "register_operand" "=u")
16675         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16676   "TARGET_USE_FANCY_MATH_387
16677    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16678        || TARGET_MIX_SSE_I387)
16679    && flag_unsafe_math_optimizations"
16680   "fxtract"
16681   [(set_attr "type" "fpspc")
16682    (set_attr "mode" "XF")])
16683
16684 (define_expand "logbxf2"
16685   [(parallel [(set (match_dup 2)
16686                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16687                               UNSPEC_XTRACT_FRACT))
16688               (set (match_operand:XF 0 "register_operand" "")
16689                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16690   "TARGET_USE_FANCY_MATH_387
16691    && flag_unsafe_math_optimizations"
16692 {
16693   operands[2] = gen_reg_rtx (XFmode);
16694 })
16695
16696 (define_expand "logb<mode>2"
16697   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16698    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16699   "TARGET_USE_FANCY_MATH_387
16700    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16701        || TARGET_MIX_SSE_I387)
16702    && flag_unsafe_math_optimizations"
16703 {
16704   rtx op0 = gen_reg_rtx (XFmode);
16705   rtx op1 = gen_reg_rtx (XFmode);
16706
16707   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16708   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16709   DONE;
16710 })
16711
16712 (define_expand "ilogbxf2"
16713   [(use (match_operand:SI 0 "register_operand" ""))
16714    (use (match_operand:XF 1 "register_operand" ""))]
16715   "TARGET_USE_FANCY_MATH_387
16716    && flag_unsafe_math_optimizations && !optimize_size"
16717 {
16718   rtx op0 = gen_reg_rtx (XFmode);
16719   rtx op1 = gen_reg_rtx (XFmode);
16720
16721   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16722   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16723   DONE;
16724 })
16725
16726 (define_expand "ilogb<mode>2"
16727   [(use (match_operand:SI 0 "register_operand" ""))
16728    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16729   "TARGET_USE_FANCY_MATH_387
16730    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16731        || TARGET_MIX_SSE_I387)
16732    && flag_unsafe_math_optimizations && !optimize_size"
16733 {
16734   rtx op0 = gen_reg_rtx (XFmode);
16735   rtx op1 = gen_reg_rtx (XFmode);
16736
16737   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16738   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16739   DONE;
16740 })
16741
16742 (define_insn "*f2xm1xf2_i387"
16743   [(set (match_operand:XF 0 "register_operand" "=f")
16744         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16745                    UNSPEC_F2XM1))]
16746   "TARGET_USE_FANCY_MATH_387
16747    && flag_unsafe_math_optimizations"
16748   "f2xm1"
16749   [(set_attr "type" "fpspc")
16750    (set_attr "mode" "XF")])
16751
16752 (define_insn "*fscalexf4_i387"
16753   [(set (match_operand:XF 0 "register_operand" "=f")
16754         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16755                     (match_operand:XF 3 "register_operand" "1")]
16756                    UNSPEC_FSCALE_FRACT))
16757    (set (match_operand:XF 1 "register_operand" "=u")
16758         (unspec:XF [(match_dup 2) (match_dup 3)]
16759                    UNSPEC_FSCALE_EXP))]
16760   "TARGET_USE_FANCY_MATH_387
16761    && flag_unsafe_math_optimizations"
16762   "fscale"
16763   [(set_attr "type" "fpspc")
16764    (set_attr "mode" "XF")])
16765
16766 (define_expand "expNcorexf3"
16767   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16768                                (match_operand:XF 2 "register_operand" "")))
16769    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16770    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16771    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16772    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16773    (parallel [(set (match_operand:XF 0 "register_operand" "")
16774                    (unspec:XF [(match_dup 8) (match_dup 4)]
16775                               UNSPEC_FSCALE_FRACT))
16776               (set (match_dup 9)
16777                    (unspec:XF [(match_dup 8) (match_dup 4)]
16778                               UNSPEC_FSCALE_EXP))])]
16779   "TARGET_USE_FANCY_MATH_387
16780    && flag_unsafe_math_optimizations && !optimize_size"
16781 {
16782   int i;
16783
16784   for (i = 3; i < 10; i++)
16785     operands[i] = gen_reg_rtx (XFmode);
16786
16787   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16788 })
16789
16790 (define_expand "expxf2"
16791   [(use (match_operand:XF 0 "register_operand" ""))
16792    (use (match_operand:XF 1 "register_operand" ""))]
16793   "TARGET_USE_FANCY_MATH_387
16794    && flag_unsafe_math_optimizations && !optimize_size"
16795 {
16796   rtx op2 = gen_reg_rtx (XFmode);
16797   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16798
16799   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16800   DONE;
16801 })
16802
16803 (define_expand "exp<mode>2"
16804   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16805    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16806  "TARGET_USE_FANCY_MATH_387
16807    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16808        || TARGET_MIX_SSE_I387)
16809    && flag_unsafe_math_optimizations && !optimize_size"
16810 {
16811   rtx op0 = gen_reg_rtx (XFmode);
16812   rtx op1 = gen_reg_rtx (XFmode);
16813
16814   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16815   emit_insn (gen_expxf2 (op0, op1));
16816   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16817   DONE;
16818 })
16819
16820 (define_expand "exp10xf2"
16821   [(use (match_operand:XF 0 "register_operand" ""))
16822    (use (match_operand:XF 1 "register_operand" ""))]
16823   "TARGET_USE_FANCY_MATH_387
16824    && flag_unsafe_math_optimizations && !optimize_size"
16825 {
16826   rtx op2 = gen_reg_rtx (XFmode);
16827   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16828
16829   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16830   DONE;
16831 })
16832
16833 (define_expand "exp10<mode>2"
16834   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16835    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16836  "TARGET_USE_FANCY_MATH_387
16837    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16838        || TARGET_MIX_SSE_I387)
16839    && flag_unsafe_math_optimizations && !optimize_size"
16840 {
16841   rtx op0 = gen_reg_rtx (XFmode);
16842   rtx op1 = gen_reg_rtx (XFmode);
16843
16844   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16845   emit_insn (gen_exp10xf2 (op0, op1));
16846   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16847   DONE;
16848 })
16849
16850 (define_expand "exp2xf2"
16851   [(use (match_operand:XF 0 "register_operand" ""))
16852    (use (match_operand:XF 1 "register_operand" ""))]
16853   "TARGET_USE_FANCY_MATH_387
16854    && flag_unsafe_math_optimizations && !optimize_size"
16855 {
16856   rtx op2 = gen_reg_rtx (XFmode);
16857   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16858
16859   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16860   DONE;
16861 })
16862
16863 (define_expand "exp2<mode>2"
16864   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16865    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16866  "TARGET_USE_FANCY_MATH_387
16867    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16868        || TARGET_MIX_SSE_I387)
16869    && flag_unsafe_math_optimizations && !optimize_size"
16870 {
16871   rtx op0 = gen_reg_rtx (XFmode);
16872   rtx op1 = gen_reg_rtx (XFmode);
16873
16874   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16875   emit_insn (gen_exp2xf2 (op0, op1));
16876   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16877   DONE;
16878 })
16879
16880 (define_expand "expm1xf2"
16881   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16882                                (match_dup 2)))
16883    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16884    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16885    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16886    (parallel [(set (match_dup 7)
16887                    (unspec:XF [(match_dup 6) (match_dup 4)]
16888                               UNSPEC_FSCALE_FRACT))
16889                    (set (match_dup 8)
16890                    (unspec:XF [(match_dup 6) (match_dup 4)]
16891                               UNSPEC_FSCALE_EXP))])
16892    (parallel [(set (match_dup 10)
16893                    (unspec:XF [(match_dup 9) (match_dup 8)]
16894                               UNSPEC_FSCALE_FRACT))
16895               (set (match_dup 11)
16896                    (unspec:XF [(match_dup 9) (match_dup 8)]
16897                               UNSPEC_FSCALE_EXP))])
16898    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16899    (set (match_operand:XF 0 "register_operand" "")
16900         (plus:XF (match_dup 12) (match_dup 7)))]
16901   "TARGET_USE_FANCY_MATH_387
16902    && flag_unsafe_math_optimizations && !optimize_size"
16903 {
16904   int i;
16905
16906   for (i = 2; i < 13; i++)
16907     operands[i] = gen_reg_rtx (XFmode);
16908  
16909   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16910   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16911 })
16912
16913 (define_expand "expm1<mode>2"
16914   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16915    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16916  "TARGET_USE_FANCY_MATH_387
16917    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16918        || TARGET_MIX_SSE_I387)
16919    && flag_unsafe_math_optimizations && !optimize_size"
16920 {
16921   rtx op0 = gen_reg_rtx (XFmode);
16922   rtx op1 = gen_reg_rtx (XFmode);
16923
16924   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16925   emit_insn (gen_expm1xf2 (op0, op1));
16926   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16927   DONE;
16928 })
16929
16930 (define_expand "ldexpxf3"
16931   [(set (match_dup 3)
16932         (float:XF (match_operand:SI 2 "register_operand" "")))
16933    (parallel [(set (match_operand:XF 0 " register_operand" "")
16934                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16935                                (match_dup 3)]
16936                               UNSPEC_FSCALE_FRACT))
16937               (set (match_dup 4)
16938                    (unspec:XF [(match_dup 1) (match_dup 3)]
16939                               UNSPEC_FSCALE_EXP))])]
16940   "TARGET_USE_FANCY_MATH_387
16941    && flag_unsafe_math_optimizations && !optimize_size"
16942 {
16943   operands[3] = gen_reg_rtx (XFmode);
16944   operands[4] = gen_reg_rtx (XFmode);
16945 })
16946
16947 (define_expand "ldexp<mode>3"
16948   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16949    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16950    (use (match_operand:SI 2 "register_operand" ""))]
16951  "TARGET_USE_FANCY_MATH_387
16952    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16953        || TARGET_MIX_SSE_I387)
16954    && flag_unsafe_math_optimizations && !optimize_size"
16955 {
16956   rtx op0 = gen_reg_rtx (XFmode);
16957   rtx op1 = gen_reg_rtx (XFmode);
16958
16959   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16960   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16961   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16962   DONE;
16963 })
16964 \f
16965
16966 (define_insn "frndintxf2"
16967   [(set (match_operand:XF 0 "register_operand" "=f")
16968         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16969          UNSPEC_FRNDINT))]
16970   "TARGET_USE_FANCY_MATH_387
16971    && flag_unsafe_math_optimizations"
16972   "frndint"
16973   [(set_attr "type" "fpspc")
16974    (set_attr "mode" "XF")])
16975
16976 (define_expand "rintdf2"
16977   [(use (match_operand:DF 0 "register_operand" ""))
16978    (use (match_operand:DF 1 "register_operand" ""))]
16979   "(TARGET_USE_FANCY_MATH_387
16980     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16981     && flag_unsafe_math_optimizations)
16982    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16983        && !flag_trapping_math
16984        && !optimize_size)"
16985 {
16986   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16987       && !flag_trapping_math
16988       && !optimize_size)
16989     ix86_expand_rint (operand0, operand1);
16990   else
16991     {
16992       rtx op0 = gen_reg_rtx (XFmode);
16993       rtx op1 = gen_reg_rtx (XFmode);
16994
16995       emit_insn (gen_extenddfxf2 (op1, operands[1]));
16996       emit_insn (gen_frndintxf2 (op0, op1));
16997
16998       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16999     }
17000   DONE;
17001 })
17002
17003 (define_expand "rintsf2"
17004   [(use (match_operand:SF 0 "register_operand" ""))
17005    (use (match_operand:SF 1 "register_operand" ""))]
17006   "(TARGET_USE_FANCY_MATH_387
17007     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17008     && flag_unsafe_math_optimizations)
17009    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17010        && !flag_trapping_math
17011        && !optimize_size)"
17012 {
17013   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17014       && !flag_trapping_math
17015       && !optimize_size)
17016     ix86_expand_rint (operand0, operand1);
17017   else
17018     {
17019       rtx op0 = gen_reg_rtx (XFmode);
17020       rtx op1 = gen_reg_rtx (XFmode);
17021
17022       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17023       emit_insn (gen_frndintxf2 (op0, op1));
17024
17025       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17026     }
17027   DONE;
17028 })
17029
17030 (define_expand "rintxf2"
17031   [(use (match_operand:XF 0 "register_operand" ""))
17032    (use (match_operand:XF 1 "register_operand" ""))]
17033   "TARGET_USE_FANCY_MATH_387
17034    && flag_unsafe_math_optimizations && !optimize_size"
17035 {
17036   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17037   DONE;
17038 })
17039
17040 (define_expand "roundsf2"
17041   [(match_operand:SF 0 "register_operand" "")
17042    (match_operand:SF 1 "nonimmediate_operand" "")]
17043   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17044    && !flag_trapping_math && !flag_rounding_math
17045    && !optimize_size"
17046 {
17047   ix86_expand_round (operand0, operand1);
17048   DONE;
17049 })
17050
17051 (define_expand "rounddf2"
17052   [(match_operand:DF 0 "register_operand" "")
17053    (match_operand:DF 1 "nonimmediate_operand" "")]
17054   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17055    && !flag_trapping_math && !flag_rounding_math
17056    && !optimize_size"
17057 {
17058   if (TARGET_64BIT)
17059     ix86_expand_round (operand0, operand1);
17060   else
17061     ix86_expand_rounddf_32 (operand0, operand1);
17062   DONE;
17063 })
17064
17065 (define_insn_and_split "*fistdi2_1"
17066   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17067         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17068          UNSPEC_FIST))]
17069   "TARGET_USE_FANCY_MATH_387
17070    && !(reload_completed || reload_in_progress)"
17071   "#"
17072   "&& 1"
17073   [(const_int 0)]
17074 {
17075   if (memory_operand (operands[0], VOIDmode))
17076     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17077   else
17078     {
17079       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17080       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17081                                          operands[2]));
17082     }
17083   DONE;
17084 }
17085   [(set_attr "type" "fpspc")
17086    (set_attr "mode" "DI")])
17087
17088 (define_insn "fistdi2"
17089   [(set (match_operand:DI 0 "memory_operand" "=m")
17090         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17091          UNSPEC_FIST))
17092    (clobber (match_scratch:XF 2 "=&1f"))]
17093   "TARGET_USE_FANCY_MATH_387"
17094   "* return output_fix_trunc (insn, operands, 0);"
17095   [(set_attr "type" "fpspc")
17096    (set_attr "mode" "DI")])
17097
17098 (define_insn "fistdi2_with_temp"
17099   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17100         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17101          UNSPEC_FIST))
17102    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17103    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17104   "TARGET_USE_FANCY_MATH_387"
17105   "#"
17106   [(set_attr "type" "fpspc")
17107    (set_attr "mode" "DI")])
17108
17109 (define_split
17110   [(set (match_operand:DI 0 "register_operand" "")
17111         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17112          UNSPEC_FIST))
17113    (clobber (match_operand:DI 2 "memory_operand" ""))
17114    (clobber (match_scratch 3 ""))]
17115   "reload_completed"
17116   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17117               (clobber (match_dup 3))])
17118    (set (match_dup 0) (match_dup 2))]
17119   "")
17120
17121 (define_split
17122   [(set (match_operand:DI 0 "memory_operand" "")
17123         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17124          UNSPEC_FIST))
17125    (clobber (match_operand:DI 2 "memory_operand" ""))
17126    (clobber (match_scratch 3 ""))]
17127   "reload_completed"
17128   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17129               (clobber (match_dup 3))])]
17130   "")
17131
17132 (define_insn_and_split "*fist<mode>2_1"
17133   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17134         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17135          UNSPEC_FIST))]
17136   "TARGET_USE_FANCY_MATH_387
17137    && !(reload_completed || reload_in_progress)"
17138   "#"
17139   "&& 1"
17140   [(const_int 0)]
17141 {
17142   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17143   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17144                                         operands[2]));
17145   DONE;
17146 }
17147   [(set_attr "type" "fpspc")
17148    (set_attr "mode" "<MODE>")])
17149
17150 (define_insn "fist<mode>2"
17151   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17152         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17153          UNSPEC_FIST))]
17154   "TARGET_USE_FANCY_MATH_387"
17155   "* return output_fix_trunc (insn, operands, 0);"
17156   [(set_attr "type" "fpspc")
17157    (set_attr "mode" "<MODE>")])
17158
17159 (define_insn "fist<mode>2_with_temp"
17160   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17161         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17162          UNSPEC_FIST))
17163    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17164   "TARGET_USE_FANCY_MATH_387"
17165   "#"
17166   [(set_attr "type" "fpspc")
17167    (set_attr "mode" "<MODE>")])
17168
17169 (define_split
17170   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17171         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17172          UNSPEC_FIST))
17173    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17174   "reload_completed"
17175   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17176                        UNSPEC_FIST))
17177    (set (match_dup 0) (match_dup 2))]
17178   "")
17179
17180 (define_split
17181   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17182         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17183          UNSPEC_FIST))
17184    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17185   "reload_completed"
17186   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17187                        UNSPEC_FIST))]
17188   "")
17189
17190 (define_expand "lrintxf<mode>2"
17191   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17192      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17193       UNSPEC_FIST))]
17194   "TARGET_USE_FANCY_MATH_387"
17195   "")
17196
17197 (define_expand "lrint<mode>di2"
17198   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17199      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17200       UNSPEC_FIX_NOTRUNC))]
17201   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17202   "")
17203
17204 (define_expand "lrint<mode>si2"
17205   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17206      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17207       UNSPEC_FIX_NOTRUNC))]
17208   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17209   "")
17210
17211 (define_expand "lround<mode>di2"
17212   [(match_operand:DI 0 "nonimmediate_operand" "")
17213    (match_operand:SSEMODEF 1 "register_operand" "")]
17214   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17215    && !flag_trapping_math && !flag_rounding_math
17216    && !optimize_size"
17217 {
17218   ix86_expand_lround (operand0, operand1);
17219   DONE;
17220 })
17221
17222 (define_expand "lround<mode>si2"
17223   [(match_operand:SI 0 "nonimmediate_operand" "")
17224    (match_operand:SSEMODEF 1 "register_operand" "")]
17225   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17226    && !flag_trapping_math && !flag_rounding_math
17227    && !optimize_size"
17228 {
17229   ix86_expand_lround (operand0, operand1);
17230   DONE;
17231 })
17232
17233 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17234 (define_insn_and_split "frndintxf2_floor"
17235   [(set (match_operand:XF 0 "register_operand" "=f")
17236         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17237          UNSPEC_FRNDINT_FLOOR))
17238    (clobber (reg:CC FLAGS_REG))]
17239   "TARGET_USE_FANCY_MATH_387
17240    && flag_unsafe_math_optimizations
17241    && !(reload_completed || reload_in_progress)"
17242   "#"
17243   "&& 1"
17244   [(const_int 0)]
17245 {
17246   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17247
17248   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17249   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17250
17251   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17252                                         operands[2], operands[3]));
17253   DONE;
17254 }
17255   [(set_attr "type" "frndint")
17256    (set_attr "i387_cw" "floor")
17257    (set_attr "mode" "XF")])
17258
17259 (define_insn "frndintxf2_floor_i387"
17260   [(set (match_operand:XF 0 "register_operand" "=f")
17261         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17262          UNSPEC_FRNDINT_FLOOR))
17263    (use (match_operand:HI 2 "memory_operand" "m"))
17264    (use (match_operand:HI 3 "memory_operand" "m"))]
17265   "TARGET_USE_FANCY_MATH_387
17266    && flag_unsafe_math_optimizations"
17267   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17268   [(set_attr "type" "frndint")
17269    (set_attr "i387_cw" "floor")
17270    (set_attr "mode" "XF")])
17271
17272 (define_expand "floorxf2"
17273   [(use (match_operand:XF 0 "register_operand" ""))
17274    (use (match_operand:XF 1 "register_operand" ""))]
17275   "TARGET_USE_FANCY_MATH_387
17276    && flag_unsafe_math_optimizations && !optimize_size"
17277 {
17278   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17279   DONE;
17280 })
17281
17282 (define_expand "floordf2"
17283   [(use (match_operand:DF 0 "register_operand" ""))
17284    (use (match_operand:DF 1 "register_operand" ""))]
17285   "((TARGET_USE_FANCY_MATH_387
17286      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17287      && flag_unsafe_math_optimizations)
17288     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17289         && !flag_trapping_math))
17290    && !optimize_size"
17291 {
17292   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17293       && !flag_trapping_math)
17294     {
17295       if (TARGET_64BIT)
17296         ix86_expand_floorceil (operand0, operand1, true);
17297       else
17298         ix86_expand_floorceildf_32 (operand0, operand1, true);
17299     }
17300   else
17301     {
17302       rtx op0 = gen_reg_rtx (XFmode);
17303       rtx op1 = gen_reg_rtx (XFmode);
17304
17305       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17306       emit_insn (gen_frndintxf2_floor (op0, op1));
17307
17308       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17309     }
17310   DONE;
17311 })
17312
17313 (define_expand "floorsf2"
17314   [(use (match_operand:SF 0 "register_operand" ""))
17315    (use (match_operand:SF 1 "register_operand" ""))]
17316   "((TARGET_USE_FANCY_MATH_387
17317      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17318      && flag_unsafe_math_optimizations)
17319     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17320         && !flag_trapping_math))
17321    && !optimize_size"
17322 {
17323   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17324       && !flag_trapping_math)
17325     ix86_expand_floorceil (operand0, operand1, true);
17326   else
17327     {
17328       rtx op0 = gen_reg_rtx (XFmode);
17329       rtx op1 = gen_reg_rtx (XFmode);
17330
17331       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17332       emit_insn (gen_frndintxf2_floor (op0, op1));
17333
17334       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17335     }
17336   DONE;
17337 })
17338
17339 (define_insn_and_split "*fist<mode>2_floor_1"
17340   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17341         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17342          UNSPEC_FIST_FLOOR))
17343    (clobber (reg:CC FLAGS_REG))]
17344   "TARGET_USE_FANCY_MATH_387
17345    && flag_unsafe_math_optimizations
17346    && !(reload_completed || reload_in_progress)"
17347   "#"
17348   "&& 1"
17349   [(const_int 0)]
17350 {
17351   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17352
17353   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17354   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17355   if (memory_operand (operands[0], VOIDmode))
17356     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17357                                       operands[2], operands[3]));
17358   else
17359     {
17360       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17361       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17362                                                   operands[2], operands[3],
17363                                                   operands[4]));
17364     }
17365   DONE;
17366 }
17367   [(set_attr "type" "fistp")
17368    (set_attr "i387_cw" "floor")
17369    (set_attr "mode" "<MODE>")])
17370
17371 (define_insn "fistdi2_floor"
17372   [(set (match_operand:DI 0 "memory_operand" "=m")
17373         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17374          UNSPEC_FIST_FLOOR))
17375    (use (match_operand:HI 2 "memory_operand" "m"))
17376    (use (match_operand:HI 3 "memory_operand" "m"))
17377    (clobber (match_scratch:XF 4 "=&1f"))]
17378   "TARGET_USE_FANCY_MATH_387
17379    && flag_unsafe_math_optimizations"
17380   "* return output_fix_trunc (insn, operands, 0);"
17381   [(set_attr "type" "fistp")
17382    (set_attr "i387_cw" "floor")
17383    (set_attr "mode" "DI")])
17384
17385 (define_insn "fistdi2_floor_with_temp"
17386   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17387         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17388          UNSPEC_FIST_FLOOR))
17389    (use (match_operand:HI 2 "memory_operand" "m,m"))
17390    (use (match_operand:HI 3 "memory_operand" "m,m"))
17391    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17392    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17393   "TARGET_USE_FANCY_MATH_387
17394    && flag_unsafe_math_optimizations"
17395   "#"
17396   [(set_attr "type" "fistp")
17397    (set_attr "i387_cw" "floor")
17398    (set_attr "mode" "DI")])
17399
17400 (define_split
17401   [(set (match_operand:DI 0 "register_operand" "")
17402         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17403          UNSPEC_FIST_FLOOR))
17404    (use (match_operand:HI 2 "memory_operand" ""))
17405    (use (match_operand:HI 3 "memory_operand" ""))
17406    (clobber (match_operand:DI 4 "memory_operand" ""))
17407    (clobber (match_scratch 5 ""))]
17408   "reload_completed"
17409   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17410               (use (match_dup 2))
17411               (use (match_dup 3))
17412               (clobber (match_dup 5))])
17413    (set (match_dup 0) (match_dup 4))]
17414   "")
17415
17416 (define_split
17417   [(set (match_operand:DI 0 "memory_operand" "")
17418         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17419          UNSPEC_FIST_FLOOR))
17420    (use (match_operand:HI 2 "memory_operand" ""))
17421    (use (match_operand:HI 3 "memory_operand" ""))
17422    (clobber (match_operand:DI 4 "memory_operand" ""))
17423    (clobber (match_scratch 5 ""))]
17424   "reload_completed"
17425   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17426               (use (match_dup 2))
17427               (use (match_dup 3))
17428               (clobber (match_dup 5))])]
17429   "")
17430
17431 (define_insn "fist<mode>2_floor"
17432   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17433         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17434          UNSPEC_FIST_FLOOR))
17435    (use (match_operand:HI 2 "memory_operand" "m"))
17436    (use (match_operand:HI 3 "memory_operand" "m"))]
17437   "TARGET_USE_FANCY_MATH_387
17438    && flag_unsafe_math_optimizations"
17439   "* return output_fix_trunc (insn, operands, 0);"
17440   [(set_attr "type" "fistp")
17441    (set_attr "i387_cw" "floor")
17442    (set_attr "mode" "<MODE>")])
17443
17444 (define_insn "fist<mode>2_floor_with_temp"
17445   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17446         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17447          UNSPEC_FIST_FLOOR))
17448    (use (match_operand:HI 2 "memory_operand" "m,m"))
17449    (use (match_operand:HI 3 "memory_operand" "m,m"))
17450    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17451   "TARGET_USE_FANCY_MATH_387
17452    && flag_unsafe_math_optimizations"
17453   "#"
17454   [(set_attr "type" "fistp")
17455    (set_attr "i387_cw" "floor")
17456    (set_attr "mode" "<MODE>")])
17457
17458 (define_split
17459   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17460         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17461          UNSPEC_FIST_FLOOR))
17462    (use (match_operand:HI 2 "memory_operand" ""))
17463    (use (match_operand:HI 3 "memory_operand" ""))
17464    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17465   "reload_completed"
17466   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17467                                   UNSPEC_FIST_FLOOR))
17468               (use (match_dup 2))
17469               (use (match_dup 3))])
17470    (set (match_dup 0) (match_dup 4))]
17471   "")
17472
17473 (define_split
17474   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17475         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17476          UNSPEC_FIST_FLOOR))
17477    (use (match_operand:HI 2 "memory_operand" ""))
17478    (use (match_operand:HI 3 "memory_operand" ""))
17479    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17480   "reload_completed"
17481   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17482                                   UNSPEC_FIST_FLOOR))
17483               (use (match_dup 2))
17484               (use (match_dup 3))])]
17485   "")
17486
17487 (define_expand "lfloorxf<mode>2"
17488   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17489                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17490                     UNSPEC_FIST_FLOOR))
17491               (clobber (reg:CC FLAGS_REG))])]
17492   "TARGET_USE_FANCY_MATH_387
17493    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17494    && flag_unsafe_math_optimizations"
17495   "")
17496
17497 (define_expand "lfloor<mode>di2"
17498   [(match_operand:DI 0 "nonimmediate_operand" "")
17499    (match_operand:SSEMODEF 1 "register_operand" "")]
17500   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17501    && !flag_trapping_math
17502    && !optimize_size"
17503 {
17504   ix86_expand_lfloorceil (operand0, operand1, true);
17505   DONE;
17506 })
17507
17508 (define_expand "lfloor<mode>si2"
17509   [(match_operand:SI 0 "nonimmediate_operand" "")
17510    (match_operand:SSEMODEF 1 "register_operand" "")]
17511   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17512    && !flag_trapping_math
17513    && (!optimize_size || !TARGET_64BIT)"
17514 {
17515   ix86_expand_lfloorceil (operand0, operand1, true);
17516   DONE;
17517 })
17518
17519 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17520 (define_insn_and_split "frndintxf2_ceil"
17521   [(set (match_operand:XF 0 "register_operand" "=f")
17522         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17523          UNSPEC_FRNDINT_CEIL))
17524    (clobber (reg:CC FLAGS_REG))]
17525   "TARGET_USE_FANCY_MATH_387
17526    && flag_unsafe_math_optimizations
17527    && !(reload_completed || reload_in_progress)"
17528   "#"
17529   "&& 1"
17530   [(const_int 0)]
17531 {
17532   ix86_optimize_mode_switching[I387_CEIL] = 1;
17533
17534   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17535   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17536
17537   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17538                                        operands[2], operands[3]));
17539   DONE;
17540 }
17541   [(set_attr "type" "frndint")
17542    (set_attr "i387_cw" "ceil")
17543    (set_attr "mode" "XF")])
17544
17545 (define_insn "frndintxf2_ceil_i387"
17546   [(set (match_operand:XF 0 "register_operand" "=f")
17547         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17548          UNSPEC_FRNDINT_CEIL))
17549    (use (match_operand:HI 2 "memory_operand" "m"))
17550    (use (match_operand:HI 3 "memory_operand" "m"))]
17551   "TARGET_USE_FANCY_MATH_387
17552    && flag_unsafe_math_optimizations"
17553   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17554   [(set_attr "type" "frndint")
17555    (set_attr "i387_cw" "ceil")
17556    (set_attr "mode" "XF")])
17557
17558 (define_expand "ceilxf2"
17559   [(use (match_operand:XF 0 "register_operand" ""))
17560    (use (match_operand:XF 1 "register_operand" ""))]
17561   "TARGET_USE_FANCY_MATH_387
17562    && flag_unsafe_math_optimizations && !optimize_size"
17563 {
17564   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17565   DONE;
17566 })
17567
17568 (define_expand "ceildf2"
17569   [(use (match_operand:DF 0 "register_operand" ""))
17570    (use (match_operand:DF 1 "register_operand" ""))]
17571   "((TARGET_USE_FANCY_MATH_387
17572      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17573      && flag_unsafe_math_optimizations)
17574     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17575         && !flag_trapping_math))
17576    && !optimize_size"
17577 {
17578   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17579       && !flag_trapping_math)
17580     {
17581       if (TARGET_64BIT)
17582         ix86_expand_floorceil (operand0, operand1, false);
17583       else
17584         ix86_expand_floorceildf_32 (operand0, operand1, false);
17585     }
17586   else
17587     {
17588       rtx op0 = gen_reg_rtx (XFmode);
17589       rtx op1 = gen_reg_rtx (XFmode);
17590
17591       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17592       emit_insn (gen_frndintxf2_ceil (op0, op1));
17593
17594       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17595     }
17596   DONE;
17597 })
17598
17599 (define_expand "ceilsf2"
17600   [(use (match_operand:SF 0 "register_operand" ""))
17601    (use (match_operand:SF 1 "register_operand" ""))]
17602   "((TARGET_USE_FANCY_MATH_387
17603      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17604      && flag_unsafe_math_optimizations)
17605     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17606         && !flag_trapping_math))
17607    && !optimize_size"
17608 {
17609   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17610       && !flag_trapping_math)
17611     ix86_expand_floorceil (operand0, operand1, false);
17612   else
17613     {
17614       rtx op0 = gen_reg_rtx (XFmode);
17615       rtx op1 = gen_reg_rtx (XFmode);
17616
17617       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17618       emit_insn (gen_frndintxf2_ceil (op0, op1));
17619
17620       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17621     }
17622   DONE;
17623 })
17624
17625 (define_insn_and_split "*fist<mode>2_ceil_1"
17626   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17627         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17628          UNSPEC_FIST_CEIL))
17629    (clobber (reg:CC FLAGS_REG))]
17630   "TARGET_USE_FANCY_MATH_387
17631    && flag_unsafe_math_optimizations
17632    && !(reload_completed || reload_in_progress)"
17633   "#"
17634   "&& 1"
17635   [(const_int 0)]
17636 {
17637   ix86_optimize_mode_switching[I387_CEIL] = 1;
17638
17639   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17640   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17641   if (memory_operand (operands[0], VOIDmode))
17642     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17643                                      operands[2], operands[3]));
17644   else
17645     {
17646       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17647       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17648                                                  operands[2], operands[3],
17649                                                  operands[4]));
17650     }
17651   DONE;
17652 }
17653   [(set_attr "type" "fistp")
17654    (set_attr "i387_cw" "ceil")
17655    (set_attr "mode" "<MODE>")])
17656
17657 (define_insn "fistdi2_ceil"
17658   [(set (match_operand:DI 0 "memory_operand" "=m")
17659         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17660          UNSPEC_FIST_CEIL))
17661    (use (match_operand:HI 2 "memory_operand" "m"))
17662    (use (match_operand:HI 3 "memory_operand" "m"))
17663    (clobber (match_scratch:XF 4 "=&1f"))]
17664   "TARGET_USE_FANCY_MATH_387
17665    && flag_unsafe_math_optimizations"
17666   "* return output_fix_trunc (insn, operands, 0);"
17667   [(set_attr "type" "fistp")
17668    (set_attr "i387_cw" "ceil")
17669    (set_attr "mode" "DI")])
17670
17671 (define_insn "fistdi2_ceil_with_temp"
17672   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17673         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17674          UNSPEC_FIST_CEIL))
17675    (use (match_operand:HI 2 "memory_operand" "m,m"))
17676    (use (match_operand:HI 3 "memory_operand" "m,m"))
17677    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17678    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17679   "TARGET_USE_FANCY_MATH_387
17680    && flag_unsafe_math_optimizations"
17681   "#"
17682   [(set_attr "type" "fistp")
17683    (set_attr "i387_cw" "ceil")
17684    (set_attr "mode" "DI")])
17685
17686 (define_split
17687   [(set (match_operand:DI 0 "register_operand" "")
17688         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17689          UNSPEC_FIST_CEIL))
17690    (use (match_operand:HI 2 "memory_operand" ""))
17691    (use (match_operand:HI 3 "memory_operand" ""))
17692    (clobber (match_operand:DI 4 "memory_operand" ""))
17693    (clobber (match_scratch 5 ""))]
17694   "reload_completed"
17695   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17696               (use (match_dup 2))
17697               (use (match_dup 3))
17698               (clobber (match_dup 5))])
17699    (set (match_dup 0) (match_dup 4))]
17700   "")
17701
17702 (define_split
17703   [(set (match_operand:DI 0 "memory_operand" "")
17704         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17705          UNSPEC_FIST_CEIL))
17706    (use (match_operand:HI 2 "memory_operand" ""))
17707    (use (match_operand:HI 3 "memory_operand" ""))
17708    (clobber (match_operand:DI 4 "memory_operand" ""))
17709    (clobber (match_scratch 5 ""))]
17710   "reload_completed"
17711   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17712               (use (match_dup 2))
17713               (use (match_dup 3))
17714               (clobber (match_dup 5))])]
17715   "")
17716
17717 (define_insn "fist<mode>2_ceil"
17718   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17719         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17720          UNSPEC_FIST_CEIL))
17721    (use (match_operand:HI 2 "memory_operand" "m"))
17722    (use (match_operand:HI 3 "memory_operand" "m"))]
17723   "TARGET_USE_FANCY_MATH_387
17724    && flag_unsafe_math_optimizations"
17725   "* return output_fix_trunc (insn, operands, 0);"
17726   [(set_attr "type" "fistp")
17727    (set_attr "i387_cw" "ceil")
17728    (set_attr "mode" "<MODE>")])
17729
17730 (define_insn "fist<mode>2_ceil_with_temp"
17731   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17732         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17733          UNSPEC_FIST_CEIL))
17734    (use (match_operand:HI 2 "memory_operand" "m,m"))
17735    (use (match_operand:HI 3 "memory_operand" "m,m"))
17736    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17737   "TARGET_USE_FANCY_MATH_387
17738    && flag_unsafe_math_optimizations"
17739   "#"
17740   [(set_attr "type" "fistp")
17741    (set_attr "i387_cw" "ceil")
17742    (set_attr "mode" "<MODE>")])
17743
17744 (define_split
17745   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17746         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17747          UNSPEC_FIST_CEIL))
17748    (use (match_operand:HI 2 "memory_operand" ""))
17749    (use (match_operand:HI 3 "memory_operand" ""))
17750    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17751   "reload_completed"
17752   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17753                                   UNSPEC_FIST_CEIL))
17754               (use (match_dup 2))
17755               (use (match_dup 3))])
17756    (set (match_dup 0) (match_dup 4))]
17757   "")
17758
17759 (define_split
17760   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17761         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17762          UNSPEC_FIST_CEIL))
17763    (use (match_operand:HI 2 "memory_operand" ""))
17764    (use (match_operand:HI 3 "memory_operand" ""))
17765    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17766   "reload_completed"
17767   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17768                                   UNSPEC_FIST_CEIL))
17769               (use (match_dup 2))
17770               (use (match_dup 3))])]
17771   "")
17772
17773 (define_expand "lceilxf<mode>2"
17774   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17775                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17776                     UNSPEC_FIST_CEIL))
17777               (clobber (reg:CC FLAGS_REG))])]
17778   "TARGET_USE_FANCY_MATH_387
17779    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17780    && flag_unsafe_math_optimizations"
17781   "")
17782
17783 (define_expand "lceil<mode>di2"
17784   [(match_operand:DI 0 "nonimmediate_operand" "")
17785    (match_operand:SSEMODEF 1 "register_operand" "")]
17786   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17787    && !flag_trapping_math"
17788 {
17789   ix86_expand_lfloorceil (operand0, operand1, false);
17790   DONE;
17791 })
17792
17793 (define_expand "lceil<mode>si2"
17794   [(match_operand:SI 0 "nonimmediate_operand" "")
17795    (match_operand:SSEMODEF 1 "register_operand" "")]
17796   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17797    && !flag_trapping_math"
17798 {
17799   ix86_expand_lfloorceil (operand0, operand1, false);
17800   DONE;
17801 })
17802
17803 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17804 (define_insn_and_split "frndintxf2_trunc"
17805   [(set (match_operand:XF 0 "register_operand" "=f")
17806         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17807          UNSPEC_FRNDINT_TRUNC))
17808    (clobber (reg:CC FLAGS_REG))]
17809   "TARGET_USE_FANCY_MATH_387
17810    && flag_unsafe_math_optimizations
17811    && !(reload_completed || reload_in_progress)"
17812   "#"
17813   "&& 1"
17814   [(const_int 0)]
17815 {
17816   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17817
17818   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17819   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17820
17821   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17822                                         operands[2], operands[3]));
17823   DONE;
17824 }
17825   [(set_attr "type" "frndint")
17826    (set_attr "i387_cw" "trunc")
17827    (set_attr "mode" "XF")])
17828
17829 (define_insn "frndintxf2_trunc_i387"
17830   [(set (match_operand:XF 0 "register_operand" "=f")
17831         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17832          UNSPEC_FRNDINT_TRUNC))
17833    (use (match_operand:HI 2 "memory_operand" "m"))
17834    (use (match_operand:HI 3 "memory_operand" "m"))]
17835   "TARGET_USE_FANCY_MATH_387
17836    && flag_unsafe_math_optimizations"
17837   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17838   [(set_attr "type" "frndint")
17839    (set_attr "i387_cw" "trunc")
17840    (set_attr "mode" "XF")])
17841
17842 (define_expand "btruncxf2"
17843   [(use (match_operand:XF 0 "register_operand" ""))
17844    (use (match_operand:XF 1 "register_operand" ""))]
17845   "TARGET_USE_FANCY_MATH_387
17846    && flag_unsafe_math_optimizations && !optimize_size"
17847 {
17848   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17849   DONE;
17850 })
17851
17852 (define_expand "btruncdf2"
17853   [(use (match_operand:DF 0 "register_operand" ""))
17854    (use (match_operand:DF 1 "register_operand" ""))]
17855   "((TARGET_USE_FANCY_MATH_387
17856      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17857      && flag_unsafe_math_optimizations)
17858     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17859         && !flag_trapping_math))
17860    && !optimize_size"
17861 {
17862   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17863       && !flag_trapping_math)
17864     {
17865       if (TARGET_64BIT)
17866         ix86_expand_trunc (operand0, operand1);
17867       else
17868         ix86_expand_truncdf_32 (operand0, operand1);
17869     }
17870   else
17871     {
17872       rtx op0 = gen_reg_rtx (XFmode);
17873       rtx op1 = gen_reg_rtx (XFmode);
17874
17875       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17876       emit_insn (gen_frndintxf2_trunc (op0, op1));
17877
17878       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17879     }
17880   DONE;
17881 })
17882
17883 (define_expand "btruncsf2"
17884   [(use (match_operand:SF 0 "register_operand" ""))
17885    (use (match_operand:SF 1 "register_operand" ""))]
17886   "((TARGET_USE_FANCY_MATH_387
17887      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17888      && flag_unsafe_math_optimizations)
17889     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17890         && !flag_trapping_math))
17891    && !optimize_size"
17892 {
17893   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17894       && !flag_trapping_math)
17895     ix86_expand_trunc (operand0, operand1);
17896   else
17897     {
17898       rtx op0 = gen_reg_rtx (XFmode);
17899       rtx op1 = gen_reg_rtx (XFmode);
17900
17901       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17902       emit_insn (gen_frndintxf2_trunc (op0, op1));
17903
17904       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17905     }
17906   DONE;
17907 })
17908
17909 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17910 (define_insn_and_split "frndintxf2_mask_pm"
17911   [(set (match_operand:XF 0 "register_operand" "=f")
17912         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17913          UNSPEC_FRNDINT_MASK_PM))
17914    (clobber (reg:CC FLAGS_REG))]
17915   "TARGET_USE_FANCY_MATH_387
17916    && flag_unsafe_math_optimizations
17917    && !(reload_completed || reload_in_progress)"
17918   "#"
17919   "&& 1"
17920   [(const_int 0)]
17921 {
17922   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17923
17924   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17925   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17926
17927   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17928                                           operands[2], operands[3]));
17929   DONE;
17930 }
17931   [(set_attr "type" "frndint")
17932    (set_attr "i387_cw" "mask_pm")
17933    (set_attr "mode" "XF")])
17934
17935 (define_insn "frndintxf2_mask_pm_i387"
17936   [(set (match_operand:XF 0 "register_operand" "=f")
17937         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17938          UNSPEC_FRNDINT_MASK_PM))
17939    (use (match_operand:HI 2 "memory_operand" "m"))
17940    (use (match_operand:HI 3 "memory_operand" "m"))]
17941   "TARGET_USE_FANCY_MATH_387
17942    && flag_unsafe_math_optimizations"
17943   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17944   [(set_attr "type" "frndint")
17945    (set_attr "i387_cw" "mask_pm")
17946    (set_attr "mode" "XF")])
17947
17948 (define_expand "nearbyintxf2"
17949   [(use (match_operand:XF 0 "register_operand" ""))
17950    (use (match_operand:XF 1 "register_operand" ""))]
17951   "TARGET_USE_FANCY_MATH_387
17952    && flag_unsafe_math_optimizations"
17953 {
17954   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17955
17956   DONE;
17957 })
17958
17959 (define_expand "nearbyintdf2"
17960   [(use (match_operand:DF 0 "register_operand" ""))
17961    (use (match_operand:DF 1 "register_operand" ""))]
17962   "TARGET_USE_FANCY_MATH_387
17963    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17964    && flag_unsafe_math_optimizations"
17965 {
17966   rtx op0 = gen_reg_rtx (XFmode);
17967   rtx op1 = gen_reg_rtx (XFmode);
17968
17969   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17970   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17971
17972   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17973   DONE;
17974 })
17975
17976 (define_expand "nearbyintsf2"
17977   [(use (match_operand:SF 0 "register_operand" ""))
17978    (use (match_operand:SF 1 "register_operand" ""))]
17979   "TARGET_USE_FANCY_MATH_387
17980    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17981    && flag_unsafe_math_optimizations"
17982 {
17983   rtx op0 = gen_reg_rtx (XFmode);
17984   rtx op1 = gen_reg_rtx (XFmode);
17985
17986   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17987   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17988
17989   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17990   DONE;
17991 })
17992
17993 (define_insn "fxam<mode>2_i387"
17994   [(set (match_operand:HI 0 "register_operand" "=a")
17995         (unspec:HI
17996           [(match_operand:X87MODEF 1 "register_operand" "f")]
17997           UNSPEC_FXAM))]
17998   "TARGET_USE_FANCY_MATH_387"
17999   "fxam\n\tfnstsw\t%0"
18000   [(set_attr "type" "multi")
18001    (set_attr "unit" "i387")
18002    (set_attr "mode" "<MODE>")])
18003
18004 (define_expand "isinf<mode>2"
18005   [(use (match_operand:SI 0 "register_operand" ""))
18006    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18007   "TARGET_USE_FANCY_MATH_387
18008   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18009       || TARGET_MIX_SSE_I387)"
18010 {
18011   rtx mask = GEN_INT (0x45);
18012   rtx val = GEN_INT (0x05);
18013
18014   rtx cond;
18015
18016   rtx scratch = gen_reg_rtx (HImode);
18017   rtx res = gen_reg_rtx (QImode);
18018
18019   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18020   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18021   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18022   cond = gen_rtx_fmt_ee (EQ, QImode,
18023                          gen_rtx_REG (CCmode, FLAGS_REG),
18024                          const0_rtx);
18025   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18026   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18027   DONE;
18028 })
18029
18030 \f
18031 ;; Block operation instructions
18032
18033 (define_expand "movmemsi"
18034   [(use (match_operand:BLK 0 "memory_operand" ""))
18035    (use (match_operand:BLK 1 "memory_operand" ""))
18036    (use (match_operand:SI 2 "nonmemory_operand" ""))
18037    (use (match_operand:SI 3 "const_int_operand" ""))
18038    (use (match_operand:SI 4 "const_int_operand" ""))
18039    (use (match_operand:SI 5 "const_int_operand" ""))]
18040   ""
18041 {
18042  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18043                          operands[4], operands[5]))
18044    DONE;
18045  else
18046    FAIL;
18047 })
18048
18049 (define_expand "movmemdi"
18050   [(use (match_operand:BLK 0 "memory_operand" ""))
18051    (use (match_operand:BLK 1 "memory_operand" ""))
18052    (use (match_operand:DI 2 "nonmemory_operand" ""))
18053    (use (match_operand:DI 3 "const_int_operand" ""))
18054    (use (match_operand:SI 4 "const_int_operand" ""))
18055    (use (match_operand:SI 5 "const_int_operand" ""))]
18056   "TARGET_64BIT"
18057 {
18058  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18059                          operands[4], operands[5]))
18060    DONE;
18061  else
18062    FAIL;
18063 })
18064
18065 ;; Most CPUs don't like single string operations
18066 ;; Handle this case here to simplify previous expander.
18067
18068 (define_expand "strmov"
18069   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18070    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18071    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18072               (clobber (reg:CC FLAGS_REG))])
18073    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18074               (clobber (reg:CC FLAGS_REG))])]
18075   ""
18076 {
18077   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18078
18079   /* If .md ever supports :P for Pmode, these can be directly
18080      in the pattern above.  */
18081   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18082   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18083
18084   if (TARGET_SINGLE_STRINGOP || optimize_size)
18085     {
18086       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18087                                       operands[2], operands[3],
18088                                       operands[5], operands[6]));
18089       DONE;
18090     }
18091
18092   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18093 })
18094
18095 (define_expand "strmov_singleop"
18096   [(parallel [(set (match_operand 1 "memory_operand" "")
18097                    (match_operand 3 "memory_operand" ""))
18098               (set (match_operand 0 "register_operand" "")
18099                    (match_operand 4 "" ""))
18100               (set (match_operand 2 "register_operand" "")
18101                    (match_operand 5 "" ""))])]
18102   "TARGET_SINGLE_STRINGOP || optimize_size"
18103   "")
18104
18105 (define_insn "*strmovdi_rex_1"
18106   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18107         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18108    (set (match_operand:DI 0 "register_operand" "=D")
18109         (plus:DI (match_dup 2)
18110                  (const_int 8)))
18111    (set (match_operand:DI 1 "register_operand" "=S")
18112         (plus:DI (match_dup 3)
18113                  (const_int 8)))]
18114   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18115   "movsq"
18116   [(set_attr "type" "str")
18117    (set_attr "mode" "DI")
18118    (set_attr "memory" "both")])
18119
18120 (define_insn "*strmovsi_1"
18121   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18122         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18123    (set (match_operand:SI 0 "register_operand" "=D")
18124         (plus:SI (match_dup 2)
18125                  (const_int 4)))
18126    (set (match_operand:SI 1 "register_operand" "=S")
18127         (plus:SI (match_dup 3)
18128                  (const_int 4)))]
18129   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18130   "{movsl|movsd}"
18131   [(set_attr "type" "str")
18132    (set_attr "mode" "SI")
18133    (set_attr "memory" "both")])
18134
18135 (define_insn "*strmovsi_rex_1"
18136   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18137         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18138    (set (match_operand:DI 0 "register_operand" "=D")
18139         (plus:DI (match_dup 2)
18140                  (const_int 4)))
18141    (set (match_operand:DI 1 "register_operand" "=S")
18142         (plus:DI (match_dup 3)
18143                  (const_int 4)))]
18144   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18145   "{movsl|movsd}"
18146   [(set_attr "type" "str")
18147    (set_attr "mode" "SI")
18148    (set_attr "memory" "both")])
18149
18150 (define_insn "*strmovhi_1"
18151   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18152         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18153    (set (match_operand:SI 0 "register_operand" "=D")
18154         (plus:SI (match_dup 2)
18155                  (const_int 2)))
18156    (set (match_operand:SI 1 "register_operand" "=S")
18157         (plus:SI (match_dup 3)
18158                  (const_int 2)))]
18159   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18160   "movsw"
18161   [(set_attr "type" "str")
18162    (set_attr "memory" "both")
18163    (set_attr "mode" "HI")])
18164
18165 (define_insn "*strmovhi_rex_1"
18166   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18167         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18168    (set (match_operand:DI 0 "register_operand" "=D")
18169         (plus:DI (match_dup 2)
18170                  (const_int 2)))
18171    (set (match_operand:DI 1 "register_operand" "=S")
18172         (plus:DI (match_dup 3)
18173                  (const_int 2)))]
18174   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18175   "movsw"
18176   [(set_attr "type" "str")
18177    (set_attr "memory" "both")
18178    (set_attr "mode" "HI")])
18179
18180 (define_insn "*strmovqi_1"
18181   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18182         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18183    (set (match_operand:SI 0 "register_operand" "=D")
18184         (plus:SI (match_dup 2)
18185                  (const_int 1)))
18186    (set (match_operand:SI 1 "register_operand" "=S")
18187         (plus:SI (match_dup 3)
18188                  (const_int 1)))]
18189   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18190   "movsb"
18191   [(set_attr "type" "str")
18192    (set_attr "memory" "both")
18193    (set_attr "mode" "QI")])
18194
18195 (define_insn "*strmovqi_rex_1"
18196   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18197         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18198    (set (match_operand:DI 0 "register_operand" "=D")
18199         (plus:DI (match_dup 2)
18200                  (const_int 1)))
18201    (set (match_operand:DI 1 "register_operand" "=S")
18202         (plus:DI (match_dup 3)
18203                  (const_int 1)))]
18204   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18205   "movsb"
18206   [(set_attr "type" "str")
18207    (set_attr "memory" "both")
18208    (set_attr "mode" "QI")])
18209
18210 (define_expand "rep_mov"
18211   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18212               (set (match_operand 0 "register_operand" "")
18213                    (match_operand 5 "" ""))
18214               (set (match_operand 2 "register_operand" "")
18215                    (match_operand 6 "" ""))
18216               (set (match_operand 1 "memory_operand" "")
18217                    (match_operand 3 "memory_operand" ""))
18218               (use (match_dup 4))])]
18219   ""
18220   "")
18221
18222 (define_insn "*rep_movdi_rex64"
18223   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18224    (set (match_operand:DI 0 "register_operand" "=D")
18225         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18226                             (const_int 3))
18227                  (match_operand:DI 3 "register_operand" "0")))
18228    (set (match_operand:DI 1 "register_operand" "=S")
18229         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18230                  (match_operand:DI 4 "register_operand" "1")))
18231    (set (mem:BLK (match_dup 3))
18232         (mem:BLK (match_dup 4)))
18233    (use (match_dup 5))]
18234   "TARGET_64BIT"
18235   "{rep\;movsq|rep movsq}"
18236   [(set_attr "type" "str")
18237    (set_attr "prefix_rep" "1")
18238    (set_attr "memory" "both")
18239    (set_attr "mode" "DI")])
18240
18241 (define_insn "*rep_movsi"
18242   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18243    (set (match_operand:SI 0 "register_operand" "=D")
18244         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18245                             (const_int 2))
18246                  (match_operand:SI 3 "register_operand" "0")))
18247    (set (match_operand:SI 1 "register_operand" "=S")
18248         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18249                  (match_operand:SI 4 "register_operand" "1")))
18250    (set (mem:BLK (match_dup 3))
18251         (mem:BLK (match_dup 4)))
18252    (use (match_dup 5))]
18253   "!TARGET_64BIT"
18254   "{rep\;movsl|rep movsd}"
18255   [(set_attr "type" "str")
18256    (set_attr "prefix_rep" "1")
18257    (set_attr "memory" "both")
18258    (set_attr "mode" "SI")])
18259
18260 (define_insn "*rep_movsi_rex64"
18261   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18262    (set (match_operand:DI 0 "register_operand" "=D")
18263         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18264                             (const_int 2))
18265                  (match_operand:DI 3 "register_operand" "0")))
18266    (set (match_operand:DI 1 "register_operand" "=S")
18267         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18268                  (match_operand:DI 4 "register_operand" "1")))
18269    (set (mem:BLK (match_dup 3))
18270         (mem:BLK (match_dup 4)))
18271    (use (match_dup 5))]
18272   "TARGET_64BIT"
18273   "{rep\;movsl|rep movsd}"
18274   [(set_attr "type" "str")
18275    (set_attr "prefix_rep" "1")
18276    (set_attr "memory" "both")
18277    (set_attr "mode" "SI")])
18278
18279 (define_insn "*rep_movqi"
18280   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18281    (set (match_operand:SI 0 "register_operand" "=D")
18282         (plus:SI (match_operand:SI 3 "register_operand" "0")
18283                  (match_operand:SI 5 "register_operand" "2")))
18284    (set (match_operand:SI 1 "register_operand" "=S")
18285         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18286    (set (mem:BLK (match_dup 3))
18287         (mem:BLK (match_dup 4)))
18288    (use (match_dup 5))]
18289   "!TARGET_64BIT"
18290   "{rep\;movsb|rep movsb}"
18291   [(set_attr "type" "str")
18292    (set_attr "prefix_rep" "1")
18293    (set_attr "memory" "both")
18294    (set_attr "mode" "SI")])
18295
18296 (define_insn "*rep_movqi_rex64"
18297   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18298    (set (match_operand:DI 0 "register_operand" "=D")
18299         (plus:DI (match_operand:DI 3 "register_operand" "0")
18300                  (match_operand:DI 5 "register_operand" "2")))
18301    (set (match_operand:DI 1 "register_operand" "=S")
18302         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18303    (set (mem:BLK (match_dup 3))
18304         (mem:BLK (match_dup 4)))
18305    (use (match_dup 5))]
18306   "TARGET_64BIT"
18307   "{rep\;movsb|rep movsb}"
18308   [(set_attr "type" "str")
18309    (set_attr "prefix_rep" "1")
18310    (set_attr "memory" "both")
18311    (set_attr "mode" "SI")])
18312
18313 (define_expand "setmemsi"
18314    [(use (match_operand:BLK 0 "memory_operand" ""))
18315     (use (match_operand:SI 1 "nonmemory_operand" ""))
18316     (use (match_operand 2 "const_int_operand" ""))
18317     (use (match_operand 3 "const_int_operand" ""))
18318     (use (match_operand:SI 4 "const_int_operand" ""))
18319     (use (match_operand:SI 5 "const_int_operand" ""))]
18320   ""
18321 {
18322  if (ix86_expand_setmem (operands[0], operands[1],
18323                          operands[2], operands[3],
18324                          operands[4], operands[5]))
18325    DONE;
18326  else
18327    FAIL;
18328 })
18329
18330 (define_expand "setmemdi"
18331    [(use (match_operand:BLK 0 "memory_operand" ""))
18332     (use (match_operand:DI 1 "nonmemory_operand" ""))
18333     (use (match_operand 2 "const_int_operand" ""))
18334     (use (match_operand 3 "const_int_operand" ""))
18335     (use (match_operand 4 "const_int_operand" ""))
18336     (use (match_operand 5 "const_int_operand" ""))]
18337   "TARGET_64BIT"
18338 {
18339  if (ix86_expand_setmem (operands[0], operands[1],
18340                          operands[2], operands[3],
18341                          operands[4], operands[5]))
18342    DONE;
18343  else
18344    FAIL;
18345 })
18346
18347 ;; Most CPUs don't like single string operations
18348 ;; Handle this case here to simplify previous expander.
18349
18350 (define_expand "strset"
18351   [(set (match_operand 1 "memory_operand" "")
18352         (match_operand 2 "register_operand" ""))
18353    (parallel [(set (match_operand 0 "register_operand" "")
18354                    (match_dup 3))
18355               (clobber (reg:CC FLAGS_REG))])]
18356   ""
18357 {
18358   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18359     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18360
18361   /* If .md ever supports :P for Pmode, this can be directly
18362      in the pattern above.  */
18363   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18364                               GEN_INT (GET_MODE_SIZE (GET_MODE
18365                                                       (operands[2]))));
18366   if (TARGET_SINGLE_STRINGOP || optimize_size)
18367     {
18368       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18369                                       operands[3]));
18370       DONE;
18371     }
18372 })
18373
18374 (define_expand "strset_singleop"
18375   [(parallel [(set (match_operand 1 "memory_operand" "")
18376                    (match_operand 2 "register_operand" ""))
18377               (set (match_operand 0 "register_operand" "")
18378                    (match_operand 3 "" ""))])]
18379   "TARGET_SINGLE_STRINGOP || optimize_size"
18380   "")
18381
18382 (define_insn "*strsetdi_rex_1"
18383   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18384         (match_operand:DI 2 "register_operand" "a"))
18385    (set (match_operand:DI 0 "register_operand" "=D")
18386         (plus:DI (match_dup 1)
18387                  (const_int 8)))]
18388   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18389   "stosq"
18390   [(set_attr "type" "str")
18391    (set_attr "memory" "store")
18392    (set_attr "mode" "DI")])
18393
18394 (define_insn "*strsetsi_1"
18395   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18396         (match_operand:SI 2 "register_operand" "a"))
18397    (set (match_operand:SI 0 "register_operand" "=D")
18398         (plus:SI (match_dup 1)
18399                  (const_int 4)))]
18400   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18401   "{stosl|stosd}"
18402   [(set_attr "type" "str")
18403    (set_attr "memory" "store")
18404    (set_attr "mode" "SI")])
18405
18406 (define_insn "*strsetsi_rex_1"
18407   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18408         (match_operand:SI 2 "register_operand" "a"))
18409    (set (match_operand:DI 0 "register_operand" "=D")
18410         (plus:DI (match_dup 1)
18411                  (const_int 4)))]
18412   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18413   "{stosl|stosd}"
18414   [(set_attr "type" "str")
18415    (set_attr "memory" "store")
18416    (set_attr "mode" "SI")])
18417
18418 (define_insn "*strsethi_1"
18419   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18420         (match_operand:HI 2 "register_operand" "a"))
18421    (set (match_operand:SI 0 "register_operand" "=D")
18422         (plus:SI (match_dup 1)
18423                  (const_int 2)))]
18424   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18425   "stosw"
18426   [(set_attr "type" "str")
18427    (set_attr "memory" "store")
18428    (set_attr "mode" "HI")])
18429
18430 (define_insn "*strsethi_rex_1"
18431   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18432         (match_operand:HI 2 "register_operand" "a"))
18433    (set (match_operand:DI 0 "register_operand" "=D")
18434         (plus:DI (match_dup 1)
18435                  (const_int 2)))]
18436   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18437   "stosw"
18438   [(set_attr "type" "str")
18439    (set_attr "memory" "store")
18440    (set_attr "mode" "HI")])
18441
18442 (define_insn "*strsetqi_1"
18443   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18444         (match_operand:QI 2 "register_operand" "a"))
18445    (set (match_operand:SI 0 "register_operand" "=D")
18446         (plus:SI (match_dup 1)
18447                  (const_int 1)))]
18448   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18449   "stosb"
18450   [(set_attr "type" "str")
18451    (set_attr "memory" "store")
18452    (set_attr "mode" "QI")])
18453
18454 (define_insn "*strsetqi_rex_1"
18455   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18456         (match_operand:QI 2 "register_operand" "a"))
18457    (set (match_operand:DI 0 "register_operand" "=D")
18458         (plus:DI (match_dup 1)
18459                  (const_int 1)))]
18460   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18461   "stosb"
18462   [(set_attr "type" "str")
18463    (set_attr "memory" "store")
18464    (set_attr "mode" "QI")])
18465
18466 (define_expand "rep_stos"
18467   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18468               (set (match_operand 0 "register_operand" "")
18469                    (match_operand 4 "" ""))
18470               (set (match_operand 2 "memory_operand" "") (const_int 0))
18471               (use (match_operand 3 "register_operand" ""))
18472               (use (match_dup 1))])]
18473   ""
18474   "")
18475
18476 (define_insn "*rep_stosdi_rex64"
18477   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18478    (set (match_operand:DI 0 "register_operand" "=D")
18479         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18480                             (const_int 3))
18481                  (match_operand:DI 3 "register_operand" "0")))
18482    (set (mem:BLK (match_dup 3))
18483         (const_int 0))
18484    (use (match_operand:DI 2 "register_operand" "a"))
18485    (use (match_dup 4))]
18486   "TARGET_64BIT"
18487   "{rep\;stosq|rep stosq}"
18488   [(set_attr "type" "str")
18489    (set_attr "prefix_rep" "1")
18490    (set_attr "memory" "store")
18491    (set_attr "mode" "DI")])
18492
18493 (define_insn "*rep_stossi"
18494   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18495    (set (match_operand:SI 0 "register_operand" "=D")
18496         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18497                             (const_int 2))
18498                  (match_operand:SI 3 "register_operand" "0")))
18499    (set (mem:BLK (match_dup 3))
18500         (const_int 0))
18501    (use (match_operand:SI 2 "register_operand" "a"))
18502    (use (match_dup 4))]
18503   "!TARGET_64BIT"
18504   "{rep\;stosl|rep stosd}"
18505   [(set_attr "type" "str")
18506    (set_attr "prefix_rep" "1")
18507    (set_attr "memory" "store")
18508    (set_attr "mode" "SI")])
18509
18510 (define_insn "*rep_stossi_rex64"
18511   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18512    (set (match_operand:DI 0 "register_operand" "=D")
18513         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18514                             (const_int 2))
18515                  (match_operand:DI 3 "register_operand" "0")))
18516    (set (mem:BLK (match_dup 3))
18517         (const_int 0))
18518    (use (match_operand:SI 2 "register_operand" "a"))
18519    (use (match_dup 4))]
18520   "TARGET_64BIT"
18521   "{rep\;stosl|rep stosd}"
18522   [(set_attr "type" "str")
18523    (set_attr "prefix_rep" "1")
18524    (set_attr "memory" "store")
18525    (set_attr "mode" "SI")])
18526
18527 (define_insn "*rep_stosqi"
18528   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18529    (set (match_operand:SI 0 "register_operand" "=D")
18530         (plus:SI (match_operand:SI 3 "register_operand" "0")
18531                  (match_operand:SI 4 "register_operand" "1")))
18532    (set (mem:BLK (match_dup 3))
18533         (const_int 0))
18534    (use (match_operand:QI 2 "register_operand" "a"))
18535    (use (match_dup 4))]
18536   "!TARGET_64BIT"
18537   "{rep\;stosb|rep stosb}"
18538   [(set_attr "type" "str")
18539    (set_attr "prefix_rep" "1")
18540    (set_attr "memory" "store")
18541    (set_attr "mode" "QI")])
18542
18543 (define_insn "*rep_stosqi_rex64"
18544   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18545    (set (match_operand:DI 0 "register_operand" "=D")
18546         (plus:DI (match_operand:DI 3 "register_operand" "0")
18547                  (match_operand:DI 4 "register_operand" "1")))
18548    (set (mem:BLK (match_dup 3))
18549         (const_int 0))
18550    (use (match_operand:QI 2 "register_operand" "a"))
18551    (use (match_dup 4))]
18552   "TARGET_64BIT"
18553   "{rep\;stosb|rep stosb}"
18554   [(set_attr "type" "str")
18555    (set_attr "prefix_rep" "1")
18556    (set_attr "memory" "store")
18557    (set_attr "mode" "QI")])
18558
18559 (define_expand "cmpstrnsi"
18560   [(set (match_operand:SI 0 "register_operand" "")
18561         (compare:SI (match_operand:BLK 1 "general_operand" "")
18562                     (match_operand:BLK 2 "general_operand" "")))
18563    (use (match_operand 3 "general_operand" ""))
18564    (use (match_operand 4 "immediate_operand" ""))]
18565   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18566 {
18567   rtx addr1, addr2, out, outlow, count, countreg, align;
18568
18569   /* Can't use this if the user has appropriated esi or edi.  */
18570   if (global_regs[4] || global_regs[5])
18571     FAIL;
18572
18573   out = operands[0];
18574   if (!REG_P (out))
18575     out = gen_reg_rtx (SImode);
18576
18577   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18578   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18579   if (addr1 != XEXP (operands[1], 0))
18580     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18581   if (addr2 != XEXP (operands[2], 0))
18582     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18583
18584   count = operands[3];
18585   countreg = ix86_zero_extend_to_Pmode (count);
18586
18587   /* %%% Iff we are testing strict equality, we can use known alignment
18588      to good advantage.  This may be possible with combine, particularly
18589      once cc0 is dead.  */
18590   align = operands[4];
18591
18592   if (CONST_INT_P (count))
18593     {
18594       if (INTVAL (count) == 0)
18595         {
18596           emit_move_insn (operands[0], const0_rtx);
18597           DONE;
18598         }
18599       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18600                                      operands[1], operands[2]));
18601     }
18602   else
18603     {
18604       if (TARGET_64BIT)
18605         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18606       else
18607         emit_insn (gen_cmpsi_1 (countreg, countreg));
18608       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18609                                   operands[1], operands[2]));
18610     }
18611
18612   outlow = gen_lowpart (QImode, out);
18613   emit_insn (gen_cmpintqi (outlow));
18614   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18615
18616   if (operands[0] != out)
18617     emit_move_insn (operands[0], out);
18618
18619   DONE;
18620 })
18621
18622 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18623
18624 (define_expand "cmpintqi"
18625   [(set (match_dup 1)
18626         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18627    (set (match_dup 2)
18628         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18629    (parallel [(set (match_operand:QI 0 "register_operand" "")
18630                    (minus:QI (match_dup 1)
18631                              (match_dup 2)))
18632               (clobber (reg:CC FLAGS_REG))])]
18633   ""
18634   "operands[1] = gen_reg_rtx (QImode);
18635    operands[2] = gen_reg_rtx (QImode);")
18636
18637 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18638 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18639
18640 (define_expand "cmpstrnqi_nz_1"
18641   [(parallel [(set (reg:CC FLAGS_REG)
18642                    (compare:CC (match_operand 4 "memory_operand" "")
18643                                (match_operand 5 "memory_operand" "")))
18644               (use (match_operand 2 "register_operand" ""))
18645               (use (match_operand:SI 3 "immediate_operand" ""))
18646               (clobber (match_operand 0 "register_operand" ""))
18647               (clobber (match_operand 1 "register_operand" ""))
18648               (clobber (match_dup 2))])]
18649   ""
18650   "")
18651
18652 (define_insn "*cmpstrnqi_nz_1"
18653   [(set (reg:CC FLAGS_REG)
18654         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18655                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18656    (use (match_operand:SI 6 "register_operand" "2"))
18657    (use (match_operand:SI 3 "immediate_operand" "i"))
18658    (clobber (match_operand:SI 0 "register_operand" "=S"))
18659    (clobber (match_operand:SI 1 "register_operand" "=D"))
18660    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18661   "!TARGET_64BIT"
18662   "repz{\;| }cmpsb"
18663   [(set_attr "type" "str")
18664    (set_attr "mode" "QI")
18665    (set_attr "prefix_rep" "1")])
18666
18667 (define_insn "*cmpstrnqi_nz_rex_1"
18668   [(set (reg:CC FLAGS_REG)
18669         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18670                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18671    (use (match_operand:DI 6 "register_operand" "2"))
18672    (use (match_operand:SI 3 "immediate_operand" "i"))
18673    (clobber (match_operand:DI 0 "register_operand" "=S"))
18674    (clobber (match_operand:DI 1 "register_operand" "=D"))
18675    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18676   "TARGET_64BIT"
18677   "repz{\;| }cmpsb"
18678   [(set_attr "type" "str")
18679    (set_attr "mode" "QI")
18680    (set_attr "prefix_rep" "1")])
18681
18682 ;; The same, but the count is not known to not be zero.
18683
18684 (define_expand "cmpstrnqi_1"
18685   [(parallel [(set (reg:CC FLAGS_REG)
18686                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18687                                      (const_int 0))
18688                   (compare:CC (match_operand 4 "memory_operand" "")
18689                               (match_operand 5 "memory_operand" ""))
18690                   (const_int 0)))
18691               (use (match_operand:SI 3 "immediate_operand" ""))
18692               (use (reg:CC FLAGS_REG))
18693               (clobber (match_operand 0 "register_operand" ""))
18694               (clobber (match_operand 1 "register_operand" ""))
18695               (clobber (match_dup 2))])]
18696   ""
18697   "")
18698
18699 (define_insn "*cmpstrnqi_1"
18700   [(set (reg:CC FLAGS_REG)
18701         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18702                              (const_int 0))
18703           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18704                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18705           (const_int 0)))
18706    (use (match_operand:SI 3 "immediate_operand" "i"))
18707    (use (reg:CC FLAGS_REG))
18708    (clobber (match_operand:SI 0 "register_operand" "=S"))
18709    (clobber (match_operand:SI 1 "register_operand" "=D"))
18710    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18711   "!TARGET_64BIT"
18712   "repz{\;| }cmpsb"
18713   [(set_attr "type" "str")
18714    (set_attr "mode" "QI")
18715    (set_attr "prefix_rep" "1")])
18716
18717 (define_insn "*cmpstrnqi_rex_1"
18718   [(set (reg:CC FLAGS_REG)
18719         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18720                              (const_int 0))
18721           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18722                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18723           (const_int 0)))
18724    (use (match_operand:SI 3 "immediate_operand" "i"))
18725    (use (reg:CC FLAGS_REG))
18726    (clobber (match_operand:DI 0 "register_operand" "=S"))
18727    (clobber (match_operand:DI 1 "register_operand" "=D"))
18728    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18729   "TARGET_64BIT"
18730   "repz{\;| }cmpsb"
18731   [(set_attr "type" "str")
18732    (set_attr "mode" "QI")
18733    (set_attr "prefix_rep" "1")])
18734
18735 (define_expand "strlensi"
18736   [(set (match_operand:SI 0 "register_operand" "")
18737         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18738                     (match_operand:QI 2 "immediate_operand" "")
18739                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18740   ""
18741 {
18742  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18743    DONE;
18744  else
18745    FAIL;
18746 })
18747
18748 (define_expand "strlendi"
18749   [(set (match_operand:DI 0 "register_operand" "")
18750         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18751                     (match_operand:QI 2 "immediate_operand" "")
18752                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18753   ""
18754 {
18755  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18756    DONE;
18757  else
18758    FAIL;
18759 })
18760
18761 (define_expand "strlenqi_1"
18762   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18763               (clobber (match_operand 1 "register_operand" ""))
18764               (clobber (reg:CC FLAGS_REG))])]
18765   ""
18766   "")
18767
18768 (define_insn "*strlenqi_1"
18769   [(set (match_operand:SI 0 "register_operand" "=&c")
18770         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18771                     (match_operand:QI 2 "register_operand" "a")
18772                     (match_operand:SI 3 "immediate_operand" "i")
18773                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18774    (clobber (match_operand:SI 1 "register_operand" "=D"))
18775    (clobber (reg:CC FLAGS_REG))]
18776   "!TARGET_64BIT"
18777   "repnz{\;| }scasb"
18778   [(set_attr "type" "str")
18779    (set_attr "mode" "QI")
18780    (set_attr "prefix_rep" "1")])
18781
18782 (define_insn "*strlenqi_rex_1"
18783   [(set (match_operand:DI 0 "register_operand" "=&c")
18784         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18785                     (match_operand:QI 2 "register_operand" "a")
18786                     (match_operand:DI 3 "immediate_operand" "i")
18787                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18788    (clobber (match_operand:DI 1 "register_operand" "=D"))
18789    (clobber (reg:CC FLAGS_REG))]
18790   "TARGET_64BIT"
18791   "repnz{\;| }scasb"
18792   [(set_attr "type" "str")
18793    (set_attr "mode" "QI")
18794    (set_attr "prefix_rep" "1")])
18795
18796 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18797 ;; handled in combine, but it is not currently up to the task.
18798 ;; When used for their truth value, the cmpstrn* expanders generate
18799 ;; code like this:
18800 ;;
18801 ;;   repz cmpsb
18802 ;;   seta       %al
18803 ;;   setb       %dl
18804 ;;   cmpb       %al, %dl
18805 ;;   jcc        label
18806 ;;
18807 ;; The intermediate three instructions are unnecessary.
18808
18809 ;; This one handles cmpstrn*_nz_1...
18810 (define_peephole2
18811   [(parallel[
18812      (set (reg:CC FLAGS_REG)
18813           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18814                       (mem:BLK (match_operand 5 "register_operand" ""))))
18815      (use (match_operand 6 "register_operand" ""))
18816      (use (match_operand:SI 3 "immediate_operand" ""))
18817      (clobber (match_operand 0 "register_operand" ""))
18818      (clobber (match_operand 1 "register_operand" ""))
18819      (clobber (match_operand 2 "register_operand" ""))])
18820    (set (match_operand:QI 7 "register_operand" "")
18821         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18822    (set (match_operand:QI 8 "register_operand" "")
18823         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18824    (set (reg FLAGS_REG)
18825         (compare (match_dup 7) (match_dup 8)))
18826   ]
18827   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18828   [(parallel[
18829      (set (reg:CC FLAGS_REG)
18830           (compare:CC (mem:BLK (match_dup 4))
18831                       (mem:BLK (match_dup 5))))
18832      (use (match_dup 6))
18833      (use (match_dup 3))
18834      (clobber (match_dup 0))
18835      (clobber (match_dup 1))
18836      (clobber (match_dup 2))])]
18837   "")
18838
18839 ;; ...and this one handles cmpstrn*_1.
18840 (define_peephole2
18841   [(parallel[
18842      (set (reg:CC FLAGS_REG)
18843           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18844                                (const_int 0))
18845             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18846                         (mem:BLK (match_operand 5 "register_operand" "")))
18847             (const_int 0)))
18848      (use (match_operand:SI 3 "immediate_operand" ""))
18849      (use (reg:CC FLAGS_REG))
18850      (clobber (match_operand 0 "register_operand" ""))
18851      (clobber (match_operand 1 "register_operand" ""))
18852      (clobber (match_operand 2 "register_operand" ""))])
18853    (set (match_operand:QI 7 "register_operand" "")
18854         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18855    (set (match_operand:QI 8 "register_operand" "")
18856         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18857    (set (reg FLAGS_REG)
18858         (compare (match_dup 7) (match_dup 8)))
18859   ]
18860   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18861   [(parallel[
18862      (set (reg:CC FLAGS_REG)
18863           (if_then_else:CC (ne (match_dup 6)
18864                                (const_int 0))
18865             (compare:CC (mem:BLK (match_dup 4))
18866                         (mem:BLK (match_dup 5)))
18867             (const_int 0)))
18868      (use (match_dup 3))
18869      (use (reg:CC FLAGS_REG))
18870      (clobber (match_dup 0))
18871      (clobber (match_dup 1))
18872      (clobber (match_dup 2))])]
18873   "")
18874
18875
18876 \f
18877 ;; Conditional move instructions.
18878
18879 (define_expand "movdicc"
18880   [(set (match_operand:DI 0 "register_operand" "")
18881         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18882                          (match_operand:DI 2 "general_operand" "")
18883                          (match_operand:DI 3 "general_operand" "")))]
18884   "TARGET_64BIT"
18885   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18886
18887 (define_insn "x86_movdicc_0_m1_rex64"
18888   [(set (match_operand:DI 0 "register_operand" "=r")
18889         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18890           (const_int -1)
18891           (const_int 0)))
18892    (clobber (reg:CC FLAGS_REG))]
18893   "TARGET_64BIT"
18894   "sbb{q}\t%0, %0"
18895   ; Since we don't have the proper number of operands for an alu insn,
18896   ; fill in all the blanks.
18897   [(set_attr "type" "alu")
18898    (set_attr "pent_pair" "pu")
18899    (set_attr "memory" "none")
18900    (set_attr "imm_disp" "false")
18901    (set_attr "mode" "DI")
18902    (set_attr "length_immediate" "0")])
18903
18904 (define_insn "*movdicc_c_rex64"
18905   [(set (match_operand:DI 0 "register_operand" "=r,r")
18906         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18907                                 [(reg FLAGS_REG) (const_int 0)])
18908                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18909                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18910   "TARGET_64BIT && TARGET_CMOVE
18911    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18912   "@
18913    cmov%O2%C1\t{%2, %0|%0, %2}
18914    cmov%O2%c1\t{%3, %0|%0, %3}"
18915   [(set_attr "type" "icmov")
18916    (set_attr "mode" "DI")])
18917
18918 (define_expand "movsicc"
18919   [(set (match_operand:SI 0 "register_operand" "")
18920         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18921                          (match_operand:SI 2 "general_operand" "")
18922                          (match_operand:SI 3 "general_operand" "")))]
18923   ""
18924   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18925
18926 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18927 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18928 ;; So just document what we're doing explicitly.
18929
18930 (define_insn "x86_movsicc_0_m1"
18931   [(set (match_operand:SI 0 "register_operand" "=r")
18932         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18933           (const_int -1)
18934           (const_int 0)))
18935    (clobber (reg:CC FLAGS_REG))]
18936   ""
18937   "sbb{l}\t%0, %0"
18938   ; Since we don't have the proper number of operands for an alu insn,
18939   ; fill in all the blanks.
18940   [(set_attr "type" "alu")
18941    (set_attr "pent_pair" "pu")
18942    (set_attr "memory" "none")
18943    (set_attr "imm_disp" "false")
18944    (set_attr "mode" "SI")
18945    (set_attr "length_immediate" "0")])
18946
18947 (define_insn "*movsicc_noc"
18948   [(set (match_operand:SI 0 "register_operand" "=r,r")
18949         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18950                                 [(reg FLAGS_REG) (const_int 0)])
18951                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18952                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18953   "TARGET_CMOVE
18954    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18955   "@
18956    cmov%O2%C1\t{%2, %0|%0, %2}
18957    cmov%O2%c1\t{%3, %0|%0, %3}"
18958   [(set_attr "type" "icmov")
18959    (set_attr "mode" "SI")])
18960
18961 (define_expand "movhicc"
18962   [(set (match_operand:HI 0 "register_operand" "")
18963         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18964                          (match_operand:HI 2 "general_operand" "")
18965                          (match_operand:HI 3 "general_operand" "")))]
18966   "TARGET_HIMODE_MATH"
18967   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18968
18969 (define_insn "*movhicc_noc"
18970   [(set (match_operand:HI 0 "register_operand" "=r,r")
18971         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18972                                 [(reg FLAGS_REG) (const_int 0)])
18973                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18974                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18975   "TARGET_CMOVE
18976    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18977   "@
18978    cmov%O2%C1\t{%2, %0|%0, %2}
18979    cmov%O2%c1\t{%3, %0|%0, %3}"
18980   [(set_attr "type" "icmov")
18981    (set_attr "mode" "HI")])
18982
18983 (define_expand "movqicc"
18984   [(set (match_operand:QI 0 "register_operand" "")
18985         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18986                          (match_operand:QI 2 "general_operand" "")
18987                          (match_operand:QI 3 "general_operand" "")))]
18988   "TARGET_QIMODE_MATH"
18989   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18990
18991 (define_insn_and_split "*movqicc_noc"
18992   [(set (match_operand:QI 0 "register_operand" "=r,r")
18993         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18994                                 [(match_operand 4 "flags_reg_operand" "")
18995                                  (const_int 0)])
18996                       (match_operand:QI 2 "register_operand" "r,0")
18997                       (match_operand:QI 3 "register_operand" "0,r")))]
18998   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18999   "#"
19000   "&& reload_completed"
19001   [(set (match_dup 0)
19002         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19003                       (match_dup 2)
19004                       (match_dup 3)))]
19005   "operands[0] = gen_lowpart (SImode, operands[0]);
19006    operands[2] = gen_lowpart (SImode, operands[2]);
19007    operands[3] = gen_lowpart (SImode, operands[3]);"
19008   [(set_attr "type" "icmov")
19009    (set_attr "mode" "SI")])
19010
19011 (define_expand "movsfcc"
19012   [(set (match_operand:SF 0 "register_operand" "")
19013         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19014                          (match_operand:SF 2 "register_operand" "")
19015                          (match_operand:SF 3 "register_operand" "")))]
19016   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19017   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19018
19019 (define_insn "*movsfcc_1_387"
19020   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19021         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19022                                 [(reg FLAGS_REG) (const_int 0)])
19023                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19024                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19025   "TARGET_80387 && TARGET_CMOVE
19026    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19027   "@
19028    fcmov%F1\t{%2, %0|%0, %2}
19029    fcmov%f1\t{%3, %0|%0, %3}
19030    cmov%O2%C1\t{%2, %0|%0, %2}
19031    cmov%O2%c1\t{%3, %0|%0, %3}"
19032   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19033    (set_attr "mode" "SF,SF,SI,SI")])
19034
19035 (define_expand "movdfcc"
19036   [(set (match_operand:DF 0 "register_operand" "")
19037         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19038                          (match_operand:DF 2 "register_operand" "")
19039                          (match_operand:DF 3 "register_operand" "")))]
19040   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19041   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19042
19043 (define_insn "*movdfcc_1"
19044   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19045         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19046                                 [(reg FLAGS_REG) (const_int 0)])
19047                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19048                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19049   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19050    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19051   "@
19052    fcmov%F1\t{%2, %0|%0, %2}
19053    fcmov%f1\t{%3, %0|%0, %3}
19054    #
19055    #"
19056   [(set_attr "type" "fcmov,fcmov,multi,multi")
19057    (set_attr "mode" "DF")])
19058
19059 (define_insn "*movdfcc_1_rex64"
19060   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19061         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19062                                 [(reg FLAGS_REG) (const_int 0)])
19063                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19064                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19065   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19066    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19067   "@
19068    fcmov%F1\t{%2, %0|%0, %2}
19069    fcmov%f1\t{%3, %0|%0, %3}
19070    cmov%O2%C1\t{%2, %0|%0, %2}
19071    cmov%O2%c1\t{%3, %0|%0, %3}"
19072   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19073    (set_attr "mode" "DF")])
19074
19075 (define_split
19076   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19077         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19078                                 [(match_operand 4 "flags_reg_operand" "")
19079                                  (const_int 0)])
19080                       (match_operand:DF 2 "nonimmediate_operand" "")
19081                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19082   "!TARGET_64BIT && reload_completed"
19083   [(set (match_dup 2)
19084         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19085                       (match_dup 5)
19086                       (match_dup 7)))
19087    (set (match_dup 3)
19088         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19089                       (match_dup 6)
19090                       (match_dup 8)))]
19091   "split_di (operands+2, 1, operands+5, operands+6);
19092    split_di (operands+3, 1, operands+7, operands+8);
19093    split_di (operands, 1, operands+2, operands+3);")
19094
19095 (define_expand "movxfcc"
19096   [(set (match_operand:XF 0 "register_operand" "")
19097         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19098                          (match_operand:XF 2 "register_operand" "")
19099                          (match_operand:XF 3 "register_operand" "")))]
19100   "TARGET_80387 && TARGET_CMOVE"
19101   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19102
19103 (define_insn "*movxfcc_1"
19104   [(set (match_operand:XF 0 "register_operand" "=f,f")
19105         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19106                                 [(reg FLAGS_REG) (const_int 0)])
19107                       (match_operand:XF 2 "register_operand" "f,0")
19108                       (match_operand:XF 3 "register_operand" "0,f")))]
19109   "TARGET_80387 && TARGET_CMOVE"
19110   "@
19111    fcmov%F1\t{%2, %0|%0, %2}
19112    fcmov%f1\t{%3, %0|%0, %3}"
19113   [(set_attr "type" "fcmov")
19114    (set_attr "mode" "XF")])
19115
19116 ;; These versions of the min/max patterns are intentionally ignorant of
19117 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19118 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19119 ;; are undefined in this condition, we're certain this is correct.
19120
19121 (define_insn "sminsf3"
19122   [(set (match_operand:SF 0 "register_operand" "=x")
19123         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19124                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19125   "TARGET_SSE_MATH"
19126   "minss\t{%2, %0|%0, %2}"
19127   [(set_attr "type" "sseadd")
19128    (set_attr "mode" "SF")])
19129
19130 (define_insn "smaxsf3"
19131   [(set (match_operand:SF 0 "register_operand" "=x")
19132         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19133                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19134   "TARGET_SSE_MATH"
19135   "maxss\t{%2, %0|%0, %2}"
19136   [(set_attr "type" "sseadd")
19137    (set_attr "mode" "SF")])
19138
19139 (define_insn "smindf3"
19140   [(set (match_operand:DF 0 "register_operand" "=x")
19141         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19142                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19143   "TARGET_SSE2 && TARGET_SSE_MATH"
19144   "minsd\t{%2, %0|%0, %2}"
19145   [(set_attr "type" "sseadd")
19146    (set_attr "mode" "DF")])
19147
19148 (define_insn "smaxdf3"
19149   [(set (match_operand:DF 0 "register_operand" "=x")
19150         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19151                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19152   "TARGET_SSE2 && TARGET_SSE_MATH"
19153   "maxsd\t{%2, %0|%0, %2}"
19154   [(set_attr "type" "sseadd")
19155    (set_attr "mode" "DF")])
19156
19157 ;; These versions of the min/max patterns implement exactly the operations
19158 ;;   min = (op1 < op2 ? op1 : op2)
19159 ;;   max = (!(op1 < op2) ? op1 : op2)
19160 ;; Their operands are not commutative, and thus they may be used in the
19161 ;; presence of -0.0 and NaN.
19162
19163 (define_insn "*ieee_sminsf3"
19164   [(set (match_operand:SF 0 "register_operand" "=x")
19165         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19166                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19167                    UNSPEC_IEEE_MIN))]
19168   "TARGET_SSE_MATH"
19169   "minss\t{%2, %0|%0, %2}"
19170   [(set_attr "type" "sseadd")
19171    (set_attr "mode" "SF")])
19172
19173 (define_insn "*ieee_smaxsf3"
19174   [(set (match_operand:SF 0 "register_operand" "=x")
19175         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19176                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19177                    UNSPEC_IEEE_MAX))]
19178   "TARGET_SSE_MATH"
19179   "maxss\t{%2, %0|%0, %2}"
19180   [(set_attr "type" "sseadd")
19181    (set_attr "mode" "SF")])
19182
19183 (define_insn "*ieee_smindf3"
19184   [(set (match_operand:DF 0 "register_operand" "=x")
19185         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19186                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19187                    UNSPEC_IEEE_MIN))]
19188   "TARGET_SSE2 && TARGET_SSE_MATH"
19189   "minsd\t{%2, %0|%0, %2}"
19190   [(set_attr "type" "sseadd")
19191    (set_attr "mode" "DF")])
19192
19193 (define_insn "*ieee_smaxdf3"
19194   [(set (match_operand:DF 0 "register_operand" "=x")
19195         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19196                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19197                    UNSPEC_IEEE_MAX))]
19198   "TARGET_SSE2 && TARGET_SSE_MATH"
19199   "maxsd\t{%2, %0|%0, %2}"
19200   [(set_attr "type" "sseadd")
19201    (set_attr "mode" "DF")])
19202
19203 ;; Make two stack loads independent:
19204 ;;   fld aa              fld aa
19205 ;;   fld %st(0)     ->   fld bb
19206 ;;   fmul bb             fmul %st(1), %st
19207 ;;
19208 ;; Actually we only match the last two instructions for simplicity.
19209 (define_peephole2
19210   [(set (match_operand 0 "fp_register_operand" "")
19211         (match_operand 1 "fp_register_operand" ""))
19212    (set (match_dup 0)
19213         (match_operator 2 "binary_fp_operator"
19214            [(match_dup 0)
19215             (match_operand 3 "memory_operand" "")]))]
19216   "REGNO (operands[0]) != REGNO (operands[1])"
19217   [(set (match_dup 0) (match_dup 3))
19218    (set (match_dup 0) (match_dup 4))]
19219
19220   ;; The % modifier is not operational anymore in peephole2's, so we have to
19221   ;; swap the operands manually in the case of addition and multiplication.
19222   "if (COMMUTATIVE_ARITH_P (operands[2]))
19223      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19224                                  operands[0], operands[1]);
19225    else
19226      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19227                                  operands[1], operands[0]);")
19228
19229 ;; Conditional addition patterns
19230 (define_expand "addqicc"
19231   [(match_operand:QI 0 "register_operand" "")
19232    (match_operand 1 "comparison_operator" "")
19233    (match_operand:QI 2 "register_operand" "")
19234    (match_operand:QI 3 "const_int_operand" "")]
19235   ""
19236   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19237
19238 (define_expand "addhicc"
19239   [(match_operand:HI 0 "register_operand" "")
19240    (match_operand 1 "comparison_operator" "")
19241    (match_operand:HI 2 "register_operand" "")
19242    (match_operand:HI 3 "const_int_operand" "")]
19243   ""
19244   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19245
19246 (define_expand "addsicc"
19247   [(match_operand:SI 0 "register_operand" "")
19248    (match_operand 1 "comparison_operator" "")
19249    (match_operand:SI 2 "register_operand" "")
19250    (match_operand:SI 3 "const_int_operand" "")]
19251   ""
19252   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19253
19254 (define_expand "adddicc"
19255   [(match_operand:DI 0 "register_operand" "")
19256    (match_operand 1 "comparison_operator" "")
19257    (match_operand:DI 2 "register_operand" "")
19258    (match_operand:DI 3 "const_int_operand" "")]
19259   "TARGET_64BIT"
19260   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19261
19262 \f
19263 ;; Misc patterns (?)
19264
19265 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19266 ;; Otherwise there will be nothing to keep
19267 ;;
19268 ;; [(set (reg ebp) (reg esp))]
19269 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19270 ;;  (clobber (eflags)]
19271 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19272 ;;
19273 ;; in proper program order.
19274 (define_insn "pro_epilogue_adjust_stack_1"
19275   [(set (match_operand:SI 0 "register_operand" "=r,r")
19276         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19277                  (match_operand:SI 2 "immediate_operand" "i,i")))
19278    (clobber (reg:CC FLAGS_REG))
19279    (clobber (mem:BLK (scratch)))]
19280   "!TARGET_64BIT"
19281 {
19282   switch (get_attr_type (insn))
19283     {
19284     case TYPE_IMOV:
19285       return "mov{l}\t{%1, %0|%0, %1}";
19286
19287     case TYPE_ALU:
19288       if (CONST_INT_P (operands[2])
19289           && (INTVAL (operands[2]) == 128
19290               || (INTVAL (operands[2]) < 0
19291                   && INTVAL (operands[2]) != -128)))
19292         {
19293           operands[2] = GEN_INT (-INTVAL (operands[2]));
19294           return "sub{l}\t{%2, %0|%0, %2}";
19295         }
19296       return "add{l}\t{%2, %0|%0, %2}";
19297
19298     case TYPE_LEA:
19299       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19300       return "lea{l}\t{%a2, %0|%0, %a2}";
19301
19302     default:
19303       gcc_unreachable ();
19304     }
19305 }
19306   [(set (attr "type")
19307         (cond [(eq_attr "alternative" "0")
19308                  (const_string "alu")
19309                (match_operand:SI 2 "const0_operand" "")
19310                  (const_string "imov")
19311               ]
19312               (const_string "lea")))
19313    (set_attr "mode" "SI")])
19314
19315 (define_insn "pro_epilogue_adjust_stack_rex64"
19316   [(set (match_operand:DI 0 "register_operand" "=r,r")
19317         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19318                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19319    (clobber (reg:CC FLAGS_REG))
19320    (clobber (mem:BLK (scratch)))]
19321   "TARGET_64BIT"
19322 {
19323   switch (get_attr_type (insn))
19324     {
19325     case TYPE_IMOV:
19326       return "mov{q}\t{%1, %0|%0, %1}";
19327
19328     case TYPE_ALU:
19329       if (CONST_INT_P (operands[2])
19330           /* Avoid overflows.  */
19331           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19332           && (INTVAL (operands[2]) == 128
19333               || (INTVAL (operands[2]) < 0
19334                   && INTVAL (operands[2]) != -128)))
19335         {
19336           operands[2] = GEN_INT (-INTVAL (operands[2]));
19337           return "sub{q}\t{%2, %0|%0, %2}";
19338         }
19339       return "add{q}\t{%2, %0|%0, %2}";
19340
19341     case TYPE_LEA:
19342       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19343       return "lea{q}\t{%a2, %0|%0, %a2}";
19344
19345     default:
19346       gcc_unreachable ();
19347     }
19348 }
19349   [(set (attr "type")
19350         (cond [(eq_attr "alternative" "0")
19351                  (const_string "alu")
19352                (match_operand:DI 2 "const0_operand" "")
19353                  (const_string "imov")
19354               ]
19355               (const_string "lea")))
19356    (set_attr "mode" "DI")])
19357
19358 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19359   [(set (match_operand:DI 0 "register_operand" "=r,r")
19360         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19361                  (match_operand:DI 3 "immediate_operand" "i,i")))
19362    (use (match_operand:DI 2 "register_operand" "r,r"))
19363    (clobber (reg:CC FLAGS_REG))
19364    (clobber (mem:BLK (scratch)))]
19365   "TARGET_64BIT"
19366 {
19367   switch (get_attr_type (insn))
19368     {
19369     case TYPE_ALU:
19370       return "add{q}\t{%2, %0|%0, %2}";
19371
19372     case TYPE_LEA:
19373       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19374       return "lea{q}\t{%a2, %0|%0, %a2}";
19375
19376     default:
19377       gcc_unreachable ();
19378     }
19379 }
19380   [(set_attr "type" "alu,lea")
19381    (set_attr "mode" "DI")])
19382
19383 (define_expand "allocate_stack_worker"
19384   [(match_operand:SI 0 "register_operand" "")]
19385   "TARGET_STACK_PROBE"
19386 {
19387   if (reload_completed)
19388     {
19389       if (TARGET_64BIT)
19390         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19391       else
19392         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19393     }
19394   else
19395     {
19396       if (TARGET_64BIT)
19397         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19398       else
19399         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19400     }
19401   DONE;
19402 })
19403
19404 (define_insn "allocate_stack_worker_1"
19405   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19406     UNSPECV_STACK_PROBE)
19407    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19408    (clobber (match_scratch:SI 1 "=0"))
19409    (clobber (reg:CC FLAGS_REG))]
19410   "!TARGET_64BIT && TARGET_STACK_PROBE"
19411   "call\t__alloca"
19412   [(set_attr "type" "multi")
19413    (set_attr "length" "5")])
19414
19415 (define_expand "allocate_stack_worker_postreload"
19416   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19417                                     UNSPECV_STACK_PROBE)
19418               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19419               (clobber (match_dup 0))
19420               (clobber (reg:CC FLAGS_REG))])]
19421   ""
19422   "")
19423
19424 (define_insn "allocate_stack_worker_rex64"
19425   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19426     UNSPECV_STACK_PROBE)
19427    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19428    (clobber (match_scratch:DI 1 "=0"))
19429    (clobber (reg:CC FLAGS_REG))]
19430   "TARGET_64BIT && TARGET_STACK_PROBE"
19431   "call\t__alloca"
19432   [(set_attr "type" "multi")
19433    (set_attr "length" "5")])
19434
19435 (define_expand "allocate_stack_worker_rex64_postreload"
19436   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19437                                     UNSPECV_STACK_PROBE)
19438               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19439               (clobber (match_dup 0))
19440               (clobber (reg:CC FLAGS_REG))])]
19441   ""
19442   "")
19443
19444 (define_expand "allocate_stack"
19445   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19446                    (minus:SI (reg:SI SP_REG)
19447                              (match_operand:SI 1 "general_operand" "")))
19448               (clobber (reg:CC FLAGS_REG))])
19449    (parallel [(set (reg:SI SP_REG)
19450                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19451               (clobber (reg:CC FLAGS_REG))])]
19452   "TARGET_STACK_PROBE"
19453 {
19454 #ifdef CHECK_STACK_LIMIT
19455   if (CONST_INT_P (operands[1])
19456       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19457     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19458                            operands[1]));
19459   else
19460 #endif
19461     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19462                                                             operands[1])));
19463
19464   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19465   DONE;
19466 })
19467
19468 (define_expand "builtin_setjmp_receiver"
19469   [(label_ref (match_operand 0 "" ""))]
19470   "!TARGET_64BIT && flag_pic"
19471 {
19472   if (TARGET_MACHO)
19473     {
19474       rtx xops[3];
19475       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19476       rtx label_rtx = gen_label_rtx ();
19477       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19478       xops[0] = xops[1] = picreg;
19479       xops[2] = gen_rtx_CONST (SImode,
19480                   gen_rtx_MINUS (SImode,
19481                     gen_rtx_LABEL_REF (SImode, label_rtx),
19482                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19483       ix86_expand_binary_operator (MINUS, SImode, xops);
19484     }
19485   else
19486     emit_insn (gen_set_got (pic_offset_table_rtx));
19487   DONE;
19488 })
19489 \f
19490 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19491
19492 (define_split
19493   [(set (match_operand 0 "register_operand" "")
19494         (match_operator 3 "promotable_binary_operator"
19495            [(match_operand 1 "register_operand" "")
19496             (match_operand 2 "aligned_operand" "")]))
19497    (clobber (reg:CC FLAGS_REG))]
19498   "! TARGET_PARTIAL_REG_STALL && reload_completed
19499    && ((GET_MODE (operands[0]) == HImode
19500         && ((!optimize_size && !TARGET_FAST_PREFIX)
19501             /* ??? next two lines just !satisfies_constraint_K (...) */
19502             || !CONST_INT_P (operands[2])
19503             || satisfies_constraint_K (operands[2])))
19504        || (GET_MODE (operands[0]) == QImode
19505            && (TARGET_PROMOTE_QImode || optimize_size)))"
19506   [(parallel [(set (match_dup 0)
19507                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19508               (clobber (reg:CC FLAGS_REG))])]
19509   "operands[0] = gen_lowpart (SImode, operands[0]);
19510    operands[1] = gen_lowpart (SImode, operands[1]);
19511    if (GET_CODE (operands[3]) != ASHIFT)
19512      operands[2] = gen_lowpart (SImode, operands[2]);
19513    PUT_MODE (operands[3], SImode);")
19514
19515 ; Promote the QImode tests, as i386 has encoding of the AND
19516 ; instruction with 32-bit sign-extended immediate and thus the
19517 ; instruction size is unchanged, except in the %eax case for
19518 ; which it is increased by one byte, hence the ! optimize_size.
19519 (define_split
19520   [(set (match_operand 0 "flags_reg_operand" "")
19521         (match_operator 2 "compare_operator"
19522           [(and (match_operand 3 "aligned_operand" "")
19523                 (match_operand 4 "const_int_operand" ""))
19524            (const_int 0)]))
19525    (set (match_operand 1 "register_operand" "")
19526         (and (match_dup 3) (match_dup 4)))]
19527   "! TARGET_PARTIAL_REG_STALL && reload_completed
19528    /* Ensure that the operand will remain sign-extended immediate.  */
19529    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19530    && ! optimize_size
19531    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19532        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19533   [(parallel [(set (match_dup 0)
19534                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19535                                     (const_int 0)]))
19536               (set (match_dup 1)
19537                    (and:SI (match_dup 3) (match_dup 4)))])]
19538 {
19539   operands[4]
19540     = gen_int_mode (INTVAL (operands[4])
19541                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19542   operands[1] = gen_lowpart (SImode, operands[1]);
19543   operands[3] = gen_lowpart (SImode, operands[3]);
19544 })
19545
19546 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19547 ; the TEST instruction with 32-bit sign-extended immediate and thus
19548 ; the instruction size would at least double, which is not what we
19549 ; want even with ! optimize_size.
19550 (define_split
19551   [(set (match_operand 0 "flags_reg_operand" "")
19552         (match_operator 1 "compare_operator"
19553           [(and (match_operand:HI 2 "aligned_operand" "")
19554                 (match_operand:HI 3 "const_int_operand" ""))
19555            (const_int 0)]))]
19556   "! TARGET_PARTIAL_REG_STALL && reload_completed
19557    /* Ensure that the operand will remain sign-extended immediate.  */
19558    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19559    && ! TARGET_FAST_PREFIX
19560    && ! optimize_size"
19561   [(set (match_dup 0)
19562         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19563                          (const_int 0)]))]
19564 {
19565   operands[3]
19566     = gen_int_mode (INTVAL (operands[3])
19567                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19568   operands[2] = gen_lowpart (SImode, operands[2]);
19569 })
19570
19571 (define_split
19572   [(set (match_operand 0 "register_operand" "")
19573         (neg (match_operand 1 "register_operand" "")))
19574    (clobber (reg:CC FLAGS_REG))]
19575   "! TARGET_PARTIAL_REG_STALL && reload_completed
19576    && (GET_MODE (operands[0]) == HImode
19577        || (GET_MODE (operands[0]) == QImode
19578            && (TARGET_PROMOTE_QImode || optimize_size)))"
19579   [(parallel [(set (match_dup 0)
19580                    (neg:SI (match_dup 1)))
19581               (clobber (reg:CC FLAGS_REG))])]
19582   "operands[0] = gen_lowpart (SImode, operands[0]);
19583    operands[1] = gen_lowpart (SImode, operands[1]);")
19584
19585 (define_split
19586   [(set (match_operand 0 "register_operand" "")
19587         (not (match_operand 1 "register_operand" "")))]
19588   "! TARGET_PARTIAL_REG_STALL && reload_completed
19589    && (GET_MODE (operands[0]) == HImode
19590        || (GET_MODE (operands[0]) == QImode
19591            && (TARGET_PROMOTE_QImode || optimize_size)))"
19592   [(set (match_dup 0)
19593         (not:SI (match_dup 1)))]
19594   "operands[0] = gen_lowpart (SImode, operands[0]);
19595    operands[1] = gen_lowpart (SImode, operands[1]);")
19596
19597 (define_split
19598   [(set (match_operand 0 "register_operand" "")
19599         (if_then_else (match_operator 1 "comparison_operator"
19600                                 [(reg FLAGS_REG) (const_int 0)])
19601                       (match_operand 2 "register_operand" "")
19602                       (match_operand 3 "register_operand" "")))]
19603   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19604    && (GET_MODE (operands[0]) == HImode
19605        || (GET_MODE (operands[0]) == QImode
19606            && (TARGET_PROMOTE_QImode || optimize_size)))"
19607   [(set (match_dup 0)
19608         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19609   "operands[0] = gen_lowpart (SImode, operands[0]);
19610    operands[2] = gen_lowpart (SImode, operands[2]);
19611    operands[3] = gen_lowpart (SImode, operands[3]);")
19612
19613 \f
19614 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19615 ;; transform a complex memory operation into two memory to register operations.
19616
19617 ;; Don't push memory operands
19618 (define_peephole2
19619   [(set (match_operand:SI 0 "push_operand" "")
19620         (match_operand:SI 1 "memory_operand" ""))
19621    (match_scratch:SI 2 "r")]
19622   "!optimize_size && !TARGET_PUSH_MEMORY
19623    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19624   [(set (match_dup 2) (match_dup 1))
19625    (set (match_dup 0) (match_dup 2))]
19626   "")
19627
19628 (define_peephole2
19629   [(set (match_operand:DI 0 "push_operand" "")
19630         (match_operand:DI 1 "memory_operand" ""))
19631    (match_scratch:DI 2 "r")]
19632   "!optimize_size && !TARGET_PUSH_MEMORY
19633    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19634   [(set (match_dup 2) (match_dup 1))
19635    (set (match_dup 0) (match_dup 2))]
19636   "")
19637
19638 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19639 ;; SImode pushes.
19640 (define_peephole2
19641   [(set (match_operand:SF 0 "push_operand" "")
19642         (match_operand:SF 1 "memory_operand" ""))
19643    (match_scratch:SF 2 "r")]
19644   "!optimize_size && !TARGET_PUSH_MEMORY
19645    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19646   [(set (match_dup 2) (match_dup 1))
19647    (set (match_dup 0) (match_dup 2))]
19648   "")
19649
19650 (define_peephole2
19651   [(set (match_operand:HI 0 "push_operand" "")
19652         (match_operand:HI 1 "memory_operand" ""))
19653    (match_scratch:HI 2 "r")]
19654   "!optimize_size && !TARGET_PUSH_MEMORY
19655    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19656   [(set (match_dup 2) (match_dup 1))
19657    (set (match_dup 0) (match_dup 2))]
19658   "")
19659
19660 (define_peephole2
19661   [(set (match_operand:QI 0 "push_operand" "")
19662         (match_operand:QI 1 "memory_operand" ""))
19663    (match_scratch:QI 2 "q")]
19664   "!optimize_size && !TARGET_PUSH_MEMORY
19665    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19666   [(set (match_dup 2) (match_dup 1))
19667    (set (match_dup 0) (match_dup 2))]
19668   "")
19669
19670 ;; Don't move an immediate directly to memory when the instruction
19671 ;; gets too big.
19672 (define_peephole2
19673   [(match_scratch:SI 1 "r")
19674    (set (match_operand:SI 0 "memory_operand" "")
19675         (const_int 0))]
19676   "! optimize_size
19677    && ! TARGET_USE_MOV0
19678    && TARGET_SPLIT_LONG_MOVES
19679    && get_attr_length (insn) >= ix86_cost->large_insn
19680    && peep2_regno_dead_p (0, FLAGS_REG)"
19681   [(parallel [(set (match_dup 1) (const_int 0))
19682               (clobber (reg:CC FLAGS_REG))])
19683    (set (match_dup 0) (match_dup 1))]
19684   "")
19685
19686 (define_peephole2
19687   [(match_scratch:HI 1 "r")
19688    (set (match_operand:HI 0 "memory_operand" "")
19689         (const_int 0))]
19690   "! optimize_size
19691    && ! TARGET_USE_MOV0
19692    && TARGET_SPLIT_LONG_MOVES
19693    && get_attr_length (insn) >= ix86_cost->large_insn
19694    && peep2_regno_dead_p (0, FLAGS_REG)"
19695   [(parallel [(set (match_dup 2) (const_int 0))
19696               (clobber (reg:CC FLAGS_REG))])
19697    (set (match_dup 0) (match_dup 1))]
19698   "operands[2] = gen_lowpart (SImode, operands[1]);")
19699
19700 (define_peephole2
19701   [(match_scratch:QI 1 "q")
19702    (set (match_operand:QI 0 "memory_operand" "")
19703         (const_int 0))]
19704   "! optimize_size
19705    && ! TARGET_USE_MOV0
19706    && TARGET_SPLIT_LONG_MOVES
19707    && get_attr_length (insn) >= ix86_cost->large_insn
19708    && peep2_regno_dead_p (0, FLAGS_REG)"
19709   [(parallel [(set (match_dup 2) (const_int 0))
19710               (clobber (reg:CC FLAGS_REG))])
19711    (set (match_dup 0) (match_dup 1))]
19712   "operands[2] = gen_lowpart (SImode, operands[1]);")
19713
19714 (define_peephole2
19715   [(match_scratch:SI 2 "r")
19716    (set (match_operand:SI 0 "memory_operand" "")
19717         (match_operand:SI 1 "immediate_operand" ""))]
19718   "! optimize_size
19719    && get_attr_length (insn) >= ix86_cost->large_insn
19720    && TARGET_SPLIT_LONG_MOVES"
19721   [(set (match_dup 2) (match_dup 1))
19722    (set (match_dup 0) (match_dup 2))]
19723   "")
19724
19725 (define_peephole2
19726   [(match_scratch:HI 2 "r")
19727    (set (match_operand:HI 0 "memory_operand" "")
19728         (match_operand:HI 1 "immediate_operand" ""))]
19729   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19730   && TARGET_SPLIT_LONG_MOVES"
19731   [(set (match_dup 2) (match_dup 1))
19732    (set (match_dup 0) (match_dup 2))]
19733   "")
19734
19735 (define_peephole2
19736   [(match_scratch:QI 2 "q")
19737    (set (match_operand:QI 0 "memory_operand" "")
19738         (match_operand:QI 1 "immediate_operand" ""))]
19739   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19740   && TARGET_SPLIT_LONG_MOVES"
19741   [(set (match_dup 2) (match_dup 1))
19742    (set (match_dup 0) (match_dup 2))]
19743   "")
19744
19745 ;; Don't compare memory with zero, load and use a test instead.
19746 (define_peephole2
19747   [(set (match_operand 0 "flags_reg_operand" "")
19748         (match_operator 1 "compare_operator"
19749           [(match_operand:SI 2 "memory_operand" "")
19750            (const_int 0)]))
19751    (match_scratch:SI 3 "r")]
19752   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19753   [(set (match_dup 3) (match_dup 2))
19754    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19755   "")
19756
19757 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19758 ;; Don't split NOTs with a displacement operand, because resulting XOR
19759 ;; will not be pairable anyway.
19760 ;;
19761 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19762 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19763 ;; so this split helps here as well.
19764 ;;
19765 ;; Note: Can't do this as a regular split because we can't get proper
19766 ;; lifetime information then.
19767
19768 (define_peephole2
19769   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19770         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19771   "!optimize_size
19772    && peep2_regno_dead_p (0, FLAGS_REG)
19773    && ((TARGET_PENTIUM
19774         && (!MEM_P (operands[0])
19775             || !memory_displacement_operand (operands[0], SImode)))
19776        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19777   [(parallel [(set (match_dup 0)
19778                    (xor:SI (match_dup 1) (const_int -1)))
19779               (clobber (reg:CC FLAGS_REG))])]
19780   "")
19781
19782 (define_peephole2
19783   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19784         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19785   "!optimize_size
19786    && peep2_regno_dead_p (0, FLAGS_REG)
19787    && ((TARGET_PENTIUM
19788         && (!MEM_P (operands[0])
19789             || !memory_displacement_operand (operands[0], HImode)))
19790        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19791   [(parallel [(set (match_dup 0)
19792                    (xor:HI (match_dup 1) (const_int -1)))
19793               (clobber (reg:CC FLAGS_REG))])]
19794   "")
19795
19796 (define_peephole2
19797   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19798         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19799   "!optimize_size
19800    && peep2_regno_dead_p (0, FLAGS_REG)
19801    && ((TARGET_PENTIUM
19802         && (!MEM_P (operands[0])
19803             || !memory_displacement_operand (operands[0], QImode)))
19804        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19805   [(parallel [(set (match_dup 0)
19806                    (xor:QI (match_dup 1) (const_int -1)))
19807               (clobber (reg:CC FLAGS_REG))])]
19808   "")
19809
19810 ;; Non pairable "test imm, reg" instructions can be translated to
19811 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19812 ;; byte opcode instead of two, have a short form for byte operands),
19813 ;; so do it for other CPUs as well.  Given that the value was dead,
19814 ;; this should not create any new dependencies.  Pass on the sub-word
19815 ;; versions if we're concerned about partial register stalls.
19816
19817 (define_peephole2
19818   [(set (match_operand 0 "flags_reg_operand" "")
19819         (match_operator 1 "compare_operator"
19820           [(and:SI (match_operand:SI 2 "register_operand" "")
19821                    (match_operand:SI 3 "immediate_operand" ""))
19822            (const_int 0)]))]
19823   "ix86_match_ccmode (insn, CCNOmode)
19824    && (true_regnum (operands[2]) != 0
19825        || satisfies_constraint_K (operands[3]))
19826    && peep2_reg_dead_p (1, operands[2])"
19827   [(parallel
19828      [(set (match_dup 0)
19829            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19830                             (const_int 0)]))
19831       (set (match_dup 2)
19832            (and:SI (match_dup 2) (match_dup 3)))])]
19833   "")
19834
19835 ;; We don't need to handle HImode case, because it will be promoted to SImode
19836 ;; on ! TARGET_PARTIAL_REG_STALL
19837
19838 (define_peephole2
19839   [(set (match_operand 0 "flags_reg_operand" "")
19840         (match_operator 1 "compare_operator"
19841           [(and:QI (match_operand:QI 2 "register_operand" "")
19842                    (match_operand:QI 3 "immediate_operand" ""))
19843            (const_int 0)]))]
19844   "! TARGET_PARTIAL_REG_STALL
19845    && ix86_match_ccmode (insn, CCNOmode)
19846    && true_regnum (operands[2]) != 0
19847    && peep2_reg_dead_p (1, operands[2])"
19848   [(parallel
19849      [(set (match_dup 0)
19850            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19851                             (const_int 0)]))
19852       (set (match_dup 2)
19853            (and:QI (match_dup 2) (match_dup 3)))])]
19854   "")
19855
19856 (define_peephole2
19857   [(set (match_operand 0 "flags_reg_operand" "")
19858         (match_operator 1 "compare_operator"
19859           [(and:SI
19860              (zero_extract:SI
19861                (match_operand 2 "ext_register_operand" "")
19862                (const_int 8)
19863                (const_int 8))
19864              (match_operand 3 "const_int_operand" ""))
19865            (const_int 0)]))]
19866   "! TARGET_PARTIAL_REG_STALL
19867    && ix86_match_ccmode (insn, CCNOmode)
19868    && true_regnum (operands[2]) != 0
19869    && peep2_reg_dead_p (1, operands[2])"
19870   [(parallel [(set (match_dup 0)
19871                    (match_op_dup 1
19872                      [(and:SI
19873                         (zero_extract:SI
19874                           (match_dup 2)
19875                           (const_int 8)
19876                           (const_int 8))
19877                         (match_dup 3))
19878                       (const_int 0)]))
19879               (set (zero_extract:SI (match_dup 2)
19880                                     (const_int 8)
19881                                     (const_int 8))
19882                    (and:SI
19883                      (zero_extract:SI
19884                        (match_dup 2)
19885                        (const_int 8)
19886                        (const_int 8))
19887                      (match_dup 3)))])]
19888   "")
19889
19890 ;; Don't do logical operations with memory inputs.
19891 (define_peephole2
19892   [(match_scratch:SI 2 "r")
19893    (parallel [(set (match_operand:SI 0 "register_operand" "")
19894                    (match_operator:SI 3 "arith_or_logical_operator"
19895                      [(match_dup 0)
19896                       (match_operand:SI 1 "memory_operand" "")]))
19897               (clobber (reg:CC FLAGS_REG))])]
19898   "! optimize_size && ! TARGET_READ_MODIFY"
19899   [(set (match_dup 2) (match_dup 1))
19900    (parallel [(set (match_dup 0)
19901                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19902               (clobber (reg:CC FLAGS_REG))])]
19903   "")
19904
19905 (define_peephole2
19906   [(match_scratch:SI 2 "r")
19907    (parallel [(set (match_operand:SI 0 "register_operand" "")
19908                    (match_operator:SI 3 "arith_or_logical_operator"
19909                      [(match_operand:SI 1 "memory_operand" "")
19910                       (match_dup 0)]))
19911               (clobber (reg:CC FLAGS_REG))])]
19912   "! optimize_size && ! TARGET_READ_MODIFY"
19913   [(set (match_dup 2) (match_dup 1))
19914    (parallel [(set (match_dup 0)
19915                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19916               (clobber (reg:CC FLAGS_REG))])]
19917   "")
19918
19919 ; Don't do logical operations with memory outputs
19920 ;
19921 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19922 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19923 ; the same decoder scheduling characteristics as the original.
19924
19925 (define_peephole2
19926   [(match_scratch:SI 2 "r")
19927    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19928                    (match_operator:SI 3 "arith_or_logical_operator"
19929                      [(match_dup 0)
19930                       (match_operand:SI 1 "nonmemory_operand" "")]))
19931               (clobber (reg:CC FLAGS_REG))])]
19932   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19933   [(set (match_dup 2) (match_dup 0))
19934    (parallel [(set (match_dup 2)
19935                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19936               (clobber (reg:CC FLAGS_REG))])
19937    (set (match_dup 0) (match_dup 2))]
19938   "")
19939
19940 (define_peephole2
19941   [(match_scratch:SI 2 "r")
19942    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19943                    (match_operator:SI 3 "arith_or_logical_operator"
19944                      [(match_operand:SI 1 "nonmemory_operand" "")
19945                       (match_dup 0)]))
19946               (clobber (reg:CC FLAGS_REG))])]
19947   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19948   [(set (match_dup 2) (match_dup 0))
19949    (parallel [(set (match_dup 2)
19950                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19951               (clobber (reg:CC FLAGS_REG))])
19952    (set (match_dup 0) (match_dup 2))]
19953   "")
19954
19955 ;; Attempt to always use XOR for zeroing registers.
19956 (define_peephole2
19957   [(set (match_operand 0 "register_operand" "")
19958         (match_operand 1 "const0_operand" ""))]
19959   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19960    && (! TARGET_USE_MOV0 || optimize_size)
19961    && GENERAL_REG_P (operands[0])
19962    && peep2_regno_dead_p (0, FLAGS_REG)"
19963   [(parallel [(set (match_dup 0) (const_int 0))
19964               (clobber (reg:CC FLAGS_REG))])]
19965 {
19966   operands[0] = gen_lowpart (word_mode, operands[0]);
19967 })
19968
19969 (define_peephole2
19970   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19971         (const_int 0))]
19972   "(GET_MODE (operands[0]) == QImode
19973     || GET_MODE (operands[0]) == HImode)
19974    && (! TARGET_USE_MOV0 || optimize_size)
19975    && peep2_regno_dead_p (0, FLAGS_REG)"
19976   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19977               (clobber (reg:CC FLAGS_REG))])])
19978
19979 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19980 (define_peephole2
19981   [(set (match_operand 0 "register_operand" "")
19982         (const_int -1))]
19983   "(GET_MODE (operands[0]) == HImode
19984     || GET_MODE (operands[0]) == SImode
19985     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19986    && (optimize_size || TARGET_PENTIUM)
19987    && peep2_regno_dead_p (0, FLAGS_REG)"
19988   [(parallel [(set (match_dup 0) (const_int -1))
19989               (clobber (reg:CC FLAGS_REG))])]
19990   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19991                               operands[0]);")
19992
19993 ;; Attempt to convert simple leas to adds. These can be created by
19994 ;; move expanders.
19995 (define_peephole2
19996   [(set (match_operand:SI 0 "register_operand" "")
19997         (plus:SI (match_dup 0)
19998                  (match_operand:SI 1 "nonmemory_operand" "")))]
19999   "peep2_regno_dead_p (0, FLAGS_REG)"
20000   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20001               (clobber (reg:CC FLAGS_REG))])]
20002   "")
20003
20004 (define_peephole2
20005   [(set (match_operand:SI 0 "register_operand" "")
20006         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20007                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20008   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20009   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20010               (clobber (reg:CC FLAGS_REG))])]
20011   "operands[2] = gen_lowpart (SImode, operands[2]);")
20012
20013 (define_peephole2
20014   [(set (match_operand:DI 0 "register_operand" "")
20015         (plus:DI (match_dup 0)
20016                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20017   "peep2_regno_dead_p (0, FLAGS_REG)"
20018   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20019               (clobber (reg:CC FLAGS_REG))])]
20020   "")
20021
20022 (define_peephole2
20023   [(set (match_operand:SI 0 "register_operand" "")
20024         (mult:SI (match_dup 0)
20025                  (match_operand:SI 1 "const_int_operand" "")))]
20026   "exact_log2 (INTVAL (operands[1])) >= 0
20027    && peep2_regno_dead_p (0, FLAGS_REG)"
20028   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20029               (clobber (reg:CC FLAGS_REG))])]
20030   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20031
20032 (define_peephole2
20033   [(set (match_operand:DI 0 "register_operand" "")
20034         (mult:DI (match_dup 0)
20035                  (match_operand:DI 1 "const_int_operand" "")))]
20036   "exact_log2 (INTVAL (operands[1])) >= 0
20037    && peep2_regno_dead_p (0, FLAGS_REG)"
20038   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20039               (clobber (reg:CC FLAGS_REG))])]
20040   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20041
20042 (define_peephole2
20043   [(set (match_operand:SI 0 "register_operand" "")
20044         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20045                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20046   "exact_log2 (INTVAL (operands[2])) >= 0
20047    && REGNO (operands[0]) == REGNO (operands[1])
20048    && peep2_regno_dead_p (0, FLAGS_REG)"
20049   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20050               (clobber (reg:CC FLAGS_REG))])]
20051   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20052
20053 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20054 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20055 ;; many CPUs it is also faster, since special hardware to avoid esp
20056 ;; dependencies is present.
20057
20058 ;; While some of these conversions may be done using splitters, we use peepholes
20059 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20060
20061 ;; Convert prologue esp subtractions to push.
20062 ;; We need register to push.  In order to keep verify_flow_info happy we have
20063 ;; two choices
20064 ;; - use scratch and clobber it in order to avoid dependencies
20065 ;; - use already live register
20066 ;; We can't use the second way right now, since there is no reliable way how to
20067 ;; verify that given register is live.  First choice will also most likely in
20068 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20069 ;; call clobbered registers are dead.  We may want to use base pointer as an
20070 ;; alternative when no register is available later.
20071
20072 (define_peephole2
20073   [(match_scratch:SI 0 "r")
20074    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20075               (clobber (reg:CC FLAGS_REG))
20076               (clobber (mem:BLK (scratch)))])]
20077   "optimize_size || !TARGET_SUB_ESP_4"
20078   [(clobber (match_dup 0))
20079    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20080               (clobber (mem:BLK (scratch)))])])
20081
20082 (define_peephole2
20083   [(match_scratch:SI 0 "r")
20084    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20085               (clobber (reg:CC FLAGS_REG))
20086               (clobber (mem:BLK (scratch)))])]
20087   "optimize_size || !TARGET_SUB_ESP_8"
20088   [(clobber (match_dup 0))
20089    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20090    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20091               (clobber (mem:BLK (scratch)))])])
20092
20093 ;; Convert esp subtractions to push.
20094 (define_peephole2
20095   [(match_scratch:SI 0 "r")
20096    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20097               (clobber (reg:CC FLAGS_REG))])]
20098   "optimize_size || !TARGET_SUB_ESP_4"
20099   [(clobber (match_dup 0))
20100    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20101
20102 (define_peephole2
20103   [(match_scratch:SI 0 "r")
20104    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20105               (clobber (reg:CC FLAGS_REG))])]
20106   "optimize_size || !TARGET_SUB_ESP_8"
20107   [(clobber (match_dup 0))
20108    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20109    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20110
20111 ;; Convert epilogue deallocator to pop.
20112 (define_peephole2
20113   [(match_scratch:SI 0 "r")
20114    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20115               (clobber (reg:CC FLAGS_REG))
20116               (clobber (mem:BLK (scratch)))])]
20117   "optimize_size || !TARGET_ADD_ESP_4"
20118   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20119               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20120               (clobber (mem:BLK (scratch)))])]
20121   "")
20122
20123 ;; Two pops case is tricky, since pop causes dependency on destination register.
20124 ;; We use two registers if available.
20125 (define_peephole2
20126   [(match_scratch:SI 0 "r")
20127    (match_scratch:SI 1 "r")
20128    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20129               (clobber (reg:CC FLAGS_REG))
20130               (clobber (mem:BLK (scratch)))])]
20131   "optimize_size || !TARGET_ADD_ESP_8"
20132   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20133               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20134               (clobber (mem:BLK (scratch)))])
20135    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20136               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20137   "")
20138
20139 (define_peephole2
20140   [(match_scratch:SI 0 "r")
20141    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20142               (clobber (reg:CC FLAGS_REG))
20143               (clobber (mem:BLK (scratch)))])]
20144   "optimize_size"
20145   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20146               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20147               (clobber (mem:BLK (scratch)))])
20148    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20149               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20150   "")
20151
20152 ;; Convert esp additions to pop.
20153 (define_peephole2
20154   [(match_scratch:SI 0 "r")
20155    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20156               (clobber (reg:CC FLAGS_REG))])]
20157   ""
20158   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20159               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20160   "")
20161
20162 ;; Two pops case is tricky, since pop causes dependency on destination register.
20163 ;; We use two registers if available.
20164 (define_peephole2
20165   [(match_scratch:SI 0 "r")
20166    (match_scratch:SI 1 "r")
20167    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20168               (clobber (reg:CC FLAGS_REG))])]
20169   ""
20170   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20171               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20172    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20173               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20174   "")
20175
20176 (define_peephole2
20177   [(match_scratch:SI 0 "r")
20178    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20179               (clobber (reg:CC FLAGS_REG))])]
20180   "optimize_size"
20181   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20182               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20183    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20184               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20185   "")
20186 \f
20187 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20188 ;; required and register dies.  Similarly for 128 to plus -128.
20189 (define_peephole2
20190   [(set (match_operand 0 "flags_reg_operand" "")
20191         (match_operator 1 "compare_operator"
20192           [(match_operand 2 "register_operand" "")
20193            (match_operand 3 "const_int_operand" "")]))]
20194   "(INTVAL (operands[3]) == -1
20195     || INTVAL (operands[3]) == 1
20196     || INTVAL (operands[3]) == 128)
20197    && ix86_match_ccmode (insn, CCGCmode)
20198    && peep2_reg_dead_p (1, operands[2])"
20199   [(parallel [(set (match_dup 0)
20200                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20201               (clobber (match_dup 2))])]
20202   "")
20203 \f
20204 (define_peephole2
20205   [(match_scratch:DI 0 "r")
20206    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20207               (clobber (reg:CC FLAGS_REG))
20208               (clobber (mem:BLK (scratch)))])]
20209   "optimize_size || !TARGET_SUB_ESP_4"
20210   [(clobber (match_dup 0))
20211    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20212               (clobber (mem:BLK (scratch)))])])
20213
20214 (define_peephole2
20215   [(match_scratch:DI 0 "r")
20216    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20217               (clobber (reg:CC FLAGS_REG))
20218               (clobber (mem:BLK (scratch)))])]
20219   "optimize_size || !TARGET_SUB_ESP_8"
20220   [(clobber (match_dup 0))
20221    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20222    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20223               (clobber (mem:BLK (scratch)))])])
20224
20225 ;; Convert esp subtractions to push.
20226 (define_peephole2
20227   [(match_scratch:DI 0 "r")
20228    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20229               (clobber (reg:CC FLAGS_REG))])]
20230   "optimize_size || !TARGET_SUB_ESP_4"
20231   [(clobber (match_dup 0))
20232    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20233
20234 (define_peephole2
20235   [(match_scratch:DI 0 "r")
20236    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20237               (clobber (reg:CC FLAGS_REG))])]
20238   "optimize_size || !TARGET_SUB_ESP_8"
20239   [(clobber (match_dup 0))
20240    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20241    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20242
20243 ;; Convert epilogue deallocator to pop.
20244 (define_peephole2
20245   [(match_scratch:DI 0 "r")
20246    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20247               (clobber (reg:CC FLAGS_REG))
20248               (clobber (mem:BLK (scratch)))])]
20249   "optimize_size || !TARGET_ADD_ESP_4"
20250   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20251               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20252               (clobber (mem:BLK (scratch)))])]
20253   "")
20254
20255 ;; Two pops case is tricky, since pop causes dependency on destination register.
20256 ;; We use two registers if available.
20257 (define_peephole2
20258   [(match_scratch:DI 0 "r")
20259    (match_scratch:DI 1 "r")
20260    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20261               (clobber (reg:CC FLAGS_REG))
20262               (clobber (mem:BLK (scratch)))])]
20263   "optimize_size || !TARGET_ADD_ESP_8"
20264   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20265               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20266               (clobber (mem:BLK (scratch)))])
20267    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20268               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20269   "")
20270
20271 (define_peephole2
20272   [(match_scratch:DI 0 "r")
20273    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20274               (clobber (reg:CC FLAGS_REG))
20275               (clobber (mem:BLK (scratch)))])]
20276   "optimize_size"
20277   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20278               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20279               (clobber (mem:BLK (scratch)))])
20280    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20281               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20282   "")
20283
20284 ;; Convert esp additions to pop.
20285 (define_peephole2
20286   [(match_scratch:DI 0 "r")
20287    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20288               (clobber (reg:CC FLAGS_REG))])]
20289   ""
20290   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20291               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20292   "")
20293
20294 ;; Two pops case is tricky, since pop causes dependency on destination register.
20295 ;; We use two registers if available.
20296 (define_peephole2
20297   [(match_scratch:DI 0 "r")
20298    (match_scratch:DI 1 "r")
20299    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20300               (clobber (reg:CC FLAGS_REG))])]
20301   ""
20302   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20303               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20304    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20305               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20306   "")
20307
20308 (define_peephole2
20309   [(match_scratch:DI 0 "r")
20310    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20311               (clobber (reg:CC FLAGS_REG))])]
20312   "optimize_size"
20313   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20314               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20315    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20316               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20317   "")
20318 \f
20319 ;; Convert imul by three, five and nine into lea
20320 (define_peephole2
20321   [(parallel
20322     [(set (match_operand:SI 0 "register_operand" "")
20323           (mult:SI (match_operand:SI 1 "register_operand" "")
20324                    (match_operand:SI 2 "const_int_operand" "")))
20325      (clobber (reg:CC FLAGS_REG))])]
20326   "INTVAL (operands[2]) == 3
20327    || INTVAL (operands[2]) == 5
20328    || INTVAL (operands[2]) == 9"
20329   [(set (match_dup 0)
20330         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20331                  (match_dup 1)))]
20332   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20333
20334 (define_peephole2
20335   [(parallel
20336     [(set (match_operand:SI 0 "register_operand" "")
20337           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20338                    (match_operand:SI 2 "const_int_operand" "")))
20339      (clobber (reg:CC FLAGS_REG))])]
20340   "!optimize_size
20341    && (INTVAL (operands[2]) == 3
20342        || INTVAL (operands[2]) == 5
20343        || INTVAL (operands[2]) == 9)"
20344   [(set (match_dup 0) (match_dup 1))
20345    (set (match_dup 0)
20346         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20347                  (match_dup 0)))]
20348   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20349
20350 (define_peephole2
20351   [(parallel
20352     [(set (match_operand:DI 0 "register_operand" "")
20353           (mult:DI (match_operand:DI 1 "register_operand" "")
20354                    (match_operand:DI 2 "const_int_operand" "")))
20355      (clobber (reg:CC FLAGS_REG))])]
20356   "TARGET_64BIT
20357    && (INTVAL (operands[2]) == 3
20358        || INTVAL (operands[2]) == 5
20359        || INTVAL (operands[2]) == 9)"
20360   [(set (match_dup 0)
20361         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20362                  (match_dup 1)))]
20363   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20364
20365 (define_peephole2
20366   [(parallel
20367     [(set (match_operand:DI 0 "register_operand" "")
20368           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20369                    (match_operand:DI 2 "const_int_operand" "")))
20370      (clobber (reg:CC FLAGS_REG))])]
20371   "TARGET_64BIT
20372    && !optimize_size
20373    && (INTVAL (operands[2]) == 3
20374        || INTVAL (operands[2]) == 5
20375        || INTVAL (operands[2]) == 9)"
20376   [(set (match_dup 0) (match_dup 1))
20377    (set (match_dup 0)
20378         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20379                  (match_dup 0)))]
20380   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20381
20382 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20383 ;; imul $32bit_imm, reg, reg is direct decoded.
20384 (define_peephole2
20385   [(match_scratch:DI 3 "r")
20386    (parallel [(set (match_operand:DI 0 "register_operand" "")
20387                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20388                             (match_operand:DI 2 "immediate_operand" "")))
20389               (clobber (reg:CC FLAGS_REG))])]
20390   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20391    && !satisfies_constraint_K (operands[2])"
20392   [(set (match_dup 3) (match_dup 1))
20393    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20394               (clobber (reg:CC FLAGS_REG))])]
20395 "")
20396
20397 (define_peephole2
20398   [(match_scratch:SI 3 "r")
20399    (parallel [(set (match_operand:SI 0 "register_operand" "")
20400                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20401                             (match_operand:SI 2 "immediate_operand" "")))
20402               (clobber (reg:CC FLAGS_REG))])]
20403   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20404    && !satisfies_constraint_K (operands[2])"
20405   [(set (match_dup 3) (match_dup 1))
20406    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20407               (clobber (reg:CC FLAGS_REG))])]
20408 "")
20409
20410 (define_peephole2
20411   [(match_scratch:SI 3 "r")
20412    (parallel [(set (match_operand:DI 0 "register_operand" "")
20413                    (zero_extend:DI
20414                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20415                               (match_operand:SI 2 "immediate_operand" ""))))
20416               (clobber (reg:CC FLAGS_REG))])]
20417   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20418    && !satisfies_constraint_K (operands[2])"
20419   [(set (match_dup 3) (match_dup 1))
20420    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20421               (clobber (reg:CC FLAGS_REG))])]
20422 "")
20423
20424 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20425 ;; Convert it into imul reg, reg
20426 ;; It would be better to force assembler to encode instruction using long
20427 ;; immediate, but there is apparently no way to do so.
20428 (define_peephole2
20429   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20430                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20431                             (match_operand:DI 2 "const_int_operand" "")))
20432               (clobber (reg:CC FLAGS_REG))])
20433    (match_scratch:DI 3 "r")]
20434   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20435    && satisfies_constraint_K (operands[2])"
20436   [(set (match_dup 3) (match_dup 2))
20437    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20438               (clobber (reg:CC FLAGS_REG))])]
20439 {
20440   if (!rtx_equal_p (operands[0], operands[1]))
20441     emit_move_insn (operands[0], operands[1]);
20442 })
20443
20444 (define_peephole2
20445   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20446                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20447                             (match_operand:SI 2 "const_int_operand" "")))
20448               (clobber (reg:CC FLAGS_REG))])
20449    (match_scratch:SI 3 "r")]
20450   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20451    && satisfies_constraint_K (operands[2])"
20452   [(set (match_dup 3) (match_dup 2))
20453    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20454               (clobber (reg:CC FLAGS_REG))])]
20455 {
20456   if (!rtx_equal_p (operands[0], operands[1]))
20457     emit_move_insn (operands[0], operands[1]);
20458 })
20459
20460 (define_peephole2
20461   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20462                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20463                             (match_operand:HI 2 "immediate_operand" "")))
20464               (clobber (reg:CC FLAGS_REG))])
20465    (match_scratch:HI 3 "r")]
20466   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20467   [(set (match_dup 3) (match_dup 2))
20468    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20469               (clobber (reg:CC FLAGS_REG))])]
20470 {
20471   if (!rtx_equal_p (operands[0], operands[1]))
20472     emit_move_insn (operands[0], operands[1]);
20473 })
20474
20475 ;; After splitting up read-modify operations, array accesses with memory
20476 ;; operands might end up in form:
20477 ;;  sall    $2, %eax
20478 ;;  movl    4(%esp), %edx
20479 ;;  addl    %edx, %eax
20480 ;; instead of pre-splitting:
20481 ;;  sall    $2, %eax
20482 ;;  addl    4(%esp), %eax
20483 ;; Turn it into:
20484 ;;  movl    4(%esp), %edx
20485 ;;  leal    (%edx,%eax,4), %eax
20486
20487 (define_peephole2
20488   [(parallel [(set (match_operand 0 "register_operand" "")
20489                    (ashift (match_operand 1 "register_operand" "")
20490                            (match_operand 2 "const_int_operand" "")))
20491                (clobber (reg:CC FLAGS_REG))])
20492    (set (match_operand 3 "register_operand")
20493         (match_operand 4 "x86_64_general_operand" ""))
20494    (parallel [(set (match_operand 5 "register_operand" "")
20495                    (plus (match_operand 6 "register_operand" "")
20496                          (match_operand 7 "register_operand" "")))
20497                    (clobber (reg:CC FLAGS_REG))])]
20498   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20499    /* Validate MODE for lea.  */
20500    && ((!TARGET_PARTIAL_REG_STALL
20501         && (GET_MODE (operands[0]) == QImode
20502             || GET_MODE (operands[0]) == HImode))
20503        || GET_MODE (operands[0]) == SImode
20504        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20505    /* We reorder load and the shift.  */
20506    && !rtx_equal_p (operands[1], operands[3])
20507    && !reg_overlap_mentioned_p (operands[0], operands[4])
20508    /* Last PLUS must consist of operand 0 and 3.  */
20509    && !rtx_equal_p (operands[0], operands[3])
20510    && (rtx_equal_p (operands[3], operands[6])
20511        || rtx_equal_p (operands[3], operands[7]))
20512    && (rtx_equal_p (operands[0], operands[6])
20513        || rtx_equal_p (operands[0], operands[7]))
20514    /* The intermediate operand 0 must die or be same as output.  */
20515    && (rtx_equal_p (operands[0], operands[5])
20516        || peep2_reg_dead_p (3, operands[0]))"
20517   [(set (match_dup 3) (match_dup 4))
20518    (set (match_dup 0) (match_dup 1))]
20519 {
20520   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20521   int scale = 1 << INTVAL (operands[2]);
20522   rtx index = gen_lowpart (Pmode, operands[1]);
20523   rtx base = gen_lowpart (Pmode, operands[3]);
20524   rtx dest = gen_lowpart (mode, operands[5]);
20525
20526   operands[1] = gen_rtx_PLUS (Pmode, base,
20527                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20528   if (mode != Pmode)
20529     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20530   operands[0] = dest;
20531 })
20532 \f
20533 ;; Call-value patterns last so that the wildcard operand does not
20534 ;; disrupt insn-recog's switch tables.
20535
20536 (define_insn "*call_value_pop_0"
20537   [(set (match_operand 0 "" "")
20538         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20539               (match_operand:SI 2 "" "")))
20540    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20541                             (match_operand:SI 3 "immediate_operand" "")))]
20542   "!TARGET_64BIT"
20543 {
20544   if (SIBLING_CALL_P (insn))
20545     return "jmp\t%P1";
20546   else
20547     return "call\t%P1";
20548 }
20549   [(set_attr "type" "callv")])
20550
20551 (define_insn "*call_value_pop_1"
20552   [(set (match_operand 0 "" "")
20553         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20554               (match_operand:SI 2 "" "")))
20555    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20556                             (match_operand:SI 3 "immediate_operand" "i")))]
20557   "!TARGET_64BIT"
20558 {
20559   if (constant_call_address_operand (operands[1], Pmode))
20560     {
20561       if (SIBLING_CALL_P (insn))
20562         return "jmp\t%P1";
20563       else
20564         return "call\t%P1";
20565     }
20566   if (SIBLING_CALL_P (insn))
20567     return "jmp\t%A1";
20568   else
20569     return "call\t%A1";
20570 }
20571   [(set_attr "type" "callv")])
20572
20573 (define_insn "*call_value_0"
20574   [(set (match_operand 0 "" "")
20575         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20576               (match_operand:SI 2 "" "")))]
20577   "!TARGET_64BIT"
20578 {
20579   if (SIBLING_CALL_P (insn))
20580     return "jmp\t%P1";
20581   else
20582     return "call\t%P1";
20583 }
20584   [(set_attr "type" "callv")])
20585
20586 (define_insn "*call_value_0_rex64"
20587   [(set (match_operand 0 "" "")
20588         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20589               (match_operand:DI 2 "const_int_operand" "")))]
20590   "TARGET_64BIT"
20591 {
20592   if (SIBLING_CALL_P (insn))
20593     return "jmp\t%P1";
20594   else
20595     return "call\t%P1";
20596 }
20597   [(set_attr "type" "callv")])
20598
20599 (define_insn "*call_value_1"
20600   [(set (match_operand 0 "" "")
20601         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20602               (match_operand:SI 2 "" "")))]
20603   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20604 {
20605   if (constant_call_address_operand (operands[1], Pmode))
20606     return "call\t%P1";
20607   return "call\t%A1";
20608 }
20609   [(set_attr "type" "callv")])
20610
20611 (define_insn "*sibcall_value_1"
20612   [(set (match_operand 0 "" "")
20613         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20614               (match_operand:SI 2 "" "")))]
20615   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20616 {
20617   if (constant_call_address_operand (operands[1], Pmode))
20618     return "jmp\t%P1";
20619   return "jmp\t%A1";
20620 }
20621   [(set_attr "type" "callv")])
20622
20623 (define_insn "*call_value_1_rex64"
20624   [(set (match_operand 0 "" "")
20625         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20626               (match_operand:DI 2 "" "")))]
20627   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20628 {
20629   if (constant_call_address_operand (operands[1], Pmode))
20630     return "call\t%P1";
20631   return "call\t%A1";
20632 }
20633   [(set_attr "type" "callv")])
20634
20635 (define_insn "*sibcall_value_1_rex64"
20636   [(set (match_operand 0 "" "")
20637         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20638               (match_operand:DI 2 "" "")))]
20639   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20640   "jmp\t%P1"
20641   [(set_attr "type" "callv")])
20642
20643 (define_insn "*sibcall_value_1_rex64_v"
20644   [(set (match_operand 0 "" "")
20645         (call (mem:QI (reg:DI R11_REG))
20646               (match_operand:DI 1 "" "")))]
20647   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20648   "jmp\t*%%r11"
20649   [(set_attr "type" "callv")])
20650 \f
20651 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20652 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20653 ;; caught for use by garbage collectors and the like.  Using an insn that
20654 ;; maps to SIGILL makes it more likely the program will rightfully die.
20655 ;; Keeping with tradition, "6" is in honor of #UD.
20656 (define_insn "trap"
20657   [(trap_if (const_int 1) (const_int 6))]
20658   ""
20659   { return ASM_SHORT "0x0b0f"; }
20660   [(set_attr "length" "2")])
20661
20662 (define_expand "sse_prologue_save"
20663   [(parallel [(set (match_operand:BLK 0 "" "")
20664                    (unspec:BLK [(reg:DI 21)
20665                                 (reg:DI 22)
20666                                 (reg:DI 23)
20667                                 (reg:DI 24)
20668                                 (reg:DI 25)
20669                                 (reg:DI 26)
20670                                 (reg:DI 27)
20671                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20672               (use (match_operand:DI 1 "register_operand" ""))
20673               (use (match_operand:DI 2 "immediate_operand" ""))
20674               (use (label_ref:DI (match_operand 3 "" "")))])]
20675   "TARGET_64BIT"
20676   "")
20677
20678 (define_insn "*sse_prologue_save_insn"
20679   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20680                           (match_operand:DI 4 "const_int_operand" "n")))
20681         (unspec:BLK [(reg:DI 21)
20682                      (reg:DI 22)
20683                      (reg:DI 23)
20684                      (reg:DI 24)
20685                      (reg:DI 25)
20686                      (reg:DI 26)
20687                      (reg:DI 27)
20688                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20689    (use (match_operand:DI 1 "register_operand" "r"))
20690    (use (match_operand:DI 2 "const_int_operand" "i"))
20691    (use (label_ref:DI (match_operand 3 "" "X")))]
20692   "TARGET_64BIT
20693    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20694    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20695   "*
20696 {
20697   int i;
20698   operands[0] = gen_rtx_MEM (Pmode,
20699                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20700   output_asm_insn (\"jmp\\t%A1\", operands);
20701   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20702     {
20703       operands[4] = adjust_address (operands[0], DImode, i*16);
20704       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20705       PUT_MODE (operands[4], TImode);
20706       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20707         output_asm_insn (\"rex\", operands);
20708       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20709     }
20710   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20711                              CODE_LABEL_NUMBER (operands[3]));
20712   return \"\";
20713 }
20714   "
20715   [(set_attr "type" "other")
20716    (set_attr "length_immediate" "0")
20717    (set_attr "length_address" "0")
20718    (set_attr "length" "135")
20719    (set_attr "memory" "store")
20720    (set_attr "modrm" "0")
20721    (set_attr "mode" "DI")])
20722
20723 (define_expand "prefetch"
20724   [(prefetch (match_operand 0 "address_operand" "")
20725              (match_operand:SI 1 "const_int_operand" "")
20726              (match_operand:SI 2 "const_int_operand" ""))]
20727   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20728 {
20729   int rw = INTVAL (operands[1]);
20730   int locality = INTVAL (operands[2]);
20731
20732   gcc_assert (rw == 0 || rw == 1);
20733   gcc_assert (locality >= 0 && locality <= 3);
20734   gcc_assert (GET_MODE (operands[0]) == Pmode
20735               || GET_MODE (operands[0]) == VOIDmode);
20736
20737   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20738      supported by SSE counterpart or the SSE prefetch is not available
20739      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20740      of locality.  */
20741   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20742     operands[2] = GEN_INT (3);
20743   else
20744     operands[1] = const0_rtx;
20745 })
20746
20747 (define_insn "*prefetch_sse"
20748   [(prefetch (match_operand:SI 0 "address_operand" "p")
20749              (const_int 0)
20750              (match_operand:SI 1 "const_int_operand" ""))]
20751   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20752 {
20753   static const char * const patterns[4] = {
20754    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20755   };
20756
20757   int locality = INTVAL (operands[1]);
20758   gcc_assert (locality >= 0 && locality <= 3);
20759
20760   return patterns[locality];
20761 }
20762   [(set_attr "type" "sse")
20763    (set_attr "memory" "none")])
20764
20765 (define_insn "*prefetch_sse_rex"
20766   [(prefetch (match_operand:DI 0 "address_operand" "p")
20767              (const_int 0)
20768              (match_operand:SI 1 "const_int_operand" ""))]
20769   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20770 {
20771   static const char * const patterns[4] = {
20772    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20773   };
20774
20775   int locality = INTVAL (operands[1]);
20776   gcc_assert (locality >= 0 && locality <= 3);
20777
20778   return patterns[locality];
20779 }
20780   [(set_attr "type" "sse")
20781    (set_attr "memory" "none")])
20782
20783 (define_insn "*prefetch_3dnow"
20784   [(prefetch (match_operand:SI 0 "address_operand" "p")
20785              (match_operand:SI 1 "const_int_operand" "n")
20786              (const_int 3))]
20787   "TARGET_3DNOW && !TARGET_64BIT"
20788 {
20789   if (INTVAL (operands[1]) == 0)
20790     return "prefetch\t%a0";
20791   else
20792     return "prefetchw\t%a0";
20793 }
20794   [(set_attr "type" "mmx")
20795    (set_attr "memory" "none")])
20796
20797 (define_insn "*prefetch_3dnow_rex"
20798   [(prefetch (match_operand:DI 0 "address_operand" "p")
20799              (match_operand:SI 1 "const_int_operand" "n")
20800              (const_int 3))]
20801   "TARGET_3DNOW && TARGET_64BIT"
20802 {
20803   if (INTVAL (operands[1]) == 0)
20804     return "prefetch\t%a0";
20805   else
20806     return "prefetchw\t%a0";
20807 }
20808   [(set_attr "type" "mmx")
20809    (set_attr "memory" "none")])
20810
20811 (define_expand "stack_protect_set"
20812   [(match_operand 0 "memory_operand" "")
20813    (match_operand 1 "memory_operand" "")]
20814   ""
20815 {
20816 #ifdef TARGET_THREAD_SSP_OFFSET
20817   if (TARGET_64BIT)
20818     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20819                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20820   else
20821     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20822                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20823 #else
20824   if (TARGET_64BIT)
20825     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20826   else
20827     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20828 #endif
20829   DONE;
20830 })
20831
20832 (define_insn "stack_protect_set_si"
20833   [(set (match_operand:SI 0 "memory_operand" "=m")
20834         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20835    (set (match_scratch:SI 2 "=&r") (const_int 0))
20836    (clobber (reg:CC FLAGS_REG))]
20837   ""
20838   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20839   [(set_attr "type" "multi")])
20840
20841 (define_insn "stack_protect_set_di"
20842   [(set (match_operand:DI 0 "memory_operand" "=m")
20843         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20844    (set (match_scratch:DI 2 "=&r") (const_int 0))
20845    (clobber (reg:CC FLAGS_REG))]
20846   "TARGET_64BIT"
20847   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20848   [(set_attr "type" "multi")])
20849
20850 (define_insn "stack_tls_protect_set_si"
20851   [(set (match_operand:SI 0 "memory_operand" "=m")
20852         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20853    (set (match_scratch:SI 2 "=&r") (const_int 0))
20854    (clobber (reg:CC FLAGS_REG))]
20855   ""
20856   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20857   [(set_attr "type" "multi")])
20858
20859 (define_insn "stack_tls_protect_set_di"
20860   [(set (match_operand:DI 0 "memory_operand" "=m")
20861         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20862    (set (match_scratch:DI 2 "=&r") (const_int 0))
20863    (clobber (reg:CC FLAGS_REG))]
20864   "TARGET_64BIT"
20865   {
20866      /* The kernel uses a different segment register for performance reasons; a
20867         system call would not have to trash the userspace segment register,
20868         which would be expensive */
20869      if (ix86_cmodel != CM_KERNEL)
20870         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20871      else
20872         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20873   }
20874   [(set_attr "type" "multi")])
20875
20876 (define_expand "stack_protect_test"
20877   [(match_operand 0 "memory_operand" "")
20878    (match_operand 1 "memory_operand" "")
20879    (match_operand 2 "" "")]
20880   ""
20881 {
20882   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20883   ix86_compare_op0 = operands[0];
20884   ix86_compare_op1 = operands[1];
20885   ix86_compare_emitted = flags;
20886
20887 #ifdef TARGET_THREAD_SSP_OFFSET
20888   if (TARGET_64BIT)
20889     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20890                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20891   else
20892     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20893                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20894 #else
20895   if (TARGET_64BIT)
20896     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20897   else
20898     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20899 #endif
20900   emit_jump_insn (gen_beq (operands[2]));
20901   DONE;
20902 })
20903
20904 (define_insn "stack_protect_test_si"
20905   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20906         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20907                      (match_operand:SI 2 "memory_operand" "m")]
20908                     UNSPEC_SP_TEST))
20909    (clobber (match_scratch:SI 3 "=&r"))]
20910   ""
20911   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20912   [(set_attr "type" "multi")])
20913
20914 (define_insn "stack_protect_test_di"
20915   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20916         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20917                      (match_operand:DI 2 "memory_operand" "m")]
20918                     UNSPEC_SP_TEST))
20919    (clobber (match_scratch:DI 3 "=&r"))]
20920   "TARGET_64BIT"
20921   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20922   [(set_attr "type" "multi")])
20923
20924 (define_insn "stack_tls_protect_test_si"
20925   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20926         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20927                      (match_operand:SI 2 "const_int_operand" "i")]
20928                     UNSPEC_SP_TLS_TEST))
20929    (clobber (match_scratch:SI 3 "=r"))]
20930   ""
20931   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20932   [(set_attr "type" "multi")])
20933
20934 (define_insn "stack_tls_protect_test_di"
20935   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20936         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20937                      (match_operand:DI 2 "const_int_operand" "i")]
20938                     UNSPEC_SP_TLS_TEST))
20939    (clobber (match_scratch:DI 3 "=r"))]
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{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20947      else
20948         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20949   }
20950   [(set_attr "type" "multi")])
20951
20952 (include "mmx.md")
20953 (include "sse.md")
20954 (include "sync.md")