]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - contrib/gcc/config/i386/i386.md
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.git] / contrib / 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
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
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          30)
91    (UNSPEC_MASKMOV              31)
92    (UNSPEC_MOVMSK               32)
93    (UNSPEC_MOVNT                33)
94    (UNSPEC_MOVU                 34)
95    (UNSPEC_RCP                  35)
96    (UNSPEC_RSQRT                36)
97    (UNSPEC_SFENCE               37)
98    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
99    (UNSPEC_PFRCP                39)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDQQU                47)
108
109    ; Generic math support
110    (UNSPEC_COPYSIGN             50)
111    (UNSPEC_IEEE_MIN             51)     ; not commutative
112    (UNSPEC_IEEE_MAX             52)     ; not commutative
113
114    ; x87 Floating point
115    (UNSPEC_SIN                  60)
116    (UNSPEC_COS                  61)
117    (UNSPEC_FPATAN               62)
118    (UNSPEC_FYL2X                63)
119    (UNSPEC_FYL2XP1              64)
120    (UNSPEC_FRNDINT              65)
121    (UNSPEC_FIST                 66)
122    (UNSPEC_F2XM1                67)
123
124    ; x87 Rounding
125    (UNSPEC_FRNDINT_FLOOR        70)
126    (UNSPEC_FRNDINT_CEIL         71)
127    (UNSPEC_FRNDINT_TRUNC        72)
128    (UNSPEC_FRNDINT_MASK_PM      73)
129    (UNSPEC_FIST_FLOOR           74)
130    (UNSPEC_FIST_CEIL            75)
131
132    ; x87 Double output FP
133    (UNSPEC_SINCOS_COS           80)
134    (UNSPEC_SINCOS_SIN           81)
135    (UNSPEC_TAN_ONE              82)
136    (UNSPEC_TAN_TAN              83)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
145
146    ; SSP patterns
147    (UNSPEC_SP_SET               100)
148    (UNSPEC_SP_TEST              101)
149    (UNSPEC_SP_TLS_SET           102)
150    (UNSPEC_SP_TLS_TEST          103)
151
152    ; SSSE3
153    (UNSPEC_PSHUFB               120)
154    (UNSPEC_PSIGN                121)
155    (UNSPEC_PALIGNR              122)
156
157    ; For SSE4A support
158    (UNSPEC_EXTRQI               130)
159    (UNSPEC_EXTRQ                131)   
160    (UNSPEC_INSERTQI             132)
161    (UNSPEC_INSERTQ              133)
162   ])
163
164 (define_constants
165   [(UNSPECV_BLOCKAGE            0)
166    (UNSPECV_STACK_PROBE         1)
167    (UNSPECV_EMMS                2)
168    (UNSPECV_LDMXCSR             3)
169    (UNSPECV_STMXCSR             4)
170    (UNSPECV_FEMMS               5)
171    (UNSPECV_CLFLUSH             6)
172    (UNSPECV_ALIGN               7)
173    (UNSPECV_MONITOR             8)
174    (UNSPECV_MWAIT               9)
175    (UNSPECV_CMPXCHG_1           10)
176    (UNSPECV_CMPXCHG_2           11)
177    (UNSPECV_XCHG                12)
178    (UNSPECV_LOCK                13)
179   ])
180
181 ;; Registers by name.
182 (define_constants
183   [(BP_REG                       6)
184    (SP_REG                       7)
185    (FLAGS_REG                   17)
186    (FPSR_REG                    18)
187    (DIRFLAG_REG                 19)
188   ])
189
190 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
191 ;; from i386.c.
192
193 ;; In C guard expressions, put expressions which may be compile-time
194 ;; constants first.  This allows for better optimization.  For
195 ;; example, write "TARGET_64BIT && reload_completed", not
196 ;; "reload_completed && TARGET_64BIT".
197
198 \f
199 ;; Processor type.  This attribute must exactly match the processor_type
200 ;; enumeration in i386.h.
201 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
202                     nocona,core2,generic32,generic64,amdfam10"
203   (const (symbol_ref "ix86_tune")))
204
205 ;; A basic instruction type.  Refinements due to arguments to be
206 ;; provided in other attributes.
207 (define_attr "type"
208   "other,multi,
209    alu,alu1,negnot,imov,imovx,lea,
210    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
211    icmp,test,ibr,setcc,icmov,
212    push,pop,call,callv,leave,
213    str,bitmanip,cld,
214    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
215    sselog,sselog1,sseiadd,sseishft,sseimul,
216    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
217    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
218   (const_string "other"))
219
220 ;; Main data type used by the insn
221 (define_attr "mode"
222   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
223   (const_string "unknown"))
224
225 ;; The CPU unit operations uses.
226 (define_attr "unit" "integer,i387,sse,mmx,unknown"
227   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
228            (const_string "i387")
229          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
230                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
231            (const_string "sse")
232          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
233            (const_string "mmx")
234          (eq_attr "type" "other")
235            (const_string "unknown")]
236          (const_string "integer")))
237
238 ;; The (bounding maximum) length of an instruction immediate.
239 (define_attr "length_immediate" ""
240   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave,
241                           bitmanip")
242            (const_int 0)
243          (eq_attr "unit" "i387,sse,mmx")
244            (const_int 0)
245          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
246                           imul,icmp,push,pop")
247            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
248          (eq_attr "type" "imov,test")
249            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
250          (eq_attr "type" "call")
251            (if_then_else (match_operand 0 "constant_call_address_operand" "")
252              (const_int 4)
253              (const_int 0))
254          (eq_attr "type" "callv")
255            (if_then_else (match_operand 1 "constant_call_address_operand" "")
256              (const_int 4)
257              (const_int 0))
258          ;; We don't know the size before shorten_branches.  Expect
259          ;; the instruction to fit for better scheduling.
260          (eq_attr "type" "ibr")
261            (const_int 1)
262          ]
263          (symbol_ref "/* Update immediate_length and other attributes! */
264                       gcc_unreachable (),1")))
265
266 ;; The (bounding maximum) length of an instruction address.
267 (define_attr "length_address" ""
268   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
269            (const_int 0)
270          (and (eq_attr "type" "call")
271               (match_operand 0 "constant_call_address_operand" ""))
272              (const_int 0)
273          (and (eq_attr "type" "callv")
274               (match_operand 1 "constant_call_address_operand" ""))
275              (const_int 0)
276          ]
277          (symbol_ref "ix86_attr_length_address_default (insn)")))
278
279 ;; Set when length prefix is used.
280 (define_attr "prefix_data16" ""
281   (if_then_else (ior (eq_attr "mode" "HI")
282                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
283     (const_int 1)
284     (const_int 0)))
285
286 ;; Set when string REP prefix is used.
287 (define_attr "prefix_rep" ""
288   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
289     (const_int 1)
290     (const_int 0)))
291
292 ;; Set when 0f opcode prefix is used.
293 (define_attr "prefix_0f" ""
294   (if_then_else
295     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
296          (eq_attr "unit" "sse,mmx"))
297     (const_int 1)
298     (const_int 0)))
299
300 ;; Set when REX opcode prefix is used.
301 (define_attr "prefix_rex" ""
302   (cond [(and (eq_attr "mode" "DI")
303               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
304            (const_int 1)
305          (and (eq_attr "mode" "QI")
306               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
307                   (const_int 0)))
308            (const_int 1)
309          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
310              (const_int 0))
311            (const_int 1)
312         ]
313         (const_int 0)))
314
315 ;; Set when modrm byte is used.
316 (define_attr "modrm" ""
317   (cond [(eq_attr "type" "str,cld,leave")
318            (const_int 0)
319          (eq_attr "unit" "i387")
320            (const_int 0)
321          (and (eq_attr "type" "incdec")
322               (ior (match_operand:SI 1 "register_operand" "")
323                    (match_operand:HI 1 "register_operand" "")))
324            (const_int 0)
325          (and (eq_attr "type" "push")
326               (not (match_operand 1 "memory_operand" "")))
327            (const_int 0)
328          (and (eq_attr "type" "pop")
329               (not (match_operand 0 "memory_operand" "")))
330            (const_int 0)
331          (and (eq_attr "type" "imov")
332               (ior (and (match_operand 0 "register_operand" "")
333                         (match_operand 1 "immediate_operand" ""))
334                    (ior (and (match_operand 0 "ax_reg_operand" "")
335                              (match_operand 1 "memory_displacement_only_operand" ""))
336                         (and (match_operand 0 "memory_displacement_only_operand" "")
337                              (match_operand 1 "ax_reg_operand" "")))))
338            (const_int 0)
339          (and (eq_attr "type" "call")
340               (match_operand 0 "constant_call_address_operand" ""))
341              (const_int 0)
342          (and (eq_attr "type" "callv")
343               (match_operand 1 "constant_call_address_operand" ""))
344              (const_int 0)
345          ]
346          (const_int 1)))
347
348 ;; The (bounding maximum) length of an instruction in bytes.
349 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
350 ;; Later we may want to split them and compute proper length as for
351 ;; other insns.
352 (define_attr "length" ""
353   (cond [(eq_attr "type" "other,multi,fistp,frndint")
354            (const_int 16)
355          (eq_attr "type" "fcmp")
356            (const_int 4)
357          (eq_attr "unit" "i387")
358            (plus (const_int 2)
359                  (plus (attr "prefix_data16")
360                        (attr "length_address")))]
361          (plus (plus (attr "modrm")
362                      (plus (attr "prefix_0f")
363                            (plus (attr "prefix_rex")
364                                  (const_int 1))))
365                (plus (attr "prefix_rep")
366                      (plus (attr "prefix_data16")
367                            (plus (attr "length_immediate")
368                                  (attr "length_address")))))))
369
370 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
371 ;; `store' if there is a simple memory reference therein, or `unknown'
372 ;; if the instruction is complex.
373
374 (define_attr "memory" "none,load,store,both,unknown"
375   (cond [(eq_attr "type" "other,multi,str")
376            (const_string "unknown")
377          (eq_attr "type" "lea,fcmov,fpspc,cld")
378            (const_string "none")
379          (eq_attr "type" "fistp,leave")
380            (const_string "both")
381          (eq_attr "type" "frndint")
382            (const_string "load")
383          (eq_attr "type" "push")
384            (if_then_else (match_operand 1 "memory_operand" "")
385              (const_string "both")
386              (const_string "store"))
387          (eq_attr "type" "pop")
388            (if_then_else (match_operand 0 "memory_operand" "")
389              (const_string "both")
390              (const_string "load"))
391          (eq_attr "type" "setcc")
392            (if_then_else (match_operand 0 "memory_operand" "")
393              (const_string "store")
394              (const_string "none"))
395          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
396            (if_then_else (ior (match_operand 0 "memory_operand" "")
397                               (match_operand 1 "memory_operand" ""))
398              (const_string "load")
399              (const_string "none"))
400          (eq_attr "type" "ibr")
401            (if_then_else (match_operand 0 "memory_operand" "")
402              (const_string "load")
403              (const_string "none"))
404          (eq_attr "type" "call")
405            (if_then_else (match_operand 0 "constant_call_address_operand" "")
406              (const_string "none")
407              (const_string "load"))
408          (eq_attr "type" "callv")
409            (if_then_else (match_operand 1 "constant_call_address_operand" "")
410              (const_string "none")
411              (const_string "load"))
412          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
413               (match_operand 1 "memory_operand" ""))
414            (const_string "both")
415          (and (match_operand 0 "memory_operand" "")
416               (match_operand 1 "memory_operand" ""))
417            (const_string "both")
418          (match_operand 0 "memory_operand" "")
419            (const_string "store")
420          (match_operand 1 "memory_operand" "")
421            (const_string "load")
422          (and (eq_attr "type"
423                  "!alu1,negnot,ishift1,
424                    imov,imovx,icmp,test,bitmanip,
425                    fmov,fcmp,fsgn,
426                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
427                    mmx,mmxmov,mmxcmp,mmxcvt")
428               (match_operand 2 "memory_operand" ""))
429            (const_string "load")
430          (and (eq_attr "type" "icmov")
431               (match_operand 3 "memory_operand" ""))
432            (const_string "load")
433         ]
434         (const_string "none")))
435
436 ;; Indicates if an instruction has both an immediate and a displacement.
437
438 (define_attr "imm_disp" "false,true,unknown"
439   (cond [(eq_attr "type" "other,multi")
440            (const_string "unknown")
441          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
442               (and (match_operand 0 "memory_displacement_operand" "")
443                    (match_operand 1 "immediate_operand" "")))
444            (const_string "true")
445          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
446               (and (match_operand 0 "memory_displacement_operand" "")
447                    (match_operand 2 "immediate_operand" "")))
448            (const_string "true")
449         ]
450         (const_string "false")))
451
452 ;; Indicates if an FP operation has an integer source.
453
454 (define_attr "fp_int_src" "false,true"
455   (const_string "false"))
456
457 ;; Defines rounding mode of an FP operation.
458
459 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
460   (const_string "any"))
461
462 ;; Describe a user's asm statement.
463 (define_asm_attributes
464   [(set_attr "length" "128")
465    (set_attr "type" "multi")])
466
467 ;; All x87 floating point modes
468 (define_mode_macro X87MODEF [SF DF XF])
469
470 ;; All integer modes handled by x87 fisttp operator.
471 (define_mode_macro X87MODEI [HI SI DI])
472
473 ;; All integer modes handled by integer x87 operators.
474 (define_mode_macro X87MODEI12 [HI SI])
475
476 ;; All SSE floating point modes
477 (define_mode_macro SSEMODEF [SF DF])
478
479 ;; All integer modes handled by SSE cvtts?2si* operators.
480 (define_mode_macro SSEMODEI24 [SI DI])
481
482 \f
483 ;; Scheduling descriptions
484
485 (include "pentium.md")
486 (include "ppro.md")
487 (include "k6.md")
488 (include "athlon.md")
489 (include "geode.md")
490
491 \f
492 ;; Operand and operator predicates and constraints
493
494 (include "predicates.md")
495 (include "constraints.md")
496
497 \f
498 ;; Compare instructions.
499
500 ;; All compare insns have expanders that save the operands away without
501 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
502 ;; after the cmp) will actually emit the cmpM.
503
504 (define_expand "cmpti"
505   [(set (reg:CC FLAGS_REG)
506         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
507                     (match_operand:TI 1 "x86_64_general_operand" "")))]
508   "TARGET_64BIT"
509 {
510   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
511     operands[0] = force_reg (TImode, operands[0]);
512   ix86_compare_op0 = operands[0];
513   ix86_compare_op1 = operands[1];
514   DONE;
515 })
516
517 (define_expand "cmpdi"
518   [(set (reg:CC FLAGS_REG)
519         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
520                     (match_operand:DI 1 "x86_64_general_operand" "")))]
521   ""
522 {
523   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
524     operands[0] = force_reg (DImode, operands[0]);
525   ix86_compare_op0 = operands[0];
526   ix86_compare_op1 = operands[1];
527   DONE;
528 })
529
530 (define_expand "cmpsi"
531   [(set (reg:CC FLAGS_REG)
532         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
533                     (match_operand:SI 1 "general_operand" "")))]
534   ""
535 {
536   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
537     operands[0] = force_reg (SImode, operands[0]);
538   ix86_compare_op0 = operands[0];
539   ix86_compare_op1 = operands[1];
540   DONE;
541 })
542
543 (define_expand "cmphi"
544   [(set (reg:CC FLAGS_REG)
545         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
546                     (match_operand:HI 1 "general_operand" "")))]
547   ""
548 {
549   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
550     operands[0] = force_reg (HImode, operands[0]);
551   ix86_compare_op0 = operands[0];
552   ix86_compare_op1 = operands[1];
553   DONE;
554 })
555
556 (define_expand "cmpqi"
557   [(set (reg:CC FLAGS_REG)
558         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
559                     (match_operand:QI 1 "general_operand" "")))]
560   "TARGET_QIMODE_MATH"
561 {
562   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
563     operands[0] = force_reg (QImode, operands[0]);
564   ix86_compare_op0 = operands[0];
565   ix86_compare_op1 = operands[1];
566   DONE;
567 })
568
569 (define_insn "cmpdi_ccno_1_rex64"
570   [(set (reg FLAGS_REG)
571         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
572                  (match_operand:DI 1 "const0_operand" "n,n")))]
573   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
574   "@
575    test{q}\t{%0, %0|%0, %0}
576    cmp{q}\t{%1, %0|%0, %1}"
577   [(set_attr "type" "test,icmp")
578    (set_attr "length_immediate" "0,1")
579    (set_attr "mode" "DI")])
580
581 (define_insn "*cmpdi_minus_1_rex64"
582   [(set (reg FLAGS_REG)
583         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
584                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
585                  (const_int 0)))]
586   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
587   "cmp{q}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "DI")])
590
591 (define_expand "cmpdi_1_rex64"
592   [(set (reg:CC FLAGS_REG)
593         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
594                     (match_operand:DI 1 "general_operand" "")))]
595   "TARGET_64BIT"
596   "")
597
598 (define_insn "cmpdi_1_insn_rex64"
599   [(set (reg FLAGS_REG)
600         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
601                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
602   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
603   "cmp{q}\t{%1, %0|%0, %1}"
604   [(set_attr "type" "icmp")
605    (set_attr "mode" "DI")])
606
607
608 (define_insn "*cmpsi_ccno_1"
609   [(set (reg FLAGS_REG)
610         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
611                  (match_operand:SI 1 "const0_operand" "n,n")))]
612   "ix86_match_ccmode (insn, CCNOmode)"
613   "@
614    test{l}\t{%0, %0|%0, %0}
615    cmp{l}\t{%1, %0|%0, %1}"
616   [(set_attr "type" "test,icmp")
617    (set_attr "length_immediate" "0,1")
618    (set_attr "mode" "SI")])
619
620 (define_insn "*cmpsi_minus_1"
621   [(set (reg FLAGS_REG)
622         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623                            (match_operand:SI 1 "general_operand" "ri,mr"))
624                  (const_int 0)))]
625   "ix86_match_ccmode (insn, CCGOCmode)"
626   "cmp{l}\t{%1, %0|%0, %1}"
627   [(set_attr "type" "icmp")
628    (set_attr "mode" "SI")])
629
630 (define_expand "cmpsi_1"
631   [(set (reg:CC FLAGS_REG)
632         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
633                     (match_operand:SI 1 "general_operand" "ri,mr")))]
634   ""
635   "")
636
637 (define_insn "*cmpsi_1_insn"
638   [(set (reg FLAGS_REG)
639         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
640                  (match_operand:SI 1 "general_operand" "ri,mr")))]
641   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
642     && ix86_match_ccmode (insn, CCmode)"
643   "cmp{l}\t{%1, %0|%0, %1}"
644   [(set_attr "type" "icmp")
645    (set_attr "mode" "SI")])
646
647 (define_insn "*cmphi_ccno_1"
648   [(set (reg FLAGS_REG)
649         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
650                  (match_operand:HI 1 "const0_operand" "n,n")))]
651   "ix86_match_ccmode (insn, CCNOmode)"
652   "@
653    test{w}\t{%0, %0|%0, %0}
654    cmp{w}\t{%1, %0|%0, %1}"
655   [(set_attr "type" "test,icmp")
656    (set_attr "length_immediate" "0,1")
657    (set_attr "mode" "HI")])
658
659 (define_insn "*cmphi_minus_1"
660   [(set (reg FLAGS_REG)
661         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
662                            (match_operand:HI 1 "general_operand" "ri,mr"))
663                  (const_int 0)))]
664   "ix86_match_ccmode (insn, CCGOCmode)"
665   "cmp{w}\t{%1, %0|%0, %1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "HI")])
668
669 (define_insn "*cmphi_1"
670   [(set (reg FLAGS_REG)
671         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
672                  (match_operand:HI 1 "general_operand" "ri,mr")))]
673   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
674    && ix86_match_ccmode (insn, CCmode)"
675   "cmp{w}\t{%1, %0|%0, %1}"
676   [(set_attr "type" "icmp")
677    (set_attr "mode" "HI")])
678
679 (define_insn "*cmpqi_ccno_1"
680   [(set (reg FLAGS_REG)
681         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
682                  (match_operand:QI 1 "const0_operand" "n,n")))]
683   "ix86_match_ccmode (insn, CCNOmode)"
684   "@
685    test{b}\t{%0, %0|%0, %0}
686    cmp{b}\t{$0, %0|%0, 0}"
687   [(set_attr "type" "test,icmp")
688    (set_attr "length_immediate" "0,1")
689    (set_attr "mode" "QI")])
690
691 (define_insn "*cmpqi_1"
692   [(set (reg FLAGS_REG)
693         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
694                  (match_operand:QI 1 "general_operand" "qi,mq")))]
695   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
696     && ix86_match_ccmode (insn, CCmode)"
697   "cmp{b}\t{%1, %0|%0, %1}"
698   [(set_attr "type" "icmp")
699    (set_attr "mode" "QI")])
700
701 (define_insn "*cmpqi_minus_1"
702   [(set (reg FLAGS_REG)
703         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
704                            (match_operand:QI 1 "general_operand" "qi,mq"))
705                  (const_int 0)))]
706   "ix86_match_ccmode (insn, CCGOCmode)"
707   "cmp{b}\t{%1, %0|%0, %1}"
708   [(set_attr "type" "icmp")
709    (set_attr "mode" "QI")])
710
711 (define_insn "*cmpqi_ext_1"
712   [(set (reg FLAGS_REG)
713         (compare
714           (match_operand:QI 0 "general_operand" "Qm")
715           (subreg:QI
716             (zero_extract:SI
717               (match_operand 1 "ext_register_operand" "Q")
718               (const_int 8)
719               (const_int 8)) 0)))]
720   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721   "cmp{b}\t{%h1, %0|%0, %h1}"
722   [(set_attr "type" "icmp")
723    (set_attr "mode" "QI")])
724
725 (define_insn "*cmpqi_ext_1_rex64"
726   [(set (reg FLAGS_REG)
727         (compare
728           (match_operand:QI 0 "register_operand" "Q")
729           (subreg:QI
730             (zero_extract:SI
731               (match_operand 1 "ext_register_operand" "Q")
732               (const_int 8)
733               (const_int 8)) 0)))]
734   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
735   "cmp{b}\t{%h1, %0|%0, %h1}"
736   [(set_attr "type" "icmp")
737    (set_attr "mode" "QI")])
738
739 (define_insn "*cmpqi_ext_2"
740   [(set (reg FLAGS_REG)
741         (compare
742           (subreg:QI
743             (zero_extract:SI
744               (match_operand 0 "ext_register_operand" "Q")
745               (const_int 8)
746               (const_int 8)) 0)
747           (match_operand:QI 1 "const0_operand" "n")))]
748   "ix86_match_ccmode (insn, CCNOmode)"
749   "test{b}\t%h0, %h0"
750   [(set_attr "type" "test")
751    (set_attr "length_immediate" "0")
752    (set_attr "mode" "QI")])
753
754 (define_expand "cmpqi_ext_3"
755   [(set (reg:CC FLAGS_REG)
756         (compare:CC
757           (subreg:QI
758             (zero_extract:SI
759               (match_operand 0 "ext_register_operand" "")
760               (const_int 8)
761               (const_int 8)) 0)
762           (match_operand:QI 1 "general_operand" "")))]
763   ""
764   "")
765
766 (define_insn "cmpqi_ext_3_insn"
767   [(set (reg FLAGS_REG)
768         (compare
769           (subreg:QI
770             (zero_extract:SI
771               (match_operand 0 "ext_register_operand" "Q")
772               (const_int 8)
773               (const_int 8)) 0)
774           (match_operand:QI 1 "general_operand" "Qmn")))]
775   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776   "cmp{b}\t{%1, %h0|%h0, %1}"
777   [(set_attr "type" "icmp")
778    (set_attr "mode" "QI")])
779
780 (define_insn "cmpqi_ext_3_insn_rex64"
781   [(set (reg FLAGS_REG)
782         (compare
783           (subreg:QI
784             (zero_extract:SI
785               (match_operand 0 "ext_register_operand" "Q")
786               (const_int 8)
787               (const_int 8)) 0)
788           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
789   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
790   "cmp{b}\t{%1, %h0|%h0, %1}"
791   [(set_attr "type" "icmp")
792    (set_attr "mode" "QI")])
793
794 (define_insn "*cmpqi_ext_4"
795   [(set (reg FLAGS_REG)
796         (compare
797           (subreg:QI
798             (zero_extract:SI
799               (match_operand 0 "ext_register_operand" "Q")
800               (const_int 8)
801               (const_int 8)) 0)
802           (subreg:QI
803             (zero_extract:SI
804               (match_operand 1 "ext_register_operand" "Q")
805               (const_int 8)
806               (const_int 8)) 0)))]
807   "ix86_match_ccmode (insn, CCmode)"
808   "cmp{b}\t{%h1, %h0|%h0, %h1}"
809   [(set_attr "type" "icmp")
810    (set_attr "mode" "QI")])
811
812 ;; These implement float point compares.
813 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
814 ;; which would allow mix and match FP modes on the compares.  Which is what
815 ;; the old patterns did, but with many more of them.
816
817 (define_expand "cmpxf"
818   [(set (reg:CC FLAGS_REG)
819         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
820                     (match_operand:XF 1 "nonmemory_operand" "")))]
821   "TARGET_80387"
822 {
823   ix86_compare_op0 = operands[0];
824   ix86_compare_op1 = operands[1];
825   DONE;
826 })
827
828 (define_expand "cmpdf"
829   [(set (reg:CC FLAGS_REG)
830         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
831                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
832   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
833 {
834   ix86_compare_op0 = operands[0];
835   ix86_compare_op1 = operands[1];
836   DONE;
837 })
838
839 (define_expand "cmpsf"
840   [(set (reg:CC FLAGS_REG)
841         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
842                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
843   "TARGET_80387 || TARGET_SSE_MATH"
844 {
845   ix86_compare_op0 = operands[0];
846   ix86_compare_op1 = operands[1];
847   DONE;
848 })
849
850 ;; FP compares, step 1:
851 ;; Set the FP condition codes.
852 ;;
853 ;; CCFPmode     compare with exceptions
854 ;; CCFPUmode    compare with no exceptions
855
856 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
857 ;; used to manage the reg stack popping would not be preserved.
858
859 (define_insn "*cmpfp_0"
860   [(set (match_operand:HI 0 "register_operand" "=a")
861         (unspec:HI
862           [(compare:CCFP
863              (match_operand 1 "register_operand" "f")
864              (match_operand 2 "const0_operand" "X"))]
865         UNSPEC_FNSTSW))]
866   "TARGET_80387
867    && FLOAT_MODE_P (GET_MODE (operands[1]))
868    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
869   "* return output_fp_compare (insn, operands, 0, 0);"
870   [(set_attr "type" "multi")
871    (set_attr "unit" "i387")
872    (set (attr "mode")
873      (cond [(match_operand:SF 1 "" "")
874               (const_string "SF")
875             (match_operand:DF 1 "" "")
876               (const_string "DF")
877            ]
878            (const_string "XF")))])
879
880 (define_insn "*cmpfp_sf"
881   [(set (match_operand:HI 0 "register_operand" "=a")
882         (unspec:HI
883           [(compare:CCFP
884              (match_operand:SF 1 "register_operand" "f")
885              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
886           UNSPEC_FNSTSW))]
887   "TARGET_80387"
888   "* return output_fp_compare (insn, operands, 0, 0);"
889   [(set_attr "type" "multi")
890    (set_attr "unit" "i387")
891    (set_attr "mode" "SF")])
892
893 (define_insn "*cmpfp_df"
894   [(set (match_operand:HI 0 "register_operand" "=a")
895         (unspec:HI
896           [(compare:CCFP
897              (match_operand:DF 1 "register_operand" "f")
898              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
899           UNSPEC_FNSTSW))]
900   "TARGET_80387"
901   "* return output_fp_compare (insn, operands, 0, 0);"
902   [(set_attr "type" "multi")
903    (set_attr "unit" "i387")
904    (set_attr "mode" "DF")])
905
906 (define_insn "*cmpfp_xf"
907   [(set (match_operand:HI 0 "register_operand" "=a")
908         (unspec:HI
909           [(compare:CCFP
910              (match_operand:XF 1 "register_operand" "f")
911              (match_operand:XF 2 "register_operand" "f"))]
912           UNSPEC_FNSTSW))]
913   "TARGET_80387"
914   "* return output_fp_compare (insn, operands, 0, 0);"
915   [(set_attr "type" "multi")
916    (set_attr "unit" "i387")
917    (set_attr "mode" "XF")])
918
919 (define_insn "*cmpfp_u"
920   [(set (match_operand:HI 0 "register_operand" "=a")
921         (unspec:HI
922           [(compare:CCFPU
923              (match_operand 1 "register_operand" "f")
924              (match_operand 2 "register_operand" "f"))]
925           UNSPEC_FNSTSW))]
926   "TARGET_80387
927    && FLOAT_MODE_P (GET_MODE (operands[1]))
928    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
929   "* return output_fp_compare (insn, operands, 0, 1);"
930   [(set_attr "type" "multi")
931    (set_attr "unit" "i387")
932    (set (attr "mode")
933      (cond [(match_operand:SF 1 "" "")
934               (const_string "SF")
935             (match_operand:DF 1 "" "")
936               (const_string "DF")
937            ]
938            (const_string "XF")))])
939
940 (define_insn "*cmpfp_<mode>"
941   [(set (match_operand:HI 0 "register_operand" "=a")
942         (unspec:HI
943           [(compare:CCFP
944              (match_operand 1 "register_operand" "f")
945              (match_operator 3 "float_operator"
946                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
947           UNSPEC_FNSTSW))]
948   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
949    && FLOAT_MODE_P (GET_MODE (operands[1]))
950    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
951   "* return output_fp_compare (insn, operands, 0, 0);"
952   [(set_attr "type" "multi")
953    (set_attr "unit" "i387")
954    (set_attr "fp_int_src" "true")
955    (set_attr "mode" "<MODE>")])
956
957 ;; FP compares, step 2
958 ;; Move the fpsw to ax.
959
960 (define_insn "x86_fnstsw_1"
961   [(set (match_operand:HI 0 "register_operand" "=a")
962         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
963   "TARGET_80387"
964   "fnstsw\t%0"
965   [(set_attr "length" "2")
966    (set_attr "mode" "SI")
967    (set_attr "unit" "i387")])
968
969 ;; FP compares, step 3
970 ;; Get ax into flags, general case.
971
972 (define_insn "x86_sahf_1"
973   [(set (reg:CC FLAGS_REG)
974         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
975   "!TARGET_64BIT"
976   "sahf"
977   [(set_attr "length" "1")
978    (set_attr "athlon_decode" "vector")
979    (set_attr "amdfam10_decode" "direct")
980    (set_attr "mode" "SI")])
981
982 ;; Pentium Pro can do steps 1 through 3 in one go.
983 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
984 (define_insn "*cmpfp_i_mixed"
985   [(set (reg:CCFP FLAGS_REG)
986         (compare:CCFP (match_operand 0 "register_operand" "f,x")
987                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
988   "TARGET_MIX_SSE_I387
989    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991   "* return output_fp_compare (insn, operands, 1, 0);"
992   [(set_attr "type" "fcmp,ssecomi")
993    (set (attr "mode")
994      (if_then_else (match_operand:SF 1 "" "")
995         (const_string "SF")
996         (const_string "DF")))
997    (set_attr "athlon_decode" "vector")
998    (set_attr "amdfam10_decode" "direct")])
999
1000 (define_insn "*cmpfp_i_sse"
1001   [(set (reg:CCFP FLAGS_REG)
1002         (compare:CCFP (match_operand 0 "register_operand" "x")
1003                       (match_operand 1 "nonimmediate_operand" "xm")))]
1004   "TARGET_SSE_MATH
1005    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1006    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007   "* return output_fp_compare (insn, operands, 1, 0);"
1008   [(set_attr "type" "ssecomi")
1009    (set (attr "mode")
1010      (if_then_else (match_operand:SF 1 "" "")
1011         (const_string "SF")
1012         (const_string "DF")))
1013    (set_attr "athlon_decode" "vector")
1014    (set_attr "amdfam10_decode" "direct")])
1015
1016 (define_insn "*cmpfp_i_i387"
1017   [(set (reg:CCFP FLAGS_REG)
1018         (compare:CCFP (match_operand 0 "register_operand" "f")
1019                       (match_operand 1 "register_operand" "f")))]
1020   "TARGET_80387 && TARGET_CMOVE
1021    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1022    && FLOAT_MODE_P (GET_MODE (operands[0]))
1023    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1024   "* return output_fp_compare (insn, operands, 1, 0);"
1025   [(set_attr "type" "fcmp")
1026    (set (attr "mode")
1027      (cond [(match_operand:SF 1 "" "")
1028               (const_string "SF")
1029             (match_operand:DF 1 "" "")
1030               (const_string "DF")
1031            ]
1032            (const_string "XF")))
1033    (set_attr "athlon_decode" "vector")
1034    (set_attr "amdfam10_decode" "direct")])
1035
1036 (define_insn "*cmpfp_iu_mixed"
1037   [(set (reg:CCFPU FLAGS_REG)
1038         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1039                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1040   "TARGET_MIX_SSE_I387
1041    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1042    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1043   "* return output_fp_compare (insn, operands, 1, 1);"
1044   [(set_attr "type" "fcmp,ssecomi")
1045    (set (attr "mode")
1046      (if_then_else (match_operand:SF 1 "" "")
1047         (const_string "SF")
1048         (const_string "DF")))
1049    (set_attr "athlon_decode" "vector")
1050    (set_attr "amdfam10_decode" "direct")])
1051
1052 (define_insn "*cmpfp_iu_sse"
1053   [(set (reg:CCFPU FLAGS_REG)
1054         (compare:CCFPU (match_operand 0 "register_operand" "x")
1055                        (match_operand 1 "nonimmediate_operand" "xm")))]
1056   "TARGET_SSE_MATH
1057    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1058    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1059   "* return output_fp_compare (insn, operands, 1, 1);"
1060   [(set_attr "type" "ssecomi")
1061    (set (attr "mode")
1062      (if_then_else (match_operand:SF 1 "" "")
1063         (const_string "SF")
1064         (const_string "DF")))
1065    (set_attr "athlon_decode" "vector")
1066    (set_attr "amdfam10_decode" "direct")])
1067
1068 (define_insn "*cmpfp_iu_387"
1069   [(set (reg:CCFPU FLAGS_REG)
1070         (compare:CCFPU (match_operand 0 "register_operand" "f")
1071                        (match_operand 1 "register_operand" "f")))]
1072   "TARGET_80387 && TARGET_CMOVE
1073    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1074    && FLOAT_MODE_P (GET_MODE (operands[0]))
1075    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1076   "* return output_fp_compare (insn, operands, 1, 1);"
1077   [(set_attr "type" "fcmp")
1078    (set (attr "mode")
1079      (cond [(match_operand:SF 1 "" "")
1080               (const_string "SF")
1081             (match_operand:DF 1 "" "")
1082               (const_string "DF")
1083            ]
1084            (const_string "XF")))
1085    (set_attr "athlon_decode" "vector")
1086    (set_attr "amdfam10_decode" "direct")])
1087 \f
1088 ;; Move instructions.
1089
1090 ;; General case of fullword move.
1091
1092 (define_expand "movsi"
1093   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1094         (match_operand:SI 1 "general_operand" ""))]
1095   ""
1096   "ix86_expand_move (SImode, operands); DONE;")
1097
1098 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1099 ;; general_operand.
1100 ;;
1101 ;; %%% We don't use a post-inc memory reference because x86 is not a
1102 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1103 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1104 ;; targets without our curiosities, and it is just as easy to represent
1105 ;; this differently.
1106
1107 (define_insn "*pushsi2"
1108   [(set (match_operand:SI 0 "push_operand" "=<")
1109         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1110   "!TARGET_64BIT"
1111   "push{l}\t%1"
1112   [(set_attr "type" "push")
1113    (set_attr "mode" "SI")])
1114
1115 ;; For 64BIT abi we always round up to 8 bytes.
1116 (define_insn "*pushsi2_rex64"
1117   [(set (match_operand:SI 0 "push_operand" "=X")
1118         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1119   "TARGET_64BIT"
1120   "push{q}\t%q1"
1121   [(set_attr "type" "push")
1122    (set_attr "mode" "SI")])
1123
1124 (define_insn "*pushsi2_prologue"
1125   [(set (match_operand:SI 0 "push_operand" "=<")
1126         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1127    (clobber (mem:BLK (scratch)))]
1128   "!TARGET_64BIT"
1129   "push{l}\t%1"
1130   [(set_attr "type" "push")
1131    (set_attr "mode" "SI")])
1132
1133 (define_insn "*popsi1_epilogue"
1134   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1135         (mem:SI (reg:SI SP_REG)))
1136    (set (reg:SI SP_REG)
1137         (plus:SI (reg:SI SP_REG) (const_int 4)))
1138    (clobber (mem:BLK (scratch)))]
1139   "!TARGET_64BIT"
1140   "pop{l}\t%0"
1141   [(set_attr "type" "pop")
1142    (set_attr "mode" "SI")])
1143
1144 (define_insn "popsi1"
1145   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1146         (mem:SI (reg:SI SP_REG)))
1147    (set (reg:SI SP_REG)
1148         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1149   "!TARGET_64BIT"
1150   "pop{l}\t%0"
1151   [(set_attr "type" "pop")
1152    (set_attr "mode" "SI")])
1153
1154 (define_insn "*movsi_xor"
1155   [(set (match_operand:SI 0 "register_operand" "=r")
1156         (match_operand:SI 1 "const0_operand" "i"))
1157    (clobber (reg:CC FLAGS_REG))]
1158   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1159   "xor{l}\t{%0, %0|%0, %0}"
1160   [(set_attr "type" "alu1")
1161    (set_attr "mode" "SI")
1162    (set_attr "length_immediate" "0")])
1163
1164 (define_insn "*movsi_or"
1165   [(set (match_operand:SI 0 "register_operand" "=r")
1166         (match_operand:SI 1 "immediate_operand" "i"))
1167    (clobber (reg:CC FLAGS_REG))]
1168   "reload_completed
1169    && operands[1] == constm1_rtx
1170    && (TARGET_PENTIUM || optimize_size)"
1171 {
1172   operands[1] = constm1_rtx;
1173   return "or{l}\t{%1, %0|%0, %1}";
1174 }
1175   [(set_attr "type" "alu1")
1176    (set_attr "mode" "SI")
1177    (set_attr "length_immediate" "1")])
1178
1179 (define_insn "*movsi_1"
1180   [(set (match_operand:SI 0 "nonimmediate_operand"
1181                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1182         (match_operand:SI 1 "general_operand"
1183                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1184   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1185 {
1186   switch (get_attr_type (insn))
1187     {
1188     case TYPE_SSELOG1:
1189       if (get_attr_mode (insn) == MODE_TI)
1190         return "pxor\t%0, %0";
1191       return "xorps\t%0, %0";
1192
1193     case TYPE_SSEMOV:
1194       switch (get_attr_mode (insn))
1195         {
1196         case MODE_TI:
1197           return "movdqa\t{%1, %0|%0, %1}";
1198         case MODE_V4SF:
1199           return "movaps\t{%1, %0|%0, %1}";
1200         case MODE_SI:
1201           return "movd\t{%1, %0|%0, %1}";
1202         case MODE_SF:
1203           return "movss\t{%1, %0|%0, %1}";
1204         default:
1205           gcc_unreachable ();
1206         }
1207
1208     case TYPE_MMXADD:
1209       return "pxor\t%0, %0";
1210
1211     case TYPE_MMXMOV:
1212       if (get_attr_mode (insn) == MODE_DI)
1213         return "movq\t{%1, %0|%0, %1}";
1214       return "movd\t{%1, %0|%0, %1}";
1215
1216     case TYPE_LEA:
1217       return "lea{l}\t{%1, %0|%0, %1}";
1218
1219     default:
1220       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1221       return "mov{l}\t{%1, %0|%0, %1}";
1222     }
1223 }
1224   [(set (attr "type")
1225      (cond [(eq_attr "alternative" "2")
1226               (const_string "mmxadd")
1227             (eq_attr "alternative" "3,4,5")
1228               (const_string "mmxmov")
1229             (eq_attr "alternative" "6")
1230               (const_string "sselog1")
1231             (eq_attr "alternative" "7,8,9,10,11")
1232               (const_string "ssemov")
1233             (match_operand:DI 1 "pic_32bit_operand" "")
1234               (const_string "lea")
1235            ]
1236            (const_string "imov")))
1237    (set (attr "mode")
1238      (cond [(eq_attr "alternative" "2,3")
1239               (const_string "DI")
1240             (eq_attr "alternative" "6,7")
1241               (if_then_else
1242                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1243                 (const_string "V4SF")
1244                 (const_string "TI"))
1245             (and (eq_attr "alternative" "8,9,10,11")
1246                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1247               (const_string "SF")
1248            ]
1249            (const_string "SI")))])
1250
1251 ;; Stores and loads of ax to arbitrary constant address.
1252 ;; We fake an second form of instruction to force reload to load address
1253 ;; into register when rax is not available
1254 (define_insn "*movabssi_1_rex64"
1255   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1256         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1257   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1258   "@
1259    movabs{l}\t{%1, %P0|%P0, %1}
1260    mov{l}\t{%1, %a0|%a0, %1}"
1261   [(set_attr "type" "imov")
1262    (set_attr "modrm" "0,*")
1263    (set_attr "length_address" "8,0")
1264    (set_attr "length_immediate" "0,*")
1265    (set_attr "memory" "store")
1266    (set_attr "mode" "SI")])
1267
1268 (define_insn "*movabssi_2_rex64"
1269   [(set (match_operand:SI 0 "register_operand" "=a,r")
1270         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1271   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1272   "@
1273    movabs{l}\t{%P1, %0|%0, %P1}
1274    mov{l}\t{%a1, %0|%0, %a1}"
1275   [(set_attr "type" "imov")
1276    (set_attr "modrm" "0,*")
1277    (set_attr "length_address" "8,0")
1278    (set_attr "length_immediate" "0")
1279    (set_attr "memory" "load")
1280    (set_attr "mode" "SI")])
1281
1282 (define_insn "*swapsi"
1283   [(set (match_operand:SI 0 "register_operand" "+r")
1284         (match_operand:SI 1 "register_operand" "+r"))
1285    (set (match_dup 1)
1286         (match_dup 0))]
1287   ""
1288   "xchg{l}\t%1, %0"
1289   [(set_attr "type" "imov")
1290    (set_attr "mode" "SI")
1291    (set_attr "pent_pair" "np")
1292    (set_attr "athlon_decode" "vector")
1293    (set_attr "amdfam10_decode" "double")])   
1294
1295 (define_expand "movhi"
1296   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1297         (match_operand:HI 1 "general_operand" ""))]
1298   ""
1299   "ix86_expand_move (HImode, operands); DONE;")
1300
1301 (define_insn "*pushhi2"
1302   [(set (match_operand:HI 0 "push_operand" "=X")
1303         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1304   "!TARGET_64BIT"
1305   "push{l}\t%k1"
1306   [(set_attr "type" "push")
1307    (set_attr "mode" "SI")])
1308
1309 ;; For 64BIT abi we always round up to 8 bytes.
1310 (define_insn "*pushhi2_rex64"
1311   [(set (match_operand:HI 0 "push_operand" "=X")
1312         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1313   "TARGET_64BIT"
1314   "push{q}\t%q1"
1315   [(set_attr "type" "push")
1316    (set_attr "mode" "DI")])
1317
1318 (define_insn "*movhi_1"
1319   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1320         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1321   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1322 {
1323   switch (get_attr_type (insn))
1324     {
1325     case TYPE_IMOVX:
1326       /* movzwl is faster than movw on p2 due to partial word stalls,
1327          though not as fast as an aligned movl.  */
1328       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1329     default:
1330       if (get_attr_mode (insn) == MODE_SI)
1331         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1332       else
1333         return "mov{w}\t{%1, %0|%0, %1}";
1334     }
1335 }
1336   [(set (attr "type")
1337      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1338               (const_string "imov")
1339             (and (eq_attr "alternative" "0")
1340                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1341                           (const_int 0))
1342                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1343                           (const_int 0))))
1344               (const_string "imov")
1345             (and (eq_attr "alternative" "1,2")
1346                  (match_operand:HI 1 "aligned_operand" ""))
1347               (const_string "imov")
1348             (and (ne (symbol_ref "TARGET_MOVX")
1349                      (const_int 0))
1350                  (eq_attr "alternative" "0,2"))
1351               (const_string "imovx")
1352            ]
1353            (const_string "imov")))
1354     (set (attr "mode")
1355       (cond [(eq_attr "type" "imovx")
1356                (const_string "SI")
1357              (and (eq_attr "alternative" "1,2")
1358                   (match_operand:HI 1 "aligned_operand" ""))
1359                (const_string "SI")
1360              (and (eq_attr "alternative" "0")
1361                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1362                            (const_int 0))
1363                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1364                            (const_int 0))))
1365                (const_string "SI")
1366             ]
1367             (const_string "HI")))])
1368
1369 ;; Stores and loads of ax to arbitrary constant address.
1370 ;; We fake an second form of instruction to force reload to load address
1371 ;; into register when rax is not available
1372 (define_insn "*movabshi_1_rex64"
1373   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1374         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1375   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1376   "@
1377    movabs{w}\t{%1, %P0|%P0, %1}
1378    mov{w}\t{%1, %a0|%a0, %1}"
1379   [(set_attr "type" "imov")
1380    (set_attr "modrm" "0,*")
1381    (set_attr "length_address" "8,0")
1382    (set_attr "length_immediate" "0,*")
1383    (set_attr "memory" "store")
1384    (set_attr "mode" "HI")])
1385
1386 (define_insn "*movabshi_2_rex64"
1387   [(set (match_operand:HI 0 "register_operand" "=a,r")
1388         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1389   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1390   "@
1391    movabs{w}\t{%P1, %0|%0, %P1}
1392    mov{w}\t{%a1, %0|%0, %a1}"
1393   [(set_attr "type" "imov")
1394    (set_attr "modrm" "0,*")
1395    (set_attr "length_address" "8,0")
1396    (set_attr "length_immediate" "0")
1397    (set_attr "memory" "load")
1398    (set_attr "mode" "HI")])
1399
1400 (define_insn "*swaphi_1"
1401   [(set (match_operand:HI 0 "register_operand" "+r")
1402         (match_operand:HI 1 "register_operand" "+r"))
1403    (set (match_dup 1)
1404         (match_dup 0))]
1405   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1406   "xchg{l}\t%k1, %k0"
1407   [(set_attr "type" "imov")
1408    (set_attr "mode" "SI")
1409    (set_attr "pent_pair" "np")
1410    (set_attr "athlon_decode" "vector")
1411    (set_attr "amdfam10_decode" "double")])   
1412
1413 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1414 (define_insn "*swaphi_2"
1415   [(set (match_operand:HI 0 "register_operand" "+r")
1416         (match_operand:HI 1 "register_operand" "+r"))
1417    (set (match_dup 1)
1418         (match_dup 0))]
1419   "TARGET_PARTIAL_REG_STALL"
1420   "xchg{w}\t%1, %0"
1421   [(set_attr "type" "imov")
1422    (set_attr "mode" "HI")
1423    (set_attr "pent_pair" "np")
1424    (set_attr "athlon_decode" "vector")])
1425
1426 (define_expand "movstricthi"
1427   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1428         (match_operand:HI 1 "general_operand" ""))]
1429   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1430 {
1431   /* Don't generate memory->memory moves, go through a register */
1432   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1433     operands[1] = force_reg (HImode, operands[1]);
1434 })
1435
1436 (define_insn "*movstricthi_1"
1437   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1438         (match_operand:HI 1 "general_operand" "rn,m"))]
1439   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1440    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1441   "mov{w}\t{%1, %0|%0, %1}"
1442   [(set_attr "type" "imov")
1443    (set_attr "mode" "HI")])
1444
1445 (define_insn "*movstricthi_xor"
1446   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1447         (match_operand:HI 1 "const0_operand" "i"))
1448    (clobber (reg:CC FLAGS_REG))]
1449   "reload_completed
1450    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1451   "xor{w}\t{%0, %0|%0, %0}"
1452   [(set_attr "type" "alu1")
1453    (set_attr "mode" "HI")
1454    (set_attr "length_immediate" "0")])
1455
1456 (define_expand "movqi"
1457   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1458         (match_operand:QI 1 "general_operand" ""))]
1459   ""
1460   "ix86_expand_move (QImode, operands); DONE;")
1461
1462 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1463 ;; "push a byte".  But actually we use pushl, which has the effect
1464 ;; of rounding the amount pushed up to a word.
1465
1466 (define_insn "*pushqi2"
1467   [(set (match_operand:QI 0 "push_operand" "=X")
1468         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1469   "!TARGET_64BIT"
1470   "push{l}\t%k1"
1471   [(set_attr "type" "push")
1472    (set_attr "mode" "SI")])
1473
1474 ;; For 64BIT abi we always round up to 8 bytes.
1475 (define_insn "*pushqi2_rex64"
1476   [(set (match_operand:QI 0 "push_operand" "=X")
1477         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1478   "TARGET_64BIT"
1479   "push{q}\t%q1"
1480   [(set_attr "type" "push")
1481    (set_attr "mode" "DI")])
1482
1483 ;; Situation is quite tricky about when to choose full sized (SImode) move
1484 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1485 ;; partial register dependency machines (such as AMD Athlon), where QImode
1486 ;; moves issue extra dependency and for partial register stalls machines
1487 ;; that don't use QImode patterns (and QImode move cause stall on the next
1488 ;; instruction).
1489 ;;
1490 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1491 ;; register stall machines with, where we use QImode instructions, since
1492 ;; partial register stall can be caused there.  Then we use movzx.
1493 (define_insn "*movqi_1"
1494   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1495         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1496   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1497 {
1498   switch (get_attr_type (insn))
1499     {
1500     case TYPE_IMOVX:
1501       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1502       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1503     default:
1504       if (get_attr_mode (insn) == MODE_SI)
1505         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1506       else
1507         return "mov{b}\t{%1, %0|%0, %1}";
1508     }
1509 }
1510   [(set (attr "type")
1511      (cond [(and (eq_attr "alternative" "5")
1512                  (not (match_operand:QI 1 "aligned_operand" "")))
1513               (const_string "imovx")
1514             (ne (symbol_ref "optimize_size") (const_int 0))
1515               (const_string "imov")
1516             (and (eq_attr "alternative" "3")
1517                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1518                           (const_int 0))
1519                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1520                           (const_int 0))))
1521               (const_string "imov")
1522             (eq_attr "alternative" "3,5")
1523               (const_string "imovx")
1524             (and (ne (symbol_ref "TARGET_MOVX")
1525                      (const_int 0))
1526                  (eq_attr "alternative" "2"))
1527               (const_string "imovx")
1528            ]
1529            (const_string "imov")))
1530    (set (attr "mode")
1531       (cond [(eq_attr "alternative" "3,4,5")
1532                (const_string "SI")
1533              (eq_attr "alternative" "6")
1534                (const_string "QI")
1535              (eq_attr "type" "imovx")
1536                (const_string "SI")
1537              (and (eq_attr "type" "imov")
1538                   (and (eq_attr "alternative" "0,1")
1539                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1540                                 (const_int 0))
1541                             (and (eq (symbol_ref "optimize_size")
1542                                      (const_int 0))
1543                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1544                                      (const_int 0))))))
1545                (const_string "SI")
1546              ;; Avoid partial register stalls when not using QImode arithmetic
1547              (and (eq_attr "type" "imov")
1548                   (and (eq_attr "alternative" "0,1")
1549                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1550                                 (const_int 0))
1551                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1552                                 (const_int 0)))))
1553                (const_string "SI")
1554            ]
1555            (const_string "QI")))])
1556
1557 (define_expand "reload_outqi"
1558   [(parallel [(match_operand:QI 0 "" "=m")
1559               (match_operand:QI 1 "register_operand" "r")
1560               (match_operand:QI 2 "register_operand" "=&q")])]
1561   ""
1562 {
1563   rtx op0, op1, op2;
1564   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1565
1566   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1567   if (! q_regs_operand (op1, QImode))
1568     {
1569       emit_insn (gen_movqi (op2, op1));
1570       op1 = op2;
1571     }
1572   emit_insn (gen_movqi (op0, op1));
1573   DONE;
1574 })
1575
1576 (define_insn "*swapqi_1"
1577   [(set (match_operand:QI 0 "register_operand" "+r")
1578         (match_operand:QI 1 "register_operand" "+r"))
1579    (set (match_dup 1)
1580         (match_dup 0))]
1581   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1582   "xchg{l}\t%k1, %k0"
1583   [(set_attr "type" "imov")
1584    (set_attr "mode" "SI")
1585    (set_attr "pent_pair" "np")
1586    (set_attr "athlon_decode" "vector")
1587    (set_attr "amdfam10_decode" "vector")])   
1588
1589 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1590 (define_insn "*swapqi_2"
1591   [(set (match_operand:QI 0 "register_operand" "+q")
1592         (match_operand:QI 1 "register_operand" "+q"))
1593    (set (match_dup 1)
1594         (match_dup 0))]
1595   "TARGET_PARTIAL_REG_STALL"
1596   "xchg{b}\t%1, %0"
1597   [(set_attr "type" "imov")
1598    (set_attr "mode" "QI")
1599    (set_attr "pent_pair" "np")
1600    (set_attr "athlon_decode" "vector")])
1601
1602 (define_expand "movstrictqi"
1603   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1604         (match_operand:QI 1 "general_operand" ""))]
1605   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1606 {
1607   /* Don't generate memory->memory moves, go through a register.  */
1608   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1609     operands[1] = force_reg (QImode, operands[1]);
1610 })
1611
1612 (define_insn "*movstrictqi_1"
1613   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1614         (match_operand:QI 1 "general_operand" "*qn,m"))]
1615   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1616    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1617   "mov{b}\t{%1, %0|%0, %1}"
1618   [(set_attr "type" "imov")
1619    (set_attr "mode" "QI")])
1620
1621 (define_insn "*movstrictqi_xor"
1622   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1623         (match_operand:QI 1 "const0_operand" "i"))
1624    (clobber (reg:CC FLAGS_REG))]
1625   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1626   "xor{b}\t{%0, %0|%0, %0}"
1627   [(set_attr "type" "alu1")
1628    (set_attr "mode" "QI")
1629    (set_attr "length_immediate" "0")])
1630
1631 (define_insn "*movsi_extv_1"
1632   [(set (match_operand:SI 0 "register_operand" "=R")
1633         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1634                          (const_int 8)
1635                          (const_int 8)))]
1636   ""
1637   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1638   [(set_attr "type" "imovx")
1639    (set_attr "mode" "SI")])
1640
1641 (define_insn "*movhi_extv_1"
1642   [(set (match_operand:HI 0 "register_operand" "=R")
1643         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1644                          (const_int 8)
1645                          (const_int 8)))]
1646   ""
1647   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1648   [(set_attr "type" "imovx")
1649    (set_attr "mode" "SI")])
1650
1651 (define_insn "*movqi_extv_1"
1652   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1653         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1654                          (const_int 8)
1655                          (const_int 8)))]
1656   "!TARGET_64BIT"
1657 {
1658   switch (get_attr_type (insn))
1659     {
1660     case TYPE_IMOVX:
1661       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1662     default:
1663       return "mov{b}\t{%h1, %0|%0, %h1}";
1664     }
1665 }
1666   [(set (attr "type")
1667      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1668                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1669                              (ne (symbol_ref "TARGET_MOVX")
1670                                  (const_int 0))))
1671         (const_string "imovx")
1672         (const_string "imov")))
1673    (set (attr "mode")
1674      (if_then_else (eq_attr "type" "imovx")
1675         (const_string "SI")
1676         (const_string "QI")))])
1677
1678 (define_insn "*movqi_extv_1_rex64"
1679   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1680         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1681                          (const_int 8)
1682                          (const_int 8)))]
1683   "TARGET_64BIT"
1684 {
1685   switch (get_attr_type (insn))
1686     {
1687     case TYPE_IMOVX:
1688       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1689     default:
1690       return "mov{b}\t{%h1, %0|%0, %h1}";
1691     }
1692 }
1693   [(set (attr "type")
1694      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1695                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1696                              (ne (symbol_ref "TARGET_MOVX")
1697                                  (const_int 0))))
1698         (const_string "imovx")
1699         (const_string "imov")))
1700    (set (attr "mode")
1701      (if_then_else (eq_attr "type" "imovx")
1702         (const_string "SI")
1703         (const_string "QI")))])
1704
1705 ;; Stores and loads of ax to arbitrary constant address.
1706 ;; We fake an second form of instruction to force reload to load address
1707 ;; into register when rax is not available
1708 (define_insn "*movabsqi_1_rex64"
1709   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1710         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1711   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1712   "@
1713    movabs{b}\t{%1, %P0|%P0, %1}
1714    mov{b}\t{%1, %a0|%a0, %1}"
1715   [(set_attr "type" "imov")
1716    (set_attr "modrm" "0,*")
1717    (set_attr "length_address" "8,0")
1718    (set_attr "length_immediate" "0,*")
1719    (set_attr "memory" "store")
1720    (set_attr "mode" "QI")])
1721
1722 (define_insn "*movabsqi_2_rex64"
1723   [(set (match_operand:QI 0 "register_operand" "=a,r")
1724         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1725   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1726   "@
1727    movabs{b}\t{%P1, %0|%0, %P1}
1728    mov{b}\t{%a1, %0|%0, %a1}"
1729   [(set_attr "type" "imov")
1730    (set_attr "modrm" "0,*")
1731    (set_attr "length_address" "8,0")
1732    (set_attr "length_immediate" "0")
1733    (set_attr "memory" "load")
1734    (set_attr "mode" "QI")])
1735
1736 (define_insn "*movdi_extzv_1"
1737   [(set (match_operand:DI 0 "register_operand" "=R")
1738         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1739                          (const_int 8)
1740                          (const_int 8)))]
1741   "TARGET_64BIT"
1742   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1743   [(set_attr "type" "imovx")
1744    (set_attr "mode" "DI")])
1745
1746 (define_insn "*movsi_extzv_1"
1747   [(set (match_operand:SI 0 "register_operand" "=R")
1748         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1749                          (const_int 8)
1750                          (const_int 8)))]
1751   ""
1752   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1753   [(set_attr "type" "imovx")
1754    (set_attr "mode" "SI")])
1755
1756 (define_insn "*movqi_extzv_2"
1757   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1758         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1759                                     (const_int 8)
1760                                     (const_int 8)) 0))]
1761   "!TARGET_64BIT"
1762 {
1763   switch (get_attr_type (insn))
1764     {
1765     case TYPE_IMOVX:
1766       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1767     default:
1768       return "mov{b}\t{%h1, %0|%0, %h1}";
1769     }
1770 }
1771   [(set (attr "type")
1772      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1773                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774                              (ne (symbol_ref "TARGET_MOVX")
1775                                  (const_int 0))))
1776         (const_string "imovx")
1777         (const_string "imov")))
1778    (set (attr "mode")
1779      (if_then_else (eq_attr "type" "imovx")
1780         (const_string "SI")
1781         (const_string "QI")))])
1782
1783 (define_insn "*movqi_extzv_2_rex64"
1784   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1785         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1786                                     (const_int 8)
1787                                     (const_int 8)) 0))]
1788   "TARGET_64BIT"
1789 {
1790   switch (get_attr_type (insn))
1791     {
1792     case TYPE_IMOVX:
1793       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1794     default:
1795       return "mov{b}\t{%h1, %0|%0, %h1}";
1796     }
1797 }
1798   [(set (attr "type")
1799      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1800                         (ne (symbol_ref "TARGET_MOVX")
1801                             (const_int 0)))
1802         (const_string "imovx")
1803         (const_string "imov")))
1804    (set (attr "mode")
1805      (if_then_else (eq_attr "type" "imovx")
1806         (const_string "SI")
1807         (const_string "QI")))])
1808
1809 (define_insn "movsi_insv_1"
1810   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1811                          (const_int 8)
1812                          (const_int 8))
1813         (match_operand:SI 1 "general_operand" "Qmn"))]
1814   "!TARGET_64BIT"
1815   "mov{b}\t{%b1, %h0|%h0, %b1}"
1816   [(set_attr "type" "imov")
1817    (set_attr "mode" "QI")])
1818
1819 (define_insn "movdi_insv_1_rex64"
1820   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1821                          (const_int 8)
1822                          (const_int 8))
1823         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1824   "TARGET_64BIT"
1825   "mov{b}\t{%b1, %h0|%h0, %b1}"
1826   [(set_attr "type" "imov")
1827    (set_attr "mode" "QI")])
1828
1829 (define_insn "*movqi_insv_2"
1830   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1831                          (const_int 8)
1832                          (const_int 8))
1833         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1834                      (const_int 8)))]
1835   ""
1836   "mov{b}\t{%h1, %h0|%h0, %h1}"
1837   [(set_attr "type" "imov")
1838    (set_attr "mode" "QI")])
1839
1840 (define_expand "movdi"
1841   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1842         (match_operand:DI 1 "general_operand" ""))]
1843   ""
1844   "ix86_expand_move (DImode, operands); DONE;")
1845
1846 (define_insn "*pushdi"
1847   [(set (match_operand:DI 0 "push_operand" "=<")
1848         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1849   "!TARGET_64BIT"
1850   "#")
1851
1852 (define_insn "*pushdi2_rex64"
1853   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1854         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1855   "TARGET_64BIT"
1856   "@
1857    push{q}\t%1
1858    #"
1859   [(set_attr "type" "push,multi")
1860    (set_attr "mode" "DI")])
1861
1862 ;; Convert impossible pushes of immediate to existing instructions.
1863 ;; First try to get scratch register and go through it.  In case this
1864 ;; fails, push sign extended lower part first and then overwrite
1865 ;; upper part by 32bit move.
1866 (define_peephole2
1867   [(match_scratch:DI 2 "r")
1868    (set (match_operand:DI 0 "push_operand" "")
1869         (match_operand:DI 1 "immediate_operand" ""))]
1870   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1871    && !x86_64_immediate_operand (operands[1], DImode)"
1872   [(set (match_dup 2) (match_dup 1))
1873    (set (match_dup 0) (match_dup 2))]
1874   "")
1875
1876 ;; We need to define this as both peepholer and splitter for case
1877 ;; peephole2 pass is not run.
1878 ;; "&& 1" is needed to keep it from matching the previous pattern.
1879 (define_peephole2
1880   [(set (match_operand:DI 0 "push_operand" "")
1881         (match_operand:DI 1 "immediate_operand" ""))]
1882   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1883    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1884   [(set (match_dup 0) (match_dup 1))
1885    (set (match_dup 2) (match_dup 3))]
1886   "split_di (operands + 1, 1, operands + 2, operands + 3);
1887    operands[1] = gen_lowpart (DImode, operands[2]);
1888    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1889                                                     GEN_INT (4)));
1890   ")
1891
1892 (define_split
1893   [(set (match_operand:DI 0 "push_operand" "")
1894         (match_operand:DI 1 "immediate_operand" ""))]
1895   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1896                     ? flow2_completed : reload_completed)
1897    && !symbolic_operand (operands[1], DImode)
1898    && !x86_64_immediate_operand (operands[1], DImode)"
1899   [(set (match_dup 0) (match_dup 1))
1900    (set (match_dup 2) (match_dup 3))]
1901   "split_di (operands + 1, 1, operands + 2, operands + 3);
1902    operands[1] = gen_lowpart (DImode, operands[2]);
1903    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1904                                                     GEN_INT (4)));
1905   ")
1906
1907 (define_insn "*pushdi2_prologue_rex64"
1908   [(set (match_operand:DI 0 "push_operand" "=<")
1909         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1910    (clobber (mem:BLK (scratch)))]
1911   "TARGET_64BIT"
1912   "push{q}\t%1"
1913   [(set_attr "type" "push")
1914    (set_attr "mode" "DI")])
1915
1916 (define_insn "*popdi1_epilogue_rex64"
1917   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1918         (mem:DI (reg:DI SP_REG)))
1919    (set (reg:DI SP_REG)
1920         (plus:DI (reg:DI SP_REG) (const_int 8)))
1921    (clobber (mem:BLK (scratch)))]
1922   "TARGET_64BIT"
1923   "pop{q}\t%0"
1924   [(set_attr "type" "pop")
1925    (set_attr "mode" "DI")])
1926
1927 (define_insn "popdi1"
1928   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1929         (mem:DI (reg:DI SP_REG)))
1930    (set (reg:DI SP_REG)
1931         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1932   "TARGET_64BIT"
1933   "pop{q}\t%0"
1934   [(set_attr "type" "pop")
1935    (set_attr "mode" "DI")])
1936
1937 (define_insn "*movdi_xor_rex64"
1938   [(set (match_operand:DI 0 "register_operand" "=r")
1939         (match_operand:DI 1 "const0_operand" "i"))
1940    (clobber (reg:CC FLAGS_REG))]
1941   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1942    && reload_completed"
1943   "xor{l}\t{%k0, %k0|%k0, %k0}"
1944   [(set_attr "type" "alu1")
1945    (set_attr "mode" "SI")
1946    (set_attr "length_immediate" "0")])
1947
1948 (define_insn "*movdi_or_rex64"
1949   [(set (match_operand:DI 0 "register_operand" "=r")
1950         (match_operand:DI 1 "const_int_operand" "i"))
1951    (clobber (reg:CC FLAGS_REG))]
1952   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1953    && reload_completed
1954    && operands[1] == constm1_rtx"
1955 {
1956   operands[1] = constm1_rtx;
1957   return "or{q}\t{%1, %0|%0, %1}";
1958 }
1959   [(set_attr "type" "alu1")
1960    (set_attr "mode" "DI")
1961    (set_attr "length_immediate" "1")])
1962
1963 (define_insn "*movdi_2"
1964   [(set (match_operand:DI 0 "nonimmediate_operand"
1965                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1966         (match_operand:DI 1 "general_operand"
1967                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1968   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1969   "@
1970    #
1971    #
1972    pxor\t%0, %0
1973    movq\t{%1, %0|%0, %1}
1974    movq\t{%1, %0|%0, %1}
1975    pxor\t%0, %0
1976    movq\t{%1, %0|%0, %1}
1977    movdqa\t{%1, %0|%0, %1}
1978    movq\t{%1, %0|%0, %1}
1979    xorps\t%0, %0
1980    movlps\t{%1, %0|%0, %1}
1981    movaps\t{%1, %0|%0, %1}
1982    movlps\t{%1, %0|%0, %1}"
1983   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1984    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1985
1986 (define_split
1987   [(set (match_operand:DI 0 "push_operand" "")
1988         (match_operand:DI 1 "general_operand" ""))]
1989   "!TARGET_64BIT && reload_completed
1990    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1991   [(const_int 0)]
1992   "ix86_split_long_move (operands); DONE;")
1993
1994 ;; %%% This multiword shite has got to go.
1995 (define_split
1996   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1997         (match_operand:DI 1 "general_operand" ""))]
1998   "!TARGET_64BIT && reload_completed
1999    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2000    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2001   [(const_int 0)]
2002   "ix86_split_long_move (operands); DONE;")
2003
2004 (define_insn "*movdi_1_rex64"
2005   [(set (match_operand:DI 0 "nonimmediate_operand"
2006                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2007         (match_operand:DI 1 "general_operand"
2008                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2009   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2010 {
2011   switch (get_attr_type (insn))
2012     {
2013     case TYPE_SSECVT:
2014       if (which_alternative == 13)
2015         return "movq2dq\t{%1, %0|%0, %1}";
2016       else
2017         return "movdq2q\t{%1, %0|%0, %1}";
2018     case TYPE_SSEMOV:
2019       if (get_attr_mode (insn) == MODE_TI)
2020           return "movdqa\t{%1, %0|%0, %1}";
2021       /* FALLTHRU */
2022     case TYPE_MMXMOV:
2023       /* Moves from and into integer register is done using movd opcode with
2024          REX prefix.  */
2025       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2026           return "movd\t{%1, %0|%0, %1}";
2027       return "movq\t{%1, %0|%0, %1}";
2028     case TYPE_SSELOG1:
2029     case TYPE_MMXADD:
2030       return "pxor\t%0, %0";
2031     case TYPE_MULTI:
2032       return "#";
2033     case TYPE_LEA:
2034       return "lea{q}\t{%a1, %0|%0, %a1}";
2035     default:
2036       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2037       if (get_attr_mode (insn) == MODE_SI)
2038         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2039       else if (which_alternative == 2)
2040         return "movabs{q}\t{%1, %0|%0, %1}";
2041       else
2042         return "mov{q}\t{%1, %0|%0, %1}";
2043     }
2044 }
2045   [(set (attr "type")
2046      (cond [(eq_attr "alternative" "5")
2047               (const_string "mmxadd")
2048             (eq_attr "alternative" "6,7,8")
2049               (const_string "mmxmov")
2050             (eq_attr "alternative" "9")
2051               (const_string "sselog1")
2052             (eq_attr "alternative" "10,11,12")
2053               (const_string "ssemov")
2054             (eq_attr "alternative" "13,14")
2055               (const_string "ssecvt")
2056             (eq_attr "alternative" "4")
2057               (const_string "multi")
2058             (match_operand:DI 1 "pic_32bit_operand" "")
2059               (const_string "lea")
2060            ]
2061            (const_string "imov")))
2062    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2063    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2064    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2065
2066 ;; Stores and loads of ax to arbitrary constant address.
2067 ;; We fake an second form of instruction to force reload to load address
2068 ;; into register when rax is not available
2069 (define_insn "*movabsdi_1_rex64"
2070   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2071         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2072   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2073   "@
2074    movabs{q}\t{%1, %P0|%P0, %1}
2075    mov{q}\t{%1, %a0|%a0, %1}"
2076   [(set_attr "type" "imov")
2077    (set_attr "modrm" "0,*")
2078    (set_attr "length_address" "8,0")
2079    (set_attr "length_immediate" "0,*")
2080    (set_attr "memory" "store")
2081    (set_attr "mode" "DI")])
2082
2083 (define_insn "*movabsdi_2_rex64"
2084   [(set (match_operand:DI 0 "register_operand" "=a,r")
2085         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2086   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2087   "@
2088    movabs{q}\t{%P1, %0|%0, %P1}
2089    mov{q}\t{%a1, %0|%0, %a1}"
2090   [(set_attr "type" "imov")
2091    (set_attr "modrm" "0,*")
2092    (set_attr "length_address" "8,0")
2093    (set_attr "length_immediate" "0")
2094    (set_attr "memory" "load")
2095    (set_attr "mode" "DI")])
2096
2097 ;; Convert impossible stores of immediate to existing instructions.
2098 ;; First try to get scratch register and go through it.  In case this
2099 ;; fails, move by 32bit parts.
2100 (define_peephole2
2101   [(match_scratch:DI 2 "r")
2102    (set (match_operand:DI 0 "memory_operand" "")
2103         (match_operand:DI 1 "immediate_operand" ""))]
2104   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2105    && !x86_64_immediate_operand (operands[1], DImode)"
2106   [(set (match_dup 2) (match_dup 1))
2107    (set (match_dup 0) (match_dup 2))]
2108   "")
2109
2110 ;; We need to define this as both peepholer and splitter for case
2111 ;; peephole2 pass is not run.
2112 ;; "&& 1" is needed to keep it from matching the previous pattern.
2113 (define_peephole2
2114   [(set (match_operand:DI 0 "memory_operand" "")
2115         (match_operand:DI 1 "immediate_operand" ""))]
2116   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2117    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2118   [(set (match_dup 2) (match_dup 3))
2119    (set (match_dup 4) (match_dup 5))]
2120   "split_di (operands, 2, operands + 2, operands + 4);")
2121
2122 (define_split
2123   [(set (match_operand:DI 0 "memory_operand" "")
2124         (match_operand:DI 1 "immediate_operand" ""))]
2125   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2126                     ? flow2_completed : reload_completed)
2127    && !symbolic_operand (operands[1], DImode)
2128    && !x86_64_immediate_operand (operands[1], DImode)"
2129   [(set (match_dup 2) (match_dup 3))
2130    (set (match_dup 4) (match_dup 5))]
2131   "split_di (operands, 2, operands + 2, operands + 4);")
2132
2133 (define_insn "*swapdi_rex64"
2134   [(set (match_operand:DI 0 "register_operand" "+r")
2135         (match_operand:DI 1 "register_operand" "+r"))
2136    (set (match_dup 1)
2137         (match_dup 0))]
2138   "TARGET_64BIT"
2139   "xchg{q}\t%1, %0"
2140   [(set_attr "type" "imov")
2141    (set_attr "mode" "DI")
2142    (set_attr "pent_pair" "np")
2143    (set_attr "athlon_decode" "vector")
2144    (set_attr "amdfam10_decode" "double")])   
2145
2146 (define_expand "movti"
2147   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2148         (match_operand:TI 1 "nonimmediate_operand" ""))]
2149   "TARGET_SSE || TARGET_64BIT"
2150 {
2151   if (TARGET_64BIT)
2152     ix86_expand_move (TImode, operands);
2153   else
2154     ix86_expand_vector_move (TImode, operands);
2155   DONE;
2156 })
2157
2158 (define_insn "*movti_internal"
2159   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2160         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2161   "TARGET_SSE && !TARGET_64BIT
2162    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2163 {
2164   switch (which_alternative)
2165     {
2166     case 0:
2167       if (get_attr_mode (insn) == MODE_V4SF)
2168         return "xorps\t%0, %0";
2169       else
2170         return "pxor\t%0, %0";
2171     case 1:
2172     case 2:
2173       if (get_attr_mode (insn) == MODE_V4SF)
2174         return "movaps\t{%1, %0|%0, %1}";
2175       else
2176         return "movdqa\t{%1, %0|%0, %1}";
2177     default:
2178       gcc_unreachable ();
2179     }
2180 }
2181   [(set_attr "type" "sselog1,ssemov,ssemov")
2182    (set (attr "mode")
2183         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2184                     (ne (symbol_ref "optimize_size") (const_int 0)))
2185                  (const_string "V4SF")
2186                (and (eq_attr "alternative" "2")
2187                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2188                         (const_int 0)))
2189                  (const_string "V4SF")]
2190               (const_string "TI")))])
2191
2192 (define_insn "*movti_rex64"
2193   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2194         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2195   "TARGET_64BIT
2196    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2197 {
2198   switch (which_alternative)
2199     {
2200     case 0:
2201     case 1:
2202       return "#";
2203     case 2:
2204       if (get_attr_mode (insn) == MODE_V4SF)
2205         return "xorps\t%0, %0";
2206       else
2207         return "pxor\t%0, %0";
2208     case 3:
2209     case 4:
2210       if (get_attr_mode (insn) == MODE_V4SF)
2211         return "movaps\t{%1, %0|%0, %1}";
2212       else
2213         return "movdqa\t{%1, %0|%0, %1}";
2214     default:
2215       gcc_unreachable ();
2216     }
2217 }
2218   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2219    (set (attr "mode")
2220         (cond [(eq_attr "alternative" "2,3")
2221                  (if_then_else
2222                    (ne (symbol_ref "optimize_size")
2223                        (const_int 0))
2224                    (const_string "V4SF")
2225                    (const_string "TI"))
2226                (eq_attr "alternative" "4")
2227                  (if_then_else
2228                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2229                             (const_int 0))
2230                         (ne (symbol_ref "optimize_size")
2231                             (const_int 0)))
2232                    (const_string "V4SF")
2233                    (const_string "TI"))]
2234                (const_string "DI")))])
2235
2236 (define_split
2237   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2238         (match_operand:TI 1 "general_operand" ""))]
2239   "reload_completed && !SSE_REG_P (operands[0])
2240    && !SSE_REG_P (operands[1])"
2241   [(const_int 0)]
2242   "ix86_split_long_move (operands); DONE;")
2243
2244 (define_expand "movsf"
2245   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2246         (match_operand:SF 1 "general_operand" ""))]
2247   ""
2248   "ix86_expand_move (SFmode, operands); DONE;")
2249
2250 (define_insn "*pushsf"
2251   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2252         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2253   "!TARGET_64BIT"
2254 {
2255   /* Anything else should be already split before reg-stack.  */
2256   gcc_assert (which_alternative == 1);
2257   return "push{l}\t%1";
2258 }
2259   [(set_attr "type" "multi,push,multi")
2260    (set_attr "unit" "i387,*,*")
2261    (set_attr "mode" "SF,SI,SF")])
2262
2263 (define_insn "*pushsf_rex64"
2264   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2265         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2266   "TARGET_64BIT"
2267 {
2268   /* Anything else should be already split before reg-stack.  */
2269   gcc_assert (which_alternative == 1);
2270   return "push{q}\t%q1";
2271 }
2272   [(set_attr "type" "multi,push,multi")
2273    (set_attr "unit" "i387,*,*")
2274    (set_attr "mode" "SF,DI,SF")])
2275
2276 (define_split
2277   [(set (match_operand:SF 0 "push_operand" "")
2278         (match_operand:SF 1 "memory_operand" ""))]
2279   "reload_completed
2280    && GET_CODE (operands[1]) == MEM
2281    && constant_pool_reference_p (operands[1])"
2282   [(set (match_dup 0)
2283         (match_dup 1))]
2284   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2285
2286
2287 ;; %%% Kill this when call knows how to work this out.
2288 (define_split
2289   [(set (match_operand:SF 0 "push_operand" "")
2290         (match_operand:SF 1 "any_fp_register_operand" ""))]
2291   "!TARGET_64BIT"
2292   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2293    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2294
2295 (define_split
2296   [(set (match_operand:SF 0 "push_operand" "")
2297         (match_operand:SF 1 "any_fp_register_operand" ""))]
2298   "TARGET_64BIT"
2299   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2300    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2301
2302 (define_insn "*movsf_1"
2303   [(set (match_operand:SF 0 "nonimmediate_operand"
2304           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2305         (match_operand:SF 1 "general_operand"
2306           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2307   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2308    && (reload_in_progress || reload_completed
2309        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2310        || GET_CODE (operands[1]) != CONST_DOUBLE
2311        || memory_operand (operands[0], SFmode))"
2312 {
2313   switch (which_alternative)
2314     {
2315     case 0:
2316       return output_387_reg_move (insn, operands);
2317
2318     case 1:
2319       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2320         return "fstp%z0\t%y0";
2321       else
2322         return "fst%z0\t%y0";
2323
2324     case 2:
2325       return standard_80387_constant_opcode (operands[1]);
2326
2327     case 3:
2328     case 4:
2329       return "mov{l}\t{%1, %0|%0, %1}";
2330     case 5:
2331       if (get_attr_mode (insn) == MODE_TI)
2332         return "pxor\t%0, %0";
2333       else
2334         return "xorps\t%0, %0";
2335     case 6:
2336       if (get_attr_mode (insn) == MODE_V4SF)
2337         return "movaps\t{%1, %0|%0, %1}";
2338       else
2339         return "movss\t{%1, %0|%0, %1}";
2340     case 7:
2341     case 8:
2342       return "movss\t{%1, %0|%0, %1}";
2343
2344     case 9:
2345     case 10:
2346       return "movd\t{%1, %0|%0, %1}";
2347
2348     case 11:
2349       return "movq\t{%1, %0|%0, %1}";
2350
2351     default:
2352       gcc_unreachable ();
2353     }
2354 }
2355   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2356    (set (attr "mode")
2357         (cond [(eq_attr "alternative" "3,4,9,10")
2358                  (const_string "SI")
2359                (eq_attr "alternative" "5")
2360                  (if_then_else
2361                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2362                                  (const_int 0))
2363                              (ne (symbol_ref "TARGET_SSE2")
2364                                  (const_int 0)))
2365                         (eq (symbol_ref "optimize_size")
2366                             (const_int 0)))
2367                    (const_string "TI")
2368                    (const_string "V4SF"))
2369                /* For architectures resolving dependencies on
2370                   whole SSE registers use APS move to break dependency
2371                   chains, otherwise use short move to avoid extra work.
2372
2373                   Do the same for architectures resolving dependencies on
2374                   the parts.  While in DF mode it is better to always handle
2375                   just register parts, the SF mode is different due to lack
2376                   of instructions to load just part of the register.  It is
2377                   better to maintain the whole registers in single format
2378                   to avoid problems on using packed logical operations.  */
2379                (eq_attr "alternative" "6")
2380                  (if_then_else
2381                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2382                             (const_int 0))
2383                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2384                             (const_int 0)))
2385                    (const_string "V4SF")
2386                    (const_string "SF"))
2387                (eq_attr "alternative" "11")
2388                  (const_string "DI")]
2389                (const_string "SF")))])
2390
2391 (define_insn "*swapsf"
2392   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2393         (match_operand:SF 1 "fp_register_operand" "+f"))
2394    (set (match_dup 1)
2395         (match_dup 0))]
2396   "reload_completed || TARGET_80387"
2397 {
2398   if (STACK_TOP_P (operands[0]))
2399     return "fxch\t%1";
2400   else
2401     return "fxch\t%0";
2402 }
2403   [(set_attr "type" "fxch")
2404    (set_attr "mode" "SF")])
2405
2406 (define_expand "movdf"
2407   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2408         (match_operand:DF 1 "general_operand" ""))]
2409   ""
2410   "ix86_expand_move (DFmode, operands); DONE;")
2411
2412 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2413 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2414 ;; On the average, pushdf using integers can be still shorter.  Allow this
2415 ;; pattern for optimize_size too.
2416
2417 (define_insn "*pushdf_nointeger"
2418   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2419         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2420   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2421 {
2422   /* This insn should be already split before reg-stack.  */
2423   gcc_unreachable ();
2424 }
2425   [(set_attr "type" "multi")
2426    (set_attr "unit" "i387,*,*,*")
2427    (set_attr "mode" "DF,SI,SI,DF")])
2428
2429 (define_insn "*pushdf_integer"
2430   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2431         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2432   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2433 {
2434   /* This insn should be already split before reg-stack.  */
2435   gcc_unreachable ();
2436 }
2437   [(set_attr "type" "multi")
2438    (set_attr "unit" "i387,*,*")
2439    (set_attr "mode" "DF,SI,DF")])
2440
2441 ;; %%% Kill this when call knows how to work this out.
2442 (define_split
2443   [(set (match_operand:DF 0 "push_operand" "")
2444         (match_operand:DF 1 "any_fp_register_operand" ""))]
2445   "!TARGET_64BIT && reload_completed"
2446   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2447    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2448   "")
2449
2450 (define_split
2451   [(set (match_operand:DF 0 "push_operand" "")
2452         (match_operand:DF 1 "any_fp_register_operand" ""))]
2453   "TARGET_64BIT && reload_completed"
2454   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2455    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2456   "")
2457
2458 (define_split
2459   [(set (match_operand:DF 0 "push_operand" "")
2460         (match_operand:DF 1 "general_operand" ""))]
2461   "reload_completed"
2462   [(const_int 0)]
2463   "ix86_split_long_move (operands); DONE;")
2464
2465 ;; Moving is usually shorter when only FP registers are used. This separate
2466 ;; movdf pattern avoids the use of integer registers for FP operations
2467 ;; when optimizing for size.
2468
2469 (define_insn "*movdf_nointeger"
2470   [(set (match_operand:DF 0 "nonimmediate_operand"
2471                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2472         (match_operand:DF 1 "general_operand"
2473                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2474   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2475    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2476    && (reload_in_progress || reload_completed
2477        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2478        || GET_CODE (operands[1]) != CONST_DOUBLE
2479        || memory_operand (operands[0], DFmode))"
2480 {
2481   switch (which_alternative)
2482     {
2483     case 0:
2484       return output_387_reg_move (insn, operands);
2485
2486     case 1:
2487       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2488         return "fstp%z0\t%y0";
2489       else
2490         return "fst%z0\t%y0";
2491
2492     case 2:
2493       return standard_80387_constant_opcode (operands[1]);
2494
2495     case 3:
2496     case 4:
2497       return "#";
2498     case 5:
2499       switch (get_attr_mode (insn))
2500         {
2501         case MODE_V4SF:
2502           return "xorps\t%0, %0";
2503         case MODE_V2DF:
2504           return "xorpd\t%0, %0";
2505         case MODE_TI:
2506           return "pxor\t%0, %0";
2507         default:
2508           gcc_unreachable ();
2509         }
2510     case 6:
2511     case 7:
2512     case 8:
2513       switch (get_attr_mode (insn))
2514         {
2515         case MODE_V4SF:
2516           return "movaps\t{%1, %0|%0, %1}";
2517         case MODE_V2DF:
2518           return "movapd\t{%1, %0|%0, %1}";
2519         case MODE_TI:
2520           return "movdqa\t{%1, %0|%0, %1}";
2521         case MODE_DI:
2522           return "movq\t{%1, %0|%0, %1}";
2523         case MODE_DF:
2524           return "movsd\t{%1, %0|%0, %1}";
2525         case MODE_V1DF:
2526           return "movlpd\t{%1, %0|%0, %1}";
2527         case MODE_V2SF:
2528           return "movlps\t{%1, %0|%0, %1}";
2529         default:
2530           gcc_unreachable ();
2531         }
2532
2533     default:
2534       gcc_unreachable ();
2535     }
2536 }
2537   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2538    (set (attr "mode")
2539         (cond [(eq_attr "alternative" "0,1,2")
2540                  (const_string "DF")
2541                (eq_attr "alternative" "3,4")
2542                  (const_string "SI")
2543
2544                /* For SSE1, we have many fewer alternatives.  */
2545                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2546                  (cond [(eq_attr "alternative" "5,6")
2547                           (const_string "V4SF")
2548                        ]
2549                    (const_string "V2SF"))
2550
2551                /* xorps is one byte shorter.  */
2552                (eq_attr "alternative" "5")
2553                  (cond [(ne (symbol_ref "optimize_size")
2554                             (const_int 0))
2555                           (const_string "V4SF")
2556                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2557                             (const_int 0))
2558                           (const_string "TI")
2559                        ]
2560                        (const_string "V2DF"))
2561
2562                /* For architectures resolving dependencies on
2563                   whole SSE registers use APD move to break dependency
2564                   chains, otherwise use short move to avoid extra work.
2565
2566                   movaps encodes one byte shorter.  */
2567                (eq_attr "alternative" "6")
2568                  (cond
2569                    [(ne (symbol_ref "optimize_size")
2570                         (const_int 0))
2571                       (const_string "V4SF")
2572                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2573                         (const_int 0))
2574                       (const_string "V2DF")
2575                    ]
2576                    (const_string "DF"))
2577                /* For architectures resolving dependencies on register
2578                   parts we may avoid extra work to zero out upper part
2579                   of register.  */
2580                (eq_attr "alternative" "7")
2581                  (if_then_else
2582                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2583                        (const_int 0))
2584                    (const_string "V1DF")
2585                    (const_string "DF"))
2586               ]
2587               (const_string "DF")))])
2588
2589 (define_insn "*movdf_integer"
2590   [(set (match_operand:DF 0 "nonimmediate_operand"
2591                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2592         (match_operand:DF 1 "general_operand"
2593                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2594   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2595    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2596    && (reload_in_progress || reload_completed
2597        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2598        || GET_CODE (operands[1]) != CONST_DOUBLE
2599        || memory_operand (operands[0], DFmode))"
2600 {
2601   switch (which_alternative)
2602     {
2603     case 0:
2604       return output_387_reg_move (insn, operands);
2605
2606     case 1:
2607       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2608         return "fstp%z0\t%y0";
2609       else
2610         return "fst%z0\t%y0";
2611
2612     case 2:
2613       return standard_80387_constant_opcode (operands[1]);
2614
2615     case 3:
2616     case 4:
2617       return "#";
2618
2619     case 5:
2620       switch (get_attr_mode (insn))
2621         {
2622         case MODE_V4SF:
2623           return "xorps\t%0, %0";
2624         case MODE_V2DF:
2625           return "xorpd\t%0, %0";
2626         case MODE_TI:
2627           return "pxor\t%0, %0";
2628         default:
2629           gcc_unreachable ();
2630         }
2631     case 6:
2632     case 7:
2633     case 8:
2634       switch (get_attr_mode (insn))
2635         {
2636         case MODE_V4SF:
2637           return "movaps\t{%1, %0|%0, %1}";
2638         case MODE_V2DF:
2639           return "movapd\t{%1, %0|%0, %1}";
2640         case MODE_TI:
2641           return "movdqa\t{%1, %0|%0, %1}";
2642         case MODE_DI:
2643           return "movq\t{%1, %0|%0, %1}";
2644         case MODE_DF:
2645           return "movsd\t{%1, %0|%0, %1}";
2646         case MODE_V1DF:
2647           return "movlpd\t{%1, %0|%0, %1}";
2648         case MODE_V2SF:
2649           return "movlps\t{%1, %0|%0, %1}";
2650         default:
2651           gcc_unreachable ();
2652         }
2653
2654     default:
2655       gcc_unreachable();
2656     }
2657 }
2658   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2659    (set (attr "mode")
2660         (cond [(eq_attr "alternative" "0,1,2")
2661                  (const_string "DF")
2662                (eq_attr "alternative" "3,4")
2663                  (const_string "SI")
2664
2665                /* For SSE1, we have many fewer alternatives.  */
2666                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2667                  (cond [(eq_attr "alternative" "5,6")
2668                           (const_string "V4SF")
2669                        ]
2670                    (const_string "V2SF"))
2671
2672                /* xorps is one byte shorter.  */
2673                (eq_attr "alternative" "5")
2674                  (cond [(ne (symbol_ref "optimize_size")
2675                             (const_int 0))
2676                           (const_string "V4SF")
2677                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2678                             (const_int 0))
2679                           (const_string "TI")
2680                        ]
2681                        (const_string "V2DF"))
2682
2683                /* For architectures resolving dependencies on
2684                   whole SSE registers use APD move to break dependency
2685                   chains, otherwise use short move to avoid extra work.
2686
2687                   movaps encodes one byte shorter.  */
2688                (eq_attr "alternative" "6")
2689                  (cond
2690                    [(ne (symbol_ref "optimize_size")
2691                         (const_int 0))
2692                       (const_string "V4SF")
2693                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2694                         (const_int 0))
2695                       (const_string "V2DF")
2696                    ]
2697                    (const_string "DF"))
2698                /* For architectures resolving dependencies on register
2699                   parts we may avoid extra work to zero out upper part
2700                   of register.  */
2701                (eq_attr "alternative" "7")
2702                  (if_then_else
2703                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2704                        (const_int 0))
2705                    (const_string "V1DF")
2706                    (const_string "DF"))
2707               ]
2708               (const_string "DF")))])
2709
2710 (define_split
2711   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2712         (match_operand:DF 1 "general_operand" ""))]
2713   "reload_completed
2714    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2715    && ! (ANY_FP_REG_P (operands[0]) ||
2716          (GET_CODE (operands[0]) == SUBREG
2717           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2718    && ! (ANY_FP_REG_P (operands[1]) ||
2719          (GET_CODE (operands[1]) == SUBREG
2720           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2721   [(const_int 0)]
2722   "ix86_split_long_move (operands); DONE;")
2723
2724 (define_insn "*swapdf"
2725   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2726         (match_operand:DF 1 "fp_register_operand" "+f"))
2727    (set (match_dup 1)
2728         (match_dup 0))]
2729   "reload_completed || TARGET_80387"
2730 {
2731   if (STACK_TOP_P (operands[0]))
2732     return "fxch\t%1";
2733   else
2734     return "fxch\t%0";
2735 }
2736   [(set_attr "type" "fxch")
2737    (set_attr "mode" "DF")])
2738
2739 (define_expand "movxf"
2740   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2741         (match_operand:XF 1 "general_operand" ""))]
2742   ""
2743   "ix86_expand_move (XFmode, operands); DONE;")
2744
2745 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2746 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2747 ;; Pushing using integer instructions is longer except for constants
2748 ;; and direct memory references.
2749 ;; (assuming that any given constant is pushed only once, but this ought to be
2750 ;;  handled elsewhere).
2751
2752 (define_insn "*pushxf_nointeger"
2753   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2754         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2755   "optimize_size"
2756 {
2757   /* This insn should be already split before reg-stack.  */
2758   gcc_unreachable ();
2759 }
2760   [(set_attr "type" "multi")
2761    (set_attr "unit" "i387,*,*")
2762    (set_attr "mode" "XF,SI,SI")])
2763
2764 (define_insn "*pushxf_integer"
2765   [(set (match_operand:XF 0 "push_operand" "=<,<")
2766         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2767   "!optimize_size"
2768 {
2769   /* This insn should be already split before reg-stack.  */
2770   gcc_unreachable ();
2771 }
2772   [(set_attr "type" "multi")
2773    (set_attr "unit" "i387,*")
2774    (set_attr "mode" "XF,SI")])
2775
2776 (define_split
2777   [(set (match_operand 0 "push_operand" "")
2778         (match_operand 1 "general_operand" ""))]
2779   "reload_completed
2780    && (GET_MODE (operands[0]) == XFmode
2781        || GET_MODE (operands[0]) == DFmode)
2782    && !ANY_FP_REG_P (operands[1])"
2783   [(const_int 0)]
2784   "ix86_split_long_move (operands); DONE;")
2785
2786 (define_split
2787   [(set (match_operand:XF 0 "push_operand" "")
2788         (match_operand:XF 1 "any_fp_register_operand" ""))]
2789   "!TARGET_64BIT"
2790   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2791    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2792   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2793
2794 (define_split
2795   [(set (match_operand:XF 0 "push_operand" "")
2796         (match_operand:XF 1 "any_fp_register_operand" ""))]
2797   "TARGET_64BIT"
2798   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2799    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2800   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2801
2802 ;; Do not use integer registers when optimizing for size
2803 (define_insn "*movxf_nointeger"
2804   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2805         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2806   "optimize_size
2807    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2808    && (reload_in_progress || reload_completed
2809        || GET_CODE (operands[1]) != CONST_DOUBLE
2810        || memory_operand (operands[0], XFmode))"
2811 {
2812   switch (which_alternative)
2813     {
2814     case 0:
2815       return output_387_reg_move (insn, operands);
2816
2817     case 1:
2818       /* There is no non-popping store to memory for XFmode.  So if
2819          we need one, follow the store with a load.  */
2820       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2821         return "fstp%z0\t%y0\;fld%z0\t%y0";
2822       else
2823         return "fstp%z0\t%y0";
2824
2825     case 2:
2826       return standard_80387_constant_opcode (operands[1]);
2827
2828     case 3: case 4:
2829       return "#";
2830     default:
2831       gcc_unreachable ();
2832     }
2833 }
2834   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2835    (set_attr "mode" "XF,XF,XF,SI,SI")])
2836
2837 (define_insn "*movxf_integer"
2838   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2839         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2840   "!optimize_size
2841    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2842    && (reload_in_progress || reload_completed
2843        || GET_CODE (operands[1]) != CONST_DOUBLE
2844        || memory_operand (operands[0], XFmode))"
2845 {
2846   switch (which_alternative)
2847     {
2848     case 0:
2849       return output_387_reg_move (insn, operands);
2850
2851     case 1:
2852       /* There is no non-popping store to memory for XFmode.  So if
2853          we need one, follow the store with a load.  */
2854       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2855         return "fstp%z0\t%y0\;fld%z0\t%y0";
2856       else
2857         return "fstp%z0\t%y0";
2858
2859     case 2:
2860       return standard_80387_constant_opcode (operands[1]);
2861
2862     case 3: case 4:
2863       return "#";
2864
2865     default:
2866       gcc_unreachable ();
2867     }
2868 }
2869   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2870    (set_attr "mode" "XF,XF,XF,SI,SI")])
2871
2872 (define_split
2873   [(set (match_operand 0 "nonimmediate_operand" "")
2874         (match_operand 1 "general_operand" ""))]
2875   "reload_completed
2876    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2877    && GET_MODE (operands[0]) == XFmode
2878    && ! (ANY_FP_REG_P (operands[0]) ||
2879          (GET_CODE (operands[0]) == SUBREG
2880           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2881    && ! (ANY_FP_REG_P (operands[1]) ||
2882          (GET_CODE (operands[1]) == SUBREG
2883           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2884   [(const_int 0)]
2885   "ix86_split_long_move (operands); DONE;")
2886
2887 (define_split
2888   [(set (match_operand 0 "register_operand" "")
2889         (match_operand 1 "memory_operand" ""))]
2890   "reload_completed
2891    && GET_CODE (operands[1]) == MEM
2892    && (GET_MODE (operands[0]) == XFmode
2893        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2894    && constant_pool_reference_p (operands[1])"
2895   [(set (match_dup 0) (match_dup 1))]
2896 {
2897   rtx c = avoid_constant_pool_reference (operands[1]);
2898   rtx r = operands[0];
2899
2900   if (GET_CODE (r) == SUBREG)
2901     r = SUBREG_REG (r);
2902
2903   if (SSE_REG_P (r))
2904     {
2905       if (!standard_sse_constant_p (c))
2906         FAIL;
2907     }
2908   else if (FP_REG_P (r))
2909     {
2910       if (!standard_80387_constant_p (c))
2911         FAIL;
2912     }
2913   else if (MMX_REG_P (r))
2914     FAIL;
2915
2916   operands[1] = c;
2917 })
2918
2919 (define_insn "swapxf"
2920   [(set (match_operand:XF 0 "register_operand" "+f")
2921         (match_operand:XF 1 "register_operand" "+f"))
2922    (set (match_dup 1)
2923         (match_dup 0))]
2924   "TARGET_80387"
2925 {
2926   if (STACK_TOP_P (operands[0]))
2927     return "fxch\t%1";
2928   else
2929     return "fxch\t%0";
2930 }
2931   [(set_attr "type" "fxch")
2932    (set_attr "mode" "XF")])
2933
2934 (define_expand "movtf"
2935   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2936         (match_operand:TF 1 "nonimmediate_operand" ""))]
2937   "TARGET_64BIT"
2938 {
2939   ix86_expand_move (TFmode, operands);
2940   DONE;
2941 })
2942
2943 (define_insn "*movtf_internal"
2944   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2945         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2946   "TARGET_64BIT
2947    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2948 {
2949   switch (which_alternative)
2950     {
2951     case 0:
2952     case 1:
2953       return "#";
2954     case 2:
2955       if (get_attr_mode (insn) == MODE_V4SF)
2956         return "xorps\t%0, %0";
2957       else
2958         return "pxor\t%0, %0";
2959     case 3:
2960     case 4:
2961       if (get_attr_mode (insn) == MODE_V4SF)
2962         return "movaps\t{%1, %0|%0, %1}";
2963       else
2964         return "movdqa\t{%1, %0|%0, %1}";
2965     default:
2966       gcc_unreachable ();
2967     }
2968 }
2969   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2970    (set (attr "mode")
2971         (cond [(eq_attr "alternative" "2,3")
2972                  (if_then_else
2973                    (ne (symbol_ref "optimize_size")
2974                        (const_int 0))
2975                    (const_string "V4SF")
2976                    (const_string "TI"))
2977                (eq_attr "alternative" "4")
2978                  (if_then_else
2979                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2980                             (const_int 0))
2981                         (ne (symbol_ref "optimize_size")
2982                             (const_int 0)))
2983                    (const_string "V4SF")
2984                    (const_string "TI"))]
2985                (const_string "DI")))])
2986
2987 (define_split
2988   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2989         (match_operand:TF 1 "general_operand" ""))]
2990   "reload_completed && !SSE_REG_P (operands[0])
2991    && !SSE_REG_P (operands[1])"
2992   [(const_int 0)]
2993   "ix86_split_long_move (operands); DONE;")
2994 \f
2995 ;; Zero extension instructions
2996
2997 (define_expand "zero_extendhisi2"
2998   [(set (match_operand:SI 0 "register_operand" "")
2999      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3000   ""
3001 {
3002   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3003     {
3004       operands[1] = force_reg (HImode, operands[1]);
3005       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3006       DONE;
3007     }
3008 })
3009
3010 (define_insn "zero_extendhisi2_and"
3011   [(set (match_operand:SI 0 "register_operand" "=r")
3012      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3013    (clobber (reg:CC FLAGS_REG))]
3014   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3015   "#"
3016   [(set_attr "type" "alu1")
3017    (set_attr "mode" "SI")])
3018
3019 (define_split
3020   [(set (match_operand:SI 0 "register_operand" "")
3021         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3022    (clobber (reg:CC FLAGS_REG))]
3023   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3024   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3025               (clobber (reg:CC FLAGS_REG))])]
3026   "")
3027
3028 (define_insn "*zero_extendhisi2_movzwl"
3029   [(set (match_operand:SI 0 "register_operand" "=r")
3030      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3031   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3032   "movz{wl|x}\t{%1, %0|%0, %1}"
3033   [(set_attr "type" "imovx")
3034    (set_attr "mode" "SI")])
3035
3036 (define_expand "zero_extendqihi2"
3037   [(parallel
3038     [(set (match_operand:HI 0 "register_operand" "")
3039        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3040      (clobber (reg:CC FLAGS_REG))])]
3041   ""
3042   "")
3043
3044 (define_insn "*zero_extendqihi2_and"
3045   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3046      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3047    (clobber (reg:CC FLAGS_REG))]
3048   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3049   "#"
3050   [(set_attr "type" "alu1")
3051    (set_attr "mode" "HI")])
3052
3053 (define_insn "*zero_extendqihi2_movzbw_and"
3054   [(set (match_operand:HI 0 "register_operand" "=r,r")
3055      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3056    (clobber (reg:CC FLAGS_REG))]
3057   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3058   "#"
3059   [(set_attr "type" "imovx,alu1")
3060    (set_attr "mode" "HI")])
3061
3062 ; zero extend to SImode here to avoid partial register stalls
3063 (define_insn "*zero_extendqihi2_movzbl"
3064   [(set (match_operand:HI 0 "register_operand" "=r")
3065      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3066   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3067   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3068   [(set_attr "type" "imovx")
3069    (set_attr "mode" "SI")])
3070
3071 ;; For the movzbw case strip only the clobber
3072 (define_split
3073   [(set (match_operand:HI 0 "register_operand" "")
3074         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3075    (clobber (reg:CC FLAGS_REG))]
3076   "reload_completed
3077    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3078    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3079   [(set (match_operand:HI 0 "register_operand" "")
3080         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3081
3082 ;; When source and destination does not overlap, clear destination
3083 ;; first and then do the movb
3084 (define_split
3085   [(set (match_operand:HI 0 "register_operand" "")
3086         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3087    (clobber (reg:CC FLAGS_REG))]
3088   "reload_completed
3089    && ANY_QI_REG_P (operands[0])
3090    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3091    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3092   [(set (match_dup 0) (const_int 0))
3093    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3094   "operands[2] = gen_lowpart (QImode, operands[0]);")
3095
3096 ;; Rest is handled by single and.
3097 (define_split
3098   [(set (match_operand:HI 0 "register_operand" "")
3099         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3100    (clobber (reg:CC FLAGS_REG))]
3101   "reload_completed
3102    && true_regnum (operands[0]) == true_regnum (operands[1])"
3103   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3104               (clobber (reg:CC FLAGS_REG))])]
3105   "")
3106
3107 (define_expand "zero_extendqisi2"
3108   [(parallel
3109     [(set (match_operand:SI 0 "register_operand" "")
3110        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3111      (clobber (reg:CC FLAGS_REG))])]
3112   ""
3113   "")
3114
3115 (define_insn "*zero_extendqisi2_and"
3116   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3117      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3118    (clobber (reg:CC FLAGS_REG))]
3119   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3120   "#"
3121   [(set_attr "type" "alu1")
3122    (set_attr "mode" "SI")])
3123
3124 (define_insn "*zero_extendqisi2_movzbw_and"
3125   [(set (match_operand:SI 0 "register_operand" "=r,r")
3126      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3127    (clobber (reg:CC FLAGS_REG))]
3128   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3129   "#"
3130   [(set_attr "type" "imovx,alu1")
3131    (set_attr "mode" "SI")])
3132
3133 (define_insn "*zero_extendqisi2_movzbw"
3134   [(set (match_operand:SI 0 "register_operand" "=r")
3135      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3136   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3137   "movz{bl|x}\t{%1, %0|%0, %1}"
3138   [(set_attr "type" "imovx")
3139    (set_attr "mode" "SI")])
3140
3141 ;; For the movzbl case strip only the clobber
3142 (define_split
3143   [(set (match_operand:SI 0 "register_operand" "")
3144         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3145    (clobber (reg:CC FLAGS_REG))]
3146   "reload_completed
3147    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3148    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3149   [(set (match_dup 0)
3150         (zero_extend:SI (match_dup 1)))])
3151
3152 ;; When source and destination does not overlap, clear destination
3153 ;; first and then do the movb
3154 (define_split
3155   [(set (match_operand:SI 0 "register_operand" "")
3156         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3157    (clobber (reg:CC FLAGS_REG))]
3158   "reload_completed
3159    && ANY_QI_REG_P (operands[0])
3160    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3161    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3162    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3163   [(set (match_dup 0) (const_int 0))
3164    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3165   "operands[2] = gen_lowpart (QImode, operands[0]);")
3166
3167 ;; Rest is handled by single and.
3168 (define_split
3169   [(set (match_operand:SI 0 "register_operand" "")
3170         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3171    (clobber (reg:CC FLAGS_REG))]
3172   "reload_completed
3173    && true_regnum (operands[0]) == true_regnum (operands[1])"
3174   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3175               (clobber (reg:CC FLAGS_REG))])]
3176   "")
3177
3178 ;; %%% Kill me once multi-word ops are sane.
3179 (define_expand "zero_extendsidi2"
3180   [(set (match_operand:DI 0 "register_operand" "=r")
3181      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3182   ""
3183   "if (!TARGET_64BIT)
3184      {
3185        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3186        DONE;
3187      }
3188   ")
3189
3190 (define_insn "zero_extendsidi2_32"
3191   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3192         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3193    (clobber (reg:CC FLAGS_REG))]
3194   "!TARGET_64BIT"
3195   "@
3196    #
3197    #
3198    #
3199    movd\t{%1, %0|%0, %1}
3200    movd\t{%1, %0|%0, %1}"
3201   [(set_attr "mode" "SI,SI,SI,DI,TI")
3202    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3203
3204 (define_insn "zero_extendsidi2_rex64"
3205   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3206      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3207   "TARGET_64BIT"
3208   "@
3209    mov\t{%k1, %k0|%k0, %k1}
3210    #
3211    movd\t{%1, %0|%0, %1}
3212    movd\t{%1, %0|%0, %1}"
3213   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3214    (set_attr "mode" "SI,DI,SI,SI")])
3215
3216 (define_split
3217   [(set (match_operand:DI 0 "memory_operand" "")
3218      (zero_extend:DI (match_dup 0)))]
3219   "TARGET_64BIT"
3220   [(set (match_dup 4) (const_int 0))]
3221   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3222
3223 (define_split
3224   [(set (match_operand:DI 0 "register_operand" "")
3225         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3226    (clobber (reg:CC FLAGS_REG))]
3227   "!TARGET_64BIT && reload_completed
3228    && true_regnum (operands[0]) == true_regnum (operands[1])"
3229   [(set (match_dup 4) (const_int 0))]
3230   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3231
3232 (define_split
3233   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3234         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3235    (clobber (reg:CC FLAGS_REG))]
3236   "!TARGET_64BIT && reload_completed
3237    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3238   [(set (match_dup 3) (match_dup 1))
3239    (set (match_dup 4) (const_int 0))]
3240   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3241
3242 (define_insn "zero_extendhidi2"
3243   [(set (match_operand:DI 0 "register_operand" "=r")
3244      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3245   "TARGET_64BIT"
3246   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3247   [(set_attr "type" "imovx")
3248    (set_attr "mode" "DI")])
3249
3250 (define_insn "zero_extendqidi2"
3251   [(set (match_operand:DI 0 "register_operand" "=r")
3252      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3253   "TARGET_64BIT"
3254   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3255   [(set_attr "type" "imovx")
3256    (set_attr "mode" "DI")])
3257 \f
3258 ;; Sign extension instructions
3259
3260 (define_expand "extendsidi2"
3261   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3262                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3263               (clobber (reg:CC FLAGS_REG))
3264               (clobber (match_scratch:SI 2 ""))])]
3265   ""
3266 {
3267   if (TARGET_64BIT)
3268     {
3269       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3270       DONE;
3271     }
3272 })
3273
3274 (define_insn "*extendsidi2_1"
3275   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3276         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3277    (clobber (reg:CC FLAGS_REG))
3278    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3279   "!TARGET_64BIT"
3280   "#")
3281
3282 (define_insn "extendsidi2_rex64"
3283   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3284         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3285   "TARGET_64BIT"
3286   "@
3287    {cltq|cdqe}
3288    movs{lq|x}\t{%1,%0|%0, %1}"
3289   [(set_attr "type" "imovx")
3290    (set_attr "mode" "DI")
3291    (set_attr "prefix_0f" "0")
3292    (set_attr "modrm" "0,1")])
3293
3294 (define_insn "extendhidi2"
3295   [(set (match_operand:DI 0 "register_operand" "=r")
3296         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3297   "TARGET_64BIT"
3298   "movs{wq|x}\t{%1,%0|%0, %1}"
3299   [(set_attr "type" "imovx")
3300    (set_attr "mode" "DI")])
3301
3302 (define_insn "extendqidi2"
3303   [(set (match_operand:DI 0 "register_operand" "=r")
3304         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3305   "TARGET_64BIT"
3306   "movs{bq|x}\t{%1,%0|%0, %1}"
3307    [(set_attr "type" "imovx")
3308     (set_attr "mode" "DI")])
3309
3310 ;; Extend to memory case when source register does die.
3311 (define_split
3312   [(set (match_operand:DI 0 "memory_operand" "")
3313         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3314    (clobber (reg:CC FLAGS_REG))
3315    (clobber (match_operand:SI 2 "register_operand" ""))]
3316   "(reload_completed
3317     && dead_or_set_p (insn, operands[1])
3318     && !reg_mentioned_p (operands[1], operands[0]))"
3319   [(set (match_dup 3) (match_dup 1))
3320    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3321               (clobber (reg:CC FLAGS_REG))])
3322    (set (match_dup 4) (match_dup 1))]
3323   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3324
3325 ;; Extend to memory case when source register does not die.
3326 (define_split
3327   [(set (match_operand:DI 0 "memory_operand" "")
3328         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3329    (clobber (reg:CC FLAGS_REG))
3330    (clobber (match_operand:SI 2 "register_operand" ""))]
3331   "reload_completed"
3332   [(const_int 0)]
3333 {
3334   split_di (&operands[0], 1, &operands[3], &operands[4]);
3335
3336   emit_move_insn (operands[3], operands[1]);
3337
3338   /* Generate a cltd if possible and doing so it profitable.  */
3339   if (true_regnum (operands[1]) == 0
3340       && true_regnum (operands[2]) == 1
3341       && (optimize_size || TARGET_USE_CLTD))
3342     {
3343       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3344     }
3345   else
3346     {
3347       emit_move_insn (operands[2], operands[1]);
3348       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3349     }
3350   emit_move_insn (operands[4], operands[2]);
3351   DONE;
3352 })
3353
3354 ;; Extend to register case.  Optimize case where source and destination
3355 ;; registers match and cases where we can use cltd.
3356 (define_split
3357   [(set (match_operand:DI 0 "register_operand" "")
3358         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3359    (clobber (reg:CC FLAGS_REG))
3360    (clobber (match_scratch:SI 2 ""))]
3361   "reload_completed"
3362   [(const_int 0)]
3363 {
3364   split_di (&operands[0], 1, &operands[3], &operands[4]);
3365
3366   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3367     emit_move_insn (operands[3], operands[1]);
3368
3369   /* Generate a cltd if possible and doing so it profitable.  */
3370   if (true_regnum (operands[3]) == 0
3371       && (optimize_size || TARGET_USE_CLTD))
3372     {
3373       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3374       DONE;
3375     }
3376
3377   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3378     emit_move_insn (operands[4], operands[1]);
3379
3380   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3381   DONE;
3382 })
3383
3384 (define_insn "extendhisi2"
3385   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3386         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3387   ""
3388 {
3389   switch (get_attr_prefix_0f (insn))
3390     {
3391     case 0:
3392       return "{cwtl|cwde}";
3393     default:
3394       return "movs{wl|x}\t{%1,%0|%0, %1}";
3395     }
3396 }
3397   [(set_attr "type" "imovx")
3398    (set_attr "mode" "SI")
3399    (set (attr "prefix_0f")
3400      ;; movsx is short decodable while cwtl is vector decoded.
3401      (if_then_else (and (eq_attr "cpu" "!k6")
3402                         (eq_attr "alternative" "0"))
3403         (const_string "0")
3404         (const_string "1")))
3405    (set (attr "modrm")
3406      (if_then_else (eq_attr "prefix_0f" "0")
3407         (const_string "0")
3408         (const_string "1")))])
3409
3410 (define_insn "*extendhisi2_zext"
3411   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3412         (zero_extend:DI
3413           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3414   "TARGET_64BIT"
3415 {
3416   switch (get_attr_prefix_0f (insn))
3417     {
3418     case 0:
3419       return "{cwtl|cwde}";
3420     default:
3421       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3422     }
3423 }
3424   [(set_attr "type" "imovx")
3425    (set_attr "mode" "SI")
3426    (set (attr "prefix_0f")
3427      ;; movsx is short decodable while cwtl is vector decoded.
3428      (if_then_else (and (eq_attr "cpu" "!k6")
3429                         (eq_attr "alternative" "0"))
3430         (const_string "0")
3431         (const_string "1")))
3432    (set (attr "modrm")
3433      (if_then_else (eq_attr "prefix_0f" "0")
3434         (const_string "0")
3435         (const_string "1")))])
3436
3437 (define_insn "extendqihi2"
3438   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3439         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3440   ""
3441 {
3442   switch (get_attr_prefix_0f (insn))
3443     {
3444     case 0:
3445       return "{cbtw|cbw}";
3446     default:
3447       return "movs{bw|x}\t{%1,%0|%0, %1}";
3448     }
3449 }
3450   [(set_attr "type" "imovx")
3451    (set_attr "mode" "HI")
3452    (set (attr "prefix_0f")
3453      ;; movsx is short decodable while cwtl is vector decoded.
3454      (if_then_else (and (eq_attr "cpu" "!k6")
3455                         (eq_attr "alternative" "0"))
3456         (const_string "0")
3457         (const_string "1")))
3458    (set (attr "modrm")
3459      (if_then_else (eq_attr "prefix_0f" "0")
3460         (const_string "0")
3461         (const_string "1")))])
3462
3463 (define_insn "extendqisi2"
3464   [(set (match_operand:SI 0 "register_operand" "=r")
3465         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3466   ""
3467   "movs{bl|x}\t{%1,%0|%0, %1}"
3468    [(set_attr "type" "imovx")
3469     (set_attr "mode" "SI")])
3470
3471 (define_insn "*extendqisi2_zext"
3472   [(set (match_operand:DI 0 "register_operand" "=r")
3473         (zero_extend:DI
3474           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3475   "TARGET_64BIT"
3476   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3477    [(set_attr "type" "imovx")
3478     (set_attr "mode" "SI")])
3479 \f
3480 ;; Conversions between float and double.
3481
3482 ;; These are all no-ops in the model used for the 80387.  So just
3483 ;; emit moves.
3484
3485 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3486 (define_insn "*dummy_extendsfdf2"
3487   [(set (match_operand:DF 0 "push_operand" "=<")
3488         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3489   "0"
3490   "#")
3491
3492 (define_split
3493   [(set (match_operand:DF 0 "push_operand" "")
3494         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3495   "!TARGET_64BIT"
3496   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3497    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3498
3499 (define_split
3500   [(set (match_operand:DF 0 "push_operand" "")
3501         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3502   "TARGET_64BIT"
3503   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3504    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3505
3506 (define_insn "*dummy_extendsfxf2"
3507   [(set (match_operand:XF 0 "push_operand" "=<")
3508         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3509   "0"
3510   "#")
3511
3512 (define_split
3513   [(set (match_operand:XF 0 "push_operand" "")
3514         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3515   ""
3516   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3517    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3518   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3519
3520 (define_split
3521   [(set (match_operand:XF 0 "push_operand" "")
3522         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3523   "TARGET_64BIT"
3524   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3525    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3526   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3527
3528 (define_split
3529   [(set (match_operand:XF 0 "push_operand" "")
3530         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3531   ""
3532   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3533    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3534   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3535
3536 (define_split
3537   [(set (match_operand:XF 0 "push_operand" "")
3538         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3539   "TARGET_64BIT"
3540   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3541    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3542   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3543
3544 (define_expand "extendsfdf2"
3545   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3546         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3547   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3548 {
3549   /* ??? Needed for compress_float_constant since all fp constants
3550      are LEGITIMATE_CONSTANT_P.  */
3551   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3552     {
3553       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3554           && standard_80387_constant_p (operands[1]) > 0)
3555         {
3556           operands[1] = simplify_const_unary_operation
3557             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3558           emit_move_insn_1 (operands[0], operands[1]);
3559           DONE;
3560         }
3561       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3562     }
3563   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3564     operands[1] = force_reg (SFmode, operands[1]);
3565 })
3566
3567 (define_insn "*extendsfdf2_mixed"
3568   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3569         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3570   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3571    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3572 {
3573   switch (which_alternative)
3574     {
3575     case 0:
3576       return output_387_reg_move (insn, operands);
3577
3578     case 1:
3579       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3580         return "fstp%z0\t%y0";
3581       else
3582         return "fst%z0\t%y0";
3583
3584     case 2:
3585       return "cvtss2sd\t{%1, %0|%0, %1}";
3586
3587     default:
3588       gcc_unreachable ();
3589     }
3590 }
3591   [(set_attr "type" "fmov,fmov,ssecvt")
3592    (set_attr "mode" "SF,XF,DF")])
3593
3594 (define_insn "*extendsfdf2_sse"
3595   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3596         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3597   "TARGET_SSE2 && TARGET_SSE_MATH
3598    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3599   "cvtss2sd\t{%1, %0|%0, %1}"
3600   [(set_attr "type" "ssecvt")
3601    (set_attr "mode" "DF")])
3602
3603 (define_insn "*extendsfdf2_i387"
3604   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3605         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3606   "TARGET_80387
3607    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3608 {
3609   switch (which_alternative)
3610     {
3611     case 0:
3612       return output_387_reg_move (insn, operands);
3613
3614     case 1:
3615       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3616         return "fstp%z0\t%y0";
3617       else
3618         return "fst%z0\t%y0";
3619
3620     default:
3621       gcc_unreachable ();
3622     }
3623 }
3624   [(set_attr "type" "fmov")
3625    (set_attr "mode" "SF,XF")])
3626
3627 (define_expand "extendsfxf2"
3628   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3629         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3630   "TARGET_80387"
3631 {
3632   /* ??? Needed for compress_float_constant since all fp constants
3633      are LEGITIMATE_CONSTANT_P.  */
3634   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3635     {
3636       if (standard_80387_constant_p (operands[1]) > 0)
3637         {
3638           operands[1] = simplify_const_unary_operation
3639             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3640           emit_move_insn_1 (operands[0], operands[1]);
3641           DONE;
3642         }
3643       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3644     }
3645   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3646     operands[1] = force_reg (SFmode, operands[1]);
3647 })
3648
3649 (define_insn "*extendsfxf2_i387"
3650   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3651         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3652   "TARGET_80387
3653    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3654 {
3655   switch (which_alternative)
3656     {
3657     case 0:
3658       return output_387_reg_move (insn, operands);
3659
3660     case 1:
3661       /* There is no non-popping store to memory for XFmode.  So if
3662          we need one, follow the store with a load.  */
3663       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3664         return "fstp%z0\t%y0";
3665       else
3666         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3667
3668     default:
3669       gcc_unreachable ();
3670     }
3671 }
3672   [(set_attr "type" "fmov")
3673    (set_attr "mode" "SF,XF")])
3674
3675 (define_expand "extenddfxf2"
3676   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3677         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3678   "TARGET_80387"
3679 {
3680   /* ??? Needed for compress_float_constant since all fp constants
3681      are LEGITIMATE_CONSTANT_P.  */
3682   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3683     {
3684       if (standard_80387_constant_p (operands[1]) > 0)
3685         {
3686           operands[1] = simplify_const_unary_operation
3687             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3688           emit_move_insn_1 (operands[0], operands[1]);
3689           DONE;
3690         }
3691       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3692     }
3693   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3694     operands[1] = force_reg (DFmode, operands[1]);
3695 })
3696
3697 (define_insn "*extenddfxf2_i387"
3698   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3699         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3700   "TARGET_80387
3701    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3702 {
3703   switch (which_alternative)
3704     {
3705     case 0:
3706       return output_387_reg_move (insn, operands);
3707
3708     case 1:
3709       /* There is no non-popping store to memory for XFmode.  So if
3710          we need one, follow the store with a load.  */
3711       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3712         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3713       else
3714         return "fstp%z0\t%y0";
3715
3716     default:
3717       gcc_unreachable ();
3718     }
3719 }
3720   [(set_attr "type" "fmov")
3721    (set_attr "mode" "DF,XF")])
3722
3723 ;; %%% This seems bad bad news.
3724 ;; This cannot output into an f-reg because there is no way to be sure
3725 ;; of truncating in that case.  Otherwise this is just like a simple move
3726 ;; insn.  So we pretend we can output to a reg in order to get better
3727 ;; register preferencing, but we really use a stack slot.
3728
3729 ;; Conversion from DFmode to SFmode.
3730
3731 (define_expand "truncdfsf2"
3732   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3733         (float_truncate:SF
3734           (match_operand:DF 1 "nonimmediate_operand" "")))]
3735   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3736 {
3737   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3738     operands[1] = force_reg (DFmode, operands[1]);
3739
3740   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3741     ;
3742   else if (flag_unsafe_math_optimizations)
3743     ;
3744   else
3745     {
3746       rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3747       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3748       DONE;
3749     }
3750 })
3751
3752 (define_expand "truncdfsf2_with_temp"
3753   [(parallel [(set (match_operand:SF 0 "" "")
3754                    (float_truncate:SF (match_operand:DF 1 "" "")))
3755               (clobber (match_operand:SF 2 "" ""))])]
3756   "")
3757
3758 (define_insn "*truncdfsf_fast_mixed"
3759   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3760         (float_truncate:SF
3761           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3762   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3763 {
3764   switch (which_alternative)
3765     {
3766     case 0:
3767       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3768         return "fstp%z0\t%y0";
3769       else
3770         return "fst%z0\t%y0";
3771     case 1:
3772       return output_387_reg_move (insn, operands);
3773     case 2:
3774       return "cvtsd2ss\t{%1, %0|%0, %1}";
3775     default:
3776       gcc_unreachable ();
3777     }
3778 }
3779   [(set_attr "type" "fmov,fmov,ssecvt")
3780    (set_attr "mode" "SF")])
3781
3782 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3783 ;; because nothing we do here is unsafe.
3784 (define_insn "*truncdfsf_fast_sse"
3785   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3786         (float_truncate:SF
3787           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3788   "TARGET_SSE2 && TARGET_SSE_MATH"
3789   "cvtsd2ss\t{%1, %0|%0, %1}"
3790   [(set_attr "type" "ssecvt")
3791    (set_attr "mode" "SF")])
3792
3793 (define_insn "*truncdfsf_fast_i387"
3794   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3795         (float_truncate:SF
3796           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3797   "TARGET_80387 && flag_unsafe_math_optimizations"
3798   "* return output_387_reg_move (insn, operands);"
3799   [(set_attr "type" "fmov")
3800    (set_attr "mode" "SF")])
3801
3802 (define_insn "*truncdfsf_mixed"
3803   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3804         (float_truncate:SF
3805           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3806    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3807   "TARGET_MIX_SSE_I387"
3808 {
3809   switch (which_alternative)
3810     {
3811     case 0:
3812       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3813         return "fstp%z0\t%y0";
3814       else
3815         return "fst%z0\t%y0";
3816     case 1:
3817       return "#";
3818     case 2:
3819       return "cvtsd2ss\t{%1, %0|%0, %1}";
3820     default:
3821       gcc_unreachable ();
3822     }
3823 }
3824   [(set_attr "type" "fmov,multi,ssecvt")
3825    (set_attr "unit" "*,i387,*")
3826    (set_attr "mode" "SF")])
3827
3828 (define_insn "*truncdfsf_i387"
3829   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3830         (float_truncate:SF
3831           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3832    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3833   "TARGET_80387"
3834 {
3835   switch (which_alternative)
3836     {
3837     case 0:
3838       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3839         return "fstp%z0\t%y0";
3840       else
3841         return "fst%z0\t%y0";
3842     case 1:
3843       return "#";
3844     default:
3845       gcc_unreachable ();
3846     }
3847 }
3848   [(set_attr "type" "fmov,multi")
3849    (set_attr "unit" "*,i387")
3850    (set_attr "mode" "SF")])
3851
3852 (define_insn "*truncdfsf2_i387_1"
3853   [(set (match_operand:SF 0 "memory_operand" "=m")
3854         (float_truncate:SF
3855           (match_operand:DF 1 "register_operand" "f")))]
3856   "TARGET_80387
3857    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3858    && !TARGET_MIX_SSE_I387"
3859 {
3860   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3861     return "fstp%z0\t%y0";
3862   else
3863     return "fst%z0\t%y0";
3864 }
3865   [(set_attr "type" "fmov")
3866    (set_attr "mode" "SF")])
3867
3868 (define_split
3869   [(set (match_operand:SF 0 "register_operand" "")
3870         (float_truncate:SF
3871          (match_operand:DF 1 "fp_register_operand" "")))
3872    (clobber (match_operand 2 "" ""))]
3873   "reload_completed"
3874   [(set (match_dup 2) (match_dup 1))
3875    (set (match_dup 0) (match_dup 2))]
3876 {
3877   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3878 })
3879
3880 ;; Conversion from XFmode to SFmode.
3881
3882 (define_expand "truncxfsf2"
3883   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3884                    (float_truncate:SF
3885                     (match_operand:XF 1 "register_operand" "")))
3886               (clobber (match_dup 2))])]
3887   "TARGET_80387"
3888 {
3889   if (flag_unsafe_math_optimizations)
3890     {
3891       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3892       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3893       if (reg != operands[0])
3894         emit_move_insn (operands[0], reg);
3895       DONE;
3896     }
3897   else
3898     operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3899 })
3900
3901 (define_insn "*truncxfsf2_mixed"
3902   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3903         (float_truncate:SF
3904          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3905    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3906   "TARGET_MIX_SSE_I387"
3907 {
3908   gcc_assert (!which_alternative);
3909   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3910     return "fstp%z0\t%y0";
3911   else
3912     return "fst%z0\t%y0";
3913 }
3914   [(set_attr "type" "fmov,multi,multi,multi")
3915    (set_attr "unit" "*,i387,i387,i387")
3916    (set_attr "mode" "SF")])
3917
3918 (define_insn "truncxfsf2_i387_noop"
3919   [(set (match_operand:SF 0 "register_operand" "=f")
3920         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3921   "TARGET_80387 && flag_unsafe_math_optimizations"
3922 {
3923   return output_387_reg_move (insn, operands);
3924 }
3925   [(set_attr "type" "fmov")
3926    (set_attr "mode" "SF")])
3927
3928 (define_insn "*truncxfsf2_i387"
3929   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3930         (float_truncate:SF
3931          (match_operand:XF 1 "register_operand" "f,f,f")))
3932    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3933   "TARGET_80387"
3934 {
3935   gcc_assert (!which_alternative);
3936   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3937     return "fstp%z0\t%y0";
3938    else
3939      return "fst%z0\t%y0";
3940 }
3941   [(set_attr "type" "fmov,multi,multi")
3942    (set_attr "unit" "*,i387,i387")
3943    (set_attr "mode" "SF")])
3944
3945 (define_insn "*truncxfsf2_i387_1"
3946   [(set (match_operand:SF 0 "memory_operand" "=m")
3947         (float_truncate:SF
3948          (match_operand:XF 1 "register_operand" "f")))]
3949   "TARGET_80387"
3950 {
3951   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3952     return "fstp%z0\t%y0";
3953   else
3954     return "fst%z0\t%y0";
3955 }
3956   [(set_attr "type" "fmov")
3957    (set_attr "mode" "SF")])
3958
3959 (define_split
3960   [(set (match_operand:SF 0 "register_operand" "")
3961         (float_truncate:SF
3962          (match_operand:XF 1 "register_operand" "")))
3963    (clobber (match_operand:SF 2 "memory_operand" ""))]
3964   "TARGET_80387 && reload_completed"
3965   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3966    (set (match_dup 0) (match_dup 2))]
3967   "")
3968
3969 (define_split
3970   [(set (match_operand:SF 0 "memory_operand" "")
3971         (float_truncate:SF
3972          (match_operand:XF 1 "register_operand" "")))
3973    (clobber (match_operand:SF 2 "memory_operand" ""))]
3974   "TARGET_80387"
3975   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3976   "")
3977
3978 ;; Conversion from XFmode to DFmode.
3979
3980 (define_expand "truncxfdf2"
3981   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3982                    (float_truncate:DF
3983                     (match_operand:XF 1 "register_operand" "")))
3984               (clobber (match_dup 2))])]
3985   "TARGET_80387"
3986 {
3987   if (flag_unsafe_math_optimizations)
3988     {
3989       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3990       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3991       if (reg != operands[0])
3992         emit_move_insn (operands[0], reg);
3993       DONE;
3994     }
3995   else
3996     operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL);
3997 })
3998
3999 (define_insn "*truncxfdf2_mixed"
4000   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4001         (float_truncate:DF
4002          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4003    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4004   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4005 {
4006   gcc_assert (!which_alternative);
4007   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4008     return "fstp%z0\t%y0";
4009   else
4010     return "fst%z0\t%y0";
4011 }
4012   [(set_attr "type" "fmov,multi,multi,multi")
4013    (set_attr "unit" "*,i387,i387,i387")
4014    (set_attr "mode" "DF")])
4015
4016 (define_insn "truncxfdf2_i387_noop"
4017   [(set (match_operand:DF 0 "register_operand" "=f")
4018         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4019   "TARGET_80387 && flag_unsafe_math_optimizations"
4020 {
4021   return output_387_reg_move (insn, operands);
4022 }
4023   [(set_attr "type" "fmov")
4024    (set_attr "mode" "DF")])
4025
4026 (define_insn "*truncxfdf2_i387"
4027   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4028         (float_truncate:DF
4029          (match_operand:XF 1 "register_operand" "f,f,f")))
4030    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4031   "TARGET_80387"
4032 {
4033   gcc_assert (!which_alternative);
4034   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4035     return "fstp%z0\t%y0";
4036   else
4037     return "fst%z0\t%y0";
4038 }
4039   [(set_attr "type" "fmov,multi,multi")
4040    (set_attr "unit" "*,i387,i387")
4041    (set_attr "mode" "DF")])
4042
4043 (define_insn "*truncxfdf2_i387_1"
4044   [(set (match_operand:DF 0 "memory_operand" "=m")
4045         (float_truncate:DF
4046           (match_operand:XF 1 "register_operand" "f")))]
4047   "TARGET_80387"
4048 {
4049   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4050     return "fstp%z0\t%y0";
4051   else
4052     return "fst%z0\t%y0";
4053 }
4054   [(set_attr "type" "fmov")
4055    (set_attr "mode" "DF")])
4056
4057 (define_split
4058   [(set (match_operand:DF 0 "register_operand" "")
4059         (float_truncate:DF
4060          (match_operand:XF 1 "register_operand" "")))
4061    (clobber (match_operand:DF 2 "memory_operand" ""))]
4062   "TARGET_80387 && reload_completed"
4063   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4064    (set (match_dup 0) (match_dup 2))]
4065   "")
4066
4067 (define_split
4068   [(set (match_operand:DF 0 "memory_operand" "")
4069         (float_truncate:DF
4070          (match_operand:XF 1 "register_operand" "")))
4071    (clobber (match_operand:DF 2 "memory_operand" ""))]
4072   "TARGET_80387"
4073   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4074   "")
4075 \f
4076 ;; Signed conversion to DImode.
4077
4078 (define_expand "fix_truncxfdi2"
4079   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4080                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4081               (clobber (reg:CC FLAGS_REG))])]
4082   "TARGET_80387"
4083 {
4084   if (TARGET_FISTTP)
4085    {
4086      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4087      DONE;
4088    }
4089 })
4090
4091 (define_expand "fix_trunc<mode>di2"
4092   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4093                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4094               (clobber (reg:CC FLAGS_REG))])]
4095   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4096 {
4097   if (TARGET_FISTTP
4098       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4099    {
4100      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4101      DONE;
4102    }
4103   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4104    {
4105      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4106      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4107      if (out != operands[0])
4108         emit_move_insn (operands[0], out);
4109      DONE;
4110    }
4111 })
4112
4113 ;; Signed conversion to SImode.
4114
4115 (define_expand "fix_truncxfsi2"
4116   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4117                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4118               (clobber (reg:CC FLAGS_REG))])]
4119   "TARGET_80387"
4120 {
4121   if (TARGET_FISTTP)
4122    {
4123      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4124      DONE;
4125    }
4126 })
4127
4128 (define_expand "fix_trunc<mode>si2"
4129   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4130                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4131               (clobber (reg:CC FLAGS_REG))])]
4132   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4133 {
4134   if (TARGET_FISTTP
4135       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4136    {
4137      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4138      DONE;
4139    }
4140   if (SSE_FLOAT_MODE_P (<MODE>mode))
4141    {
4142      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4143      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4144      if (out != operands[0])
4145         emit_move_insn (operands[0], out);
4146      DONE;
4147    }
4148 })
4149
4150 ;; Signed conversion to HImode.
4151
4152 (define_expand "fix_trunc<mode>hi2"
4153   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4154                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4155               (clobber (reg:CC FLAGS_REG))])]
4156   "TARGET_80387
4157    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4158 {
4159   if (TARGET_FISTTP)
4160    {
4161      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4162      DONE;
4163    }
4164 })
4165
4166 ;; When SSE is available, it is always faster to use it!
4167 (define_insn "fix_truncsfdi_sse"
4168   [(set (match_operand:DI 0 "register_operand" "=r,r")
4169         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4170   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4171   "cvttss2si{q}\t{%1, %0|%0, %1}"
4172   [(set_attr "type" "sseicvt")
4173    (set_attr "mode" "SF")
4174    (set_attr "athlon_decode" "double,vector")
4175    (set_attr "amdfam10_decode" "double,double")])
4176
4177 (define_insn "fix_truncdfdi_sse"
4178   [(set (match_operand:DI 0 "register_operand" "=r,r")
4179         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4180   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4181   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4182   [(set_attr "type" "sseicvt")
4183    (set_attr "mode" "DF")
4184    (set_attr "athlon_decode" "double,vector")
4185    (set_attr "amdfam10_decode" "double,double")])
4186
4187 (define_insn "fix_truncsfsi_sse"
4188   [(set (match_operand:SI 0 "register_operand" "=r,r")
4189         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4190   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4191   "cvttss2si\t{%1, %0|%0, %1}"
4192   [(set_attr "type" "sseicvt")
4193    (set_attr "mode" "DF")
4194    (set_attr "athlon_decode" "double,vector")
4195    (set_attr "amdfam10_decode" "double,double")])
4196
4197 (define_insn "fix_truncdfsi_sse"
4198   [(set (match_operand:SI 0 "register_operand" "=r,r")
4199         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4200   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4201   "cvttsd2si\t{%1, %0|%0, %1}"
4202   [(set_attr "type" "sseicvt")
4203    (set_attr "mode" "DF")
4204    (set_attr "athlon_decode" "double,vector")
4205    (set_attr "amdfam10_decode" "double,double")])
4206
4207 ;; Avoid vector decoded forms of the instruction.
4208 (define_peephole2
4209   [(match_scratch:DF 2 "Y")
4210    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4211         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4212   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4213   [(set (match_dup 2) (match_dup 1))
4214    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4215   "")
4216
4217 (define_peephole2
4218   [(match_scratch:SF 2 "x")
4219    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4220         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4221   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4222   [(set (match_dup 2) (match_dup 1))
4223    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4224   "")
4225
4226 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4227   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4228         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4229   "TARGET_FISTTP
4230    && FLOAT_MODE_P (GET_MODE (operands[1]))
4231    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4232          && (TARGET_64BIT || <MODE>mode != DImode))
4233         && TARGET_SSE_MATH)
4234    && !(reload_completed || reload_in_progress)"
4235   "#"
4236   "&& 1"
4237   [(const_int 0)]
4238 {
4239   if (memory_operand (operands[0], VOIDmode))
4240     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4241   else
4242     {
4243       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4244       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4245                                                             operands[1],
4246                                                             operands[2]));
4247     }
4248   DONE;
4249 }
4250   [(set_attr "type" "fisttp")
4251    (set_attr "mode" "<MODE>")])
4252
4253 (define_insn "fix_trunc<mode>_i387_fisttp"
4254   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4255         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4256    (clobber (match_scratch:XF 2 "=&1f"))]
4257   "TARGET_FISTTP
4258    && FLOAT_MODE_P (GET_MODE (operands[1]))
4259    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4260          && (TARGET_64BIT || <MODE>mode != DImode))
4261         && TARGET_SSE_MATH)"
4262   "* return output_fix_trunc (insn, operands, 1);"
4263   [(set_attr "type" "fisttp")
4264    (set_attr "mode" "<MODE>")])
4265
4266 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4267   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4268         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4269    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4270    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4271   "TARGET_FISTTP
4272    && FLOAT_MODE_P (GET_MODE (operands[1]))
4273    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4274         && (TARGET_64BIT || <MODE>mode != DImode))
4275         && TARGET_SSE_MATH)"
4276   "#"
4277   [(set_attr "type" "fisttp")
4278    (set_attr "mode" "<MODE>")])
4279
4280 (define_split
4281   [(set (match_operand:X87MODEI 0 "register_operand" "")
4282         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4283    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4284    (clobber (match_scratch 3 ""))]
4285   "reload_completed"
4286   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4287               (clobber (match_dup 3))])
4288    (set (match_dup 0) (match_dup 2))]
4289   "")
4290
4291 (define_split
4292   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4293         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4294    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4295    (clobber (match_scratch 3 ""))]
4296   "reload_completed"
4297   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4298               (clobber (match_dup 3))])]
4299   "")
4300
4301 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4302 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4303 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4304 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4305 ;; function in i386.c.
4306 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4307   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4308         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4309    (clobber (reg:CC FLAGS_REG))]
4310   "TARGET_80387 && !TARGET_FISTTP
4311    && FLOAT_MODE_P (GET_MODE (operands[1]))
4312    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4313          && (TARGET_64BIT || <MODE>mode != DImode))
4314    && !(reload_completed || reload_in_progress)"
4315   "#"
4316   "&& 1"
4317   [(const_int 0)]
4318 {
4319   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4320
4321   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4322   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4323   if (memory_operand (operands[0], VOIDmode))
4324     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4325                                          operands[2], operands[3]));
4326   else
4327     {
4328       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4329       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4330                                                      operands[2], operands[3],
4331                                                      operands[4]));
4332     }
4333   DONE;
4334 }
4335   [(set_attr "type" "fistp")
4336    (set_attr "i387_cw" "trunc")
4337    (set_attr "mode" "<MODE>")])
4338
4339 (define_insn "fix_truncdi_i387"
4340   [(set (match_operand:DI 0 "memory_operand" "=m")
4341         (fix:DI (match_operand 1 "register_operand" "f")))
4342    (use (match_operand:HI 2 "memory_operand" "m"))
4343    (use (match_operand:HI 3 "memory_operand" "m"))
4344    (clobber (match_scratch:XF 4 "=&1f"))]
4345   "TARGET_80387 && !TARGET_FISTTP
4346    && FLOAT_MODE_P (GET_MODE (operands[1]))
4347    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4348   "* return output_fix_trunc (insn, operands, 0);"
4349   [(set_attr "type" "fistp")
4350    (set_attr "i387_cw" "trunc")
4351    (set_attr "mode" "DI")])
4352
4353 (define_insn "fix_truncdi_i387_with_temp"
4354   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4355         (fix:DI (match_operand 1 "register_operand" "f,f")))
4356    (use (match_operand:HI 2 "memory_operand" "m,m"))
4357    (use (match_operand:HI 3 "memory_operand" "m,m"))
4358    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4359    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4360   "TARGET_80387 && !TARGET_FISTTP
4361    && FLOAT_MODE_P (GET_MODE (operands[1]))
4362    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4363   "#"
4364   [(set_attr "type" "fistp")
4365    (set_attr "i387_cw" "trunc")
4366    (set_attr "mode" "DI")])
4367
4368 (define_split
4369   [(set (match_operand:DI 0 "register_operand" "")
4370         (fix:DI (match_operand 1 "register_operand" "")))
4371    (use (match_operand:HI 2 "memory_operand" ""))
4372    (use (match_operand:HI 3 "memory_operand" ""))
4373    (clobber (match_operand:DI 4 "memory_operand" ""))
4374    (clobber (match_scratch 5 ""))]
4375   "reload_completed"
4376   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4377               (use (match_dup 2))
4378               (use (match_dup 3))
4379               (clobber (match_dup 5))])
4380    (set (match_dup 0) (match_dup 4))]
4381   "")
4382
4383 (define_split
4384   [(set (match_operand:DI 0 "memory_operand" "")
4385         (fix:DI (match_operand 1 "register_operand" "")))
4386    (use (match_operand:HI 2 "memory_operand" ""))
4387    (use (match_operand:HI 3 "memory_operand" ""))
4388    (clobber (match_operand:DI 4 "memory_operand" ""))
4389    (clobber (match_scratch 5 ""))]
4390   "reload_completed"
4391   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4392               (use (match_dup 2))
4393               (use (match_dup 3))
4394               (clobber (match_dup 5))])]
4395   "")
4396
4397 (define_insn "fix_trunc<mode>_i387"
4398   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4399         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4400    (use (match_operand:HI 2 "memory_operand" "m"))
4401    (use (match_operand:HI 3 "memory_operand" "m"))]
4402   "TARGET_80387 && !TARGET_FISTTP
4403    && FLOAT_MODE_P (GET_MODE (operands[1]))
4404    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4405   "* return output_fix_trunc (insn, operands, 0);"
4406   [(set_attr "type" "fistp")
4407    (set_attr "i387_cw" "trunc")
4408    (set_attr "mode" "<MODE>")])
4409
4410 (define_insn "fix_trunc<mode>_i387_with_temp"
4411   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4412         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4413    (use (match_operand:HI 2 "memory_operand" "m,m"))
4414    (use (match_operand:HI 3 "memory_operand" "m,m"))
4415    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4416   "TARGET_80387 && !TARGET_FISTTP
4417    && FLOAT_MODE_P (GET_MODE (operands[1]))
4418    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4419   "#"
4420   [(set_attr "type" "fistp")
4421    (set_attr "i387_cw" "trunc")
4422    (set_attr "mode" "<MODE>")])
4423
4424 (define_split
4425   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4426         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4427    (use (match_operand:HI 2 "memory_operand" ""))
4428    (use (match_operand:HI 3 "memory_operand" ""))
4429    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4430   "reload_completed"
4431   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4432               (use (match_dup 2))
4433               (use (match_dup 3))])
4434    (set (match_dup 0) (match_dup 4))]
4435   "")
4436
4437 (define_split
4438   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4439         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4440    (use (match_operand:HI 2 "memory_operand" ""))
4441    (use (match_operand:HI 3 "memory_operand" ""))
4442    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4443   "reload_completed"
4444   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4445               (use (match_dup 2))
4446               (use (match_dup 3))])]
4447   "")
4448
4449 (define_insn "x86_fnstcw_1"
4450   [(set (match_operand:HI 0 "memory_operand" "=m")
4451         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4452   "TARGET_80387"
4453   "fnstcw\t%0"
4454   [(set_attr "length" "2")
4455    (set_attr "mode" "HI")
4456    (set_attr "unit" "i387")])
4457
4458 (define_insn "x86_fldcw_1"
4459   [(set (reg:HI FPSR_REG)
4460         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4461   "TARGET_80387"
4462   "fldcw\t%0"
4463   [(set_attr "length" "2")
4464    (set_attr "mode" "HI")
4465    (set_attr "unit" "i387")
4466    (set_attr "athlon_decode" "vector")
4467    (set_attr "amdfam10_decode" "vector")])   
4468 \f
4469 ;; Conversion between fixed point and floating point.
4470
4471 ;; Even though we only accept memory inputs, the backend _really_
4472 ;; wants to be able to do this between registers.
4473
4474 (define_expand "floathisf2"
4475   [(set (match_operand:SF 0 "register_operand" "")
4476         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4477   "TARGET_80387 || TARGET_SSE_MATH"
4478 {
4479   if (TARGET_SSE_MATH)
4480     {
4481       emit_insn (gen_floatsisf2 (operands[0],
4482                                  convert_to_mode (SImode, operands[1], 0)));
4483       DONE;
4484     }
4485 })
4486
4487 (define_insn "*floathisf2_i387"
4488   [(set (match_operand:SF 0 "register_operand" "=f,f")
4489         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4490   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4491   "@
4492    fild%z1\t%1
4493    #"
4494   [(set_attr "type" "fmov,multi")
4495    (set_attr "mode" "SF")
4496    (set_attr "unit" "*,i387")
4497    (set_attr "fp_int_src" "true")])
4498
4499 (define_expand "floatsisf2"
4500   [(set (match_operand:SF 0 "register_operand" "")
4501         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4502   "TARGET_80387 || TARGET_SSE_MATH"
4503   "")
4504
4505 (define_insn "*floatsisf2_mixed"
4506   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4507         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4508   "TARGET_MIX_SSE_I387"
4509   "@
4510    fild%z1\t%1
4511    #
4512    cvtsi2ss\t{%1, %0|%0, %1}
4513    cvtsi2ss\t{%1, %0|%0, %1}"
4514   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4515    (set_attr "mode" "SF")
4516    (set_attr "unit" "*,i387,*,*")
4517    (set_attr "athlon_decode" "*,*,vector,double")
4518    (set_attr "amdfam10_decode" "*,*,vector,double")
4519    (set_attr "fp_int_src" "true")])
4520
4521 (define_insn "*floatsisf2_sse"
4522   [(set (match_operand:SF 0 "register_operand" "=x,x")
4523         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4524   "TARGET_SSE_MATH"
4525   "cvtsi2ss\t{%1, %0|%0, %1}"
4526   [(set_attr "type" "sseicvt")
4527    (set_attr "mode" "SF")
4528    (set_attr "athlon_decode" "vector,double")
4529    (set_attr "amdfam10_decode" "vector,double")
4530    (set_attr "fp_int_src" "true")])
4531
4532 (define_insn "*floatsisf2_i387"
4533   [(set (match_operand:SF 0 "register_operand" "=f,f")
4534         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4535   "TARGET_80387"
4536   "@
4537    fild%z1\t%1
4538    #"
4539   [(set_attr "type" "fmov,multi")
4540    (set_attr "mode" "SF")
4541    (set_attr "unit" "*,i387")
4542    (set_attr "fp_int_src" "true")])
4543
4544 (define_expand "floatdisf2"
4545   [(set (match_operand:SF 0 "register_operand" "")
4546         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4547   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4548   "")
4549
4550 (define_insn "*floatdisf2_mixed"
4551   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4552         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4553   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4554   "@
4555    fild%z1\t%1
4556    #
4557    cvtsi2ss{q}\t{%1, %0|%0, %1}
4558    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4559   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4560    (set_attr "mode" "SF")
4561    (set_attr "unit" "*,i387,*,*")
4562    (set_attr "athlon_decode" "*,*,vector,double")
4563    (set_attr "amdfam10_decode" "*,*,vector,double")
4564    (set_attr "fp_int_src" "true")])
4565
4566 (define_insn "*floatdisf2_sse"
4567   [(set (match_operand:SF 0 "register_operand" "=x,x")
4568         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4569   "TARGET_64BIT && TARGET_SSE_MATH"
4570   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4571   [(set_attr "type" "sseicvt")
4572    (set_attr "mode" "SF")
4573    (set_attr "athlon_decode" "vector,double")
4574    (set_attr "amdfam10_decode" "vector,double")
4575    (set_attr "fp_int_src" "true")])
4576
4577 (define_insn "*floatdisf2_i387"
4578   [(set (match_operand:SF 0 "register_operand" "=f,f")
4579         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4580   "TARGET_80387"
4581   "@
4582    fild%z1\t%1
4583    #"
4584   [(set_attr "type" "fmov,multi")
4585    (set_attr "mode" "SF")
4586    (set_attr "unit" "*,i387")
4587    (set_attr "fp_int_src" "true")])
4588
4589 (define_expand "floathidf2"
4590   [(set (match_operand:DF 0 "register_operand" "")
4591         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4592   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4593 {
4594   if (TARGET_SSE2 && TARGET_SSE_MATH)
4595     {
4596       emit_insn (gen_floatsidf2 (operands[0],
4597                                  convert_to_mode (SImode, operands[1], 0)));
4598       DONE;
4599     }
4600 })
4601
4602 (define_insn "*floathidf2_i387"
4603   [(set (match_operand:DF 0 "register_operand" "=f,f")
4604         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4605   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4606   "@
4607    fild%z1\t%1
4608    #"
4609   [(set_attr "type" "fmov,multi")
4610    (set_attr "mode" "DF")
4611    (set_attr "unit" "*,i387")
4612    (set_attr "fp_int_src" "true")])
4613
4614 (define_expand "floatsidf2"
4615   [(set (match_operand:DF 0 "register_operand" "")
4616         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4617   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4618   "")
4619
4620 (define_insn "*floatsidf2_mixed"
4621   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4622         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4623   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4624   "@
4625    fild%z1\t%1
4626    #
4627    cvtsi2sd\t{%1, %0|%0, %1}
4628    cvtsi2sd\t{%1, %0|%0, %1}"
4629   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4630    (set_attr "mode" "DF")
4631    (set_attr "unit" "*,i387,*,*")
4632    (set_attr "athlon_decode" "*,*,double,direct")
4633    (set_attr "amdfam10_decode" "*,*,vector,double")
4634    (set_attr "fp_int_src" "true")])
4635
4636 (define_insn "*floatsidf2_sse"
4637   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4638         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4639   "TARGET_SSE2 && TARGET_SSE_MATH"
4640   "cvtsi2sd\t{%1, %0|%0, %1}"
4641   [(set_attr "type" "sseicvt")
4642    (set_attr "mode" "DF")
4643    (set_attr "athlon_decode" "double,direct")
4644    (set_attr "amdfam10_decode" "vector,double")
4645    (set_attr "fp_int_src" "true")])
4646
4647 (define_insn "*floatsidf2_i387"
4648   [(set (match_operand:DF 0 "register_operand" "=f,f")
4649         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4650   "TARGET_80387"
4651   "@
4652    fild%z1\t%1
4653    #"
4654   [(set_attr "type" "fmov,multi")
4655    (set_attr "mode" "DF")
4656    (set_attr "unit" "*,i387")
4657    (set_attr "fp_int_src" "true")])
4658
4659 (define_expand "floatdidf2"
4660   [(set (match_operand:DF 0 "register_operand" "")
4661         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4662   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4663   "")
4664
4665 (define_insn "*floatdidf2_mixed"
4666   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4667         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4668   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4669   "@
4670    fild%z1\t%1
4671    #
4672    cvtsi2sd{q}\t{%1, %0|%0, %1}
4673    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4674   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4675    (set_attr "mode" "DF")
4676    (set_attr "unit" "*,i387,*,*")
4677    (set_attr "athlon_decode" "*,*,double,direct")
4678    (set_attr "amdfam10_decode" "*,*,vector,double")
4679    (set_attr "fp_int_src" "true")])
4680
4681 (define_insn "*floatdidf2_sse"
4682   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4683         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4684   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4685   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4686   [(set_attr "type" "sseicvt")
4687    (set_attr "mode" "DF")
4688    (set_attr "athlon_decode" "double,direct")
4689    (set_attr "amdfam10_decode" "vector,double")
4690    (set_attr "fp_int_src" "true")])
4691
4692 (define_insn "*floatdidf2_i387"
4693   [(set (match_operand:DF 0 "register_operand" "=f,f")
4694         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4695   "TARGET_80387"
4696   "@
4697    fild%z1\t%1
4698    #"
4699   [(set_attr "type" "fmov,multi")
4700    (set_attr "mode" "DF")
4701    (set_attr "unit" "*,i387")
4702    (set_attr "fp_int_src" "true")])
4703
4704 (define_insn "floathixf2"
4705   [(set (match_operand:XF 0 "register_operand" "=f,f")
4706         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4707   "TARGET_80387"
4708   "@
4709    fild%z1\t%1
4710    #"
4711   [(set_attr "type" "fmov,multi")
4712    (set_attr "mode" "XF")
4713    (set_attr "unit" "*,i387")
4714    (set_attr "fp_int_src" "true")])
4715
4716 (define_insn "floatsixf2"
4717   [(set (match_operand:XF 0 "register_operand" "=f,f")
4718         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4719   "TARGET_80387"
4720   "@
4721    fild%z1\t%1
4722    #"
4723   [(set_attr "type" "fmov,multi")
4724    (set_attr "mode" "XF")
4725    (set_attr "unit" "*,i387")
4726    (set_attr "fp_int_src" "true")])
4727
4728 (define_insn "floatdixf2"
4729   [(set (match_operand:XF 0 "register_operand" "=f,f")
4730         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4731   "TARGET_80387"
4732   "@
4733    fild%z1\t%1
4734    #"
4735   [(set_attr "type" "fmov,multi")
4736    (set_attr "mode" "XF")
4737    (set_attr "unit" "*,i387")
4738    (set_attr "fp_int_src" "true")])
4739
4740 ;; %%% Kill these when reload knows how to do it.
4741 (define_split
4742   [(set (match_operand 0 "fp_register_operand" "")
4743         (float (match_operand 1 "register_operand" "")))]
4744   "reload_completed
4745    && TARGET_80387
4746    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4747   [(const_int 0)]
4748 {
4749   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4750   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4751   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4752   ix86_free_from_memory (GET_MODE (operands[1]));
4753   DONE;
4754 })
4755
4756 (define_expand "floatunssisf2"
4757   [(use (match_operand:SF 0 "register_operand" ""))
4758    (use (match_operand:SI 1 "register_operand" ""))]
4759   "!TARGET_64BIT && TARGET_SSE_MATH"
4760   "x86_emit_floatuns (operands); DONE;")
4761
4762 (define_expand "floatunsdisf2"
4763   [(use (match_operand:SF 0 "register_operand" ""))
4764    (use (match_operand:DI 1 "register_operand" ""))]
4765   "TARGET_64BIT && TARGET_SSE_MATH"
4766   "x86_emit_floatuns (operands); DONE;")
4767
4768 (define_expand "floatunsdidf2"
4769   [(use (match_operand:DF 0 "register_operand" ""))
4770    (use (match_operand:DI 1 "register_operand" ""))]
4771   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4772   "x86_emit_floatuns (operands); DONE;")
4773 \f
4774 ;; SSE extract/set expanders
4775
4776 \f
4777 ;; Add instructions
4778
4779 ;; %%% splits for addditi3
4780
4781 (define_expand "addti3"
4782   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4783         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4784                  (match_operand:TI 2 "x86_64_general_operand" "")))
4785    (clobber (reg:CC FLAGS_REG))]
4786   "TARGET_64BIT"
4787   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4788
4789 (define_insn "*addti3_1"
4790   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4791         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4792                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4793    (clobber (reg:CC FLAGS_REG))]
4794   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4795   "#")
4796
4797 (define_split
4798   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4799         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4800                  (match_operand:TI 2 "x86_64_general_operand" "")))
4801    (clobber (reg:CC FLAGS_REG))]
4802   "TARGET_64BIT && reload_completed"
4803   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4804                                           UNSPEC_ADD_CARRY))
4805               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4806    (parallel [(set (match_dup 3)
4807                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4808                                      (match_dup 4))
4809                             (match_dup 5)))
4810               (clobber (reg:CC FLAGS_REG))])]
4811   "split_ti (operands+0, 1, operands+0, operands+3);
4812    split_ti (operands+1, 1, operands+1, operands+4);
4813    split_ti (operands+2, 1, operands+2, operands+5);")
4814
4815 ;; %%% splits for addsidi3
4816 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4817 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4818 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4819
4820 (define_expand "adddi3"
4821   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4822         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4823                  (match_operand:DI 2 "x86_64_general_operand" "")))
4824    (clobber (reg:CC FLAGS_REG))]
4825   ""
4826   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4827
4828 (define_insn "*adddi3_1"
4829   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4830         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4831                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4832    (clobber (reg:CC FLAGS_REG))]
4833   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4834   "#")
4835
4836 (define_split
4837   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4838         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4839                  (match_operand:DI 2 "general_operand" "")))
4840    (clobber (reg:CC FLAGS_REG))]
4841   "!TARGET_64BIT && reload_completed"
4842   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4843                                           UNSPEC_ADD_CARRY))
4844               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4845    (parallel [(set (match_dup 3)
4846                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4847                                      (match_dup 4))
4848                             (match_dup 5)))
4849               (clobber (reg:CC FLAGS_REG))])]
4850   "split_di (operands+0, 1, operands+0, operands+3);
4851    split_di (operands+1, 1, operands+1, operands+4);
4852    split_di (operands+2, 1, operands+2, operands+5);")
4853
4854 (define_insn "adddi3_carry_rex64"
4855   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4856           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4857                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4858                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4859    (clobber (reg:CC FLAGS_REG))]
4860   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4861   "adc{q}\t{%2, %0|%0, %2}"
4862   [(set_attr "type" "alu")
4863    (set_attr "pent_pair" "pu")
4864    (set_attr "mode" "DI")])
4865
4866 (define_insn "*adddi3_cc_rex64"
4867   [(set (reg:CC FLAGS_REG)
4868         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4869                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4870                    UNSPEC_ADD_CARRY))
4871    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4872         (plus:DI (match_dup 1) (match_dup 2)))]
4873   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4874   "add{q}\t{%2, %0|%0, %2}"
4875   [(set_attr "type" "alu")
4876    (set_attr "mode" "DI")])
4877
4878 (define_insn "addqi3_carry"
4879   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4880           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4881                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4882                    (match_operand:QI 2 "general_operand" "qi,qm")))
4883    (clobber (reg:CC FLAGS_REG))]
4884   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4885   "adc{b}\t{%2, %0|%0, %2}"
4886   [(set_attr "type" "alu")
4887    (set_attr "pent_pair" "pu")
4888    (set_attr "mode" "QI")])
4889
4890 (define_insn "addhi3_carry"
4891   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4892           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4893                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4894                    (match_operand:HI 2 "general_operand" "ri,rm")))
4895    (clobber (reg:CC FLAGS_REG))]
4896   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4897   "adc{w}\t{%2, %0|%0, %2}"
4898   [(set_attr "type" "alu")
4899    (set_attr "pent_pair" "pu")
4900    (set_attr "mode" "HI")])
4901
4902 (define_insn "addsi3_carry"
4903   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4904           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4905                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4906                    (match_operand:SI 2 "general_operand" "ri,rm")))
4907    (clobber (reg:CC FLAGS_REG))]
4908   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4909   "adc{l}\t{%2, %0|%0, %2}"
4910   [(set_attr "type" "alu")
4911    (set_attr "pent_pair" "pu")
4912    (set_attr "mode" "SI")])
4913
4914 (define_insn "*addsi3_carry_zext"
4915   [(set (match_operand:DI 0 "register_operand" "=r")
4916           (zero_extend:DI
4917             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4918                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4919                      (match_operand:SI 2 "general_operand" "rim"))))
4920    (clobber (reg:CC FLAGS_REG))]
4921   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4922   "adc{l}\t{%2, %k0|%k0, %2}"
4923   [(set_attr "type" "alu")
4924    (set_attr "pent_pair" "pu")
4925    (set_attr "mode" "SI")])
4926
4927 (define_insn "*addsi3_cc"
4928   [(set (reg:CC FLAGS_REG)
4929         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4930                     (match_operand:SI 2 "general_operand" "ri,rm")]
4931                    UNSPEC_ADD_CARRY))
4932    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4933         (plus:SI (match_dup 1) (match_dup 2)))]
4934   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4935   "add{l}\t{%2, %0|%0, %2}"
4936   [(set_attr "type" "alu")
4937    (set_attr "mode" "SI")])
4938
4939 (define_insn "addqi3_cc"
4940   [(set (reg:CC FLAGS_REG)
4941         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4942                     (match_operand:QI 2 "general_operand" "qi,qm")]
4943                    UNSPEC_ADD_CARRY))
4944    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4945         (plus:QI (match_dup 1) (match_dup 2)))]
4946   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4947   "add{b}\t{%2, %0|%0, %2}"
4948   [(set_attr "type" "alu")
4949    (set_attr "mode" "QI")])
4950
4951 (define_expand "addsi3"
4952   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4953                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4954                             (match_operand:SI 2 "general_operand" "")))
4955               (clobber (reg:CC FLAGS_REG))])]
4956   ""
4957   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4958
4959 (define_insn "*lea_1"
4960   [(set (match_operand:SI 0 "register_operand" "=r")
4961         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4962   "!TARGET_64BIT"
4963   "lea{l}\t{%a1, %0|%0, %a1}"
4964   [(set_attr "type" "lea")
4965    (set_attr "mode" "SI")])
4966
4967 (define_insn "*lea_1_rex64"
4968   [(set (match_operand:SI 0 "register_operand" "=r")
4969         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4970   "TARGET_64BIT"
4971   "lea{l}\t{%a1, %0|%0, %a1}"
4972   [(set_attr "type" "lea")
4973    (set_attr "mode" "SI")])
4974
4975 (define_insn "*lea_1_zext"
4976   [(set (match_operand:DI 0 "register_operand" "=r")
4977         (zero_extend:DI
4978          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4979   "TARGET_64BIT"
4980   "lea{l}\t{%a1, %k0|%k0, %a1}"
4981   [(set_attr "type" "lea")
4982    (set_attr "mode" "SI")])
4983
4984 (define_insn "*lea_2_rex64"
4985   [(set (match_operand:DI 0 "register_operand" "=r")
4986         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4987   "TARGET_64BIT"
4988   "lea{q}\t{%a1, %0|%0, %a1}"
4989   [(set_attr "type" "lea")
4990    (set_attr "mode" "DI")])
4991
4992 ;; The lea patterns for non-Pmodes needs to be matched by several
4993 ;; insns converted to real lea by splitters.
4994
4995 (define_insn_and_split "*lea_general_1"
4996   [(set (match_operand 0 "register_operand" "=r")
4997         (plus (plus (match_operand 1 "index_register_operand" "l")
4998                     (match_operand 2 "register_operand" "r"))
4999               (match_operand 3 "immediate_operand" "i")))]
5000   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5001     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5002    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5003    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5004    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5005    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5006        || GET_MODE (operands[3]) == VOIDmode)"
5007   "#"
5008   "&& reload_completed"
5009   [(const_int 0)]
5010 {
5011   rtx pat;
5012   operands[0] = gen_lowpart (SImode, operands[0]);
5013   operands[1] = gen_lowpart (Pmode, operands[1]);
5014   operands[2] = gen_lowpart (Pmode, operands[2]);
5015   operands[3] = gen_lowpart (Pmode, operands[3]);
5016   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5017                       operands[3]);
5018   if (Pmode != SImode)
5019     pat = gen_rtx_SUBREG (SImode, pat, 0);
5020   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5021   DONE;
5022 }
5023   [(set_attr "type" "lea")
5024    (set_attr "mode" "SI")])
5025
5026 (define_insn_and_split "*lea_general_1_zext"
5027   [(set (match_operand:DI 0 "register_operand" "=r")
5028         (zero_extend:DI
5029           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5030                             (match_operand:SI 2 "register_operand" "r"))
5031                    (match_operand:SI 3 "immediate_operand" "i"))))]
5032   "TARGET_64BIT"
5033   "#"
5034   "&& reload_completed"
5035   [(set (match_dup 0)
5036         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5037                                                      (match_dup 2))
5038                                             (match_dup 3)) 0)))]
5039 {
5040   operands[1] = gen_lowpart (Pmode, operands[1]);
5041   operands[2] = gen_lowpart (Pmode, operands[2]);
5042   operands[3] = gen_lowpart (Pmode, operands[3]);
5043 }
5044   [(set_attr "type" "lea")
5045    (set_attr "mode" "SI")])
5046
5047 (define_insn_and_split "*lea_general_2"
5048   [(set (match_operand 0 "register_operand" "=r")
5049         (plus (mult (match_operand 1 "index_register_operand" "l")
5050                     (match_operand 2 "const248_operand" "i"))
5051               (match_operand 3 "nonmemory_operand" "ri")))]
5052   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5053     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5054    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5055    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5056    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5057        || GET_MODE (operands[3]) == VOIDmode)"
5058   "#"
5059   "&& reload_completed"
5060   [(const_int 0)]
5061 {
5062   rtx pat;
5063   operands[0] = gen_lowpart (SImode, operands[0]);
5064   operands[1] = gen_lowpart (Pmode, operands[1]);
5065   operands[3] = gen_lowpart (Pmode, operands[3]);
5066   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5067                       operands[3]);
5068   if (Pmode != SImode)
5069     pat = gen_rtx_SUBREG (SImode, pat, 0);
5070   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5071   DONE;
5072 }
5073   [(set_attr "type" "lea")
5074    (set_attr "mode" "SI")])
5075
5076 (define_insn_and_split "*lea_general_2_zext"
5077   [(set (match_operand:DI 0 "register_operand" "=r")
5078         (zero_extend:DI
5079           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5080                             (match_operand:SI 2 "const248_operand" "n"))
5081                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5082   "TARGET_64BIT"
5083   "#"
5084   "&& reload_completed"
5085   [(set (match_dup 0)
5086         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5087                                                      (match_dup 2))
5088                                             (match_dup 3)) 0)))]
5089 {
5090   operands[1] = gen_lowpart (Pmode, operands[1]);
5091   operands[3] = gen_lowpart (Pmode, operands[3]);
5092 }
5093   [(set_attr "type" "lea")
5094    (set_attr "mode" "SI")])
5095
5096 (define_insn_and_split "*lea_general_3"
5097   [(set (match_operand 0 "register_operand" "=r")
5098         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5099                           (match_operand 2 "const248_operand" "i"))
5100                     (match_operand 3 "register_operand" "r"))
5101               (match_operand 4 "immediate_operand" "i")))]
5102   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5103     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5104    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5105    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5106    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5107   "#"
5108   "&& reload_completed"
5109   [(const_int 0)]
5110 {
5111   rtx pat;
5112   operands[0] = gen_lowpart (SImode, operands[0]);
5113   operands[1] = gen_lowpart (Pmode, operands[1]);
5114   operands[3] = gen_lowpart (Pmode, operands[3]);
5115   operands[4] = gen_lowpart (Pmode, operands[4]);
5116   pat = gen_rtx_PLUS (Pmode,
5117                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5118                                                          operands[2]),
5119                                     operands[3]),
5120                       operands[4]);
5121   if (Pmode != SImode)
5122     pat = gen_rtx_SUBREG (SImode, pat, 0);
5123   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5124   DONE;
5125 }
5126   [(set_attr "type" "lea")
5127    (set_attr "mode" "SI")])
5128
5129 (define_insn_and_split "*lea_general_3_zext"
5130   [(set (match_operand:DI 0 "register_operand" "=r")
5131         (zero_extend:DI
5132           (plus:SI (plus:SI (mult:SI
5133                               (match_operand:SI 1 "index_register_operand" "l")
5134                               (match_operand:SI 2 "const248_operand" "n"))
5135                             (match_operand:SI 3 "register_operand" "r"))
5136                    (match_operand:SI 4 "immediate_operand" "i"))))]
5137   "TARGET_64BIT"
5138   "#"
5139   "&& reload_completed"
5140   [(set (match_dup 0)
5141         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5142                                                               (match_dup 2))
5143                                                      (match_dup 3))
5144                                             (match_dup 4)) 0)))]
5145 {
5146   operands[1] = gen_lowpart (Pmode, operands[1]);
5147   operands[3] = gen_lowpart (Pmode, operands[3]);
5148   operands[4] = gen_lowpart (Pmode, operands[4]);
5149 }
5150   [(set_attr "type" "lea")
5151    (set_attr "mode" "SI")])
5152
5153 (define_insn "*adddi_1_rex64"
5154   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5155         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5156                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5157    (clobber (reg:CC FLAGS_REG))]
5158   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5159 {
5160   switch (get_attr_type (insn))
5161     {
5162     case TYPE_LEA:
5163       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5164       return "lea{q}\t{%a2, %0|%0, %a2}";
5165
5166     case TYPE_INCDEC:
5167       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5168       if (operands[2] == const1_rtx)
5169         return "inc{q}\t%0";
5170       else
5171         {
5172           gcc_assert (operands[2] == constm1_rtx);
5173           return "dec{q}\t%0";
5174         }
5175
5176     default:
5177       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5178
5179       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5180          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5181       if (GET_CODE (operands[2]) == CONST_INT
5182           /* Avoid overflows.  */
5183           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5184           && (INTVAL (operands[2]) == 128
5185               || (INTVAL (operands[2]) < 0
5186                   && INTVAL (operands[2]) != -128)))
5187         {
5188           operands[2] = GEN_INT (-INTVAL (operands[2]));
5189           return "sub{q}\t{%2, %0|%0, %2}";
5190         }
5191       return "add{q}\t{%2, %0|%0, %2}";
5192     }
5193 }
5194   [(set (attr "type")
5195      (cond [(eq_attr "alternative" "2")
5196               (const_string "lea")
5197             ; Current assemblers are broken and do not allow @GOTOFF in
5198             ; ought but a memory context.
5199             (match_operand:DI 2 "pic_symbolic_operand" "")
5200               (const_string "lea")
5201             (match_operand:DI 2 "incdec_operand" "")
5202               (const_string "incdec")
5203            ]
5204            (const_string "alu")))
5205    (set_attr "mode" "DI")])
5206
5207 ;; Convert lea to the lea pattern to avoid flags dependency.
5208 (define_split
5209   [(set (match_operand:DI 0 "register_operand" "")
5210         (plus:DI (match_operand:DI 1 "register_operand" "")
5211                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5212    (clobber (reg:CC FLAGS_REG))]
5213   "TARGET_64BIT && reload_completed
5214    && true_regnum (operands[0]) != true_regnum (operands[1])"
5215   [(set (match_dup 0)
5216         (plus:DI (match_dup 1)
5217                  (match_dup 2)))]
5218   "")
5219
5220 (define_insn "*adddi_2_rex64"
5221   [(set (reg FLAGS_REG)
5222         (compare
5223           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5224                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5225           (const_int 0)))
5226    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5227         (plus:DI (match_dup 1) (match_dup 2)))]
5228   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5229    && ix86_binary_operator_ok (PLUS, DImode, operands)
5230    /* Current assemblers are broken and do not allow @GOTOFF in
5231       ought but a memory context.  */
5232    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5233 {
5234   switch (get_attr_type (insn))
5235     {
5236     case TYPE_INCDEC:
5237       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5238       if (operands[2] == const1_rtx)
5239         return "inc{q}\t%0";
5240       else
5241         {
5242           gcc_assert (operands[2] == constm1_rtx);
5243           return "dec{q}\t%0";
5244         }
5245
5246     default:
5247       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5248       /* ???? We ought to handle there the 32bit case too
5249          - do we need new constraint?  */
5250       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5251          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5252       if (GET_CODE (operands[2]) == CONST_INT
5253           /* Avoid overflows.  */
5254           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5255           && (INTVAL (operands[2]) == 128
5256               || (INTVAL (operands[2]) < 0
5257                   && INTVAL (operands[2]) != -128)))
5258         {
5259           operands[2] = GEN_INT (-INTVAL (operands[2]));
5260           return "sub{q}\t{%2, %0|%0, %2}";
5261         }
5262       return "add{q}\t{%2, %0|%0, %2}";
5263     }
5264 }
5265   [(set (attr "type")
5266      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5267         (const_string "incdec")
5268         (const_string "alu")))
5269    (set_attr "mode" "DI")])
5270
5271 (define_insn "*adddi_3_rex64"
5272   [(set (reg FLAGS_REG)
5273         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5274                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5275    (clobber (match_scratch:DI 0 "=r"))]
5276   "TARGET_64BIT
5277    && ix86_match_ccmode (insn, CCZmode)
5278    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5279    /* Current assemblers are broken and do not allow @GOTOFF in
5280       ought but a memory context.  */
5281    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5282 {
5283   switch (get_attr_type (insn))
5284     {
5285     case TYPE_INCDEC:
5286       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5287       if (operands[2] == const1_rtx)
5288         return "inc{q}\t%0";
5289       else
5290         {
5291           gcc_assert (operands[2] == constm1_rtx);
5292           return "dec{q}\t%0";
5293         }
5294
5295     default:
5296       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5297       /* ???? We ought to handle there the 32bit case too
5298          - do we need new constraint?  */
5299       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5300          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5301       if (GET_CODE (operands[2]) == CONST_INT
5302           /* Avoid overflows.  */
5303           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5304           && (INTVAL (operands[2]) == 128
5305               || (INTVAL (operands[2]) < 0
5306                   && INTVAL (operands[2]) != -128)))
5307         {
5308           operands[2] = GEN_INT (-INTVAL (operands[2]));
5309           return "sub{q}\t{%2, %0|%0, %2}";
5310         }
5311       return "add{q}\t{%2, %0|%0, %2}";
5312     }
5313 }
5314   [(set (attr "type")
5315      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5316         (const_string "incdec")
5317         (const_string "alu")))
5318    (set_attr "mode" "DI")])
5319
5320 ; For comparisons against 1, -1 and 128, we may generate better code
5321 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5322 ; is matched then.  We can't accept general immediate, because for
5323 ; case of overflows,  the result is messed up.
5324 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5325 ; when negated.
5326 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5327 ; only for comparisons not depending on it.
5328 (define_insn "*adddi_4_rex64"
5329   [(set (reg FLAGS_REG)
5330         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5331                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5332    (clobber (match_scratch:DI 0 "=rm"))]
5333   "TARGET_64BIT
5334    &&  ix86_match_ccmode (insn, CCGCmode)"
5335 {
5336   switch (get_attr_type (insn))
5337     {
5338     case TYPE_INCDEC:
5339       if (operands[2] == constm1_rtx)
5340         return "inc{q}\t%0";
5341       else
5342         {
5343           gcc_assert (operands[2] == const1_rtx);
5344           return "dec{q}\t%0";
5345         }
5346
5347     default:
5348       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5349       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5350          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5351       if ((INTVAL (operands[2]) == -128
5352            || (INTVAL (operands[2]) > 0
5353                && INTVAL (operands[2]) != 128))
5354           /* Avoid overflows.  */
5355           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5356         return "sub{q}\t{%2, %0|%0, %2}";
5357       operands[2] = GEN_INT (-INTVAL (operands[2]));
5358       return "add{q}\t{%2, %0|%0, %2}";
5359     }
5360 }
5361   [(set (attr "type")
5362      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5363         (const_string "incdec")
5364         (const_string "alu")))
5365    (set_attr "mode" "DI")])
5366
5367 (define_insn "*adddi_5_rex64"
5368   [(set (reg FLAGS_REG)
5369         (compare
5370           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5371                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5372           (const_int 0)))
5373    (clobber (match_scratch:DI 0 "=r"))]
5374   "TARGET_64BIT
5375    && ix86_match_ccmode (insn, CCGOCmode)
5376    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5377    /* Current assemblers are broken and do not allow @GOTOFF in
5378       ought but a memory context.  */
5379    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5380 {
5381   switch (get_attr_type (insn))
5382     {
5383     case TYPE_INCDEC:
5384       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5385       if (operands[2] == const1_rtx)
5386         return "inc{q}\t%0";
5387       else
5388         {
5389           gcc_assert (operands[2] == constm1_rtx);
5390           return "dec{q}\t%0";
5391         }
5392
5393     default:
5394       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5395       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5396          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5397       if (GET_CODE (operands[2]) == CONST_INT
5398           /* Avoid overflows.  */
5399           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5400           && (INTVAL (operands[2]) == 128
5401               || (INTVAL (operands[2]) < 0
5402                   && INTVAL (operands[2]) != -128)))
5403         {
5404           operands[2] = GEN_INT (-INTVAL (operands[2]));
5405           return "sub{q}\t{%2, %0|%0, %2}";
5406         }
5407       return "add{q}\t{%2, %0|%0, %2}";
5408     }
5409 }
5410   [(set (attr "type")
5411      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5412         (const_string "incdec")
5413         (const_string "alu")))
5414    (set_attr "mode" "DI")])
5415
5416
5417 (define_insn "*addsi_1"
5418   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5419         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5420                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5421    (clobber (reg:CC FLAGS_REG))]
5422   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5423 {
5424   switch (get_attr_type (insn))
5425     {
5426     case TYPE_LEA:
5427       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5428       return "lea{l}\t{%a2, %0|%0, %a2}";
5429
5430     case TYPE_INCDEC:
5431       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5432       if (operands[2] == const1_rtx)
5433         return "inc{l}\t%0";
5434       else
5435         {
5436           gcc_assert (operands[2] == constm1_rtx);
5437           return "dec{l}\t%0";
5438         }
5439
5440     default:
5441       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5442
5443       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5444          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5445       if (GET_CODE (operands[2]) == CONST_INT
5446           && (INTVAL (operands[2]) == 128
5447               || (INTVAL (operands[2]) < 0
5448                   && INTVAL (operands[2]) != -128)))
5449         {
5450           operands[2] = GEN_INT (-INTVAL (operands[2]));
5451           return "sub{l}\t{%2, %0|%0, %2}";
5452         }
5453       return "add{l}\t{%2, %0|%0, %2}";
5454     }
5455 }
5456   [(set (attr "type")
5457      (cond [(eq_attr "alternative" "2")
5458               (const_string "lea")
5459             ; Current assemblers are broken and do not allow @GOTOFF in
5460             ; ought but a memory context.
5461             (match_operand:SI 2 "pic_symbolic_operand" "")
5462               (const_string "lea")
5463             (match_operand:SI 2 "incdec_operand" "")
5464               (const_string "incdec")
5465            ]
5466            (const_string "alu")))
5467    (set_attr "mode" "SI")])
5468
5469 ;; Convert lea to the lea pattern to avoid flags dependency.
5470 (define_split
5471   [(set (match_operand 0 "register_operand" "")
5472         (plus (match_operand 1 "register_operand" "")
5473               (match_operand 2 "nonmemory_operand" "")))
5474    (clobber (reg:CC FLAGS_REG))]
5475   "reload_completed
5476    && true_regnum (operands[0]) != true_regnum (operands[1])"
5477   [(const_int 0)]
5478 {
5479   rtx pat;
5480   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5481      may confuse gen_lowpart.  */
5482   if (GET_MODE (operands[0]) != Pmode)
5483     {
5484       operands[1] = gen_lowpart (Pmode, operands[1]);
5485       operands[2] = gen_lowpart (Pmode, operands[2]);
5486     }
5487   operands[0] = gen_lowpart (SImode, operands[0]);
5488   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5489   if (Pmode != SImode)
5490     pat = gen_rtx_SUBREG (SImode, pat, 0);
5491   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5492   DONE;
5493 })
5494
5495 ;; It may seem that nonimmediate operand is proper one for operand 1.
5496 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5497 ;; we take care in ix86_binary_operator_ok to not allow two memory
5498 ;; operands so proper swapping will be done in reload.  This allow
5499 ;; patterns constructed from addsi_1 to match.
5500 (define_insn "addsi_1_zext"
5501   [(set (match_operand:DI 0 "register_operand" "=r,r")
5502         (zero_extend:DI
5503           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5504                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5505    (clobber (reg:CC FLAGS_REG))]
5506   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5507 {
5508   switch (get_attr_type (insn))
5509     {
5510     case TYPE_LEA:
5511       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5512       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5513
5514     case TYPE_INCDEC:
5515       if (operands[2] == const1_rtx)
5516         return "inc{l}\t%k0";
5517       else
5518         {
5519           gcc_assert (operands[2] == constm1_rtx);
5520           return "dec{l}\t%k0";
5521         }
5522
5523     default:
5524       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5525          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5526       if (GET_CODE (operands[2]) == CONST_INT
5527           && (INTVAL (operands[2]) == 128
5528               || (INTVAL (operands[2]) < 0
5529                   && INTVAL (operands[2]) != -128)))
5530         {
5531           operands[2] = GEN_INT (-INTVAL (operands[2]));
5532           return "sub{l}\t{%2, %k0|%k0, %2}";
5533         }
5534       return "add{l}\t{%2, %k0|%k0, %2}";
5535     }
5536 }
5537   [(set (attr "type")
5538      (cond [(eq_attr "alternative" "1")
5539               (const_string "lea")
5540             ; Current assemblers are broken and do not allow @GOTOFF in
5541             ; ought but a memory context.
5542             (match_operand:SI 2 "pic_symbolic_operand" "")
5543               (const_string "lea")
5544             (match_operand:SI 2 "incdec_operand" "")
5545               (const_string "incdec")
5546            ]
5547            (const_string "alu")))
5548    (set_attr "mode" "SI")])
5549
5550 ;; Convert lea to the lea pattern to avoid flags dependency.
5551 (define_split
5552   [(set (match_operand:DI 0 "register_operand" "")
5553         (zero_extend:DI
5554           (plus:SI (match_operand:SI 1 "register_operand" "")
5555                    (match_operand:SI 2 "nonmemory_operand" ""))))
5556    (clobber (reg:CC FLAGS_REG))]
5557   "TARGET_64BIT && reload_completed
5558    && true_regnum (operands[0]) != true_regnum (operands[1])"
5559   [(set (match_dup 0)
5560         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5561 {
5562   operands[1] = gen_lowpart (Pmode, operands[1]);
5563   operands[2] = gen_lowpart (Pmode, operands[2]);
5564 })
5565
5566 (define_insn "*addsi_2"
5567   [(set (reg FLAGS_REG)
5568         (compare
5569           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5570                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5571           (const_int 0)))
5572    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5573         (plus:SI (match_dup 1) (match_dup 2)))]
5574   "ix86_match_ccmode (insn, CCGOCmode)
5575    && ix86_binary_operator_ok (PLUS, SImode, operands)
5576    /* Current assemblers are broken and do not allow @GOTOFF in
5577       ought but a memory context.  */
5578    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5579 {
5580   switch (get_attr_type (insn))
5581     {
5582     case TYPE_INCDEC:
5583       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5584       if (operands[2] == const1_rtx)
5585         return "inc{l}\t%0";
5586       else
5587         {
5588           gcc_assert (operands[2] == constm1_rtx);
5589           return "dec{l}\t%0";
5590         }
5591
5592     default:
5593       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5594       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5595          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5596       if (GET_CODE (operands[2]) == CONST_INT
5597           && (INTVAL (operands[2]) == 128
5598               || (INTVAL (operands[2]) < 0
5599                   && INTVAL (operands[2]) != -128)))
5600         {
5601           operands[2] = GEN_INT (-INTVAL (operands[2]));
5602           return "sub{l}\t{%2, %0|%0, %2}";
5603         }
5604       return "add{l}\t{%2, %0|%0, %2}";
5605     }
5606 }
5607   [(set (attr "type")
5608      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5609         (const_string "incdec")
5610         (const_string "alu")))
5611    (set_attr "mode" "SI")])
5612
5613 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5614 (define_insn "*addsi_2_zext"
5615   [(set (reg FLAGS_REG)
5616         (compare
5617           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5618                    (match_operand:SI 2 "general_operand" "rmni"))
5619           (const_int 0)))
5620    (set (match_operand:DI 0 "register_operand" "=r")
5621         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5622   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5623    && ix86_binary_operator_ok (PLUS, SImode, operands)
5624    /* Current assemblers are broken and do not allow @GOTOFF in
5625       ought but a memory context.  */
5626    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5627 {
5628   switch (get_attr_type (insn))
5629     {
5630     case TYPE_INCDEC:
5631       if (operands[2] == const1_rtx)
5632         return "inc{l}\t%k0";
5633       else
5634         {
5635           gcc_assert (operands[2] == constm1_rtx);
5636           return "dec{l}\t%k0";
5637         }
5638
5639     default:
5640       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5641          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5642       if (GET_CODE (operands[2]) == CONST_INT
5643           && (INTVAL (operands[2]) == 128
5644               || (INTVAL (operands[2]) < 0
5645                   && INTVAL (operands[2]) != -128)))
5646         {
5647           operands[2] = GEN_INT (-INTVAL (operands[2]));
5648           return "sub{l}\t{%2, %k0|%k0, %2}";
5649         }
5650       return "add{l}\t{%2, %k0|%k0, %2}";
5651     }
5652 }
5653   [(set (attr "type")
5654      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5655         (const_string "incdec")
5656         (const_string "alu")))
5657    (set_attr "mode" "SI")])
5658
5659 (define_insn "*addsi_3"
5660   [(set (reg FLAGS_REG)
5661         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5662                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5663    (clobber (match_scratch:SI 0 "=r"))]
5664   "ix86_match_ccmode (insn, CCZmode)
5665    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5666    /* Current assemblers are broken and do not allow @GOTOFF in
5667       ought but a memory context.  */
5668    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5669 {
5670   switch (get_attr_type (insn))
5671     {
5672     case TYPE_INCDEC:
5673       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5674       if (operands[2] == const1_rtx)
5675         return "inc{l}\t%0";
5676       else
5677         {
5678           gcc_assert (operands[2] == constm1_rtx);
5679           return "dec{l}\t%0";
5680         }
5681
5682     default:
5683       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5684       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5685          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5686       if (GET_CODE (operands[2]) == CONST_INT
5687           && (INTVAL (operands[2]) == 128
5688               || (INTVAL (operands[2]) < 0
5689                   && INTVAL (operands[2]) != -128)))
5690         {
5691           operands[2] = GEN_INT (-INTVAL (operands[2]));
5692           return "sub{l}\t{%2, %0|%0, %2}";
5693         }
5694       return "add{l}\t{%2, %0|%0, %2}";
5695     }
5696 }
5697   [(set (attr "type")
5698      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5699         (const_string "incdec")
5700         (const_string "alu")))
5701    (set_attr "mode" "SI")])
5702
5703 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5704 (define_insn "*addsi_3_zext"
5705   [(set (reg FLAGS_REG)
5706         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5707                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5708    (set (match_operand:DI 0 "register_operand" "=r")
5709         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5710   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5711    && ix86_binary_operator_ok (PLUS, SImode, operands)
5712    /* Current assemblers are broken and do not allow @GOTOFF in
5713       ought but a memory context.  */
5714    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5715 {
5716   switch (get_attr_type (insn))
5717     {
5718     case TYPE_INCDEC:
5719       if (operands[2] == const1_rtx)
5720         return "inc{l}\t%k0";
5721       else
5722         {
5723           gcc_assert (operands[2] == constm1_rtx);
5724           return "dec{l}\t%k0";
5725         }
5726
5727     default:
5728       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5729          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5730       if (GET_CODE (operands[2]) == CONST_INT
5731           && (INTVAL (operands[2]) == 128
5732               || (INTVAL (operands[2]) < 0
5733                   && INTVAL (operands[2]) != -128)))
5734         {
5735           operands[2] = GEN_INT (-INTVAL (operands[2]));
5736           return "sub{l}\t{%2, %k0|%k0, %2}";
5737         }
5738       return "add{l}\t{%2, %k0|%k0, %2}";
5739     }
5740 }
5741   [(set (attr "type")
5742      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5743         (const_string "incdec")
5744         (const_string "alu")))
5745    (set_attr "mode" "SI")])
5746
5747 ; For comparisons against 1, -1 and 128, we may generate better code
5748 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5749 ; is matched then.  We can't accept general immediate, because for
5750 ; case of overflows,  the result is messed up.
5751 ; This pattern also don't hold of 0x80000000, since the value overflows
5752 ; when negated.
5753 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5754 ; only for comparisons not depending on it.
5755 (define_insn "*addsi_4"
5756   [(set (reg FLAGS_REG)
5757         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5758                  (match_operand:SI 2 "const_int_operand" "n")))
5759    (clobber (match_scratch:SI 0 "=rm"))]
5760   "ix86_match_ccmode (insn, CCGCmode)
5761    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5762 {
5763   switch (get_attr_type (insn))
5764     {
5765     case TYPE_INCDEC:
5766       if (operands[2] == constm1_rtx)
5767         return "inc{l}\t%0";
5768       else
5769         {
5770           gcc_assert (operands[2] == const1_rtx);
5771           return "dec{l}\t%0";
5772         }
5773
5774     default:
5775       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5776       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5777          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5778       if ((INTVAL (operands[2]) == -128
5779            || (INTVAL (operands[2]) > 0
5780                && INTVAL (operands[2]) != 128)))
5781         return "sub{l}\t{%2, %0|%0, %2}";
5782       operands[2] = GEN_INT (-INTVAL (operands[2]));
5783       return "add{l}\t{%2, %0|%0, %2}";
5784     }
5785 }
5786   [(set (attr "type")
5787      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5788         (const_string "incdec")
5789         (const_string "alu")))
5790    (set_attr "mode" "SI")])
5791
5792 (define_insn "*addsi_5"
5793   [(set (reg FLAGS_REG)
5794         (compare
5795           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5796                    (match_operand:SI 2 "general_operand" "rmni"))
5797           (const_int 0)))
5798    (clobber (match_scratch:SI 0 "=r"))]
5799   "ix86_match_ccmode (insn, CCGOCmode)
5800    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5801    /* Current assemblers are broken and do not allow @GOTOFF in
5802       ought but a memory context.  */
5803    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5804 {
5805   switch (get_attr_type (insn))
5806     {
5807     case TYPE_INCDEC:
5808       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809       if (operands[2] == const1_rtx)
5810         return "inc{l}\t%0";
5811       else
5812         {
5813           gcc_assert (operands[2] == constm1_rtx);
5814           return "dec{l}\t%0";
5815         }
5816
5817     default:
5818       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5819       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5820          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5821       if (GET_CODE (operands[2]) == CONST_INT
5822           && (INTVAL (operands[2]) == 128
5823               || (INTVAL (operands[2]) < 0
5824                   && INTVAL (operands[2]) != -128)))
5825         {
5826           operands[2] = GEN_INT (-INTVAL (operands[2]));
5827           return "sub{l}\t{%2, %0|%0, %2}";
5828         }
5829       return "add{l}\t{%2, %0|%0, %2}";
5830     }
5831 }
5832   [(set (attr "type")
5833      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5834         (const_string "incdec")
5835         (const_string "alu")))
5836    (set_attr "mode" "SI")])
5837
5838 (define_expand "addhi3"
5839   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5840                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5841                             (match_operand:HI 2 "general_operand" "")))
5842               (clobber (reg:CC FLAGS_REG))])]
5843   "TARGET_HIMODE_MATH"
5844   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5845
5846 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5847 ;; type optimizations enabled by define-splits.  This is not important
5848 ;; for PII, and in fact harmful because of partial register stalls.
5849
5850 (define_insn "*addhi_1_lea"
5851   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5852         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5853                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5854    (clobber (reg:CC FLAGS_REG))]
5855   "!TARGET_PARTIAL_REG_STALL
5856    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5857 {
5858   switch (get_attr_type (insn))
5859     {
5860     case TYPE_LEA:
5861       return "#";
5862     case TYPE_INCDEC:
5863       if (operands[2] == const1_rtx)
5864         return "inc{w}\t%0";
5865       else
5866         {
5867           gcc_assert (operands[2] == constm1_rtx);
5868           return "dec{w}\t%0";
5869         }
5870
5871     default:
5872       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5873          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5874       if (GET_CODE (operands[2]) == CONST_INT
5875           && (INTVAL (operands[2]) == 128
5876               || (INTVAL (operands[2]) < 0
5877                   && INTVAL (operands[2]) != -128)))
5878         {
5879           operands[2] = GEN_INT (-INTVAL (operands[2]));
5880           return "sub{w}\t{%2, %0|%0, %2}";
5881         }
5882       return "add{w}\t{%2, %0|%0, %2}";
5883     }
5884 }
5885   [(set (attr "type")
5886      (if_then_else (eq_attr "alternative" "2")
5887         (const_string "lea")
5888         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5889            (const_string "incdec")
5890            (const_string "alu"))))
5891    (set_attr "mode" "HI,HI,SI")])
5892
5893 (define_insn "*addhi_1"
5894   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5895         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5896                  (match_operand:HI 2 "general_operand" "ri,rm")))
5897    (clobber (reg:CC FLAGS_REG))]
5898   "TARGET_PARTIAL_REG_STALL
5899    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5900 {
5901   switch (get_attr_type (insn))
5902     {
5903     case TYPE_INCDEC:
5904       if (operands[2] == const1_rtx)
5905         return "inc{w}\t%0";
5906       else
5907         {
5908           gcc_assert (operands[2] == constm1_rtx);
5909           return "dec{w}\t%0";
5910         }
5911
5912     default:
5913       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5914          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5915       if (GET_CODE (operands[2]) == CONST_INT
5916           && (INTVAL (operands[2]) == 128
5917               || (INTVAL (operands[2]) < 0
5918                   && INTVAL (operands[2]) != -128)))
5919         {
5920           operands[2] = GEN_INT (-INTVAL (operands[2]));
5921           return "sub{w}\t{%2, %0|%0, %2}";
5922         }
5923       return "add{w}\t{%2, %0|%0, %2}";
5924     }
5925 }
5926   [(set (attr "type")
5927      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5928         (const_string "incdec")
5929         (const_string "alu")))
5930    (set_attr "mode" "HI")])
5931
5932 (define_insn "*addhi_2"
5933   [(set (reg FLAGS_REG)
5934         (compare
5935           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5936                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5937           (const_int 0)))
5938    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5939         (plus:HI (match_dup 1) (match_dup 2)))]
5940   "ix86_match_ccmode (insn, CCGOCmode)
5941    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5942 {
5943   switch (get_attr_type (insn))
5944     {
5945     case TYPE_INCDEC:
5946       if (operands[2] == const1_rtx)
5947         return "inc{w}\t%0";
5948       else
5949         {
5950           gcc_assert (operands[2] == constm1_rtx);
5951           return "dec{w}\t%0";
5952         }
5953
5954     default:
5955       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5956          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5957       if (GET_CODE (operands[2]) == CONST_INT
5958           && (INTVAL (operands[2]) == 128
5959               || (INTVAL (operands[2]) < 0
5960                   && INTVAL (operands[2]) != -128)))
5961         {
5962           operands[2] = GEN_INT (-INTVAL (operands[2]));
5963           return "sub{w}\t{%2, %0|%0, %2}";
5964         }
5965       return "add{w}\t{%2, %0|%0, %2}";
5966     }
5967 }
5968   [(set (attr "type")
5969      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5970         (const_string "incdec")
5971         (const_string "alu")))
5972    (set_attr "mode" "HI")])
5973
5974 (define_insn "*addhi_3"
5975   [(set (reg FLAGS_REG)
5976         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5977                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5978    (clobber (match_scratch:HI 0 "=r"))]
5979   "ix86_match_ccmode (insn, CCZmode)
5980    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5981 {
5982   switch (get_attr_type (insn))
5983     {
5984     case TYPE_INCDEC:
5985       if (operands[2] == const1_rtx)
5986         return "inc{w}\t%0";
5987       else
5988         {
5989           gcc_assert (operands[2] == constm1_rtx);
5990           return "dec{w}\t%0";
5991         }
5992
5993     default:
5994       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5995          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5996       if (GET_CODE (operands[2]) == CONST_INT
5997           && (INTVAL (operands[2]) == 128
5998               || (INTVAL (operands[2]) < 0
5999                   && INTVAL (operands[2]) != -128)))
6000         {
6001           operands[2] = GEN_INT (-INTVAL (operands[2]));
6002           return "sub{w}\t{%2, %0|%0, %2}";
6003         }
6004       return "add{w}\t{%2, %0|%0, %2}";
6005     }
6006 }
6007   [(set (attr "type")
6008      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6009         (const_string "incdec")
6010         (const_string "alu")))
6011    (set_attr "mode" "HI")])
6012
6013 ; See comments above addsi_4 for details.
6014 (define_insn "*addhi_4"
6015   [(set (reg FLAGS_REG)
6016         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6017                  (match_operand:HI 2 "const_int_operand" "n")))
6018    (clobber (match_scratch:HI 0 "=rm"))]
6019   "ix86_match_ccmode (insn, CCGCmode)
6020    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6021 {
6022   switch (get_attr_type (insn))
6023     {
6024     case TYPE_INCDEC:
6025       if (operands[2] == constm1_rtx)
6026         return "inc{w}\t%0";
6027       else
6028         {
6029           gcc_assert (operands[2] == const1_rtx);
6030           return "dec{w}\t%0";
6031         }
6032
6033     default:
6034       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6035       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6036          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6037       if ((INTVAL (operands[2]) == -128
6038            || (INTVAL (operands[2]) > 0
6039                && INTVAL (operands[2]) != 128)))
6040         return "sub{w}\t{%2, %0|%0, %2}";
6041       operands[2] = GEN_INT (-INTVAL (operands[2]));
6042       return "add{w}\t{%2, %0|%0, %2}";
6043     }
6044 }
6045   [(set (attr "type")
6046      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6047         (const_string "incdec")
6048         (const_string "alu")))
6049    (set_attr "mode" "SI")])
6050
6051
6052 (define_insn "*addhi_5"
6053   [(set (reg FLAGS_REG)
6054         (compare
6055           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6056                    (match_operand:HI 2 "general_operand" "rmni"))
6057           (const_int 0)))
6058    (clobber (match_scratch:HI 0 "=r"))]
6059   "ix86_match_ccmode (insn, CCGOCmode)
6060    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6061 {
6062   switch (get_attr_type (insn))
6063     {
6064     case TYPE_INCDEC:
6065       if (operands[2] == const1_rtx)
6066         return "inc{w}\t%0";
6067       else
6068         {
6069           gcc_assert (operands[2] == constm1_rtx);
6070           return "dec{w}\t%0";
6071         }
6072
6073     default:
6074       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6075          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6076       if (GET_CODE (operands[2]) == CONST_INT
6077           && (INTVAL (operands[2]) == 128
6078               || (INTVAL (operands[2]) < 0
6079                   && INTVAL (operands[2]) != -128)))
6080         {
6081           operands[2] = GEN_INT (-INTVAL (operands[2]));
6082           return "sub{w}\t{%2, %0|%0, %2}";
6083         }
6084       return "add{w}\t{%2, %0|%0, %2}";
6085     }
6086 }
6087   [(set (attr "type")
6088      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6089         (const_string "incdec")
6090         (const_string "alu")))
6091    (set_attr "mode" "HI")])
6092
6093 (define_expand "addqi3"
6094   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6095                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6096                             (match_operand:QI 2 "general_operand" "")))
6097               (clobber (reg:CC FLAGS_REG))])]
6098   "TARGET_QIMODE_MATH"
6099   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6100
6101 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6102 (define_insn "*addqi_1_lea"
6103   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6104         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6105                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6106    (clobber (reg:CC FLAGS_REG))]
6107   "!TARGET_PARTIAL_REG_STALL
6108    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6109 {
6110   int widen = (which_alternative == 2);
6111   switch (get_attr_type (insn))
6112     {
6113     case TYPE_LEA:
6114       return "#";
6115     case TYPE_INCDEC:
6116       if (operands[2] == const1_rtx)
6117         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6118       else
6119         {
6120           gcc_assert (operands[2] == constm1_rtx);
6121           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6122         }
6123
6124     default:
6125       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6126          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6127       if (GET_CODE (operands[2]) == CONST_INT
6128           && (INTVAL (operands[2]) == 128
6129               || (INTVAL (operands[2]) < 0
6130                   && INTVAL (operands[2]) != -128)))
6131         {
6132           operands[2] = GEN_INT (-INTVAL (operands[2]));
6133           if (widen)
6134             return "sub{l}\t{%2, %k0|%k0, %2}";
6135           else
6136             return "sub{b}\t{%2, %0|%0, %2}";
6137         }
6138       if (widen)
6139         return "add{l}\t{%k2, %k0|%k0, %k2}";
6140       else
6141         return "add{b}\t{%2, %0|%0, %2}";
6142     }
6143 }
6144   [(set (attr "type")
6145      (if_then_else (eq_attr "alternative" "3")
6146         (const_string "lea")
6147         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6148            (const_string "incdec")
6149            (const_string "alu"))))
6150    (set_attr "mode" "QI,QI,SI,SI")])
6151
6152 (define_insn "*addqi_1"
6153   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6154         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6155                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6156    (clobber (reg:CC FLAGS_REG))]
6157   "TARGET_PARTIAL_REG_STALL
6158    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6159 {
6160   int widen = (which_alternative == 2);
6161   switch (get_attr_type (insn))
6162     {
6163     case TYPE_INCDEC:
6164       if (operands[2] == const1_rtx)
6165         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6166       else
6167         {
6168           gcc_assert (operands[2] == constm1_rtx);
6169           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6170         }
6171
6172     default:
6173       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6174          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6175       if (GET_CODE (operands[2]) == CONST_INT
6176           && (INTVAL (operands[2]) == 128
6177               || (INTVAL (operands[2]) < 0
6178                   && INTVAL (operands[2]) != -128)))
6179         {
6180           operands[2] = GEN_INT (-INTVAL (operands[2]));
6181           if (widen)
6182             return "sub{l}\t{%2, %k0|%k0, %2}";
6183           else
6184             return "sub{b}\t{%2, %0|%0, %2}";
6185         }
6186       if (widen)
6187         return "add{l}\t{%k2, %k0|%k0, %k2}";
6188       else
6189         return "add{b}\t{%2, %0|%0, %2}";
6190     }
6191 }
6192   [(set (attr "type")
6193      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6194         (const_string "incdec")
6195         (const_string "alu")))
6196    (set_attr "mode" "QI,QI,SI")])
6197
6198 (define_insn "*addqi_1_slp"
6199   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6200         (plus:QI (match_dup 0)
6201                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6202    (clobber (reg:CC FLAGS_REG))]
6203   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6204    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6205 {
6206   switch (get_attr_type (insn))
6207     {
6208     case TYPE_INCDEC:
6209       if (operands[1] == const1_rtx)
6210         return "inc{b}\t%0";
6211       else
6212         {
6213           gcc_assert (operands[1] == constm1_rtx);
6214           return "dec{b}\t%0";
6215         }
6216
6217     default:
6218       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6219       if (GET_CODE (operands[1]) == CONST_INT
6220           && INTVAL (operands[1]) < 0)
6221         {
6222           operands[1] = GEN_INT (-INTVAL (operands[1]));
6223           return "sub{b}\t{%1, %0|%0, %1}";
6224         }
6225       return "add{b}\t{%1, %0|%0, %1}";
6226     }
6227 }
6228   [(set (attr "type")
6229      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6230         (const_string "incdec")
6231         (const_string "alu1")))
6232    (set (attr "memory")
6233      (if_then_else (match_operand 1 "memory_operand" "")
6234         (const_string "load")
6235         (const_string "none")))
6236    (set_attr "mode" "QI")])
6237
6238 (define_insn "*addqi_2"
6239   [(set (reg FLAGS_REG)
6240         (compare
6241           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6242                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6243           (const_int 0)))
6244    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6245         (plus:QI (match_dup 1) (match_dup 2)))]
6246   "ix86_match_ccmode (insn, CCGOCmode)
6247    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6248 {
6249   switch (get_attr_type (insn))
6250     {
6251     case TYPE_INCDEC:
6252       if (operands[2] == const1_rtx)
6253         return "inc{b}\t%0";
6254       else
6255         {
6256           gcc_assert (operands[2] == constm1_rtx
6257                       || (GET_CODE (operands[2]) == CONST_INT
6258                           && INTVAL (operands[2]) == 255));
6259           return "dec{b}\t%0";
6260         }
6261
6262     default:
6263       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6264       if (GET_CODE (operands[2]) == CONST_INT
6265           && INTVAL (operands[2]) < 0)
6266         {
6267           operands[2] = GEN_INT (-INTVAL (operands[2]));
6268           return "sub{b}\t{%2, %0|%0, %2}";
6269         }
6270       return "add{b}\t{%2, %0|%0, %2}";
6271     }
6272 }
6273   [(set (attr "type")
6274      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6275         (const_string "incdec")
6276         (const_string "alu")))
6277    (set_attr "mode" "QI")])
6278
6279 (define_insn "*addqi_3"
6280   [(set (reg FLAGS_REG)
6281         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6282                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6283    (clobber (match_scratch:QI 0 "=q"))]
6284   "ix86_match_ccmode (insn, CCZmode)
6285    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6286 {
6287   switch (get_attr_type (insn))
6288     {
6289     case TYPE_INCDEC:
6290       if (operands[2] == const1_rtx)
6291         return "inc{b}\t%0";
6292       else
6293         {
6294           gcc_assert (operands[2] == constm1_rtx
6295                       || (GET_CODE (operands[2]) == CONST_INT
6296                           && INTVAL (operands[2]) == 255));
6297           return "dec{b}\t%0";
6298         }
6299
6300     default:
6301       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6302       if (GET_CODE (operands[2]) == CONST_INT
6303           && INTVAL (operands[2]) < 0)
6304         {
6305           operands[2] = GEN_INT (-INTVAL (operands[2]));
6306           return "sub{b}\t{%2, %0|%0, %2}";
6307         }
6308       return "add{b}\t{%2, %0|%0, %2}";
6309     }
6310 }
6311   [(set (attr "type")
6312      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6313         (const_string "incdec")
6314         (const_string "alu")))
6315    (set_attr "mode" "QI")])
6316
6317 ; See comments above addsi_4 for details.
6318 (define_insn "*addqi_4"
6319   [(set (reg FLAGS_REG)
6320         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6321                  (match_operand:QI 2 "const_int_operand" "n")))
6322    (clobber (match_scratch:QI 0 "=qm"))]
6323   "ix86_match_ccmode (insn, CCGCmode)
6324    && (INTVAL (operands[2]) & 0xff) != 0x80"
6325 {
6326   switch (get_attr_type (insn))
6327     {
6328     case TYPE_INCDEC:
6329       if (operands[2] == constm1_rtx
6330           || (GET_CODE (operands[2]) == CONST_INT
6331               && INTVAL (operands[2]) == 255))
6332         return "inc{b}\t%0";
6333       else
6334         {
6335           gcc_assert (operands[2] == const1_rtx);
6336           return "dec{b}\t%0";
6337         }
6338
6339     default:
6340       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6341       if (INTVAL (operands[2]) < 0)
6342         {
6343           operands[2] = GEN_INT (-INTVAL (operands[2]));
6344           return "add{b}\t{%2, %0|%0, %2}";
6345         }
6346       return "sub{b}\t{%2, %0|%0, %2}";
6347     }
6348 }
6349   [(set (attr "type")
6350      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6351         (const_string "incdec")
6352         (const_string "alu")))
6353    (set_attr "mode" "QI")])
6354
6355
6356 (define_insn "*addqi_5"
6357   [(set (reg FLAGS_REG)
6358         (compare
6359           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6360                    (match_operand:QI 2 "general_operand" "qmni"))
6361           (const_int 0)))
6362    (clobber (match_scratch:QI 0 "=q"))]
6363   "ix86_match_ccmode (insn, CCGOCmode)
6364    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6365 {
6366   switch (get_attr_type (insn))
6367     {
6368     case TYPE_INCDEC:
6369       if (operands[2] == const1_rtx)
6370         return "inc{b}\t%0";
6371       else
6372         {
6373           gcc_assert (operands[2] == constm1_rtx
6374                       || (GET_CODE (operands[2]) == CONST_INT
6375                           && INTVAL (operands[2]) == 255));
6376           return "dec{b}\t%0";
6377         }
6378
6379     default:
6380       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6381       if (GET_CODE (operands[2]) == CONST_INT
6382           && INTVAL (operands[2]) < 0)
6383         {
6384           operands[2] = GEN_INT (-INTVAL (operands[2]));
6385           return "sub{b}\t{%2, %0|%0, %2}";
6386         }
6387       return "add{b}\t{%2, %0|%0, %2}";
6388     }
6389 }
6390   [(set (attr "type")
6391      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6392         (const_string "incdec")
6393         (const_string "alu")))
6394    (set_attr "mode" "QI")])
6395
6396
6397 (define_insn "addqi_ext_1"
6398   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6399                          (const_int 8)
6400                          (const_int 8))
6401         (plus:SI
6402           (zero_extract:SI
6403             (match_operand 1 "ext_register_operand" "0")
6404             (const_int 8)
6405             (const_int 8))
6406           (match_operand:QI 2 "general_operand" "Qmn")))
6407    (clobber (reg:CC FLAGS_REG))]
6408   "!TARGET_64BIT"
6409 {
6410   switch (get_attr_type (insn))
6411     {
6412     case TYPE_INCDEC:
6413       if (operands[2] == const1_rtx)
6414         return "inc{b}\t%h0";
6415       else
6416         {
6417           gcc_assert (operands[2] == constm1_rtx
6418                       || (GET_CODE (operands[2]) == CONST_INT
6419                           && INTVAL (operands[2]) == 255));
6420           return "dec{b}\t%h0";
6421         }
6422
6423     default:
6424       return "add{b}\t{%2, %h0|%h0, %2}";
6425     }
6426 }
6427   [(set (attr "type")
6428      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6429         (const_string "incdec")
6430         (const_string "alu")))
6431    (set_attr "mode" "QI")])
6432
6433 (define_insn "*addqi_ext_1_rex64"
6434   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6435                          (const_int 8)
6436                          (const_int 8))
6437         (plus:SI
6438           (zero_extract:SI
6439             (match_operand 1 "ext_register_operand" "0")
6440             (const_int 8)
6441             (const_int 8))
6442           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6443    (clobber (reg:CC FLAGS_REG))]
6444   "TARGET_64BIT"
6445 {
6446   switch (get_attr_type (insn))
6447     {
6448     case TYPE_INCDEC:
6449       if (operands[2] == const1_rtx)
6450         return "inc{b}\t%h0";
6451       else
6452         {
6453           gcc_assert (operands[2] == constm1_rtx
6454                       || (GET_CODE (operands[2]) == CONST_INT
6455                           && INTVAL (operands[2]) == 255));
6456           return "dec{b}\t%h0";
6457         }
6458
6459     default:
6460       return "add{b}\t{%2, %h0|%h0, %2}";
6461     }
6462 }
6463   [(set (attr "type")
6464      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6465         (const_string "incdec")
6466         (const_string "alu")))
6467    (set_attr "mode" "QI")])
6468
6469 (define_insn "*addqi_ext_2"
6470   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6471                          (const_int 8)
6472                          (const_int 8))
6473         (plus:SI
6474           (zero_extract:SI
6475             (match_operand 1 "ext_register_operand" "%0")
6476             (const_int 8)
6477             (const_int 8))
6478           (zero_extract:SI
6479             (match_operand 2 "ext_register_operand" "Q")
6480             (const_int 8)
6481             (const_int 8))))
6482    (clobber (reg:CC FLAGS_REG))]
6483   ""
6484   "add{b}\t{%h2, %h0|%h0, %h2}"
6485   [(set_attr "type" "alu")
6486    (set_attr "mode" "QI")])
6487
6488 ;; The patterns that match these are at the end of this file.
6489
6490 (define_expand "addxf3"
6491   [(set (match_operand:XF 0 "register_operand" "")
6492         (plus:XF (match_operand:XF 1 "register_operand" "")
6493                  (match_operand:XF 2 "register_operand" "")))]
6494   "TARGET_80387"
6495   "")
6496
6497 (define_expand "adddf3"
6498   [(set (match_operand:DF 0 "register_operand" "")
6499         (plus:DF (match_operand:DF 1 "register_operand" "")
6500                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6501   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6502   "")
6503
6504 (define_expand "addsf3"
6505   [(set (match_operand:SF 0 "register_operand" "")
6506         (plus:SF (match_operand:SF 1 "register_operand" "")
6507                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6508   "TARGET_80387 || TARGET_SSE_MATH"
6509   "")
6510 \f
6511 ;; Subtract instructions
6512
6513 ;; %%% splits for subditi3
6514
6515 (define_expand "subti3"
6516   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6517                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6518                              (match_operand:TI 2 "x86_64_general_operand" "")))
6519               (clobber (reg:CC FLAGS_REG))])]
6520   "TARGET_64BIT"
6521   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6522
6523 (define_insn "*subti3_1"
6524   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6525         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6526                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6527    (clobber (reg:CC FLAGS_REG))]
6528   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6529   "#")
6530
6531 (define_split
6532   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6533         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6534                   (match_operand:TI 2 "x86_64_general_operand" "")))
6535    (clobber (reg:CC FLAGS_REG))]
6536   "TARGET_64BIT && reload_completed"
6537   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6538               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6539    (parallel [(set (match_dup 3)
6540                    (minus:DI (match_dup 4)
6541                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6542                                       (match_dup 5))))
6543               (clobber (reg:CC FLAGS_REG))])]
6544   "split_ti (operands+0, 1, operands+0, operands+3);
6545    split_ti (operands+1, 1, operands+1, operands+4);
6546    split_ti (operands+2, 1, operands+2, operands+5);")
6547
6548 ;; %%% splits for subsidi3
6549
6550 (define_expand "subdi3"
6551   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6552                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6553                              (match_operand:DI 2 "x86_64_general_operand" "")))
6554               (clobber (reg:CC FLAGS_REG))])]
6555   ""
6556   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6557
6558 (define_insn "*subdi3_1"
6559   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6560         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6561                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6562    (clobber (reg:CC FLAGS_REG))]
6563   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6564   "#")
6565
6566 (define_split
6567   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6568         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6569                   (match_operand:DI 2 "general_operand" "")))
6570    (clobber (reg:CC FLAGS_REG))]
6571   "!TARGET_64BIT && reload_completed"
6572   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6573               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6574    (parallel [(set (match_dup 3)
6575                    (minus:SI (match_dup 4)
6576                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6577                                       (match_dup 5))))
6578               (clobber (reg:CC FLAGS_REG))])]
6579   "split_di (operands+0, 1, operands+0, operands+3);
6580    split_di (operands+1, 1, operands+1, operands+4);
6581    split_di (operands+2, 1, operands+2, operands+5);")
6582
6583 (define_insn "subdi3_carry_rex64"
6584   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6585           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6586             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6587                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6588    (clobber (reg:CC FLAGS_REG))]
6589   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6590   "sbb{q}\t{%2, %0|%0, %2}"
6591   [(set_attr "type" "alu")
6592    (set_attr "pent_pair" "pu")
6593    (set_attr "mode" "DI")])
6594
6595 (define_insn "*subdi_1_rex64"
6596   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6597         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6598                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6599    (clobber (reg:CC FLAGS_REG))]
6600   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6601   "sub{q}\t{%2, %0|%0, %2}"
6602   [(set_attr "type" "alu")
6603    (set_attr "mode" "DI")])
6604
6605 (define_insn "*subdi_2_rex64"
6606   [(set (reg FLAGS_REG)
6607         (compare
6608           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6609                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6610           (const_int 0)))
6611    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6612         (minus:DI (match_dup 1) (match_dup 2)))]
6613   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6614    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6615   "sub{q}\t{%2, %0|%0, %2}"
6616   [(set_attr "type" "alu")
6617    (set_attr "mode" "DI")])
6618
6619 (define_insn "*subdi_3_rex63"
6620   [(set (reg FLAGS_REG)
6621         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6622                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6623    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6624         (minus:DI (match_dup 1) (match_dup 2)))]
6625   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6626    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6627   "sub{q}\t{%2, %0|%0, %2}"
6628   [(set_attr "type" "alu")
6629    (set_attr "mode" "DI")])
6630
6631 (define_insn "subqi3_carry"
6632   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6633           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6634             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6635                (match_operand:QI 2 "general_operand" "qi,qm"))))
6636    (clobber (reg:CC FLAGS_REG))]
6637   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6638   "sbb{b}\t{%2, %0|%0, %2}"
6639   [(set_attr "type" "alu")
6640    (set_attr "pent_pair" "pu")
6641    (set_attr "mode" "QI")])
6642
6643 (define_insn "subhi3_carry"
6644   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6645           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6646             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6647                (match_operand:HI 2 "general_operand" "ri,rm"))))
6648    (clobber (reg:CC FLAGS_REG))]
6649   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6650   "sbb{w}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "pent_pair" "pu")
6653    (set_attr "mode" "HI")])
6654
6655 (define_insn "subsi3_carry"
6656   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6657           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6658             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6659                (match_operand:SI 2 "general_operand" "ri,rm"))))
6660    (clobber (reg:CC FLAGS_REG))]
6661   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6662   "sbb{l}\t{%2, %0|%0, %2}"
6663   [(set_attr "type" "alu")
6664    (set_attr "pent_pair" "pu")
6665    (set_attr "mode" "SI")])
6666
6667 (define_insn "subsi3_carry_zext"
6668   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6669           (zero_extend:DI
6670             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6671               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6672                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6673    (clobber (reg:CC FLAGS_REG))]
6674   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6675   "sbb{l}\t{%2, %k0|%k0, %2}"
6676   [(set_attr "type" "alu")
6677    (set_attr "pent_pair" "pu")
6678    (set_attr "mode" "SI")])
6679
6680 (define_expand "subsi3"
6681   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6682                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6683                              (match_operand:SI 2 "general_operand" "")))
6684               (clobber (reg:CC FLAGS_REG))])]
6685   ""
6686   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6687
6688 (define_insn "*subsi_1"
6689   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6690         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6691                   (match_operand:SI 2 "general_operand" "ri,rm")))
6692    (clobber (reg:CC FLAGS_REG))]
6693   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6694   "sub{l}\t{%2, %0|%0, %2}"
6695   [(set_attr "type" "alu")
6696    (set_attr "mode" "SI")])
6697
6698 (define_insn "*subsi_1_zext"
6699   [(set (match_operand:DI 0 "register_operand" "=r")
6700         (zero_extend:DI
6701           (minus:SI (match_operand:SI 1 "register_operand" "0")
6702                     (match_operand:SI 2 "general_operand" "rim"))))
6703    (clobber (reg:CC FLAGS_REG))]
6704   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6705   "sub{l}\t{%2, %k0|%k0, %2}"
6706   [(set_attr "type" "alu")
6707    (set_attr "mode" "SI")])
6708
6709 (define_insn "*subsi_2"
6710   [(set (reg FLAGS_REG)
6711         (compare
6712           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6713                     (match_operand:SI 2 "general_operand" "ri,rm"))
6714           (const_int 0)))
6715    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6716         (minus:SI (match_dup 1) (match_dup 2)))]
6717   "ix86_match_ccmode (insn, CCGOCmode)
6718    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6719   "sub{l}\t{%2, %0|%0, %2}"
6720   [(set_attr "type" "alu")
6721    (set_attr "mode" "SI")])
6722
6723 (define_insn "*subsi_2_zext"
6724   [(set (reg FLAGS_REG)
6725         (compare
6726           (minus:SI (match_operand:SI 1 "register_operand" "0")
6727                     (match_operand:SI 2 "general_operand" "rim"))
6728           (const_int 0)))
6729    (set (match_operand:DI 0 "register_operand" "=r")
6730         (zero_extend:DI
6731           (minus:SI (match_dup 1)
6732                     (match_dup 2))))]
6733   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6734    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6735   "sub{l}\t{%2, %k0|%k0, %2}"
6736   [(set_attr "type" "alu")
6737    (set_attr "mode" "SI")])
6738
6739 (define_insn "*subsi_3"
6740   [(set (reg FLAGS_REG)
6741         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6742                  (match_operand:SI 2 "general_operand" "ri,rm")))
6743    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6744         (minus:SI (match_dup 1) (match_dup 2)))]
6745   "ix86_match_ccmode (insn, CCmode)
6746    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6747   "sub{l}\t{%2, %0|%0, %2}"
6748   [(set_attr "type" "alu")
6749    (set_attr "mode" "SI")])
6750
6751 (define_insn "*subsi_3_zext"
6752   [(set (reg FLAGS_REG)
6753         (compare (match_operand:SI 1 "register_operand" "0")
6754                  (match_operand:SI 2 "general_operand" "rim")))
6755    (set (match_operand:DI 0 "register_operand" "=r")
6756         (zero_extend:DI
6757           (minus:SI (match_dup 1)
6758                     (match_dup 2))))]
6759   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6760    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6761   "sub{l}\t{%2, %1|%1, %2}"
6762   [(set_attr "type" "alu")
6763    (set_attr "mode" "DI")])
6764
6765 (define_expand "subhi3"
6766   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6767                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6768                              (match_operand:HI 2 "general_operand" "")))
6769               (clobber (reg:CC FLAGS_REG))])]
6770   "TARGET_HIMODE_MATH"
6771   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6772
6773 (define_insn "*subhi_1"
6774   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6775         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6776                   (match_operand:HI 2 "general_operand" "ri,rm")))
6777    (clobber (reg:CC FLAGS_REG))]
6778   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6779   "sub{w}\t{%2, %0|%0, %2}"
6780   [(set_attr "type" "alu")
6781    (set_attr "mode" "HI")])
6782
6783 (define_insn "*subhi_2"
6784   [(set (reg FLAGS_REG)
6785         (compare
6786           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6787                     (match_operand:HI 2 "general_operand" "ri,rm"))
6788           (const_int 0)))
6789    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6790         (minus:HI (match_dup 1) (match_dup 2)))]
6791   "ix86_match_ccmode (insn, CCGOCmode)
6792    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6793   "sub{w}\t{%2, %0|%0, %2}"
6794   [(set_attr "type" "alu")
6795    (set_attr "mode" "HI")])
6796
6797 (define_insn "*subhi_3"
6798   [(set (reg FLAGS_REG)
6799         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6800                  (match_operand:HI 2 "general_operand" "ri,rm")))
6801    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6802         (minus:HI (match_dup 1) (match_dup 2)))]
6803   "ix86_match_ccmode (insn, CCmode)
6804    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6805   "sub{w}\t{%2, %0|%0, %2}"
6806   [(set_attr "type" "alu")
6807    (set_attr "mode" "HI")])
6808
6809 (define_expand "subqi3"
6810   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6811                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6812                              (match_operand:QI 2 "general_operand" "")))
6813               (clobber (reg:CC FLAGS_REG))])]
6814   "TARGET_QIMODE_MATH"
6815   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6816
6817 (define_insn "*subqi_1"
6818   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6819         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6820                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6821    (clobber (reg:CC FLAGS_REG))]
6822   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6823   "sub{b}\t{%2, %0|%0, %2}"
6824   [(set_attr "type" "alu")
6825    (set_attr "mode" "QI")])
6826
6827 (define_insn "*subqi_1_slp"
6828   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6829         (minus:QI (match_dup 0)
6830                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6831    (clobber (reg:CC FLAGS_REG))]
6832   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6833    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6834   "sub{b}\t{%1, %0|%0, %1}"
6835   [(set_attr "type" "alu1")
6836    (set_attr "mode" "QI")])
6837
6838 (define_insn "*subqi_2"
6839   [(set (reg FLAGS_REG)
6840         (compare
6841           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6842                     (match_operand:QI 2 "general_operand" "qi,qm"))
6843           (const_int 0)))
6844    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6845         (minus:HI (match_dup 1) (match_dup 2)))]
6846   "ix86_match_ccmode (insn, CCGOCmode)
6847    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6848   "sub{b}\t{%2, %0|%0, %2}"
6849   [(set_attr "type" "alu")
6850    (set_attr "mode" "QI")])
6851
6852 (define_insn "*subqi_3"
6853   [(set (reg FLAGS_REG)
6854         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6855                  (match_operand:QI 2 "general_operand" "qi,qm")))
6856    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6857         (minus:HI (match_dup 1) (match_dup 2)))]
6858   "ix86_match_ccmode (insn, CCmode)
6859    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6860   "sub{b}\t{%2, %0|%0, %2}"
6861   [(set_attr "type" "alu")
6862    (set_attr "mode" "QI")])
6863
6864 ;; The patterns that match these are at the end of this file.
6865
6866 (define_expand "subxf3"
6867   [(set (match_operand:XF 0 "register_operand" "")
6868         (minus:XF (match_operand:XF 1 "register_operand" "")
6869                   (match_operand:XF 2 "register_operand" "")))]
6870   "TARGET_80387"
6871   "")
6872
6873 (define_expand "subdf3"
6874   [(set (match_operand:DF 0 "register_operand" "")
6875         (minus:DF (match_operand:DF 1 "register_operand" "")
6876                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6877   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6878   "")
6879
6880 (define_expand "subsf3"
6881   [(set (match_operand:SF 0 "register_operand" "")
6882         (minus:SF (match_operand:SF 1 "register_operand" "")
6883                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6884   "TARGET_80387 || TARGET_SSE_MATH"
6885   "")
6886 \f
6887 ;; Multiply instructions
6888
6889 (define_expand "muldi3"
6890   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6891                    (mult:DI (match_operand:DI 1 "register_operand" "")
6892                             (match_operand:DI 2 "x86_64_general_operand" "")))
6893               (clobber (reg:CC FLAGS_REG))])]
6894   "TARGET_64BIT"
6895   "")
6896
6897 ;; On AMDFAM10 
6898 ;; IMUL reg64, reg64, imm8      Direct
6899 ;; IMUL reg64, mem64, imm8      VectorPath
6900 ;; IMUL reg64, reg64, imm32     Direct
6901 ;; IMUL reg64, mem64, imm32     VectorPath 
6902 ;; IMUL reg64, reg64            Direct
6903 ;; IMUL reg64, mem64            Direct
6904
6905 (define_insn "*muldi3_1_rex64"
6906   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6907         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6908                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6909    (clobber (reg:CC FLAGS_REG))]
6910   "TARGET_64BIT
6911    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6912   "@
6913    imul{q}\t{%2, %1, %0|%0, %1, %2}
6914    imul{q}\t{%2, %1, %0|%0, %1, %2}
6915    imul{q}\t{%2, %0|%0, %2}"
6916   [(set_attr "type" "imul")
6917    (set_attr "prefix_0f" "0,0,1")
6918    (set (attr "athlon_decode")
6919         (cond [(eq_attr "cpu" "athlon")
6920                   (const_string "vector")
6921                (eq_attr "alternative" "1")
6922                   (const_string "vector")
6923                (and (eq_attr "alternative" "2")
6924                     (match_operand 1 "memory_operand" ""))
6925                   (const_string "vector")]
6926               (const_string "direct")))
6927    (set (attr "amdfam10_decode")
6928         (cond [(and (eq_attr "alternative" "0,1")
6929                     (match_operand 1 "memory_operand" ""))
6930                   (const_string "vector")]
6931               (const_string "direct")))       
6932    (set_attr "mode" "DI")])
6933
6934 (define_expand "mulsi3"
6935   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6936                    (mult:SI (match_operand:SI 1 "register_operand" "")
6937                             (match_operand:SI 2 "general_operand" "")))
6938               (clobber (reg:CC FLAGS_REG))])]
6939   ""
6940   "")
6941
6942 ;; On AMDFAM10 
6943 ;; IMUL reg32, reg32, imm8      Direct
6944 ;; IMUL reg32, mem32, imm8      VectorPath
6945 ;; IMUL reg32, reg32, imm32     Direct
6946 ;; IMUL reg32, mem32, imm32     VectorPath
6947 ;; IMUL reg32, reg32            Direct
6948 ;; IMUL reg32, mem32            Direct
6949
6950 (define_insn "*mulsi3_1"
6951   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6952         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6953                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6954    (clobber (reg:CC FLAGS_REG))]
6955   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6956   "@
6957    imul{l}\t{%2, %1, %0|%0, %1, %2}
6958    imul{l}\t{%2, %1, %0|%0, %1, %2}
6959    imul{l}\t{%2, %0|%0, %2}"
6960   [(set_attr "type" "imul")
6961    (set_attr "prefix_0f" "0,0,1")
6962    (set (attr "athlon_decode")
6963         (cond [(eq_attr "cpu" "athlon")
6964                   (const_string "vector")
6965                (eq_attr "alternative" "1")
6966                   (const_string "vector")
6967                (and (eq_attr "alternative" "2")
6968                     (match_operand 1 "memory_operand" ""))
6969                   (const_string "vector")]
6970               (const_string "direct")))
6971    (set (attr "amdfam10_decode")
6972         (cond [(and (eq_attr "alternative" "0,1")
6973                     (match_operand 1 "memory_operand" ""))
6974                   (const_string "vector")]
6975               (const_string "direct")))       
6976    (set_attr "mode" "SI")])
6977
6978 (define_insn "*mulsi3_1_zext"
6979   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6980         (zero_extend:DI
6981           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6982                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6983    (clobber (reg:CC FLAGS_REG))]
6984   "TARGET_64BIT
6985    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6986   "@
6987    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6988    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6989    imul{l}\t{%2, %k0|%k0, %2}"
6990   [(set_attr "type" "imul")
6991    (set_attr "prefix_0f" "0,0,1")
6992    (set (attr "athlon_decode")
6993         (cond [(eq_attr "cpu" "athlon")
6994                   (const_string "vector")
6995                (eq_attr "alternative" "1")
6996                   (const_string "vector")
6997                (and (eq_attr "alternative" "2")
6998                     (match_operand 1 "memory_operand" ""))
6999                   (const_string "vector")]
7000               (const_string "direct")))
7001    (set (attr "amdfam10_decode")
7002         (cond [(and (eq_attr "alternative" "0,1")
7003                     (match_operand 1 "memory_operand" ""))
7004                   (const_string "vector")]
7005               (const_string "direct")))       
7006    (set_attr "mode" "SI")])
7007
7008 (define_expand "mulhi3"
7009   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7010                    (mult:HI (match_operand:HI 1 "register_operand" "")
7011                             (match_operand:HI 2 "general_operand" "")))
7012               (clobber (reg:CC FLAGS_REG))])]
7013   "TARGET_HIMODE_MATH"
7014   "")
7015
7016 ;; On AMDFAM10
7017 ;; IMUL reg16, reg16, imm8      VectorPath
7018 ;; IMUL reg16, mem16, imm8      VectorPath
7019 ;; IMUL reg16, reg16, imm16     VectorPath
7020 ;; IMUL reg16, mem16, imm16     VectorPath
7021 ;; IMUL reg16, reg16            Direct
7022 ;; IMUL reg16, mem16            Direct
7023 (define_insn "*mulhi3_1"
7024   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7025         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7026                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7027    (clobber (reg:CC FLAGS_REG))]
7028   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7029   "@
7030    imul{w}\t{%2, %1, %0|%0, %1, %2}
7031    imul{w}\t{%2, %1, %0|%0, %1, %2}
7032    imul{w}\t{%2, %0|%0, %2}"
7033   [(set_attr "type" "imul")
7034    (set_attr "prefix_0f" "0,0,1")
7035    (set (attr "athlon_decode")
7036         (cond [(eq_attr "cpu" "athlon")
7037                   (const_string "vector")
7038                (eq_attr "alternative" "1,2")
7039                   (const_string "vector")]
7040               (const_string "direct")))
7041    (set (attr "amdfam10_decode")
7042         (cond [(eq_attr "alternative" "0,1")
7043                   (const_string "vector")]
7044               (const_string "direct")))
7045    (set_attr "mode" "HI")])
7046
7047 (define_expand "mulqi3"
7048   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7049                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7050                             (match_operand:QI 2 "register_operand" "")))
7051               (clobber (reg:CC FLAGS_REG))])]
7052   "TARGET_QIMODE_MATH"
7053   "")
7054
7055 ;;On AMDFAM10
7056 ;; MUL reg8     Direct
7057 ;; MUL mem8     Direct
7058
7059 (define_insn "*mulqi3_1"
7060   [(set (match_operand:QI 0 "register_operand" "=a")
7061         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7062                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7063    (clobber (reg:CC FLAGS_REG))]
7064   "TARGET_QIMODE_MATH
7065    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7066   "mul{b}\t%2"
7067   [(set_attr "type" "imul")
7068    (set_attr "length_immediate" "0")
7069    (set (attr "athlon_decode")
7070      (if_then_else (eq_attr "cpu" "athlon")
7071         (const_string "vector")
7072         (const_string "direct")))
7073    (set_attr "amdfam10_decode" "direct")        
7074    (set_attr "mode" "QI")])
7075
7076 (define_expand "umulqihi3"
7077   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7078                    (mult:HI (zero_extend:HI
7079                               (match_operand:QI 1 "nonimmediate_operand" ""))
7080                             (zero_extend:HI
7081                               (match_operand:QI 2 "register_operand" ""))))
7082               (clobber (reg:CC FLAGS_REG))])]
7083   "TARGET_QIMODE_MATH"
7084   "")
7085
7086 (define_insn "*umulqihi3_1"
7087   [(set (match_operand:HI 0 "register_operand" "=a")
7088         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7089                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7090    (clobber (reg:CC FLAGS_REG))]
7091   "TARGET_QIMODE_MATH
7092    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7093   "mul{b}\t%2"
7094   [(set_attr "type" "imul")
7095    (set_attr "length_immediate" "0")
7096    (set (attr "athlon_decode")
7097      (if_then_else (eq_attr "cpu" "athlon")
7098         (const_string "vector")
7099         (const_string "direct")))
7100    (set_attr "amdfam10_decode" "direct")        
7101    (set_attr "mode" "QI")])
7102
7103 (define_expand "mulqihi3"
7104   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7105                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7106                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7107               (clobber (reg:CC FLAGS_REG))])]
7108   "TARGET_QIMODE_MATH"
7109   "")
7110
7111 (define_insn "*mulqihi3_insn"
7112   [(set (match_operand:HI 0 "register_operand" "=a")
7113         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7114                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7115    (clobber (reg:CC FLAGS_REG))]
7116   "TARGET_QIMODE_MATH
7117    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7118   "imul{b}\t%2"
7119   [(set_attr "type" "imul")
7120    (set_attr "length_immediate" "0")
7121    (set (attr "athlon_decode")
7122      (if_then_else (eq_attr "cpu" "athlon")
7123         (const_string "vector")
7124         (const_string "direct")))
7125    (set_attr "amdfam10_decode" "direct")        
7126    (set_attr "mode" "QI")])
7127
7128 (define_expand "umulditi3"
7129   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7130                    (mult:TI (zero_extend:TI
7131                               (match_operand:DI 1 "nonimmediate_operand" ""))
7132                             (zero_extend:TI
7133                               (match_operand:DI 2 "register_operand" ""))))
7134               (clobber (reg:CC FLAGS_REG))])]
7135   "TARGET_64BIT"
7136   "")
7137
7138 (define_insn "*umulditi3_insn"
7139   [(set (match_operand:TI 0 "register_operand" "=A")
7140         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7141                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7142    (clobber (reg:CC FLAGS_REG))]
7143   "TARGET_64BIT
7144    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7145   "mul{q}\t%2"
7146   [(set_attr "type" "imul")
7147    (set_attr "length_immediate" "0")
7148    (set (attr "athlon_decode")
7149      (if_then_else (eq_attr "cpu" "athlon")
7150         (const_string "vector")
7151         (const_string "double")))
7152    (set_attr "amdfam10_decode" "double")        
7153    (set_attr "mode" "DI")])
7154
7155 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7156 (define_expand "umulsidi3"
7157   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7158                    (mult:DI (zero_extend:DI
7159                               (match_operand:SI 1 "nonimmediate_operand" ""))
7160                             (zero_extend:DI
7161                               (match_operand:SI 2 "register_operand" ""))))
7162               (clobber (reg:CC FLAGS_REG))])]
7163   "!TARGET_64BIT"
7164   "")
7165
7166 (define_insn "*umulsidi3_insn"
7167   [(set (match_operand:DI 0 "register_operand" "=A")
7168         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7169                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7170    (clobber (reg:CC FLAGS_REG))]
7171   "!TARGET_64BIT
7172    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7173   "mul{l}\t%2"
7174   [(set_attr "type" "imul")
7175    (set_attr "length_immediate" "0")
7176    (set (attr "athlon_decode")
7177      (if_then_else (eq_attr "cpu" "athlon")
7178         (const_string "vector")
7179         (const_string "double")))
7180    (set_attr "amdfam10_decode" "double")        
7181    (set_attr "mode" "SI")])
7182
7183 (define_expand "mulditi3"
7184   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7185                    (mult:TI (sign_extend:TI
7186                               (match_operand:DI 1 "nonimmediate_operand" ""))
7187                             (sign_extend:TI
7188                               (match_operand:DI 2 "register_operand" ""))))
7189               (clobber (reg:CC FLAGS_REG))])]
7190   "TARGET_64BIT"
7191   "")
7192
7193 (define_insn "*mulditi3_insn"
7194   [(set (match_operand:TI 0 "register_operand" "=A")
7195         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7196                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7197    (clobber (reg:CC FLAGS_REG))]
7198   "TARGET_64BIT
7199    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7200   "imul{q}\t%2"
7201   [(set_attr "type" "imul")
7202    (set_attr "length_immediate" "0")
7203    (set (attr "athlon_decode")
7204      (if_then_else (eq_attr "cpu" "athlon")
7205         (const_string "vector")
7206         (const_string "double")))
7207    (set_attr "amdfam10_decode" "double")
7208    (set_attr "mode" "DI")])
7209
7210 (define_expand "mulsidi3"
7211   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7212                    (mult:DI (sign_extend:DI
7213                               (match_operand:SI 1 "nonimmediate_operand" ""))
7214                             (sign_extend:DI
7215                               (match_operand:SI 2 "register_operand" ""))))
7216               (clobber (reg:CC FLAGS_REG))])]
7217   "!TARGET_64BIT"
7218   "")
7219
7220 (define_insn "*mulsidi3_insn"
7221   [(set (match_operand:DI 0 "register_operand" "=A")
7222         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7223                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7224    (clobber (reg:CC FLAGS_REG))]
7225   "!TARGET_64BIT
7226    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7227   "imul{l}\t%2"
7228   [(set_attr "type" "imul")
7229    (set_attr "length_immediate" "0")
7230    (set (attr "athlon_decode")
7231      (if_then_else (eq_attr "cpu" "athlon")
7232         (const_string "vector")
7233         (const_string "double")))
7234    (set_attr "amdfam10_decode" "double")        
7235    (set_attr "mode" "SI")])
7236
7237 (define_expand "umuldi3_highpart"
7238   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7239                    (truncate:DI
7240                      (lshiftrt:TI
7241                        (mult:TI (zero_extend:TI
7242                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7243                                 (zero_extend:TI
7244                                   (match_operand:DI 2 "register_operand" "")))
7245                        (const_int 64))))
7246               (clobber (match_scratch:DI 3 ""))
7247               (clobber (reg:CC FLAGS_REG))])]
7248   "TARGET_64BIT"
7249   "")
7250
7251 (define_insn "*umuldi3_highpart_rex64"
7252   [(set (match_operand:DI 0 "register_operand" "=d")
7253         (truncate:DI
7254           (lshiftrt:TI
7255             (mult:TI (zero_extend:TI
7256                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7257                      (zero_extend:TI
7258                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7259             (const_int 64))))
7260    (clobber (match_scratch:DI 3 "=1"))
7261    (clobber (reg:CC FLAGS_REG))]
7262   "TARGET_64BIT
7263    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7264   "mul{q}\t%2"
7265   [(set_attr "type" "imul")
7266    (set_attr "length_immediate" "0")
7267    (set (attr "athlon_decode")
7268      (if_then_else (eq_attr "cpu" "athlon")
7269         (const_string "vector")
7270         (const_string "double")))
7271    (set_attr "amdfam10_decode" "double")        
7272    (set_attr "mode" "DI")])
7273
7274 (define_expand "umulsi3_highpart"
7275   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7276                    (truncate:SI
7277                      (lshiftrt:DI
7278                        (mult:DI (zero_extend:DI
7279                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7280                                 (zero_extend:DI
7281                                   (match_operand:SI 2 "register_operand" "")))
7282                        (const_int 32))))
7283               (clobber (match_scratch:SI 3 ""))
7284               (clobber (reg:CC FLAGS_REG))])]
7285   ""
7286   "")
7287
7288 (define_insn "*umulsi3_highpart_insn"
7289   [(set (match_operand:SI 0 "register_operand" "=d")
7290         (truncate:SI
7291           (lshiftrt:DI
7292             (mult:DI (zero_extend:DI
7293                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7294                      (zero_extend:DI
7295                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7296             (const_int 32))))
7297    (clobber (match_scratch:SI 3 "=1"))
7298    (clobber (reg:CC FLAGS_REG))]
7299   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7300   "mul{l}\t%2"
7301   [(set_attr "type" "imul")
7302    (set_attr "length_immediate" "0")
7303    (set (attr "athlon_decode")
7304      (if_then_else (eq_attr "cpu" "athlon")
7305         (const_string "vector")
7306         (const_string "double")))
7307    (set_attr "amdfam10_decode" "double")
7308    (set_attr "mode" "SI")])
7309
7310 (define_insn "*umulsi3_highpart_zext"
7311   [(set (match_operand:DI 0 "register_operand" "=d")
7312         (zero_extend:DI (truncate:SI
7313           (lshiftrt:DI
7314             (mult:DI (zero_extend:DI
7315                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7316                      (zero_extend:DI
7317                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7318             (const_int 32)))))
7319    (clobber (match_scratch:SI 3 "=1"))
7320    (clobber (reg:CC FLAGS_REG))]
7321   "TARGET_64BIT
7322    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7323   "mul{l}\t%2"
7324   [(set_attr "type" "imul")
7325    (set_attr "length_immediate" "0")
7326    (set (attr "athlon_decode")
7327      (if_then_else (eq_attr "cpu" "athlon")
7328         (const_string "vector")
7329         (const_string "double")))
7330    (set_attr "amdfam10_decode" "double")
7331    (set_attr "mode" "SI")])
7332
7333 (define_expand "smuldi3_highpart"
7334   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7335                    (truncate:DI
7336                      (lshiftrt:TI
7337                        (mult:TI (sign_extend:TI
7338                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7339                                 (sign_extend:TI
7340                                   (match_operand:DI 2 "register_operand" "")))
7341                        (const_int 64))))
7342               (clobber (match_scratch:DI 3 ""))
7343               (clobber (reg:CC FLAGS_REG))])]
7344   "TARGET_64BIT"
7345   "")
7346
7347 (define_insn "*smuldi3_highpart_rex64"
7348   [(set (match_operand:DI 0 "register_operand" "=d")
7349         (truncate:DI
7350           (lshiftrt:TI
7351             (mult:TI (sign_extend:TI
7352                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7353                      (sign_extend:TI
7354                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7355             (const_int 64))))
7356    (clobber (match_scratch:DI 3 "=1"))
7357    (clobber (reg:CC FLAGS_REG))]
7358   "TARGET_64BIT
7359    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7360   "imul{q}\t%2"
7361   [(set_attr "type" "imul")
7362    (set (attr "athlon_decode")
7363      (if_then_else (eq_attr "cpu" "athlon")
7364         (const_string "vector")
7365         (const_string "double")))
7366    (set_attr "amdfam10_decode" "double")
7367    (set_attr "mode" "DI")])
7368
7369 (define_expand "smulsi3_highpart"
7370   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7371                    (truncate:SI
7372                      (lshiftrt:DI
7373                        (mult:DI (sign_extend:DI
7374                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7375                                 (sign_extend:DI
7376                                   (match_operand:SI 2 "register_operand" "")))
7377                        (const_int 32))))
7378               (clobber (match_scratch:SI 3 ""))
7379               (clobber (reg:CC FLAGS_REG))])]
7380   ""
7381   "")
7382
7383 (define_insn "*smulsi3_highpart_insn"
7384   [(set (match_operand:SI 0 "register_operand" "=d")
7385         (truncate:SI
7386           (lshiftrt:DI
7387             (mult:DI (sign_extend:DI
7388                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7389                      (sign_extend:DI
7390                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7391             (const_int 32))))
7392    (clobber (match_scratch:SI 3 "=1"))
7393    (clobber (reg:CC FLAGS_REG))]
7394   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7395   "imul{l}\t%2"
7396   [(set_attr "type" "imul")
7397    (set (attr "athlon_decode")
7398      (if_then_else (eq_attr "cpu" "athlon")
7399         (const_string "vector")
7400         (const_string "double")))
7401    (set_attr "amdfam10_decode" "double")
7402    (set_attr "mode" "SI")])
7403
7404 (define_insn "*smulsi3_highpart_zext"
7405   [(set (match_operand:DI 0 "register_operand" "=d")
7406         (zero_extend:DI (truncate:SI
7407           (lshiftrt:DI
7408             (mult:DI (sign_extend:DI
7409                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7410                      (sign_extend:DI
7411                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7412             (const_int 32)))))
7413    (clobber (match_scratch:SI 3 "=1"))
7414    (clobber (reg:CC FLAGS_REG))]
7415   "TARGET_64BIT
7416    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7417   "imul{l}\t%2"
7418   [(set_attr "type" "imul")
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 ;; The patterns that match these are at the end of this file.
7427
7428 (define_expand "mulxf3"
7429   [(set (match_operand:XF 0 "register_operand" "")
7430         (mult:XF (match_operand:XF 1 "register_operand" "")
7431                  (match_operand:XF 2 "register_operand" "")))]
7432   "TARGET_80387"
7433   "")
7434
7435 (define_expand "muldf3"
7436   [(set (match_operand:DF 0 "register_operand" "")
7437         (mult:DF (match_operand:DF 1 "register_operand" "")
7438                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7439   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7440   "")
7441
7442 (define_expand "mulsf3"
7443   [(set (match_operand:SF 0 "register_operand" "")
7444         (mult:SF (match_operand:SF 1 "register_operand" "")
7445                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7446   "TARGET_80387 || TARGET_SSE_MATH"
7447   "")
7448 \f
7449 ;; Divide instructions
7450
7451 (define_insn "divqi3"
7452   [(set (match_operand:QI 0 "register_operand" "=a")
7453         (div:QI (match_operand:HI 1 "register_operand" "0")
7454                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7455    (clobber (reg:CC FLAGS_REG))]
7456   "TARGET_QIMODE_MATH"
7457   "idiv{b}\t%2"
7458   [(set_attr "type" "idiv")
7459    (set_attr "mode" "QI")])
7460
7461 (define_insn "udivqi3"
7462   [(set (match_operand:QI 0 "register_operand" "=a")
7463         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7464                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7465    (clobber (reg:CC FLAGS_REG))]
7466   "TARGET_QIMODE_MATH"
7467   "div{b}\t%2"
7468   [(set_attr "type" "idiv")
7469    (set_attr "mode" "QI")])
7470
7471 ;; The patterns that match these are at the end of this file.
7472
7473 (define_expand "divxf3"
7474   [(set (match_operand:XF 0 "register_operand" "")
7475         (div:XF (match_operand:XF 1 "register_operand" "")
7476                 (match_operand:XF 2 "register_operand" "")))]
7477   "TARGET_80387"
7478   "")
7479
7480 (define_expand "divdf3"
7481   [(set (match_operand:DF 0 "register_operand" "")
7482         (div:DF (match_operand:DF 1 "register_operand" "")
7483                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7484    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7485    "")
7486
7487 (define_expand "divsf3"
7488   [(set (match_operand:SF 0 "register_operand" "")
7489         (div:SF (match_operand:SF 1 "register_operand" "")
7490                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7491   "TARGET_80387 || TARGET_SSE_MATH"
7492   "")
7493 \f
7494 ;; Remainder instructions.
7495
7496 (define_expand "divmoddi4"
7497   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7498                    (div:DI (match_operand:DI 1 "register_operand" "")
7499                            (match_operand:DI 2 "nonimmediate_operand" "")))
7500               (set (match_operand:DI 3 "register_operand" "")
7501                    (mod:DI (match_dup 1) (match_dup 2)))
7502               (clobber (reg:CC FLAGS_REG))])]
7503   "TARGET_64BIT"
7504   "")
7505
7506 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7507 ;; Penalize eax case slightly because it results in worse scheduling
7508 ;; of code.
7509 (define_insn "*divmoddi4_nocltd_rex64"
7510   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7511         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7512                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7513    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7514         (mod:DI (match_dup 2) (match_dup 3)))
7515    (clobber (reg:CC FLAGS_REG))]
7516   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7517   "#"
7518   [(set_attr "type" "multi")])
7519
7520 (define_insn "*divmoddi4_cltd_rex64"
7521   [(set (match_operand:DI 0 "register_operand" "=a")
7522         (div:DI (match_operand:DI 2 "register_operand" "a")
7523                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7524    (set (match_operand:DI 1 "register_operand" "=&d")
7525         (mod:DI (match_dup 2) (match_dup 3)))
7526    (clobber (reg:CC FLAGS_REG))]
7527   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7528   "#"
7529   [(set_attr "type" "multi")])
7530
7531 (define_insn "*divmoddi_noext_rex64"
7532   [(set (match_operand:DI 0 "register_operand" "=a")
7533         (div:DI (match_operand:DI 1 "register_operand" "0")
7534                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7535    (set (match_operand:DI 3 "register_operand" "=d")
7536         (mod:DI (match_dup 1) (match_dup 2)))
7537    (use (match_operand:DI 4 "register_operand" "3"))
7538    (clobber (reg:CC FLAGS_REG))]
7539   "TARGET_64BIT"
7540   "idiv{q}\t%2"
7541   [(set_attr "type" "idiv")
7542    (set_attr "mode" "DI")])
7543
7544 (define_split
7545   [(set (match_operand:DI 0 "register_operand" "")
7546         (div:DI (match_operand:DI 1 "register_operand" "")
7547                 (match_operand:DI 2 "nonimmediate_operand" "")))
7548    (set (match_operand:DI 3 "register_operand" "")
7549         (mod:DI (match_dup 1) (match_dup 2)))
7550    (clobber (reg:CC FLAGS_REG))]
7551   "TARGET_64BIT && reload_completed"
7552   [(parallel [(set (match_dup 3)
7553                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7554               (clobber (reg:CC FLAGS_REG))])
7555    (parallel [(set (match_dup 0)
7556                    (div:DI (reg:DI 0) (match_dup 2)))
7557               (set (match_dup 3)
7558                    (mod:DI (reg:DI 0) (match_dup 2)))
7559               (use (match_dup 3))
7560               (clobber (reg:CC FLAGS_REG))])]
7561 {
7562   /* Avoid use of cltd in favor of a mov+shift.  */
7563   if (!TARGET_USE_CLTD && !optimize_size)
7564     {
7565       if (true_regnum (operands[1]))
7566         emit_move_insn (operands[0], operands[1]);
7567       else
7568         emit_move_insn (operands[3], operands[1]);
7569       operands[4] = operands[3];
7570     }
7571   else
7572     {
7573       gcc_assert (!true_regnum (operands[1]));
7574       operands[4] = operands[1];
7575     }
7576 })
7577
7578
7579 (define_expand "divmodsi4"
7580   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7581                    (div:SI (match_operand:SI 1 "register_operand" "")
7582                            (match_operand:SI 2 "nonimmediate_operand" "")))
7583               (set (match_operand:SI 3 "register_operand" "")
7584                    (mod:SI (match_dup 1) (match_dup 2)))
7585               (clobber (reg:CC FLAGS_REG))])]
7586   ""
7587   "")
7588
7589 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7590 ;; Penalize eax case slightly because it results in worse scheduling
7591 ;; of code.
7592 (define_insn "*divmodsi4_nocltd"
7593   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7594         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7595                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7596    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7597         (mod:SI (match_dup 2) (match_dup 3)))
7598    (clobber (reg:CC FLAGS_REG))]
7599   "!optimize_size && !TARGET_USE_CLTD"
7600   "#"
7601   [(set_attr "type" "multi")])
7602
7603 (define_insn "*divmodsi4_cltd"
7604   [(set (match_operand:SI 0 "register_operand" "=a")
7605         (div:SI (match_operand:SI 2 "register_operand" "a")
7606                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7607    (set (match_operand:SI 1 "register_operand" "=&d")
7608         (mod:SI (match_dup 2) (match_dup 3)))
7609    (clobber (reg:CC FLAGS_REG))]
7610   "optimize_size || TARGET_USE_CLTD"
7611   "#"
7612   [(set_attr "type" "multi")])
7613
7614 (define_insn "*divmodsi_noext"
7615   [(set (match_operand:SI 0 "register_operand" "=a")
7616         (div:SI (match_operand:SI 1 "register_operand" "0")
7617                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7618    (set (match_operand:SI 3 "register_operand" "=d")
7619         (mod:SI (match_dup 1) (match_dup 2)))
7620    (use (match_operand:SI 4 "register_operand" "3"))
7621    (clobber (reg:CC FLAGS_REG))]
7622   ""
7623   "idiv{l}\t%2"
7624   [(set_attr "type" "idiv")
7625    (set_attr "mode" "SI")])
7626
7627 (define_split
7628   [(set (match_operand:SI 0 "register_operand" "")
7629         (div:SI (match_operand:SI 1 "register_operand" "")
7630                 (match_operand:SI 2 "nonimmediate_operand" "")))
7631    (set (match_operand:SI 3 "register_operand" "")
7632         (mod:SI (match_dup 1) (match_dup 2)))
7633    (clobber (reg:CC FLAGS_REG))]
7634   "reload_completed"
7635   [(parallel [(set (match_dup 3)
7636                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7637               (clobber (reg:CC FLAGS_REG))])
7638    (parallel [(set (match_dup 0)
7639                    (div:SI (reg:SI 0) (match_dup 2)))
7640               (set (match_dup 3)
7641                    (mod:SI (reg:SI 0) (match_dup 2)))
7642               (use (match_dup 3))
7643               (clobber (reg:CC FLAGS_REG))])]
7644 {
7645   /* Avoid use of cltd in favor of a mov+shift.  */
7646   if (!TARGET_USE_CLTD && !optimize_size)
7647     {
7648       if (true_regnum (operands[1]))
7649         emit_move_insn (operands[0], operands[1]);
7650       else
7651         emit_move_insn (operands[3], operands[1]);
7652       operands[4] = operands[3];
7653     }
7654   else
7655     {
7656       gcc_assert (!true_regnum (operands[1]));
7657       operands[4] = operands[1];
7658     }
7659 })
7660 ;; %%% Split me.
7661 (define_insn "divmodhi4"
7662   [(set (match_operand:HI 0 "register_operand" "=a")
7663         (div:HI (match_operand:HI 1 "register_operand" "0")
7664                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7665    (set (match_operand:HI 3 "register_operand" "=&d")
7666         (mod:HI (match_dup 1) (match_dup 2)))
7667    (clobber (reg:CC FLAGS_REG))]
7668   "TARGET_HIMODE_MATH"
7669   "cwtd\;idiv{w}\t%2"
7670   [(set_attr "type" "multi")
7671    (set_attr "length_immediate" "0")
7672    (set_attr "mode" "SI")])
7673
7674 (define_insn "udivmoddi4"
7675   [(set (match_operand:DI 0 "register_operand" "=a")
7676         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7677                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7678    (set (match_operand:DI 3 "register_operand" "=&d")
7679         (umod:DI (match_dup 1) (match_dup 2)))
7680    (clobber (reg:CC FLAGS_REG))]
7681   "TARGET_64BIT"
7682   "xor{q}\t%3, %3\;div{q}\t%2"
7683   [(set_attr "type" "multi")
7684    (set_attr "length_immediate" "0")
7685    (set_attr "mode" "DI")])
7686
7687 (define_insn "*udivmoddi4_noext"
7688   [(set (match_operand:DI 0 "register_operand" "=a")
7689         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7690                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7691    (set (match_operand:DI 3 "register_operand" "=d")
7692         (umod:DI (match_dup 1) (match_dup 2)))
7693    (use (match_dup 3))
7694    (clobber (reg:CC FLAGS_REG))]
7695   "TARGET_64BIT"
7696   "div{q}\t%2"
7697   [(set_attr "type" "idiv")
7698    (set_attr "mode" "DI")])
7699
7700 (define_split
7701   [(set (match_operand:DI 0 "register_operand" "")
7702         (udiv:DI (match_operand:DI 1 "register_operand" "")
7703                  (match_operand:DI 2 "nonimmediate_operand" "")))
7704    (set (match_operand:DI 3 "register_operand" "")
7705         (umod:DI (match_dup 1) (match_dup 2)))
7706    (clobber (reg:CC FLAGS_REG))]
7707   "TARGET_64BIT && reload_completed"
7708   [(set (match_dup 3) (const_int 0))
7709    (parallel [(set (match_dup 0)
7710                    (udiv:DI (match_dup 1) (match_dup 2)))
7711               (set (match_dup 3)
7712                    (umod:DI (match_dup 1) (match_dup 2)))
7713               (use (match_dup 3))
7714               (clobber (reg:CC FLAGS_REG))])]
7715   "")
7716
7717 (define_insn "udivmodsi4"
7718   [(set (match_operand:SI 0 "register_operand" "=a")
7719         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7720                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7721    (set (match_operand:SI 3 "register_operand" "=&d")
7722         (umod:SI (match_dup 1) (match_dup 2)))
7723    (clobber (reg:CC FLAGS_REG))]
7724   ""
7725   "xor{l}\t%3, %3\;div{l}\t%2"
7726   [(set_attr "type" "multi")
7727    (set_attr "length_immediate" "0")
7728    (set_attr "mode" "SI")])
7729
7730 (define_insn "*udivmodsi4_noext"
7731   [(set (match_operand:SI 0 "register_operand" "=a")
7732         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7733                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7734    (set (match_operand:SI 3 "register_operand" "=d")
7735         (umod:SI (match_dup 1) (match_dup 2)))
7736    (use (match_dup 3))
7737    (clobber (reg:CC FLAGS_REG))]
7738   ""
7739   "div{l}\t%2"
7740   [(set_attr "type" "idiv")
7741    (set_attr "mode" "SI")])
7742
7743 (define_split
7744   [(set (match_operand:SI 0 "register_operand" "")
7745         (udiv:SI (match_operand:SI 1 "register_operand" "")
7746                  (match_operand:SI 2 "nonimmediate_operand" "")))
7747    (set (match_operand:SI 3 "register_operand" "")
7748         (umod:SI (match_dup 1) (match_dup 2)))
7749    (clobber (reg:CC FLAGS_REG))]
7750   "reload_completed"
7751   [(set (match_dup 3) (const_int 0))
7752    (parallel [(set (match_dup 0)
7753                    (udiv:SI (match_dup 1) (match_dup 2)))
7754               (set (match_dup 3)
7755                    (umod:SI (match_dup 1) (match_dup 2)))
7756               (use (match_dup 3))
7757               (clobber (reg:CC FLAGS_REG))])]
7758   "")
7759
7760 (define_expand "udivmodhi4"
7761   [(set (match_dup 4) (const_int 0))
7762    (parallel [(set (match_operand:HI 0 "register_operand" "")
7763                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7764                             (match_operand:HI 2 "nonimmediate_operand" "")))
7765               (set (match_operand:HI 3 "register_operand" "")
7766                    (umod:HI (match_dup 1) (match_dup 2)))
7767               (use (match_dup 4))
7768               (clobber (reg:CC FLAGS_REG))])]
7769   "TARGET_HIMODE_MATH"
7770   "operands[4] = gen_reg_rtx (HImode);")
7771
7772 (define_insn "*udivmodhi_noext"
7773   [(set (match_operand:HI 0 "register_operand" "=a")
7774         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7775                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7776    (set (match_operand:HI 3 "register_operand" "=d")
7777         (umod:HI (match_dup 1) (match_dup 2)))
7778    (use (match_operand:HI 4 "register_operand" "3"))
7779    (clobber (reg:CC FLAGS_REG))]
7780   ""
7781   "div{w}\t%2"
7782   [(set_attr "type" "idiv")
7783    (set_attr "mode" "HI")])
7784
7785 ;; We cannot use div/idiv for double division, because it causes
7786 ;; "division by zero" on the overflow and that's not what we expect
7787 ;; from truncate.  Because true (non truncating) double division is
7788 ;; never generated, we can't create this insn anyway.
7789 ;
7790 ;(define_insn ""
7791 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7792 ;       (truncate:SI
7793 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7794 ;                  (zero_extend:DI
7795 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7796 ;   (set (match_operand:SI 3 "register_operand" "=d")
7797 ;       (truncate:SI
7798 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7799 ;   (clobber (reg:CC FLAGS_REG))]
7800 ;  ""
7801 ;  "div{l}\t{%2, %0|%0, %2}"
7802 ;  [(set_attr "type" "idiv")])
7803 \f
7804 ;;- Logical AND instructions
7805
7806 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7807 ;; Note that this excludes ah.
7808
7809 (define_insn "*testdi_1_rex64"
7810   [(set (reg FLAGS_REG)
7811         (compare
7812           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7813                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7814           (const_int 0)))]
7815   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7816    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7817   "@
7818    test{l}\t{%k1, %k0|%k0, %k1}
7819    test{l}\t{%k1, %k0|%k0, %k1}
7820    test{q}\t{%1, %0|%0, %1}
7821    test{q}\t{%1, %0|%0, %1}
7822    test{q}\t{%1, %0|%0, %1}"
7823   [(set_attr "type" "test")
7824    (set_attr "modrm" "0,1,0,1,1")
7825    (set_attr "mode" "SI,SI,DI,DI,DI")
7826    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7827
7828 (define_insn "testsi_1"
7829   [(set (reg FLAGS_REG)
7830         (compare
7831           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7832                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7833           (const_int 0)))]
7834   "ix86_match_ccmode (insn, CCNOmode)
7835    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7836   "test{l}\t{%1, %0|%0, %1}"
7837   [(set_attr "type" "test")
7838    (set_attr "modrm" "0,1,1")
7839    (set_attr "mode" "SI")
7840    (set_attr "pent_pair" "uv,np,uv")])
7841
7842 (define_expand "testsi_ccno_1"
7843   [(set (reg:CCNO FLAGS_REG)
7844         (compare:CCNO
7845           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7846                   (match_operand:SI 1 "nonmemory_operand" ""))
7847           (const_int 0)))]
7848   ""
7849   "")
7850
7851 (define_insn "*testhi_1"
7852   [(set (reg FLAGS_REG)
7853         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7854                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7855                  (const_int 0)))]
7856   "ix86_match_ccmode (insn, CCNOmode)
7857    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7858   "test{w}\t{%1, %0|%0, %1}"
7859   [(set_attr "type" "test")
7860    (set_attr "modrm" "0,1,1")
7861    (set_attr "mode" "HI")
7862    (set_attr "pent_pair" "uv,np,uv")])
7863
7864 (define_expand "testqi_ccz_1"
7865   [(set (reg:CCZ FLAGS_REG)
7866         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7867                              (match_operand:QI 1 "nonmemory_operand" ""))
7868                  (const_int 0)))]
7869   ""
7870   "")
7871
7872 (define_insn "*testqi_1_maybe_si"
7873   [(set (reg FLAGS_REG)
7874         (compare
7875           (and:QI
7876             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7877             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7878           (const_int 0)))]
7879    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7880     && ix86_match_ccmode (insn,
7881                          GET_CODE (operands[1]) == CONST_INT
7882                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7883 {
7884   if (which_alternative == 3)
7885     {
7886       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7887         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7888       return "test{l}\t{%1, %k0|%k0, %1}";
7889     }
7890   return "test{b}\t{%1, %0|%0, %1}";
7891 }
7892   [(set_attr "type" "test")
7893    (set_attr "modrm" "0,1,1,1")
7894    (set_attr "mode" "QI,QI,QI,SI")
7895    (set_attr "pent_pair" "uv,np,uv,np")])
7896
7897 (define_insn "*testqi_1"
7898   [(set (reg FLAGS_REG)
7899         (compare
7900           (and:QI
7901             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7902             (match_operand:QI 1 "general_operand" "n,n,qn"))
7903           (const_int 0)))]
7904   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7905    && ix86_match_ccmode (insn, CCNOmode)"
7906   "test{b}\t{%1, %0|%0, %1}"
7907   [(set_attr "type" "test")
7908    (set_attr "modrm" "0,1,1")
7909    (set_attr "mode" "QI")
7910    (set_attr "pent_pair" "uv,np,uv")])
7911
7912 (define_expand "testqi_ext_ccno_0"
7913   [(set (reg:CCNO FLAGS_REG)
7914         (compare:CCNO
7915           (and:SI
7916             (zero_extract:SI
7917               (match_operand 0 "ext_register_operand" "")
7918               (const_int 8)
7919               (const_int 8))
7920             (match_operand 1 "const_int_operand" ""))
7921           (const_int 0)))]
7922   ""
7923   "")
7924
7925 (define_insn "*testqi_ext_0"
7926   [(set (reg FLAGS_REG)
7927         (compare
7928           (and:SI
7929             (zero_extract:SI
7930               (match_operand 0 "ext_register_operand" "Q")
7931               (const_int 8)
7932               (const_int 8))
7933             (match_operand 1 "const_int_operand" "n"))
7934           (const_int 0)))]
7935   "ix86_match_ccmode (insn, CCNOmode)"
7936   "test{b}\t{%1, %h0|%h0, %1}"
7937   [(set_attr "type" "test")
7938    (set_attr "mode" "QI")
7939    (set_attr "length_immediate" "1")
7940    (set_attr "pent_pair" "np")])
7941
7942 (define_insn "*testqi_ext_1"
7943   [(set (reg FLAGS_REG)
7944         (compare
7945           (and:SI
7946             (zero_extract:SI
7947               (match_operand 0 "ext_register_operand" "Q")
7948               (const_int 8)
7949               (const_int 8))
7950             (zero_extend:SI
7951               (match_operand:QI 1 "general_operand" "Qm")))
7952           (const_int 0)))]
7953   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7954    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7955   "test{b}\t{%1, %h0|%h0, %1}"
7956   [(set_attr "type" "test")
7957    (set_attr "mode" "QI")])
7958
7959 (define_insn "*testqi_ext_1_rex64"
7960   [(set (reg FLAGS_REG)
7961         (compare
7962           (and:SI
7963             (zero_extract:SI
7964               (match_operand 0 "ext_register_operand" "Q")
7965               (const_int 8)
7966               (const_int 8))
7967             (zero_extend:SI
7968               (match_operand:QI 1 "register_operand" "Q")))
7969           (const_int 0)))]
7970   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7971   "test{b}\t{%1, %h0|%h0, %1}"
7972   [(set_attr "type" "test")
7973    (set_attr "mode" "QI")])
7974
7975 (define_insn "*testqi_ext_2"
7976   [(set (reg FLAGS_REG)
7977         (compare
7978           (and:SI
7979             (zero_extract:SI
7980               (match_operand 0 "ext_register_operand" "Q")
7981               (const_int 8)
7982               (const_int 8))
7983             (zero_extract:SI
7984               (match_operand 1 "ext_register_operand" "Q")
7985               (const_int 8)
7986               (const_int 8)))
7987           (const_int 0)))]
7988   "ix86_match_ccmode (insn, CCNOmode)"
7989   "test{b}\t{%h1, %h0|%h0, %h1}"
7990   [(set_attr "type" "test")
7991    (set_attr "mode" "QI")])
7992
7993 ;; Combine likes to form bit extractions for some tests.  Humor it.
7994 (define_insn "*testqi_ext_3"
7995   [(set (reg FLAGS_REG)
7996         (compare (zero_extract:SI
7997                    (match_operand 0 "nonimmediate_operand" "rm")
7998                    (match_operand:SI 1 "const_int_operand" "")
7999                    (match_operand:SI 2 "const_int_operand" ""))
8000                  (const_int 0)))]
8001   "ix86_match_ccmode (insn, CCNOmode)
8002    && INTVAL (operands[1]) > 0
8003    && INTVAL (operands[2]) >= 0
8004    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8005    && (GET_MODE (operands[0]) == SImode
8006        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8007        || GET_MODE (operands[0]) == HImode
8008        || GET_MODE (operands[0]) == QImode)"
8009   "#")
8010
8011 (define_insn "*testqi_ext_3_rex64"
8012   [(set (reg FLAGS_REG)
8013         (compare (zero_extract:DI
8014                    (match_operand 0 "nonimmediate_operand" "rm")
8015                    (match_operand:DI 1 "const_int_operand" "")
8016                    (match_operand:DI 2 "const_int_operand" ""))
8017                  (const_int 0)))]
8018   "TARGET_64BIT
8019    && ix86_match_ccmode (insn, CCNOmode)
8020    && INTVAL (operands[1]) > 0
8021    && INTVAL (operands[2]) >= 0
8022    /* Ensure that resulting mask is zero or sign extended operand.  */
8023    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8024        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8025            && INTVAL (operands[1]) > 32))
8026    && (GET_MODE (operands[0]) == SImode
8027        || GET_MODE (operands[0]) == DImode
8028        || GET_MODE (operands[0]) == HImode
8029        || GET_MODE (operands[0]) == QImode)"
8030   "#")
8031
8032 (define_split
8033   [(set (match_operand 0 "flags_reg_operand" "")
8034         (match_operator 1 "compare_operator"
8035           [(zero_extract
8036              (match_operand 2 "nonimmediate_operand" "")
8037              (match_operand 3 "const_int_operand" "")
8038              (match_operand 4 "const_int_operand" ""))
8039            (const_int 0)]))]
8040   "ix86_match_ccmode (insn, CCNOmode)"
8041   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8042 {
8043   rtx val = operands[2];
8044   HOST_WIDE_INT len = INTVAL (operands[3]);
8045   HOST_WIDE_INT pos = INTVAL (operands[4]);
8046   HOST_WIDE_INT mask;
8047   enum machine_mode mode, submode;
8048
8049   mode = GET_MODE (val);
8050   if (GET_CODE (val) == MEM)
8051     {
8052       /* ??? Combine likes to put non-volatile mem extractions in QImode
8053          no matter the size of the test.  So find a mode that works.  */
8054       if (! MEM_VOLATILE_P (val))
8055         {
8056           mode = smallest_mode_for_size (pos + len, MODE_INT);
8057           val = adjust_address (val, mode, 0);
8058         }
8059     }
8060   else if (GET_CODE (val) == SUBREG
8061            && (submode = GET_MODE (SUBREG_REG (val)),
8062                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8063            && pos + len <= GET_MODE_BITSIZE (submode))
8064     {
8065       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8066       mode = submode;
8067       val = SUBREG_REG (val);
8068     }
8069   else if (mode == HImode && pos + len <= 8)
8070     {
8071       /* Small HImode tests can be converted to QImode.  */
8072       mode = QImode;
8073       val = gen_lowpart (QImode, val);
8074     }
8075
8076   if (len == HOST_BITS_PER_WIDE_INT)
8077     mask = -1;
8078   else
8079     mask = ((HOST_WIDE_INT)1 << len) - 1;
8080   mask <<= pos;
8081
8082   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8083 })
8084
8085 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8086 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8087 ;; this is relatively important trick.
8088 ;; Do the conversion only post-reload to avoid limiting of the register class
8089 ;; to QI regs.
8090 (define_split
8091   [(set (match_operand 0 "flags_reg_operand" "")
8092         (match_operator 1 "compare_operator"
8093           [(and (match_operand 2 "register_operand" "")
8094                 (match_operand 3 "const_int_operand" ""))
8095            (const_int 0)]))]
8096    "reload_completed
8097     && QI_REG_P (operands[2])
8098     && GET_MODE (operands[2]) != QImode
8099     && ((ix86_match_ccmode (insn, CCZmode)
8100          && !(INTVAL (operands[3]) & ~(255 << 8)))
8101         || (ix86_match_ccmode (insn, CCNOmode)
8102             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8103   [(set (match_dup 0)
8104         (match_op_dup 1
8105           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8106                    (match_dup 3))
8107            (const_int 0)]))]
8108   "operands[2] = gen_lowpart (SImode, operands[2]);
8109    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8110
8111 (define_split
8112   [(set (match_operand 0 "flags_reg_operand" "")
8113         (match_operator 1 "compare_operator"
8114           [(and (match_operand 2 "nonimmediate_operand" "")
8115                 (match_operand 3 "const_int_operand" ""))
8116            (const_int 0)]))]
8117    "reload_completed
8118     && GET_MODE (operands[2]) != QImode
8119     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8120     && ((ix86_match_ccmode (insn, CCZmode)
8121          && !(INTVAL (operands[3]) & ~255))
8122         || (ix86_match_ccmode (insn, CCNOmode)
8123             && !(INTVAL (operands[3]) & ~127)))"
8124   [(set (match_dup 0)
8125         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8126                          (const_int 0)]))]
8127   "operands[2] = gen_lowpart (QImode, operands[2]);
8128    operands[3] = gen_lowpart (QImode, operands[3]);")
8129
8130
8131 ;; %%% This used to optimize known byte-wide and operations to memory,
8132 ;; and sometimes to QImode registers.  If this is considered useful,
8133 ;; it should be done with splitters.
8134
8135 (define_expand "anddi3"
8136   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8137         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8138                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8139    (clobber (reg:CC FLAGS_REG))]
8140   "TARGET_64BIT"
8141   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8142
8143 (define_insn "*anddi_1_rex64"
8144   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8145         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8146                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8147    (clobber (reg:CC FLAGS_REG))]
8148   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8149 {
8150   switch (get_attr_type (insn))
8151     {
8152     case TYPE_IMOVX:
8153       {
8154         enum machine_mode mode;
8155
8156         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8157         if (INTVAL (operands[2]) == 0xff)
8158           mode = QImode;
8159         else
8160           {
8161             gcc_assert (INTVAL (operands[2]) == 0xffff);
8162             mode = HImode;
8163           }
8164
8165         operands[1] = gen_lowpart (mode, operands[1]);
8166         if (mode == QImode)
8167           return "movz{bq|x}\t{%1,%0|%0, %1}";
8168         else
8169           return "movz{wq|x}\t{%1,%0|%0, %1}";
8170       }
8171
8172     default:
8173       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8174       if (get_attr_mode (insn) == MODE_SI)
8175         return "and{l}\t{%k2, %k0|%k0, %k2}";
8176       else
8177         return "and{q}\t{%2, %0|%0, %2}";
8178     }
8179 }
8180   [(set_attr "type" "alu,alu,alu,imovx")
8181    (set_attr "length_immediate" "*,*,*,0")
8182    (set_attr "mode" "SI,DI,DI,DI")])
8183
8184 (define_insn "*anddi_2"
8185   [(set (reg FLAGS_REG)
8186         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8187                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8188                  (const_int 0)))
8189    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8190         (and:DI (match_dup 1) (match_dup 2)))]
8191   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8192    && ix86_binary_operator_ok (AND, DImode, operands)"
8193   "@
8194    and{l}\t{%k2, %k0|%k0, %k2}
8195    and{q}\t{%2, %0|%0, %2}
8196    and{q}\t{%2, %0|%0, %2}"
8197   [(set_attr "type" "alu")
8198    (set_attr "mode" "SI,DI,DI")])
8199
8200 (define_expand "andsi3"
8201   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8202         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8203                 (match_operand:SI 2 "general_operand" "")))
8204    (clobber (reg:CC FLAGS_REG))]
8205   ""
8206   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8207
8208 (define_insn "*andsi_1"
8209   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8210         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8211                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8212    (clobber (reg:CC FLAGS_REG))]
8213   "ix86_binary_operator_ok (AND, SImode, operands)"
8214 {
8215   switch (get_attr_type (insn))
8216     {
8217     case TYPE_IMOVX:
8218       {
8219         enum machine_mode mode;
8220
8221         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8222         if (INTVAL (operands[2]) == 0xff)
8223           mode = QImode;
8224         else
8225           {
8226             gcc_assert (INTVAL (operands[2]) == 0xffff);
8227             mode = HImode;
8228           }
8229
8230         operands[1] = gen_lowpart (mode, operands[1]);
8231         if (mode == QImode)
8232           return "movz{bl|x}\t{%1,%0|%0, %1}";
8233         else
8234           return "movz{wl|x}\t{%1,%0|%0, %1}";
8235       }
8236
8237     default:
8238       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8239       return "and{l}\t{%2, %0|%0, %2}";
8240     }
8241 }
8242   [(set_attr "type" "alu,alu,imovx")
8243    (set_attr "length_immediate" "*,*,0")
8244    (set_attr "mode" "SI")])
8245
8246 (define_split
8247   [(set (match_operand 0 "register_operand" "")
8248         (and (match_dup 0)
8249              (const_int -65536)))
8250    (clobber (reg:CC FLAGS_REG))]
8251   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8252   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8253   "operands[1] = gen_lowpart (HImode, operands[0]);")
8254
8255 (define_split
8256   [(set (match_operand 0 "ext_register_operand" "")
8257         (and (match_dup 0)
8258              (const_int -256)))
8259    (clobber (reg:CC FLAGS_REG))]
8260   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8261   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8262   "operands[1] = gen_lowpart (QImode, operands[0]);")
8263
8264 (define_split
8265   [(set (match_operand 0 "ext_register_operand" "")
8266         (and (match_dup 0)
8267              (const_int -65281)))
8268    (clobber (reg:CC FLAGS_REG))]
8269   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8270   [(parallel [(set (zero_extract:SI (match_dup 0)
8271                                     (const_int 8)
8272                                     (const_int 8))
8273                    (xor:SI
8274                      (zero_extract:SI (match_dup 0)
8275                                       (const_int 8)
8276                                       (const_int 8))
8277                      (zero_extract:SI (match_dup 0)
8278                                       (const_int 8)
8279                                       (const_int 8))))
8280               (clobber (reg:CC FLAGS_REG))])]
8281   "operands[0] = gen_lowpart (SImode, operands[0]);")
8282
8283 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8284 (define_insn "*andsi_1_zext"
8285   [(set (match_operand:DI 0 "register_operand" "=r")
8286         (zero_extend:DI
8287           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8288                   (match_operand:SI 2 "general_operand" "rim"))))
8289    (clobber (reg:CC FLAGS_REG))]
8290   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8291   "and{l}\t{%2, %k0|%k0, %2}"
8292   [(set_attr "type" "alu")
8293    (set_attr "mode" "SI")])
8294
8295 (define_insn "*andsi_2"
8296   [(set (reg FLAGS_REG)
8297         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8298                          (match_operand:SI 2 "general_operand" "rim,ri"))
8299                  (const_int 0)))
8300    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8301         (and:SI (match_dup 1) (match_dup 2)))]
8302   "ix86_match_ccmode (insn, CCNOmode)
8303    && ix86_binary_operator_ok (AND, SImode, operands)"
8304   "and{l}\t{%2, %0|%0, %2}"
8305   [(set_attr "type" "alu")
8306    (set_attr "mode" "SI")])
8307
8308 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8309 (define_insn "*andsi_2_zext"
8310   [(set (reg FLAGS_REG)
8311         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8312                          (match_operand:SI 2 "general_operand" "rim"))
8313                  (const_int 0)))
8314    (set (match_operand:DI 0 "register_operand" "=r")
8315         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8316   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8317    && ix86_binary_operator_ok (AND, SImode, operands)"
8318   "and{l}\t{%2, %k0|%k0, %2}"
8319   [(set_attr "type" "alu")
8320    (set_attr "mode" "SI")])
8321
8322 (define_expand "andhi3"
8323   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8324         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8325                 (match_operand:HI 2 "general_operand" "")))
8326    (clobber (reg:CC FLAGS_REG))]
8327   "TARGET_HIMODE_MATH"
8328   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8329
8330 (define_insn "*andhi_1"
8331   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8332         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8333                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8334    (clobber (reg:CC FLAGS_REG))]
8335   "ix86_binary_operator_ok (AND, HImode, operands)"
8336 {
8337   switch (get_attr_type (insn))
8338     {
8339     case TYPE_IMOVX:
8340       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8341       gcc_assert (INTVAL (operands[2]) == 0xff);
8342       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8343
8344     default:
8345       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8346
8347       return "and{w}\t{%2, %0|%0, %2}";
8348     }
8349 }
8350   [(set_attr "type" "alu,alu,imovx")
8351    (set_attr "length_immediate" "*,*,0")
8352    (set_attr "mode" "HI,HI,SI")])
8353
8354 (define_insn "*andhi_2"
8355   [(set (reg FLAGS_REG)
8356         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8357                          (match_operand:HI 2 "general_operand" "rim,ri"))
8358                  (const_int 0)))
8359    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8360         (and:HI (match_dup 1) (match_dup 2)))]
8361   "ix86_match_ccmode (insn, CCNOmode)
8362    && ix86_binary_operator_ok (AND, HImode, operands)"
8363   "and{w}\t{%2, %0|%0, %2}"
8364   [(set_attr "type" "alu")
8365    (set_attr "mode" "HI")])
8366
8367 (define_expand "andqi3"
8368   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8369         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8370                 (match_operand:QI 2 "general_operand" "")))
8371    (clobber (reg:CC FLAGS_REG))]
8372   "TARGET_QIMODE_MATH"
8373   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8374
8375 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8376 (define_insn "*andqi_1"
8377   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8378         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8379                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8380    (clobber (reg:CC FLAGS_REG))]
8381   "ix86_binary_operator_ok (AND, QImode, operands)"
8382   "@
8383    and{b}\t{%2, %0|%0, %2}
8384    and{b}\t{%2, %0|%0, %2}
8385    and{l}\t{%k2, %k0|%k0, %k2}"
8386   [(set_attr "type" "alu")
8387    (set_attr "mode" "QI,QI,SI")])
8388
8389 (define_insn "*andqi_1_slp"
8390   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8391         (and:QI (match_dup 0)
8392                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8393    (clobber (reg:CC FLAGS_REG))]
8394   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8395    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8396   "and{b}\t{%1, %0|%0, %1}"
8397   [(set_attr "type" "alu1")
8398    (set_attr "mode" "QI")])
8399
8400 (define_insn "*andqi_2_maybe_si"
8401   [(set (reg FLAGS_REG)
8402         (compare (and:QI
8403                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8404                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8405                  (const_int 0)))
8406    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8407         (and:QI (match_dup 1) (match_dup 2)))]
8408   "ix86_binary_operator_ok (AND, QImode, operands)
8409    && ix86_match_ccmode (insn,
8410                          GET_CODE (operands[2]) == CONST_INT
8411                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8412 {
8413   if (which_alternative == 2)
8414     {
8415       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8416         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8417       return "and{l}\t{%2, %k0|%k0, %2}";
8418     }
8419   return "and{b}\t{%2, %0|%0, %2}";
8420 }
8421   [(set_attr "type" "alu")
8422    (set_attr "mode" "QI,QI,SI")])
8423
8424 (define_insn "*andqi_2"
8425   [(set (reg FLAGS_REG)
8426         (compare (and:QI
8427                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8428                    (match_operand:QI 2 "general_operand" "qim,qi"))
8429                  (const_int 0)))
8430    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8431         (and:QI (match_dup 1) (match_dup 2)))]
8432   "ix86_match_ccmode (insn, CCNOmode)
8433    && ix86_binary_operator_ok (AND, QImode, operands)"
8434   "and{b}\t{%2, %0|%0, %2}"
8435   [(set_attr "type" "alu")
8436    (set_attr "mode" "QI")])
8437
8438 (define_insn "*andqi_2_slp"
8439   [(set (reg FLAGS_REG)
8440         (compare (and:QI
8441                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8442                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8443                  (const_int 0)))
8444    (set (strict_low_part (match_dup 0))
8445         (and:QI (match_dup 0) (match_dup 1)))]
8446   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8447    && ix86_match_ccmode (insn, CCNOmode)
8448    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8449   "and{b}\t{%1, %0|%0, %1}"
8450   [(set_attr "type" "alu1")
8451    (set_attr "mode" "QI")])
8452
8453 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8454 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8455 ;; for a QImode operand, which of course failed.
8456
8457 (define_insn "andqi_ext_0"
8458   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8459                          (const_int 8)
8460                          (const_int 8))
8461         (and:SI
8462           (zero_extract:SI
8463             (match_operand 1 "ext_register_operand" "0")
8464             (const_int 8)
8465             (const_int 8))
8466           (match_operand 2 "const_int_operand" "n")))
8467    (clobber (reg:CC FLAGS_REG))]
8468   ""
8469   "and{b}\t{%2, %h0|%h0, %2}"
8470   [(set_attr "type" "alu")
8471    (set_attr "length_immediate" "1")
8472    (set_attr "mode" "QI")])
8473
8474 ;; Generated by peephole translating test to and.  This shows up
8475 ;; often in fp comparisons.
8476
8477 (define_insn "*andqi_ext_0_cc"
8478   [(set (reg FLAGS_REG)
8479         (compare
8480           (and:SI
8481             (zero_extract:SI
8482               (match_operand 1 "ext_register_operand" "0")
8483               (const_int 8)
8484               (const_int 8))
8485             (match_operand 2 "const_int_operand" "n"))
8486           (const_int 0)))
8487    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8488                          (const_int 8)
8489                          (const_int 8))
8490         (and:SI
8491           (zero_extract:SI
8492             (match_dup 1)
8493             (const_int 8)
8494             (const_int 8))
8495           (match_dup 2)))]
8496   "ix86_match_ccmode (insn, CCNOmode)"
8497   "and{b}\t{%2, %h0|%h0, %2}"
8498   [(set_attr "type" "alu")
8499    (set_attr "length_immediate" "1")
8500    (set_attr "mode" "QI")])
8501
8502 (define_insn "*andqi_ext_1"
8503   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8504                          (const_int 8)
8505                          (const_int 8))
8506         (and:SI
8507           (zero_extract:SI
8508             (match_operand 1 "ext_register_operand" "0")
8509             (const_int 8)
8510             (const_int 8))
8511           (zero_extend:SI
8512             (match_operand:QI 2 "general_operand" "Qm"))))
8513    (clobber (reg:CC FLAGS_REG))]
8514   "!TARGET_64BIT"
8515   "and{b}\t{%2, %h0|%h0, %2}"
8516   [(set_attr "type" "alu")
8517    (set_attr "length_immediate" "0")
8518    (set_attr "mode" "QI")])
8519
8520 (define_insn "*andqi_ext_1_rex64"
8521   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8522                          (const_int 8)
8523                          (const_int 8))
8524         (and:SI
8525           (zero_extract:SI
8526             (match_operand 1 "ext_register_operand" "0")
8527             (const_int 8)
8528             (const_int 8))
8529           (zero_extend:SI
8530             (match_operand 2 "ext_register_operand" "Q"))))
8531    (clobber (reg:CC FLAGS_REG))]
8532   "TARGET_64BIT"
8533   "and{b}\t{%2, %h0|%h0, %2}"
8534   [(set_attr "type" "alu")
8535    (set_attr "length_immediate" "0")
8536    (set_attr "mode" "QI")])
8537
8538 (define_insn "*andqi_ext_2"
8539   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8540                          (const_int 8)
8541                          (const_int 8))
8542         (and:SI
8543           (zero_extract:SI
8544             (match_operand 1 "ext_register_operand" "%0")
8545             (const_int 8)
8546             (const_int 8))
8547           (zero_extract:SI
8548             (match_operand 2 "ext_register_operand" "Q")
8549             (const_int 8)
8550             (const_int 8))))
8551    (clobber (reg:CC FLAGS_REG))]
8552   ""
8553   "and{b}\t{%h2, %h0|%h0, %h2}"
8554   [(set_attr "type" "alu")
8555    (set_attr "length_immediate" "0")
8556    (set_attr "mode" "QI")])
8557
8558 ;; Convert wide AND instructions with immediate operand to shorter QImode
8559 ;; equivalents when possible.
8560 ;; Don't do the splitting with memory operands, since it introduces risk
8561 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8562 ;; for size, but that can (should?) be handled by generic code instead.
8563 (define_split
8564   [(set (match_operand 0 "register_operand" "")
8565         (and (match_operand 1 "register_operand" "")
8566              (match_operand 2 "const_int_operand" "")))
8567    (clobber (reg:CC FLAGS_REG))]
8568    "reload_completed
8569     && QI_REG_P (operands[0])
8570     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8571     && !(~INTVAL (operands[2]) & ~(255 << 8))
8572     && GET_MODE (operands[0]) != QImode"
8573   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8574                    (and:SI (zero_extract:SI (match_dup 1)
8575                                             (const_int 8) (const_int 8))
8576                            (match_dup 2)))
8577               (clobber (reg:CC FLAGS_REG))])]
8578   "operands[0] = gen_lowpart (SImode, operands[0]);
8579    operands[1] = gen_lowpart (SImode, operands[1]);
8580    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8581
8582 ;; Since AND can be encoded with sign extended immediate, this is only
8583 ;; profitable when 7th bit is not set.
8584 (define_split
8585   [(set (match_operand 0 "register_operand" "")
8586         (and (match_operand 1 "general_operand" "")
8587              (match_operand 2 "const_int_operand" "")))
8588    (clobber (reg:CC FLAGS_REG))]
8589    "reload_completed
8590     && ANY_QI_REG_P (operands[0])
8591     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8592     && !(~INTVAL (operands[2]) & ~255)
8593     && !(INTVAL (operands[2]) & 128)
8594     && GET_MODE (operands[0]) != QImode"
8595   [(parallel [(set (strict_low_part (match_dup 0))
8596                    (and:QI (match_dup 1)
8597                            (match_dup 2)))
8598               (clobber (reg:CC FLAGS_REG))])]
8599   "operands[0] = gen_lowpart (QImode, operands[0]);
8600    operands[1] = gen_lowpart (QImode, operands[1]);
8601    operands[2] = gen_lowpart (QImode, operands[2]);")
8602 \f
8603 ;; Logical inclusive OR instructions
8604
8605 ;; %%% This used to optimize known byte-wide and operations to memory.
8606 ;; If this is considered useful, it should be done with splitters.
8607
8608 (define_expand "iordi3"
8609   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8610         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8611                 (match_operand:DI 2 "x86_64_general_operand" "")))
8612    (clobber (reg:CC FLAGS_REG))]
8613   "TARGET_64BIT"
8614   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8615
8616 (define_insn "*iordi_1_rex64"
8617   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8618         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8619                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8620    (clobber (reg:CC FLAGS_REG))]
8621   "TARGET_64BIT
8622    && ix86_binary_operator_ok (IOR, DImode, operands)"
8623   "or{q}\t{%2, %0|%0, %2}"
8624   [(set_attr "type" "alu")
8625    (set_attr "mode" "DI")])
8626
8627 (define_insn "*iordi_2_rex64"
8628   [(set (reg FLAGS_REG)
8629         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8630                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8631                  (const_int 0)))
8632    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8633         (ior:DI (match_dup 1) (match_dup 2)))]
8634   "TARGET_64BIT
8635    && ix86_match_ccmode (insn, CCNOmode)
8636    && ix86_binary_operator_ok (IOR, DImode, operands)"
8637   "or{q}\t{%2, %0|%0, %2}"
8638   [(set_attr "type" "alu")
8639    (set_attr "mode" "DI")])
8640
8641 (define_insn "*iordi_3_rex64"
8642   [(set (reg FLAGS_REG)
8643         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8644                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8645                  (const_int 0)))
8646    (clobber (match_scratch:DI 0 "=r"))]
8647   "TARGET_64BIT
8648    && ix86_match_ccmode (insn, CCNOmode)
8649    && ix86_binary_operator_ok (IOR, DImode, operands)"
8650   "or{q}\t{%2, %0|%0, %2}"
8651   [(set_attr "type" "alu")
8652    (set_attr "mode" "DI")])
8653
8654
8655 (define_expand "iorsi3"
8656   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8657         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8658                 (match_operand:SI 2 "general_operand" "")))
8659    (clobber (reg:CC FLAGS_REG))]
8660   ""
8661   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8662
8663 (define_insn "*iorsi_1"
8664   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8665         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8666                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8667    (clobber (reg:CC FLAGS_REG))]
8668   "ix86_binary_operator_ok (IOR, SImode, operands)"
8669   "or{l}\t{%2, %0|%0, %2}"
8670   [(set_attr "type" "alu")
8671    (set_attr "mode" "SI")])
8672
8673 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8674 (define_insn "*iorsi_1_zext"
8675   [(set (match_operand:DI 0 "register_operand" "=rm")
8676         (zero_extend:DI
8677           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8678                   (match_operand:SI 2 "general_operand" "rim"))))
8679    (clobber (reg:CC FLAGS_REG))]
8680   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8681   "or{l}\t{%2, %k0|%k0, %2}"
8682   [(set_attr "type" "alu")
8683    (set_attr "mode" "SI")])
8684
8685 (define_insn "*iorsi_1_zext_imm"
8686   [(set (match_operand:DI 0 "register_operand" "=rm")
8687         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8688                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8689    (clobber (reg:CC FLAGS_REG))]
8690   "TARGET_64BIT"
8691   "or{l}\t{%2, %k0|%k0, %2}"
8692   [(set_attr "type" "alu")
8693    (set_attr "mode" "SI")])
8694
8695 (define_insn "*iorsi_2"
8696   [(set (reg FLAGS_REG)
8697         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8698                          (match_operand:SI 2 "general_operand" "rim,ri"))
8699                  (const_int 0)))
8700    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8701         (ior:SI (match_dup 1) (match_dup 2)))]
8702   "ix86_match_ccmode (insn, CCNOmode)
8703    && ix86_binary_operator_ok (IOR, SImode, operands)"
8704   "or{l}\t{%2, %0|%0, %2}"
8705   [(set_attr "type" "alu")
8706    (set_attr "mode" "SI")])
8707
8708 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8709 ;; ??? Special case for immediate operand is missing - it is tricky.
8710 (define_insn "*iorsi_2_zext"
8711   [(set (reg FLAGS_REG)
8712         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8713                          (match_operand:SI 2 "general_operand" "rim"))
8714                  (const_int 0)))
8715    (set (match_operand:DI 0 "register_operand" "=r")
8716         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8717   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8718    && ix86_binary_operator_ok (IOR, SImode, operands)"
8719   "or{l}\t{%2, %k0|%k0, %2}"
8720   [(set_attr "type" "alu")
8721    (set_attr "mode" "SI")])
8722
8723 (define_insn "*iorsi_2_zext_imm"
8724   [(set (reg FLAGS_REG)
8725         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8726                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8727                  (const_int 0)))
8728    (set (match_operand:DI 0 "register_operand" "=r")
8729         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8730   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8731    && ix86_binary_operator_ok (IOR, SImode, operands)"
8732   "or{l}\t{%2, %k0|%k0, %2}"
8733   [(set_attr "type" "alu")
8734    (set_attr "mode" "SI")])
8735
8736 (define_insn "*iorsi_3"
8737   [(set (reg FLAGS_REG)
8738         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8739                          (match_operand:SI 2 "general_operand" "rim"))
8740                  (const_int 0)))
8741    (clobber (match_scratch:SI 0 "=r"))]
8742   "ix86_match_ccmode (insn, CCNOmode)
8743    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8744   "or{l}\t{%2, %0|%0, %2}"
8745   [(set_attr "type" "alu")
8746    (set_attr "mode" "SI")])
8747
8748 (define_expand "iorhi3"
8749   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8750         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8751                 (match_operand:HI 2 "general_operand" "")))
8752    (clobber (reg:CC FLAGS_REG))]
8753   "TARGET_HIMODE_MATH"
8754   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8755
8756 (define_insn "*iorhi_1"
8757   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8758         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8759                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "ix86_binary_operator_ok (IOR, HImode, operands)"
8762   "or{w}\t{%2, %0|%0, %2}"
8763   [(set_attr "type" "alu")
8764    (set_attr "mode" "HI")])
8765
8766 (define_insn "*iorhi_2"
8767   [(set (reg FLAGS_REG)
8768         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8769                          (match_operand:HI 2 "general_operand" "rim,ri"))
8770                  (const_int 0)))
8771    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8772         (ior:HI (match_dup 1) (match_dup 2)))]
8773   "ix86_match_ccmode (insn, CCNOmode)
8774    && ix86_binary_operator_ok (IOR, HImode, operands)"
8775   "or{w}\t{%2, %0|%0, %2}"
8776   [(set_attr "type" "alu")
8777    (set_attr "mode" "HI")])
8778
8779 (define_insn "*iorhi_3"
8780   [(set (reg FLAGS_REG)
8781         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8782                          (match_operand:HI 2 "general_operand" "rim"))
8783                  (const_int 0)))
8784    (clobber (match_scratch:HI 0 "=r"))]
8785   "ix86_match_ccmode (insn, CCNOmode)
8786    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8787   "or{w}\t{%2, %0|%0, %2}"
8788   [(set_attr "type" "alu")
8789    (set_attr "mode" "HI")])
8790
8791 (define_expand "iorqi3"
8792   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8793         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8794                 (match_operand:QI 2 "general_operand" "")))
8795    (clobber (reg:CC FLAGS_REG))]
8796   "TARGET_QIMODE_MATH"
8797   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8798
8799 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8800 (define_insn "*iorqi_1"
8801   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8802         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8803                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8804    (clobber (reg:CC FLAGS_REG))]
8805   "ix86_binary_operator_ok (IOR, QImode, operands)"
8806   "@
8807    or{b}\t{%2, %0|%0, %2}
8808    or{b}\t{%2, %0|%0, %2}
8809    or{l}\t{%k2, %k0|%k0, %k2}"
8810   [(set_attr "type" "alu")
8811    (set_attr "mode" "QI,QI,SI")])
8812
8813 (define_insn "*iorqi_1_slp"
8814   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8815         (ior:QI (match_dup 0)
8816                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8817    (clobber (reg:CC FLAGS_REG))]
8818   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8819    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8820   "or{b}\t{%1, %0|%0, %1}"
8821   [(set_attr "type" "alu1")
8822    (set_attr "mode" "QI")])
8823
8824 (define_insn "*iorqi_2"
8825   [(set (reg FLAGS_REG)
8826         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8827                          (match_operand:QI 2 "general_operand" "qim,qi"))
8828                  (const_int 0)))
8829    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8830         (ior:QI (match_dup 1) (match_dup 2)))]
8831   "ix86_match_ccmode (insn, CCNOmode)
8832    && ix86_binary_operator_ok (IOR, QImode, operands)"
8833   "or{b}\t{%2, %0|%0, %2}"
8834   [(set_attr "type" "alu")
8835    (set_attr "mode" "QI")])
8836
8837 (define_insn "*iorqi_2_slp"
8838   [(set (reg FLAGS_REG)
8839         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8840                          (match_operand:QI 1 "general_operand" "qim,qi"))
8841                  (const_int 0)))
8842    (set (strict_low_part (match_dup 0))
8843         (ior:QI (match_dup 0) (match_dup 1)))]
8844   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8845    && ix86_match_ccmode (insn, CCNOmode)
8846    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8847   "or{b}\t{%1, %0|%0, %1}"
8848   [(set_attr "type" "alu1")
8849    (set_attr "mode" "QI")])
8850
8851 (define_insn "*iorqi_3"
8852   [(set (reg FLAGS_REG)
8853         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8854                          (match_operand:QI 2 "general_operand" "qim"))
8855                  (const_int 0)))
8856    (clobber (match_scratch:QI 0 "=q"))]
8857   "ix86_match_ccmode (insn, CCNOmode)
8858    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8859   "or{b}\t{%2, %0|%0, %2}"
8860   [(set_attr "type" "alu")
8861    (set_attr "mode" "QI")])
8862
8863 (define_insn "iorqi_ext_0"
8864   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8865                          (const_int 8)
8866                          (const_int 8))
8867         (ior:SI
8868           (zero_extract:SI
8869             (match_operand 1 "ext_register_operand" "0")
8870             (const_int 8)
8871             (const_int 8))
8872           (match_operand 2 "const_int_operand" "n")))
8873    (clobber (reg:CC FLAGS_REG))]
8874   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8875   "or{b}\t{%2, %h0|%h0, %2}"
8876   [(set_attr "type" "alu")
8877    (set_attr "length_immediate" "1")
8878    (set_attr "mode" "QI")])
8879
8880 (define_insn "*iorqi_ext_1"
8881   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8882                          (const_int 8)
8883                          (const_int 8))
8884         (ior:SI
8885           (zero_extract:SI
8886             (match_operand 1 "ext_register_operand" "0")
8887             (const_int 8)
8888             (const_int 8))
8889           (zero_extend:SI
8890             (match_operand:QI 2 "general_operand" "Qm"))))
8891    (clobber (reg:CC FLAGS_REG))]
8892   "!TARGET_64BIT
8893    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8894   "or{b}\t{%2, %h0|%h0, %2}"
8895   [(set_attr "type" "alu")
8896    (set_attr "length_immediate" "0")
8897    (set_attr "mode" "QI")])
8898
8899 (define_insn "*iorqi_ext_1_rex64"
8900   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8901                          (const_int 8)
8902                          (const_int 8))
8903         (ior:SI
8904           (zero_extract:SI
8905             (match_operand 1 "ext_register_operand" "0")
8906             (const_int 8)
8907             (const_int 8))
8908           (zero_extend:SI
8909             (match_operand 2 "ext_register_operand" "Q"))))
8910    (clobber (reg:CC FLAGS_REG))]
8911   "TARGET_64BIT
8912    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8913   "or{b}\t{%2, %h0|%h0, %2}"
8914   [(set_attr "type" "alu")
8915    (set_attr "length_immediate" "0")
8916    (set_attr "mode" "QI")])
8917
8918 (define_insn "*iorqi_ext_2"
8919   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8920                          (const_int 8)
8921                          (const_int 8))
8922         (ior:SI
8923           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8924                            (const_int 8)
8925                            (const_int 8))
8926           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8927                            (const_int 8)
8928                            (const_int 8))))
8929    (clobber (reg:CC FLAGS_REG))]
8930   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8931   "ior{b}\t{%h2, %h0|%h0, %h2}"
8932   [(set_attr "type" "alu")
8933    (set_attr "length_immediate" "0")
8934    (set_attr "mode" "QI")])
8935
8936 (define_split
8937   [(set (match_operand 0 "register_operand" "")
8938         (ior (match_operand 1 "register_operand" "")
8939              (match_operand 2 "const_int_operand" "")))
8940    (clobber (reg:CC FLAGS_REG))]
8941    "reload_completed
8942     && QI_REG_P (operands[0])
8943     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8944     && !(INTVAL (operands[2]) & ~(255 << 8))
8945     && GET_MODE (operands[0]) != QImode"
8946   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8947                    (ior:SI (zero_extract:SI (match_dup 1)
8948                                             (const_int 8) (const_int 8))
8949                            (match_dup 2)))
8950               (clobber (reg:CC FLAGS_REG))])]
8951   "operands[0] = gen_lowpart (SImode, operands[0]);
8952    operands[1] = gen_lowpart (SImode, operands[1]);
8953    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8954
8955 ;; Since OR can be encoded with sign extended immediate, this is only
8956 ;; profitable when 7th bit is set.
8957 (define_split
8958   [(set (match_operand 0 "register_operand" "")
8959         (ior (match_operand 1 "general_operand" "")
8960              (match_operand 2 "const_int_operand" "")))
8961    (clobber (reg:CC FLAGS_REG))]
8962    "reload_completed
8963     && ANY_QI_REG_P (operands[0])
8964     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8965     && !(INTVAL (operands[2]) & ~255)
8966     && (INTVAL (operands[2]) & 128)
8967     && GET_MODE (operands[0]) != QImode"
8968   [(parallel [(set (strict_low_part (match_dup 0))
8969                    (ior:QI (match_dup 1)
8970                            (match_dup 2)))
8971               (clobber (reg:CC FLAGS_REG))])]
8972   "operands[0] = gen_lowpart (QImode, operands[0]);
8973    operands[1] = gen_lowpart (QImode, operands[1]);
8974    operands[2] = gen_lowpart (QImode, operands[2]);")
8975 \f
8976 ;; Logical XOR instructions
8977
8978 ;; %%% This used to optimize known byte-wide and operations to memory.
8979 ;; If this is considered useful, it should be done with splitters.
8980
8981 (define_expand "xordi3"
8982   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8983         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8984                 (match_operand:DI 2 "x86_64_general_operand" "")))
8985    (clobber (reg:CC FLAGS_REG))]
8986   "TARGET_64BIT"
8987   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8988
8989 (define_insn "*xordi_1_rex64"
8990   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8991         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8992                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8993    (clobber (reg:CC FLAGS_REG))]
8994   "TARGET_64BIT
8995    && ix86_binary_operator_ok (XOR, DImode, operands)"
8996   "@
8997    xor{q}\t{%2, %0|%0, %2}
8998    xor{q}\t{%2, %0|%0, %2}"
8999   [(set_attr "type" "alu")
9000    (set_attr "mode" "DI,DI")])
9001
9002 (define_insn "*xordi_2_rex64"
9003   [(set (reg FLAGS_REG)
9004         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9005                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9006                  (const_int 0)))
9007    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9008         (xor:DI (match_dup 1) (match_dup 2)))]
9009   "TARGET_64BIT
9010    && ix86_match_ccmode (insn, CCNOmode)
9011    && ix86_binary_operator_ok (XOR, DImode, operands)"
9012   "@
9013    xor{q}\t{%2, %0|%0, %2}
9014    xor{q}\t{%2, %0|%0, %2}"
9015   [(set_attr "type" "alu")
9016    (set_attr "mode" "DI,DI")])
9017
9018 (define_insn "*xordi_3_rex64"
9019   [(set (reg FLAGS_REG)
9020         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9021                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9022                  (const_int 0)))
9023    (clobber (match_scratch:DI 0 "=r"))]
9024   "TARGET_64BIT
9025    && ix86_match_ccmode (insn, CCNOmode)
9026    && ix86_binary_operator_ok (XOR, DImode, operands)"
9027   "xor{q}\t{%2, %0|%0, %2}"
9028   [(set_attr "type" "alu")
9029    (set_attr "mode" "DI")])
9030
9031 (define_expand "xorsi3"
9032   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9033         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9034                 (match_operand:SI 2 "general_operand" "")))
9035    (clobber (reg:CC FLAGS_REG))]
9036   ""
9037   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9038
9039 (define_insn "*xorsi_1"
9040   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9041         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9042                 (match_operand:SI 2 "general_operand" "ri,rm")))
9043    (clobber (reg:CC FLAGS_REG))]
9044   "ix86_binary_operator_ok (XOR, SImode, operands)"
9045   "xor{l}\t{%2, %0|%0, %2}"
9046   [(set_attr "type" "alu")
9047    (set_attr "mode" "SI")])
9048
9049 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9050 ;; Add speccase for immediates
9051 (define_insn "*xorsi_1_zext"
9052   [(set (match_operand:DI 0 "register_operand" "=r")
9053         (zero_extend:DI
9054           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9055                   (match_operand:SI 2 "general_operand" "rim"))))
9056    (clobber (reg:CC FLAGS_REG))]
9057   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9058   "xor{l}\t{%2, %k0|%k0, %2}"
9059   [(set_attr "type" "alu")
9060    (set_attr "mode" "SI")])
9061
9062 (define_insn "*xorsi_1_zext_imm"
9063   [(set (match_operand:DI 0 "register_operand" "=r")
9064         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9065                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9066    (clobber (reg:CC FLAGS_REG))]
9067   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9068   "xor{l}\t{%2, %k0|%k0, %2}"
9069   [(set_attr "type" "alu")
9070    (set_attr "mode" "SI")])
9071
9072 (define_insn "*xorsi_2"
9073   [(set (reg FLAGS_REG)
9074         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9075                          (match_operand:SI 2 "general_operand" "rim,ri"))
9076                  (const_int 0)))
9077    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9078         (xor:SI (match_dup 1) (match_dup 2)))]
9079   "ix86_match_ccmode (insn, CCNOmode)
9080    && ix86_binary_operator_ok (XOR, SImode, operands)"
9081   "xor{l}\t{%2, %0|%0, %2}"
9082   [(set_attr "type" "alu")
9083    (set_attr "mode" "SI")])
9084
9085 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9086 ;; ??? Special case for immediate operand is missing - it is tricky.
9087 (define_insn "*xorsi_2_zext"
9088   [(set (reg FLAGS_REG)
9089         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9090                          (match_operand:SI 2 "general_operand" "rim"))
9091                  (const_int 0)))
9092    (set (match_operand:DI 0 "register_operand" "=r")
9093         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9094   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9095    && ix86_binary_operator_ok (XOR, SImode, operands)"
9096   "xor{l}\t{%2, %k0|%k0, %2}"
9097   [(set_attr "type" "alu")
9098    (set_attr "mode" "SI")])
9099
9100 (define_insn "*xorsi_2_zext_imm"
9101   [(set (reg FLAGS_REG)
9102         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9103                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9104                  (const_int 0)))
9105    (set (match_operand:DI 0 "register_operand" "=r")
9106         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9107   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9108    && ix86_binary_operator_ok (XOR, SImode, operands)"
9109   "xor{l}\t{%2, %k0|%k0, %2}"
9110   [(set_attr "type" "alu")
9111    (set_attr "mode" "SI")])
9112
9113 (define_insn "*xorsi_3"
9114   [(set (reg FLAGS_REG)
9115         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9116                          (match_operand:SI 2 "general_operand" "rim"))
9117                  (const_int 0)))
9118    (clobber (match_scratch:SI 0 "=r"))]
9119   "ix86_match_ccmode (insn, CCNOmode)
9120    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9121   "xor{l}\t{%2, %0|%0, %2}"
9122   [(set_attr "type" "alu")
9123    (set_attr "mode" "SI")])
9124
9125 (define_expand "xorhi3"
9126   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9127         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9128                 (match_operand:HI 2 "general_operand" "")))
9129    (clobber (reg:CC FLAGS_REG))]
9130   "TARGET_HIMODE_MATH"
9131   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9132
9133 (define_insn "*xorhi_1"
9134   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9135         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9136                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "ix86_binary_operator_ok (XOR, HImode, operands)"
9139   "xor{w}\t{%2, %0|%0, %2}"
9140   [(set_attr "type" "alu")
9141    (set_attr "mode" "HI")])
9142
9143 (define_insn "*xorhi_2"
9144   [(set (reg FLAGS_REG)
9145         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9146                          (match_operand:HI 2 "general_operand" "rim,ri"))
9147                  (const_int 0)))
9148    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9149         (xor:HI (match_dup 1) (match_dup 2)))]
9150   "ix86_match_ccmode (insn, CCNOmode)
9151    && ix86_binary_operator_ok (XOR, HImode, operands)"
9152   "xor{w}\t{%2, %0|%0, %2}"
9153   [(set_attr "type" "alu")
9154    (set_attr "mode" "HI")])
9155
9156 (define_insn "*xorhi_3"
9157   [(set (reg FLAGS_REG)
9158         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9159                          (match_operand:HI 2 "general_operand" "rim"))
9160                  (const_int 0)))
9161    (clobber (match_scratch:HI 0 "=r"))]
9162   "ix86_match_ccmode (insn, CCNOmode)
9163    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9164   "xor{w}\t{%2, %0|%0, %2}"
9165   [(set_attr "type" "alu")
9166    (set_attr "mode" "HI")])
9167
9168 (define_expand "xorqi3"
9169   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9170         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9171                 (match_operand:QI 2 "general_operand" "")))
9172    (clobber (reg:CC FLAGS_REG))]
9173   "TARGET_QIMODE_MATH"
9174   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9175
9176 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9177 (define_insn "*xorqi_1"
9178   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9179         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9180                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9181    (clobber (reg:CC FLAGS_REG))]
9182   "ix86_binary_operator_ok (XOR, QImode, operands)"
9183   "@
9184    xor{b}\t{%2, %0|%0, %2}
9185    xor{b}\t{%2, %0|%0, %2}
9186    xor{l}\t{%k2, %k0|%k0, %k2}"
9187   [(set_attr "type" "alu")
9188    (set_attr "mode" "QI,QI,SI")])
9189
9190 (define_insn "*xorqi_1_slp"
9191   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9192         (xor:QI (match_dup 0)
9193                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9194    (clobber (reg:CC FLAGS_REG))]
9195   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9196    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9197   "xor{b}\t{%1, %0|%0, %1}"
9198   [(set_attr "type" "alu1")
9199    (set_attr "mode" "QI")])
9200
9201 (define_insn "xorqi_ext_0"
9202   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9203                          (const_int 8)
9204                          (const_int 8))
9205         (xor:SI
9206           (zero_extract:SI
9207             (match_operand 1 "ext_register_operand" "0")
9208             (const_int 8)
9209             (const_int 8))
9210           (match_operand 2 "const_int_operand" "n")))
9211    (clobber (reg:CC FLAGS_REG))]
9212   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9213   "xor{b}\t{%2, %h0|%h0, %2}"
9214   [(set_attr "type" "alu")
9215    (set_attr "length_immediate" "1")
9216    (set_attr "mode" "QI")])
9217
9218 (define_insn "*xorqi_ext_1"
9219   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9220                          (const_int 8)
9221                          (const_int 8))
9222         (xor:SI
9223           (zero_extract:SI
9224             (match_operand 1 "ext_register_operand" "0")
9225             (const_int 8)
9226             (const_int 8))
9227           (zero_extend:SI
9228             (match_operand:QI 2 "general_operand" "Qm"))))
9229    (clobber (reg:CC FLAGS_REG))]
9230   "!TARGET_64BIT
9231    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9232   "xor{b}\t{%2, %h0|%h0, %2}"
9233   [(set_attr "type" "alu")
9234    (set_attr "length_immediate" "0")
9235    (set_attr "mode" "QI")])
9236
9237 (define_insn "*xorqi_ext_1_rex64"
9238   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9239                          (const_int 8)
9240                          (const_int 8))
9241         (xor:SI
9242           (zero_extract:SI
9243             (match_operand 1 "ext_register_operand" "0")
9244             (const_int 8)
9245             (const_int 8))
9246           (zero_extend:SI
9247             (match_operand 2 "ext_register_operand" "Q"))))
9248    (clobber (reg:CC FLAGS_REG))]
9249   "TARGET_64BIT
9250    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9251   "xor{b}\t{%2, %h0|%h0, %2}"
9252   [(set_attr "type" "alu")
9253    (set_attr "length_immediate" "0")
9254    (set_attr "mode" "QI")])
9255
9256 (define_insn "*xorqi_ext_2"
9257   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9258                          (const_int 8)
9259                          (const_int 8))
9260         (xor:SI
9261           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9262                            (const_int 8)
9263                            (const_int 8))
9264           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9265                            (const_int 8)
9266                            (const_int 8))))
9267    (clobber (reg:CC FLAGS_REG))]
9268   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9269   "xor{b}\t{%h2, %h0|%h0, %h2}"
9270   [(set_attr "type" "alu")
9271    (set_attr "length_immediate" "0")
9272    (set_attr "mode" "QI")])
9273
9274 (define_insn "*xorqi_cc_1"
9275   [(set (reg FLAGS_REG)
9276         (compare
9277           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9278                   (match_operand:QI 2 "general_operand" "qim,qi"))
9279           (const_int 0)))
9280    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9281         (xor:QI (match_dup 1) (match_dup 2)))]
9282   "ix86_match_ccmode (insn, CCNOmode)
9283    && ix86_binary_operator_ok (XOR, QImode, operands)"
9284   "xor{b}\t{%2, %0|%0, %2}"
9285   [(set_attr "type" "alu")
9286    (set_attr "mode" "QI")])
9287
9288 (define_insn "*xorqi_2_slp"
9289   [(set (reg FLAGS_REG)
9290         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9291                          (match_operand:QI 1 "general_operand" "qim,qi"))
9292                  (const_int 0)))
9293    (set (strict_low_part (match_dup 0))
9294         (xor:QI (match_dup 0) (match_dup 1)))]
9295   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9296    && ix86_match_ccmode (insn, CCNOmode)
9297    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9298   "xor{b}\t{%1, %0|%0, %1}"
9299   [(set_attr "type" "alu1")
9300    (set_attr "mode" "QI")])
9301
9302 (define_insn "*xorqi_cc_2"
9303   [(set (reg FLAGS_REG)
9304         (compare
9305           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9306                   (match_operand:QI 2 "general_operand" "qim"))
9307           (const_int 0)))
9308    (clobber (match_scratch:QI 0 "=q"))]
9309   "ix86_match_ccmode (insn, CCNOmode)
9310    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9311   "xor{b}\t{%2, %0|%0, %2}"
9312   [(set_attr "type" "alu")
9313    (set_attr "mode" "QI")])
9314
9315 (define_insn "*xorqi_cc_ext_1"
9316   [(set (reg FLAGS_REG)
9317         (compare
9318           (xor:SI
9319             (zero_extract:SI
9320               (match_operand 1 "ext_register_operand" "0")
9321               (const_int 8)
9322               (const_int 8))
9323             (match_operand:QI 2 "general_operand" "qmn"))
9324           (const_int 0)))
9325    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9326                          (const_int 8)
9327                          (const_int 8))
9328         (xor:SI
9329           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9330           (match_dup 2)))]
9331   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9332   "xor{b}\t{%2, %h0|%h0, %2}"
9333   [(set_attr "type" "alu")
9334    (set_attr "mode" "QI")])
9335
9336 (define_insn "*xorqi_cc_ext_1_rex64"
9337   [(set (reg FLAGS_REG)
9338         (compare
9339           (xor:SI
9340             (zero_extract:SI
9341               (match_operand 1 "ext_register_operand" "0")
9342               (const_int 8)
9343               (const_int 8))
9344             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9345           (const_int 0)))
9346    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9347                          (const_int 8)
9348                          (const_int 8))
9349         (xor:SI
9350           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9351           (match_dup 2)))]
9352   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9353   "xor{b}\t{%2, %h0|%h0, %2}"
9354   [(set_attr "type" "alu")
9355    (set_attr "mode" "QI")])
9356
9357 (define_expand "xorqi_cc_ext_1"
9358   [(parallel [
9359      (set (reg:CCNO FLAGS_REG)
9360           (compare:CCNO
9361             (xor:SI
9362               (zero_extract:SI
9363                 (match_operand 1 "ext_register_operand" "")
9364                 (const_int 8)
9365                 (const_int 8))
9366               (match_operand:QI 2 "general_operand" ""))
9367             (const_int 0)))
9368      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9369                            (const_int 8)
9370                            (const_int 8))
9371           (xor:SI
9372             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9373             (match_dup 2)))])]
9374   ""
9375   "")
9376
9377 (define_split
9378   [(set (match_operand 0 "register_operand" "")
9379         (xor (match_operand 1 "register_operand" "")
9380              (match_operand 2 "const_int_operand" "")))
9381    (clobber (reg:CC FLAGS_REG))]
9382    "reload_completed
9383     && QI_REG_P (operands[0])
9384     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9385     && !(INTVAL (operands[2]) & ~(255 << 8))
9386     && GET_MODE (operands[0]) != QImode"
9387   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9388                    (xor:SI (zero_extract:SI (match_dup 1)
9389                                             (const_int 8) (const_int 8))
9390                            (match_dup 2)))
9391               (clobber (reg:CC FLAGS_REG))])]
9392   "operands[0] = gen_lowpart (SImode, operands[0]);
9393    operands[1] = gen_lowpart (SImode, operands[1]);
9394    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9395
9396 ;; Since XOR can be encoded with sign extended immediate, this is only
9397 ;; profitable when 7th bit is set.
9398 (define_split
9399   [(set (match_operand 0 "register_operand" "")
9400         (xor (match_operand 1 "general_operand" "")
9401              (match_operand 2 "const_int_operand" "")))
9402    (clobber (reg:CC FLAGS_REG))]
9403    "reload_completed
9404     && ANY_QI_REG_P (operands[0])
9405     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9406     && !(INTVAL (operands[2]) & ~255)
9407     && (INTVAL (operands[2]) & 128)
9408     && GET_MODE (operands[0]) != QImode"
9409   [(parallel [(set (strict_low_part (match_dup 0))
9410                    (xor:QI (match_dup 1)
9411                            (match_dup 2)))
9412               (clobber (reg:CC FLAGS_REG))])]
9413   "operands[0] = gen_lowpart (QImode, operands[0]);
9414    operands[1] = gen_lowpart (QImode, operands[1]);
9415    operands[2] = gen_lowpart (QImode, operands[2]);")
9416 \f
9417 ;; Negation instructions
9418
9419 (define_expand "negti2"
9420   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9421                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9422               (clobber (reg:CC FLAGS_REG))])]
9423   "TARGET_64BIT"
9424   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9425
9426 (define_insn "*negti2_1"
9427   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9428         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9429    (clobber (reg:CC FLAGS_REG))]
9430   "TARGET_64BIT
9431    && ix86_unary_operator_ok (NEG, TImode, operands)"
9432   "#")
9433
9434 (define_split
9435   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9436         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9437    (clobber (reg:CC FLAGS_REG))]
9438   "TARGET_64BIT && reload_completed"
9439   [(parallel
9440     [(set (reg:CCZ FLAGS_REG)
9441           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9442      (set (match_dup 0) (neg:DI (match_dup 2)))])
9443    (parallel
9444     [(set (match_dup 1)
9445           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9446                             (match_dup 3))
9447                    (const_int 0)))
9448      (clobber (reg:CC FLAGS_REG))])
9449    (parallel
9450     [(set (match_dup 1)
9451           (neg:DI (match_dup 1)))
9452      (clobber (reg:CC FLAGS_REG))])]
9453   "split_ti (operands+1, 1, operands+2, operands+3);
9454    split_ti (operands+0, 1, operands+0, operands+1);")
9455
9456 (define_expand "negdi2"
9457   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9458                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9459               (clobber (reg:CC FLAGS_REG))])]
9460   ""
9461   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9462
9463 (define_insn "*negdi2_1"
9464   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9465         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9466    (clobber (reg:CC FLAGS_REG))]
9467   "!TARGET_64BIT
9468    && ix86_unary_operator_ok (NEG, DImode, operands)"
9469   "#")
9470
9471 (define_split
9472   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9473         (neg:DI (match_operand:DI 1 "general_operand" "")))
9474    (clobber (reg:CC FLAGS_REG))]
9475   "!TARGET_64BIT && reload_completed"
9476   [(parallel
9477     [(set (reg:CCZ FLAGS_REG)
9478           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9479      (set (match_dup 0) (neg:SI (match_dup 2)))])
9480    (parallel
9481     [(set (match_dup 1)
9482           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9483                             (match_dup 3))
9484                    (const_int 0)))
9485      (clobber (reg:CC FLAGS_REG))])
9486    (parallel
9487     [(set (match_dup 1)
9488           (neg:SI (match_dup 1)))
9489      (clobber (reg:CC FLAGS_REG))])]
9490   "split_di (operands+1, 1, operands+2, operands+3);
9491    split_di (operands+0, 1, operands+0, operands+1);")
9492
9493 (define_insn "*negdi2_1_rex64"
9494   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9495         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9496    (clobber (reg:CC FLAGS_REG))]
9497   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9498   "neg{q}\t%0"
9499   [(set_attr "type" "negnot")
9500    (set_attr "mode" "DI")])
9501
9502 ;; The problem with neg is that it does not perform (compare x 0),
9503 ;; it really performs (compare 0 x), which leaves us with the zero
9504 ;; flag being the only useful item.
9505
9506 (define_insn "*negdi2_cmpz_rex64"
9507   [(set (reg:CCZ FLAGS_REG)
9508         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9509                      (const_int 0)))
9510    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9511         (neg:DI (match_dup 1)))]
9512   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9513   "neg{q}\t%0"
9514   [(set_attr "type" "negnot")
9515    (set_attr "mode" "DI")])
9516
9517
9518 (define_expand "negsi2"
9519   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9520                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9521               (clobber (reg:CC FLAGS_REG))])]
9522   ""
9523   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9524
9525 (define_insn "*negsi2_1"
9526   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9527         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9528    (clobber (reg:CC FLAGS_REG))]
9529   "ix86_unary_operator_ok (NEG, SImode, operands)"
9530   "neg{l}\t%0"
9531   [(set_attr "type" "negnot")
9532    (set_attr "mode" "SI")])
9533
9534 ;; Combine is quite creative about this pattern.
9535 (define_insn "*negsi2_1_zext"
9536   [(set (match_operand:DI 0 "register_operand" "=r")
9537         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9538                                         (const_int 32)))
9539                      (const_int 32)))
9540    (clobber (reg:CC FLAGS_REG))]
9541   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9542   "neg{l}\t%k0"
9543   [(set_attr "type" "negnot")
9544    (set_attr "mode" "SI")])
9545
9546 ;; The problem with neg is that it does not perform (compare x 0),
9547 ;; it really performs (compare 0 x), which leaves us with the zero
9548 ;; flag being the only useful item.
9549
9550 (define_insn "*negsi2_cmpz"
9551   [(set (reg:CCZ FLAGS_REG)
9552         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9553                      (const_int 0)))
9554    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9555         (neg:SI (match_dup 1)))]
9556   "ix86_unary_operator_ok (NEG, SImode, operands)"
9557   "neg{l}\t%0"
9558   [(set_attr "type" "negnot")
9559    (set_attr "mode" "SI")])
9560
9561 (define_insn "*negsi2_cmpz_zext"
9562   [(set (reg:CCZ FLAGS_REG)
9563         (compare:CCZ (lshiftrt:DI
9564                        (neg:DI (ashift:DI
9565                                  (match_operand:DI 1 "register_operand" "0")
9566                                  (const_int 32)))
9567                        (const_int 32))
9568                      (const_int 0)))
9569    (set (match_operand:DI 0 "register_operand" "=r")
9570         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9571                                         (const_int 32)))
9572                      (const_int 32)))]
9573   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9574   "neg{l}\t%k0"
9575   [(set_attr "type" "negnot")
9576    (set_attr "mode" "SI")])
9577
9578 (define_expand "neghi2"
9579   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9580                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9581               (clobber (reg:CC FLAGS_REG))])]
9582   "TARGET_HIMODE_MATH"
9583   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9584
9585 (define_insn "*neghi2_1"
9586   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9587         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9588    (clobber (reg:CC FLAGS_REG))]
9589   "ix86_unary_operator_ok (NEG, HImode, operands)"
9590   "neg{w}\t%0"
9591   [(set_attr "type" "negnot")
9592    (set_attr "mode" "HI")])
9593
9594 (define_insn "*neghi2_cmpz"
9595   [(set (reg:CCZ FLAGS_REG)
9596         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9597                      (const_int 0)))
9598    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9599         (neg:HI (match_dup 1)))]
9600   "ix86_unary_operator_ok (NEG, HImode, operands)"
9601   "neg{w}\t%0"
9602   [(set_attr "type" "negnot")
9603    (set_attr "mode" "HI")])
9604
9605 (define_expand "negqi2"
9606   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9607                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9608               (clobber (reg:CC FLAGS_REG))])]
9609   "TARGET_QIMODE_MATH"
9610   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9611
9612 (define_insn "*negqi2_1"
9613   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9614         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9615    (clobber (reg:CC FLAGS_REG))]
9616   "ix86_unary_operator_ok (NEG, QImode, operands)"
9617   "neg{b}\t%0"
9618   [(set_attr "type" "negnot")
9619    (set_attr "mode" "QI")])
9620
9621 (define_insn "*negqi2_cmpz"
9622   [(set (reg:CCZ FLAGS_REG)
9623         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9624                      (const_int 0)))
9625    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9626         (neg:QI (match_dup 1)))]
9627   "ix86_unary_operator_ok (NEG, QImode, operands)"
9628   "neg{b}\t%0"
9629   [(set_attr "type" "negnot")
9630    (set_attr "mode" "QI")])
9631
9632 ;; Changing of sign for FP values is doable using integer unit too.
9633
9634 (define_expand "negsf2"
9635   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9636         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9637   "TARGET_80387 || TARGET_SSE_MATH"
9638   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9639
9640 (define_expand "abssf2"
9641   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9642         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9643   "TARGET_80387 || TARGET_SSE_MATH"
9644   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9645
9646 (define_insn "*absnegsf2_mixed"
9647   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9648         (match_operator:SF 3 "absneg_operator"
9649           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9650    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9651    (clobber (reg:CC FLAGS_REG))]
9652   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9653    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9654   "#")
9655
9656 (define_insn "*absnegsf2_sse"
9657   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9658         (match_operator:SF 3 "absneg_operator"
9659           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9660    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9661    (clobber (reg:CC FLAGS_REG))]
9662   "TARGET_SSE_MATH
9663    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9664   "#")
9665
9666 (define_insn "*absnegsf2_i387"
9667   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9668         (match_operator:SF 3 "absneg_operator"
9669           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9670    (use (match_operand 2 "" ""))
9671    (clobber (reg:CC FLAGS_REG))]
9672   "TARGET_80387 && !TARGET_SSE_MATH
9673    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9674   "#")
9675
9676 (define_expand "copysignsf3"
9677   [(match_operand:SF 0 "register_operand" "")
9678    (match_operand:SF 1 "nonmemory_operand" "")
9679    (match_operand:SF 2 "register_operand" "")]
9680   "TARGET_SSE_MATH"
9681 {
9682   ix86_expand_copysign (operands);
9683   DONE;
9684 })
9685
9686 (define_insn_and_split "copysignsf3_const"
9687   [(set (match_operand:SF 0 "register_operand"          "=x")
9688         (unspec:SF
9689           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9690            (match_operand:SF 2 "register_operand"       "0")
9691            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9692           UNSPEC_COPYSIGN))]
9693   "TARGET_SSE_MATH"
9694   "#"
9695   "&& reload_completed"
9696   [(const_int 0)]
9697 {
9698   ix86_split_copysign_const (operands);
9699   DONE;
9700 })
9701
9702 (define_insn "copysignsf3_var"
9703   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9704         (unspec:SF
9705           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9706            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9707            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9708            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9709           UNSPEC_COPYSIGN))
9710    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9711   "TARGET_SSE_MATH"
9712   "#")
9713
9714 (define_split
9715   [(set (match_operand:SF 0 "register_operand" "")
9716         (unspec:SF
9717           [(match_operand:SF 2 "register_operand" "")
9718            (match_operand:SF 3 "register_operand" "")
9719            (match_operand:V4SF 4 "" "")
9720            (match_operand:V4SF 5 "" "")]
9721           UNSPEC_COPYSIGN))
9722    (clobber (match_scratch:V4SF 1 ""))]
9723   "TARGET_SSE_MATH && reload_completed"
9724   [(const_int 0)]
9725 {
9726   ix86_split_copysign_var (operands);
9727   DONE;
9728 })
9729
9730 (define_expand "negdf2"
9731   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9732         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9733   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9734   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9735
9736 (define_expand "absdf2"
9737   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9738         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9739   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9740   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9741
9742 (define_insn "*absnegdf2_mixed"
9743   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9744         (match_operator:DF 3 "absneg_operator"
9745           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9746    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9747    (clobber (reg:CC FLAGS_REG))]
9748   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9749    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9750   "#")
9751
9752 (define_insn "*absnegdf2_sse"
9753   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9754         (match_operator:DF 3 "absneg_operator"
9755           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9756    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9757    (clobber (reg:CC FLAGS_REG))]
9758   "TARGET_SSE2 && TARGET_SSE_MATH
9759    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9760   "#")
9761
9762 (define_insn "*absnegdf2_i387"
9763   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9764         (match_operator:DF 3 "absneg_operator"
9765           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9766    (use (match_operand 2 "" ""))
9767    (clobber (reg:CC FLAGS_REG))]
9768   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9769    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9770   "#")
9771
9772 (define_expand "copysigndf3"
9773   [(match_operand:DF 0 "register_operand" "")
9774    (match_operand:DF 1 "nonmemory_operand" "")
9775    (match_operand:DF 2 "register_operand" "")]
9776   "TARGET_SSE2 && TARGET_SSE_MATH"
9777 {
9778   ix86_expand_copysign (operands);
9779   DONE;
9780 })
9781
9782 (define_insn_and_split "copysigndf3_const"
9783   [(set (match_operand:DF 0 "register_operand"          "=x")
9784         (unspec:DF
9785           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9786            (match_operand:DF 2 "register_operand"       "0")
9787            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9788           UNSPEC_COPYSIGN))]
9789   "TARGET_SSE2 && TARGET_SSE_MATH"
9790   "#"
9791   "&& reload_completed"
9792   [(const_int 0)]
9793 {
9794   ix86_split_copysign_const (operands);
9795   DONE;
9796 })
9797
9798 (define_insn "copysigndf3_var"
9799   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9800         (unspec:DF
9801           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9802            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9803            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9804            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9805           UNSPEC_COPYSIGN))
9806    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9807   "TARGET_SSE2 && TARGET_SSE_MATH"
9808   "#")
9809
9810 (define_split
9811   [(set (match_operand:DF 0 "register_operand" "")
9812         (unspec:DF
9813           [(match_operand:DF 2 "register_operand" "")
9814            (match_operand:DF 3 "register_operand" "")
9815            (match_operand:V2DF 4 "" "")
9816            (match_operand:V2DF 5 "" "")]
9817           UNSPEC_COPYSIGN))
9818    (clobber (match_scratch:V2DF 1 ""))]
9819   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9820   [(const_int 0)]
9821 {
9822   ix86_split_copysign_var (operands);
9823   DONE;
9824 })
9825
9826 (define_expand "negxf2"
9827   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9828         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9829   "TARGET_80387"
9830   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9831
9832 (define_expand "absxf2"
9833   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9834         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9835   "TARGET_80387"
9836   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9837
9838 (define_insn "*absnegxf2_i387"
9839   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9840         (match_operator:XF 3 "absneg_operator"
9841           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9842    (use (match_operand 2 "" ""))
9843    (clobber (reg:CC FLAGS_REG))]
9844   "TARGET_80387
9845    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9846   "#")
9847
9848 ;; Splitters for fp abs and neg.
9849
9850 (define_split
9851   [(set (match_operand 0 "fp_register_operand" "")
9852         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9853    (use (match_operand 2 "" ""))
9854    (clobber (reg:CC FLAGS_REG))]
9855   "reload_completed"
9856   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9857
9858 (define_split
9859   [(set (match_operand 0 "register_operand" "")
9860         (match_operator 3 "absneg_operator"
9861           [(match_operand 1 "register_operand" "")]))
9862    (use (match_operand 2 "nonimmediate_operand" ""))
9863    (clobber (reg:CC FLAGS_REG))]
9864   "reload_completed && SSE_REG_P (operands[0])"
9865   [(set (match_dup 0) (match_dup 3))]
9866 {
9867   enum machine_mode mode = GET_MODE (operands[0]);
9868   enum machine_mode vmode = GET_MODE (operands[2]);
9869   rtx tmp;
9870
9871   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9872   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9873   if (operands_match_p (operands[0], operands[2]))
9874     {
9875       tmp = operands[1];
9876       operands[1] = operands[2];
9877       operands[2] = tmp;
9878     }
9879   if (GET_CODE (operands[3]) == ABS)
9880     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9881   else
9882     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9883   operands[3] = tmp;
9884 })
9885
9886 (define_split
9887   [(set (match_operand:SF 0 "register_operand" "")
9888         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9889    (use (match_operand:V4SF 2 "" ""))
9890    (clobber (reg:CC FLAGS_REG))]
9891   "reload_completed"
9892   [(parallel [(set (match_dup 0) (match_dup 1))
9893               (clobber (reg:CC FLAGS_REG))])]
9894 {
9895   rtx tmp;
9896   operands[0] = gen_lowpart (SImode, operands[0]);
9897   if (GET_CODE (operands[1]) == ABS)
9898     {
9899       tmp = gen_int_mode (0x7fffffff, SImode);
9900       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9901     }
9902   else
9903     {
9904       tmp = gen_int_mode (0x80000000, SImode);
9905       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9906     }
9907   operands[1] = tmp;
9908 })
9909
9910 (define_split
9911   [(set (match_operand:DF 0 "register_operand" "")
9912         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9913    (use (match_operand 2 "" ""))
9914    (clobber (reg:CC FLAGS_REG))]
9915   "reload_completed"
9916   [(parallel [(set (match_dup 0) (match_dup 1))
9917               (clobber (reg:CC FLAGS_REG))])]
9918 {
9919   rtx tmp;
9920   if (TARGET_64BIT)
9921     {
9922       tmp = gen_lowpart (DImode, operands[0]);
9923       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9924       operands[0] = tmp;
9925
9926       if (GET_CODE (operands[1]) == ABS)
9927         tmp = const0_rtx;
9928       else
9929         tmp = gen_rtx_NOT (DImode, tmp);
9930     }
9931   else
9932     {
9933       operands[0] = gen_highpart (SImode, operands[0]);
9934       if (GET_CODE (operands[1]) == ABS)
9935         {
9936           tmp = gen_int_mode (0x7fffffff, SImode);
9937           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9938         }
9939       else
9940         {
9941           tmp = gen_int_mode (0x80000000, SImode);
9942           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9943         }
9944     }
9945   operands[1] = tmp;
9946 })
9947
9948 (define_split
9949   [(set (match_operand:XF 0 "register_operand" "")
9950         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9951    (use (match_operand 2 "" ""))
9952    (clobber (reg:CC FLAGS_REG))]
9953   "reload_completed"
9954   [(parallel [(set (match_dup 0) (match_dup 1))
9955               (clobber (reg:CC FLAGS_REG))])]
9956 {
9957   rtx tmp;
9958   operands[0] = gen_rtx_REG (SImode,
9959                              true_regnum (operands[0])
9960                              + (TARGET_64BIT ? 1 : 2));
9961   if (GET_CODE (operands[1]) == ABS)
9962     {
9963       tmp = GEN_INT (0x7fff);
9964       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9965     }
9966   else
9967     {
9968       tmp = GEN_INT (0x8000);
9969       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9970     }
9971   operands[1] = tmp;
9972 })
9973
9974 (define_split
9975   [(set (match_operand 0 "memory_operand" "")
9976         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9977    (use (match_operand 2 "" ""))
9978    (clobber (reg:CC FLAGS_REG))]
9979   "reload_completed"
9980   [(parallel [(set (match_dup 0) (match_dup 1))
9981               (clobber (reg:CC FLAGS_REG))])]
9982 {
9983   enum machine_mode mode = GET_MODE (operands[0]);
9984   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9985   rtx tmp;
9986
9987   operands[0] = adjust_address (operands[0], QImode, size - 1);
9988   if (GET_CODE (operands[1]) == ABS)
9989     {
9990       tmp = gen_int_mode (0x7f, QImode);
9991       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9992     }
9993   else
9994     {
9995       tmp = gen_int_mode (0x80, QImode);
9996       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9997     }
9998   operands[1] = tmp;
9999 })
10000
10001 ;; Conditionalize these after reload. If they match before reload, we
10002 ;; lose the clobber and ability to use integer instructions.
10003
10004 (define_insn "*negsf2_1"
10005   [(set (match_operand:SF 0 "register_operand" "=f")
10006         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10007   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10008   "fchs"
10009   [(set_attr "type" "fsgn")
10010    (set_attr "mode" "SF")])
10011
10012 (define_insn "*negdf2_1"
10013   [(set (match_operand:DF 0 "register_operand" "=f")
10014         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10015   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10016   "fchs"
10017   [(set_attr "type" "fsgn")
10018    (set_attr "mode" "DF")])
10019
10020 (define_insn "*negxf2_1"
10021   [(set (match_operand:XF 0 "register_operand" "=f")
10022         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10023   "TARGET_80387"
10024   "fchs"
10025   [(set_attr "type" "fsgn")
10026    (set_attr "mode" "XF")])
10027
10028 (define_insn "*abssf2_1"
10029   [(set (match_operand:SF 0 "register_operand" "=f")
10030         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10031   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10032   "fabs"
10033   [(set_attr "type" "fsgn")
10034    (set_attr "mode" "SF")])
10035
10036 (define_insn "*absdf2_1"
10037   [(set (match_operand:DF 0 "register_operand" "=f")
10038         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10039   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10040   "fabs"
10041   [(set_attr "type" "fsgn")
10042    (set_attr "mode" "DF")])
10043
10044 (define_insn "*absxf2_1"
10045   [(set (match_operand:XF 0 "register_operand" "=f")
10046         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10047   "TARGET_80387"
10048   "fabs"
10049   [(set_attr "type" "fsgn")
10050    (set_attr "mode" "DF")])
10051
10052 (define_insn "*negextendsfdf2"
10053   [(set (match_operand:DF 0 "register_operand" "=f")
10054         (neg:DF (float_extend:DF
10055                   (match_operand:SF 1 "register_operand" "0"))))]
10056   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10057   "fchs"
10058   [(set_attr "type" "fsgn")
10059    (set_attr "mode" "DF")])
10060
10061 (define_insn "*negextenddfxf2"
10062   [(set (match_operand:XF 0 "register_operand" "=f")
10063         (neg:XF (float_extend:XF
10064                   (match_operand:DF 1 "register_operand" "0"))))]
10065   "TARGET_80387"
10066   "fchs"
10067   [(set_attr "type" "fsgn")
10068    (set_attr "mode" "XF")])
10069
10070 (define_insn "*negextendsfxf2"
10071   [(set (match_operand:XF 0 "register_operand" "=f")
10072         (neg:XF (float_extend:XF
10073                   (match_operand:SF 1 "register_operand" "0"))))]
10074   "TARGET_80387"
10075   "fchs"
10076   [(set_attr "type" "fsgn")
10077    (set_attr "mode" "XF")])
10078
10079 (define_insn "*absextendsfdf2"
10080   [(set (match_operand:DF 0 "register_operand" "=f")
10081         (abs:DF (float_extend:DF
10082                   (match_operand:SF 1 "register_operand" "0"))))]
10083   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10084   "fabs"
10085   [(set_attr "type" "fsgn")
10086    (set_attr "mode" "DF")])
10087
10088 (define_insn "*absextenddfxf2"
10089   [(set (match_operand:XF 0 "register_operand" "=f")
10090         (abs:XF (float_extend:XF
10091           (match_operand:DF 1 "register_operand" "0"))))]
10092   "TARGET_80387"
10093   "fabs"
10094   [(set_attr "type" "fsgn")
10095    (set_attr "mode" "XF")])
10096
10097 (define_insn "*absextendsfxf2"
10098   [(set (match_operand:XF 0 "register_operand" "=f")
10099         (abs:XF (float_extend:XF
10100           (match_operand:SF 1 "register_operand" "0"))))]
10101   "TARGET_80387"
10102   "fabs"
10103   [(set_attr "type" "fsgn")
10104    (set_attr "mode" "XF")])
10105 \f
10106 ;; One complement instructions
10107
10108 (define_expand "one_cmpldi2"
10109   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10110         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10111   "TARGET_64BIT"
10112   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10113
10114 (define_insn "*one_cmpldi2_1_rex64"
10115   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10116         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10117   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10118   "not{q}\t%0"
10119   [(set_attr "type" "negnot")
10120    (set_attr "mode" "DI")])
10121
10122 (define_insn "*one_cmpldi2_2_rex64"
10123   [(set (reg FLAGS_REG)
10124         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10125                  (const_int 0)))
10126    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10127         (not:DI (match_dup 1)))]
10128   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10129    && ix86_unary_operator_ok (NOT, DImode, operands)"
10130   "#"
10131   [(set_attr "type" "alu1")
10132    (set_attr "mode" "DI")])
10133
10134 (define_split
10135   [(set (match_operand 0 "flags_reg_operand" "")
10136         (match_operator 2 "compare_operator"
10137           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10138            (const_int 0)]))
10139    (set (match_operand:DI 1 "nonimmediate_operand" "")
10140         (not:DI (match_dup 3)))]
10141   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10142   [(parallel [(set (match_dup 0)
10143                    (match_op_dup 2
10144                      [(xor:DI (match_dup 3) (const_int -1))
10145                       (const_int 0)]))
10146               (set (match_dup 1)
10147                    (xor:DI (match_dup 3) (const_int -1)))])]
10148   "")
10149
10150 (define_expand "one_cmplsi2"
10151   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10152         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10153   ""
10154   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10155
10156 (define_insn "*one_cmplsi2_1"
10157   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10158         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10159   "ix86_unary_operator_ok (NOT, SImode, operands)"
10160   "not{l}\t%0"
10161   [(set_attr "type" "negnot")
10162    (set_attr "mode" "SI")])
10163
10164 ;; ??? Currently never generated - xor is used instead.
10165 (define_insn "*one_cmplsi2_1_zext"
10166   [(set (match_operand:DI 0 "register_operand" "=r")
10167         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10168   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10169   "not{l}\t%k0"
10170   [(set_attr "type" "negnot")
10171    (set_attr "mode" "SI")])
10172
10173 (define_insn "*one_cmplsi2_2"
10174   [(set (reg FLAGS_REG)
10175         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10176                  (const_int 0)))
10177    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10178         (not:SI (match_dup 1)))]
10179   "ix86_match_ccmode (insn, CCNOmode)
10180    && ix86_unary_operator_ok (NOT, SImode, operands)"
10181   "#"
10182   [(set_attr "type" "alu1")
10183    (set_attr "mode" "SI")])
10184
10185 (define_split
10186   [(set (match_operand 0 "flags_reg_operand" "")
10187         (match_operator 2 "compare_operator"
10188           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10189            (const_int 0)]))
10190    (set (match_operand:SI 1 "nonimmediate_operand" "")
10191         (not:SI (match_dup 3)))]
10192   "ix86_match_ccmode (insn, CCNOmode)"
10193   [(parallel [(set (match_dup 0)
10194                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10195                                     (const_int 0)]))
10196               (set (match_dup 1)
10197                    (xor:SI (match_dup 3) (const_int -1)))])]
10198   "")
10199
10200 ;; ??? Currently never generated - xor is used instead.
10201 (define_insn "*one_cmplsi2_2_zext"
10202   [(set (reg FLAGS_REG)
10203         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10204                  (const_int 0)))
10205    (set (match_operand:DI 0 "register_operand" "=r")
10206         (zero_extend:DI (not:SI (match_dup 1))))]
10207   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10208    && ix86_unary_operator_ok (NOT, SImode, operands)"
10209   "#"
10210   [(set_attr "type" "alu1")
10211    (set_attr "mode" "SI")])
10212
10213 (define_split
10214   [(set (match_operand 0 "flags_reg_operand" "")
10215         (match_operator 2 "compare_operator"
10216           [(not:SI (match_operand:SI 3 "register_operand" ""))
10217            (const_int 0)]))
10218    (set (match_operand:DI 1 "register_operand" "")
10219         (zero_extend:DI (not:SI (match_dup 3))))]
10220   "ix86_match_ccmode (insn, CCNOmode)"
10221   [(parallel [(set (match_dup 0)
10222                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10223                                     (const_int 0)]))
10224               (set (match_dup 1)
10225                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10226   "")
10227
10228 (define_expand "one_cmplhi2"
10229   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10230         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10231   "TARGET_HIMODE_MATH"
10232   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10233
10234 (define_insn "*one_cmplhi2_1"
10235   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10236         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10237   "ix86_unary_operator_ok (NOT, HImode, operands)"
10238   "not{w}\t%0"
10239   [(set_attr "type" "negnot")
10240    (set_attr "mode" "HI")])
10241
10242 (define_insn "*one_cmplhi2_2"
10243   [(set (reg FLAGS_REG)
10244         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10245                  (const_int 0)))
10246    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10247         (not:HI (match_dup 1)))]
10248   "ix86_match_ccmode (insn, CCNOmode)
10249    && ix86_unary_operator_ok (NEG, HImode, operands)"
10250   "#"
10251   [(set_attr "type" "alu1")
10252    (set_attr "mode" "HI")])
10253
10254 (define_split
10255   [(set (match_operand 0 "flags_reg_operand" "")
10256         (match_operator 2 "compare_operator"
10257           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10258            (const_int 0)]))
10259    (set (match_operand:HI 1 "nonimmediate_operand" "")
10260         (not:HI (match_dup 3)))]
10261   "ix86_match_ccmode (insn, CCNOmode)"
10262   [(parallel [(set (match_dup 0)
10263                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10264                                     (const_int 0)]))
10265               (set (match_dup 1)
10266                    (xor:HI (match_dup 3) (const_int -1)))])]
10267   "")
10268
10269 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10270 (define_expand "one_cmplqi2"
10271   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10272         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10273   "TARGET_QIMODE_MATH"
10274   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10275
10276 (define_insn "*one_cmplqi2_1"
10277   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10278         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10279   "ix86_unary_operator_ok (NOT, QImode, operands)"
10280   "@
10281    not{b}\t%0
10282    not{l}\t%k0"
10283   [(set_attr "type" "negnot")
10284    (set_attr "mode" "QI,SI")])
10285
10286 (define_insn "*one_cmplqi2_2"
10287   [(set (reg FLAGS_REG)
10288         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10289                  (const_int 0)))
10290    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10291         (not:QI (match_dup 1)))]
10292   "ix86_match_ccmode (insn, CCNOmode)
10293    && ix86_unary_operator_ok (NOT, QImode, operands)"
10294   "#"
10295   [(set_attr "type" "alu1")
10296    (set_attr "mode" "QI")])
10297
10298 (define_split
10299   [(set (match_operand 0 "flags_reg_operand" "")
10300         (match_operator 2 "compare_operator"
10301           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10302            (const_int 0)]))
10303    (set (match_operand:QI 1 "nonimmediate_operand" "")
10304         (not:QI (match_dup 3)))]
10305   "ix86_match_ccmode (insn, CCNOmode)"
10306   [(parallel [(set (match_dup 0)
10307                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10308                                     (const_int 0)]))
10309               (set (match_dup 1)
10310                    (xor:QI (match_dup 3) (const_int -1)))])]
10311   "")
10312 \f
10313 ;; Arithmetic shift instructions
10314
10315 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10316 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10317 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10318 ;; from the assembler input.
10319 ;;
10320 ;; This instruction shifts the target reg/mem as usual, but instead of
10321 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10322 ;; is a left shift double, bits are taken from the high order bits of
10323 ;; reg, else if the insn is a shift right double, bits are taken from the
10324 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10325 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10326 ;;
10327 ;; Since sh[lr]d does not change the `reg' operand, that is done
10328 ;; separately, making all shifts emit pairs of shift double and normal
10329 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10330 ;; support a 63 bit shift, each shift where the count is in a reg expands
10331 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10332 ;;
10333 ;; If the shift count is a constant, we need never emit more than one
10334 ;; shift pair, instead using moves and sign extension for counts greater
10335 ;; than 31.
10336
10337 (define_expand "ashlti3"
10338   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10339                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10340                               (match_operand:QI 2 "nonmemory_operand" "")))
10341               (clobber (reg:CC FLAGS_REG))])]
10342   "TARGET_64BIT"
10343 {
10344   if (! immediate_operand (operands[2], QImode))
10345     {
10346       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10347       DONE;
10348     }
10349   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10350   DONE;
10351 })
10352
10353 (define_insn "ashlti3_1"
10354   [(set (match_operand:TI 0 "register_operand" "=r")
10355         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10356                    (match_operand:QI 2 "register_operand" "c")))
10357    (clobber (match_scratch:DI 3 "=&r"))
10358    (clobber (reg:CC FLAGS_REG))]
10359   "TARGET_64BIT"
10360   "#"
10361   [(set_attr "type" "multi")])
10362
10363 (define_insn "*ashlti3_2"
10364   [(set (match_operand:TI 0 "register_operand" "=r")
10365         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10366                    (match_operand:QI 2 "immediate_operand" "O")))
10367    (clobber (reg:CC FLAGS_REG))]
10368   "TARGET_64BIT"
10369   "#"
10370   [(set_attr "type" "multi")])
10371
10372 (define_split
10373   [(set (match_operand:TI 0 "register_operand" "")
10374         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10375                    (match_operand:QI 2 "register_operand" "")))
10376    (clobber (match_scratch:DI 3 ""))
10377    (clobber (reg:CC FLAGS_REG))]
10378   "TARGET_64BIT && reload_completed"
10379   [(const_int 0)]
10380   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10381
10382 (define_split
10383   [(set (match_operand:TI 0 "register_operand" "")
10384         (ashift:TI (match_operand:TI 1 "register_operand" "")
10385                    (match_operand:QI 2 "immediate_operand" "")))
10386    (clobber (reg:CC FLAGS_REG))]
10387   "TARGET_64BIT && reload_completed"
10388   [(const_int 0)]
10389   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10390
10391 (define_insn "x86_64_shld"
10392   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10393         (ior:DI (ashift:DI (match_dup 0)
10394                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10395                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10396                   (minus:QI (const_int 64) (match_dup 2)))))
10397    (clobber (reg:CC FLAGS_REG))]
10398   "TARGET_64BIT"
10399   "@
10400    shld{q}\t{%2, %1, %0|%0, %1, %2}
10401    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10402   [(set_attr "type" "ishift")
10403    (set_attr "prefix_0f" "1")
10404    (set_attr "mode" "DI")
10405    (set_attr "athlon_decode" "vector")
10406    (set_attr "amdfam10_decode" "vector")])   
10407
10408 (define_expand "x86_64_shift_adj"
10409   [(set (reg:CCZ FLAGS_REG)
10410         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10411                              (const_int 64))
10412                      (const_int 0)))
10413    (set (match_operand:DI 0 "register_operand" "")
10414         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10415                          (match_operand:DI 1 "register_operand" "")
10416                          (match_dup 0)))
10417    (set (match_dup 1)
10418         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10419                          (match_operand:DI 3 "register_operand" "r")
10420                          (match_dup 1)))]
10421   "TARGET_64BIT"
10422   "")
10423
10424 (define_expand "ashldi3"
10425   [(set (match_operand:DI 0 "shiftdi_operand" "")
10426         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10427                    (match_operand:QI 2 "nonmemory_operand" "")))]
10428   ""
10429   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10430
10431 (define_insn "*ashldi3_1_rex64"
10432   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10433         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10434                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10435    (clobber (reg:CC FLAGS_REG))]
10436   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10437 {
10438   switch (get_attr_type (insn))
10439     {
10440     case TYPE_ALU:
10441       gcc_assert (operands[2] == const1_rtx);
10442       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10443       return "add{q}\t{%0, %0|%0, %0}";
10444
10445     case TYPE_LEA:
10446       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10447       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10448       operands[1] = gen_rtx_MULT (DImode, operands[1],
10449                                   GEN_INT (1 << INTVAL (operands[2])));
10450       return "lea{q}\t{%a1, %0|%0, %a1}";
10451
10452     default:
10453       if (REG_P (operands[2]))
10454         return "sal{q}\t{%b2, %0|%0, %b2}";
10455       else if (operands[2] == const1_rtx
10456                && (TARGET_SHIFT1 || optimize_size))
10457         return "sal{q}\t%0";
10458       else
10459         return "sal{q}\t{%2, %0|%0, %2}";
10460     }
10461 }
10462   [(set (attr "type")
10463      (cond [(eq_attr "alternative" "1")
10464               (const_string "lea")
10465             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10466                           (const_int 0))
10467                       (match_operand 0 "register_operand" ""))
10468                  (match_operand 2 "const1_operand" ""))
10469               (const_string "alu")
10470            ]
10471            (const_string "ishift")))
10472    (set_attr "mode" "DI")])
10473
10474 ;; Convert lea to the lea pattern to avoid flags dependency.
10475 (define_split
10476   [(set (match_operand:DI 0 "register_operand" "")
10477         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10478                    (match_operand:QI 2 "immediate_operand" "")))
10479    (clobber (reg:CC FLAGS_REG))]
10480   "TARGET_64BIT && reload_completed
10481    && true_regnum (operands[0]) != true_regnum (operands[1])"
10482   [(set (match_dup 0)
10483         (mult:DI (match_dup 1)
10484                  (match_dup 2)))]
10485   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10486
10487 ;; This pattern can't accept a variable shift count, since shifts by
10488 ;; zero don't affect the flags.  We assume that shifts by constant
10489 ;; zero are optimized away.
10490 (define_insn "*ashldi3_cmp_rex64"
10491   [(set (reg FLAGS_REG)
10492         (compare
10493           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10494                      (match_operand:QI 2 "immediate_operand" "e"))
10495           (const_int 0)))
10496    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10497         (ashift:DI (match_dup 1) (match_dup 2)))]
10498   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10499    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10500    && (optimize_size
10501        || !TARGET_PARTIAL_FLAG_REG_STALL
10502        || (operands[2] == const1_rtx
10503            && (TARGET_SHIFT1
10504                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10505 {
10506   switch (get_attr_type (insn))
10507     {
10508     case TYPE_ALU:
10509       gcc_assert (operands[2] == const1_rtx);
10510       return "add{q}\t{%0, %0|%0, %0}";
10511
10512     default:
10513       if (REG_P (operands[2]))
10514         return "sal{q}\t{%b2, %0|%0, %b2}";
10515       else if (operands[2] == const1_rtx
10516                && (TARGET_SHIFT1 || optimize_size))
10517         return "sal{q}\t%0";
10518       else
10519         return "sal{q}\t{%2, %0|%0, %2}";
10520     }
10521 }
10522   [(set (attr "type")
10523      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10524                           (const_int 0))
10525                       (match_operand 0 "register_operand" ""))
10526                  (match_operand 2 "const1_operand" ""))
10527               (const_string "alu")
10528            ]
10529            (const_string "ishift")))
10530    (set_attr "mode" "DI")])
10531
10532 (define_insn "*ashldi3_cconly_rex64"
10533   [(set (reg FLAGS_REG)
10534         (compare
10535           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10536                      (match_operand:QI 2 "immediate_operand" "e"))
10537           (const_int 0)))
10538    (clobber (match_scratch:DI 0 "=r"))]
10539   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10540    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10541    && (optimize_size
10542        || !TARGET_PARTIAL_FLAG_REG_STALL
10543        || (operands[2] == const1_rtx
10544            && (TARGET_SHIFT1
10545                || TARGET_DOUBLE_WITH_ADD)))"
10546 {
10547   switch (get_attr_type (insn))
10548     {
10549     case TYPE_ALU:
10550       gcc_assert (operands[2] == const1_rtx);
10551       return "add{q}\t{%0, %0|%0, %0}";
10552
10553     default:
10554       if (REG_P (operands[2]))
10555         return "sal{q}\t{%b2, %0|%0, %b2}";
10556       else if (operands[2] == const1_rtx
10557                && (TARGET_SHIFT1 || optimize_size))
10558         return "sal{q}\t%0";
10559       else
10560         return "sal{q}\t{%2, %0|%0, %2}";
10561     }
10562 }
10563   [(set (attr "type")
10564      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10565                           (const_int 0))
10566                       (match_operand 0 "register_operand" ""))
10567                  (match_operand 2 "const1_operand" ""))
10568               (const_string "alu")
10569            ]
10570            (const_string "ishift")))
10571    (set_attr "mode" "DI")])
10572
10573 (define_insn "*ashldi3_1"
10574   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10575         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10576                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10577    (clobber (reg:CC FLAGS_REG))]
10578   "!TARGET_64BIT"
10579   "#"
10580   [(set_attr "type" "multi")])
10581
10582 ;; By default we don't ask for a scratch register, because when DImode
10583 ;; values are manipulated, registers are already at a premium.  But if
10584 ;; we have one handy, we won't turn it away.
10585 (define_peephole2
10586   [(match_scratch:SI 3 "r")
10587    (parallel [(set (match_operand:DI 0 "register_operand" "")
10588                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10589                               (match_operand:QI 2 "nonmemory_operand" "")))
10590               (clobber (reg:CC FLAGS_REG))])
10591    (match_dup 3)]
10592   "!TARGET_64BIT && TARGET_CMOVE"
10593   [(const_int 0)]
10594   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10595
10596 (define_split
10597   [(set (match_operand:DI 0 "register_operand" "")
10598         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10599                    (match_operand:QI 2 "nonmemory_operand" "")))
10600    (clobber (reg:CC FLAGS_REG))]
10601   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10602                      ? flow2_completed : reload_completed)"
10603   [(const_int 0)]
10604   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10605
10606 (define_insn "x86_shld_1"
10607   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10608         (ior:SI (ashift:SI (match_dup 0)
10609                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10610                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10611                   (minus:QI (const_int 32) (match_dup 2)))))
10612    (clobber (reg:CC FLAGS_REG))]
10613   ""
10614   "@
10615    shld{l}\t{%2, %1, %0|%0, %1, %2}
10616    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10617   [(set_attr "type" "ishift")
10618    (set_attr "prefix_0f" "1")
10619    (set_attr "mode" "SI")
10620    (set_attr "pent_pair" "np")
10621    (set_attr "athlon_decode" "vector")
10622    (set_attr "amdfam10_decode" "vector")])   
10623
10624 (define_expand "x86_shift_adj_1"
10625   [(set (reg:CCZ FLAGS_REG)
10626         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10627                              (const_int 32))
10628                      (const_int 0)))
10629    (set (match_operand:SI 0 "register_operand" "")
10630         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10631                          (match_operand:SI 1 "register_operand" "")
10632                          (match_dup 0)))
10633    (set (match_dup 1)
10634         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10635                          (match_operand:SI 3 "register_operand" "r")
10636                          (match_dup 1)))]
10637   "TARGET_CMOVE"
10638   "")
10639
10640 (define_expand "x86_shift_adj_2"
10641   [(use (match_operand:SI 0 "register_operand" ""))
10642    (use (match_operand:SI 1 "register_operand" ""))
10643    (use (match_operand:QI 2 "register_operand" ""))]
10644   ""
10645 {
10646   rtx label = gen_label_rtx ();
10647   rtx tmp;
10648
10649   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10650
10651   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10652   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10653   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10654                               gen_rtx_LABEL_REF (VOIDmode, label),
10655                               pc_rtx);
10656   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10657   JUMP_LABEL (tmp) = label;
10658
10659   emit_move_insn (operands[0], operands[1]);
10660   ix86_expand_clear (operands[1]);
10661
10662   emit_label (label);
10663   LABEL_NUSES (label) = 1;
10664
10665   DONE;
10666 })
10667
10668 (define_expand "ashlsi3"
10669   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10670         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10671                    (match_operand:QI 2 "nonmemory_operand" "")))
10672    (clobber (reg:CC FLAGS_REG))]
10673   ""
10674   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10675
10676 (define_insn "*ashlsi3_1"
10677   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10678         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10679                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10680    (clobber (reg:CC FLAGS_REG))]
10681   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10682 {
10683   switch (get_attr_type (insn))
10684     {
10685     case TYPE_ALU:
10686       gcc_assert (operands[2] == const1_rtx);
10687       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10688       return "add{l}\t{%0, %0|%0, %0}";
10689
10690     case TYPE_LEA:
10691       return "#";
10692
10693     default:
10694       if (REG_P (operands[2]))
10695         return "sal{l}\t{%b2, %0|%0, %b2}";
10696       else if (operands[2] == const1_rtx
10697                && (TARGET_SHIFT1 || optimize_size))
10698         return "sal{l}\t%0";
10699       else
10700         return "sal{l}\t{%2, %0|%0, %2}";
10701     }
10702 }
10703   [(set (attr "type")
10704      (cond [(eq_attr "alternative" "1")
10705               (const_string "lea")
10706             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10707                           (const_int 0))
10708                       (match_operand 0 "register_operand" ""))
10709                  (match_operand 2 "const1_operand" ""))
10710               (const_string "alu")
10711            ]
10712            (const_string "ishift")))
10713    (set_attr "mode" "SI")])
10714
10715 ;; Convert lea to the lea pattern to avoid flags dependency.
10716 (define_split
10717   [(set (match_operand 0 "register_operand" "")
10718         (ashift (match_operand 1 "index_register_operand" "")
10719                 (match_operand:QI 2 "const_int_operand" "")))
10720    (clobber (reg:CC FLAGS_REG))]
10721   "reload_completed
10722    && true_regnum (operands[0]) != true_regnum (operands[1])
10723    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10724   [(const_int 0)]
10725 {
10726   rtx pat;
10727   enum machine_mode mode = GET_MODE (operands[0]);
10728
10729   if (GET_MODE_SIZE (mode) < 4)
10730     operands[0] = gen_lowpart (SImode, operands[0]);
10731   if (mode != Pmode)
10732     operands[1] = gen_lowpart (Pmode, operands[1]);
10733   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10734
10735   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10736   if (Pmode != SImode)
10737     pat = gen_rtx_SUBREG (SImode, pat, 0);
10738   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10739   DONE;
10740 })
10741
10742 ;; Rare case of shifting RSP is handled by generating move and shift
10743 (define_split
10744   [(set (match_operand 0 "register_operand" "")
10745         (ashift (match_operand 1 "register_operand" "")
10746                 (match_operand:QI 2 "const_int_operand" "")))
10747    (clobber (reg:CC FLAGS_REG))]
10748   "reload_completed
10749    && true_regnum (operands[0]) != true_regnum (operands[1])"
10750   [(const_int 0)]
10751 {
10752   rtx pat, clob;
10753   emit_move_insn (operands[0], operands[1]);
10754   pat = gen_rtx_SET (VOIDmode, operands[0],
10755                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10756                                      operands[0], operands[2]));
10757   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10758   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10759   DONE;
10760 })
10761
10762 (define_insn "*ashlsi3_1_zext"
10763   [(set (match_operand:DI 0 "register_operand" "=r,r")
10764         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10765                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10766    (clobber (reg:CC FLAGS_REG))]
10767   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10768 {
10769   switch (get_attr_type (insn))
10770     {
10771     case TYPE_ALU:
10772       gcc_assert (operands[2] == const1_rtx);
10773       return "add{l}\t{%k0, %k0|%k0, %k0}";
10774
10775     case TYPE_LEA:
10776       return "#";
10777
10778     default:
10779       if (REG_P (operands[2]))
10780         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10781       else if (operands[2] == const1_rtx
10782                && (TARGET_SHIFT1 || optimize_size))
10783         return "sal{l}\t%k0";
10784       else
10785         return "sal{l}\t{%2, %k0|%k0, %2}";
10786     }
10787 }
10788   [(set (attr "type")
10789      (cond [(eq_attr "alternative" "1")
10790               (const_string "lea")
10791             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10792                      (const_int 0))
10793                  (match_operand 2 "const1_operand" ""))
10794               (const_string "alu")
10795            ]
10796            (const_string "ishift")))
10797    (set_attr "mode" "SI")])
10798
10799 ;; Convert lea to the lea pattern to avoid flags dependency.
10800 (define_split
10801   [(set (match_operand:DI 0 "register_operand" "")
10802         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10803                                 (match_operand:QI 2 "const_int_operand" ""))))
10804    (clobber (reg:CC FLAGS_REG))]
10805   "TARGET_64BIT && reload_completed
10806    && true_regnum (operands[0]) != true_regnum (operands[1])"
10807   [(set (match_dup 0) (zero_extend:DI
10808                         (subreg:SI (mult:SI (match_dup 1)
10809                                             (match_dup 2)) 0)))]
10810 {
10811   operands[1] = gen_lowpart (Pmode, operands[1]);
10812   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10813 })
10814
10815 ;; This pattern can't accept a variable shift count, since shifts by
10816 ;; zero don't affect the flags.  We assume that shifts by constant
10817 ;; zero are optimized away.
10818 (define_insn "*ashlsi3_cmp"
10819   [(set (reg FLAGS_REG)
10820         (compare
10821           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10822                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10823           (const_int 0)))
10824    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10825         (ashift:SI (match_dup 1) (match_dup 2)))]
10826   "ix86_match_ccmode (insn, CCGOCmode)
10827    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10828    && (optimize_size
10829        || !TARGET_PARTIAL_FLAG_REG_STALL
10830        || (operands[2] == const1_rtx
10831            && (TARGET_SHIFT1
10832                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10833 {
10834   switch (get_attr_type (insn))
10835     {
10836     case TYPE_ALU:
10837       gcc_assert (operands[2] == const1_rtx);
10838       return "add{l}\t{%0, %0|%0, %0}";
10839
10840     default:
10841       if (REG_P (operands[2]))
10842         return "sal{l}\t{%b2, %0|%0, %b2}";
10843       else if (operands[2] == const1_rtx
10844                && (TARGET_SHIFT1 || optimize_size))
10845         return "sal{l}\t%0";
10846       else
10847         return "sal{l}\t{%2, %0|%0, %2}";
10848     }
10849 }
10850   [(set (attr "type")
10851      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10852                           (const_int 0))
10853                       (match_operand 0 "register_operand" ""))
10854                  (match_operand 2 "const1_operand" ""))
10855               (const_string "alu")
10856            ]
10857            (const_string "ishift")))
10858    (set_attr "mode" "SI")])
10859
10860 (define_insn "*ashlsi3_cconly"
10861   [(set (reg FLAGS_REG)
10862         (compare
10863           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10864                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10865           (const_int 0)))
10866    (clobber (match_scratch:SI 0 "=r"))]
10867   "ix86_match_ccmode (insn, CCGOCmode)
10868    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10869    && (optimize_size
10870        || !TARGET_PARTIAL_FLAG_REG_STALL
10871        || (operands[2] == const1_rtx
10872            && (TARGET_SHIFT1
10873                || TARGET_DOUBLE_WITH_ADD)))"
10874 {
10875   switch (get_attr_type (insn))
10876     {
10877     case TYPE_ALU:
10878       gcc_assert (operands[2] == const1_rtx);
10879       return "add{l}\t{%0, %0|%0, %0}";
10880
10881     default:
10882       if (REG_P (operands[2]))
10883         return "sal{l}\t{%b2, %0|%0, %b2}";
10884       else if (operands[2] == const1_rtx
10885                && (TARGET_SHIFT1 || optimize_size))
10886         return "sal{l}\t%0";
10887       else
10888         return "sal{l}\t{%2, %0|%0, %2}";
10889     }
10890 }
10891   [(set (attr "type")
10892      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10893                           (const_int 0))
10894                       (match_operand 0 "register_operand" ""))
10895                  (match_operand 2 "const1_operand" ""))
10896               (const_string "alu")
10897            ]
10898            (const_string "ishift")))
10899    (set_attr "mode" "SI")])
10900
10901 (define_insn "*ashlsi3_cmp_zext"
10902   [(set (reg FLAGS_REG)
10903         (compare
10904           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10905                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10906           (const_int 0)))
10907    (set (match_operand:DI 0 "register_operand" "=r")
10908         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10909   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10910    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10911    && (optimize_size
10912        || !TARGET_PARTIAL_FLAG_REG_STALL
10913        || (operands[2] == const1_rtx
10914            && (TARGET_SHIFT1
10915                || TARGET_DOUBLE_WITH_ADD)))"
10916 {
10917   switch (get_attr_type (insn))
10918     {
10919     case TYPE_ALU:
10920       gcc_assert (operands[2] == const1_rtx);
10921       return "add{l}\t{%k0, %k0|%k0, %k0}";
10922
10923     default:
10924       if (REG_P (operands[2]))
10925         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10926       else if (operands[2] == const1_rtx
10927                && (TARGET_SHIFT1 || optimize_size))
10928         return "sal{l}\t%k0";
10929       else
10930         return "sal{l}\t{%2, %k0|%k0, %2}";
10931     }
10932 }
10933   [(set (attr "type")
10934      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10935                      (const_int 0))
10936                  (match_operand 2 "const1_operand" ""))
10937               (const_string "alu")
10938            ]
10939            (const_string "ishift")))
10940    (set_attr "mode" "SI")])
10941
10942 (define_expand "ashlhi3"
10943   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10944         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10945                    (match_operand:QI 2 "nonmemory_operand" "")))
10946    (clobber (reg:CC FLAGS_REG))]
10947   "TARGET_HIMODE_MATH"
10948   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10949
10950 (define_insn "*ashlhi3_1_lea"
10951   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10952         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10953                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10954    (clobber (reg:CC FLAGS_REG))]
10955   "!TARGET_PARTIAL_REG_STALL
10956    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10957 {
10958   switch (get_attr_type (insn))
10959     {
10960     case TYPE_LEA:
10961       return "#";
10962     case TYPE_ALU:
10963       gcc_assert (operands[2] == const1_rtx);
10964       return "add{w}\t{%0, %0|%0, %0}";
10965
10966     default:
10967       if (REG_P (operands[2]))
10968         return "sal{w}\t{%b2, %0|%0, %b2}";
10969       else if (operands[2] == const1_rtx
10970                && (TARGET_SHIFT1 || optimize_size))
10971         return "sal{w}\t%0";
10972       else
10973         return "sal{w}\t{%2, %0|%0, %2}";
10974     }
10975 }
10976   [(set (attr "type")
10977      (cond [(eq_attr "alternative" "1")
10978               (const_string "lea")
10979             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980                           (const_int 0))
10981                       (match_operand 0 "register_operand" ""))
10982                  (match_operand 2 "const1_operand" ""))
10983               (const_string "alu")
10984            ]
10985            (const_string "ishift")))
10986    (set_attr "mode" "HI,SI")])
10987
10988 (define_insn "*ashlhi3_1"
10989   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10990         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10991                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10992    (clobber (reg:CC FLAGS_REG))]
10993   "TARGET_PARTIAL_REG_STALL
10994    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10995 {
10996   switch (get_attr_type (insn))
10997     {
10998     case TYPE_ALU:
10999       gcc_assert (operands[2] == const1_rtx);
11000       return "add{w}\t{%0, %0|%0, %0}";
11001
11002     default:
11003       if (REG_P (operands[2]))
11004         return "sal{w}\t{%b2, %0|%0, %b2}";
11005       else if (operands[2] == const1_rtx
11006                && (TARGET_SHIFT1 || optimize_size))
11007         return "sal{w}\t%0";
11008       else
11009         return "sal{w}\t{%2, %0|%0, %2}";
11010     }
11011 }
11012   [(set (attr "type")
11013      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11014                           (const_int 0))
11015                       (match_operand 0 "register_operand" ""))
11016                  (match_operand 2 "const1_operand" ""))
11017               (const_string "alu")
11018            ]
11019            (const_string "ishift")))
11020    (set_attr "mode" "HI")])
11021
11022 ;; This pattern can't accept a variable shift count, since shifts by
11023 ;; zero don't affect the flags.  We assume that shifts by constant
11024 ;; zero are optimized away.
11025 (define_insn "*ashlhi3_cmp"
11026   [(set (reg FLAGS_REG)
11027         (compare
11028           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11029                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11030           (const_int 0)))
11031    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11032         (ashift:HI (match_dup 1) (match_dup 2)))]
11033   "ix86_match_ccmode (insn, CCGOCmode)
11034    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11035    && (optimize_size
11036        || !TARGET_PARTIAL_FLAG_REG_STALL
11037        || (operands[2] == const1_rtx
11038            && (TARGET_SHIFT1
11039                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11040 {
11041   switch (get_attr_type (insn))
11042     {
11043     case TYPE_ALU:
11044       gcc_assert (operands[2] == const1_rtx);
11045       return "add{w}\t{%0, %0|%0, %0}";
11046
11047     default:
11048       if (REG_P (operands[2]))
11049         return "sal{w}\t{%b2, %0|%0, %b2}";
11050       else if (operands[2] == const1_rtx
11051                && (TARGET_SHIFT1 || optimize_size))
11052         return "sal{w}\t%0";
11053       else
11054         return "sal{w}\t{%2, %0|%0, %2}";
11055     }
11056 }
11057   [(set (attr "type")
11058      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11059                           (const_int 0))
11060                       (match_operand 0 "register_operand" ""))
11061                  (match_operand 2 "const1_operand" ""))
11062               (const_string "alu")
11063            ]
11064            (const_string "ishift")))
11065    (set_attr "mode" "HI")])
11066
11067 (define_insn "*ashlhi3_cconly"
11068   [(set (reg FLAGS_REG)
11069         (compare
11070           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11071                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11072           (const_int 0)))
11073    (clobber (match_scratch:HI 0 "=r"))]
11074   "ix86_match_ccmode (insn, CCGOCmode)
11075    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11076    && (optimize_size
11077        || !TARGET_PARTIAL_FLAG_REG_STALL
11078        || (operands[2] == const1_rtx
11079            && (TARGET_SHIFT1
11080                || TARGET_DOUBLE_WITH_ADD)))"
11081 {
11082   switch (get_attr_type (insn))
11083     {
11084     case TYPE_ALU:
11085       gcc_assert (operands[2] == const1_rtx);
11086       return "add{w}\t{%0, %0|%0, %0}";
11087
11088     default:
11089       if (REG_P (operands[2]))
11090         return "sal{w}\t{%b2, %0|%0, %b2}";
11091       else if (operands[2] == const1_rtx
11092                && (TARGET_SHIFT1 || optimize_size))
11093         return "sal{w}\t%0";
11094       else
11095         return "sal{w}\t{%2, %0|%0, %2}";
11096     }
11097 }
11098   [(set (attr "type")
11099      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11100                           (const_int 0))
11101                       (match_operand 0 "register_operand" ""))
11102                  (match_operand 2 "const1_operand" ""))
11103               (const_string "alu")
11104            ]
11105            (const_string "ishift")))
11106    (set_attr "mode" "HI")])
11107
11108 (define_expand "ashlqi3"
11109   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11110         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11111                    (match_operand:QI 2 "nonmemory_operand" "")))
11112    (clobber (reg:CC FLAGS_REG))]
11113   "TARGET_QIMODE_MATH"
11114   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11115
11116 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11117
11118 (define_insn "*ashlqi3_1_lea"
11119   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11120         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11121                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11122    (clobber (reg:CC FLAGS_REG))]
11123   "!TARGET_PARTIAL_REG_STALL
11124    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11125 {
11126   switch (get_attr_type (insn))
11127     {
11128     case TYPE_LEA:
11129       return "#";
11130     case TYPE_ALU:
11131       gcc_assert (operands[2] == const1_rtx);
11132       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11133         return "add{l}\t{%k0, %k0|%k0, %k0}";
11134       else
11135         return "add{b}\t{%0, %0|%0, %0}";
11136
11137     default:
11138       if (REG_P (operands[2]))
11139         {
11140           if (get_attr_mode (insn) == MODE_SI)
11141             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11142           else
11143             return "sal{b}\t{%b2, %0|%0, %b2}";
11144         }
11145       else if (operands[2] == const1_rtx
11146                && (TARGET_SHIFT1 || optimize_size))
11147         {
11148           if (get_attr_mode (insn) == MODE_SI)
11149             return "sal{l}\t%0";
11150           else
11151             return "sal{b}\t%0";
11152         }
11153       else
11154         {
11155           if (get_attr_mode (insn) == MODE_SI)
11156             return "sal{l}\t{%2, %k0|%k0, %2}";
11157           else
11158             return "sal{b}\t{%2, %0|%0, %2}";
11159         }
11160     }
11161 }
11162   [(set (attr "type")
11163      (cond [(eq_attr "alternative" "2")
11164               (const_string "lea")
11165             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11166                           (const_int 0))
11167                       (match_operand 0 "register_operand" ""))
11168                  (match_operand 2 "const1_operand" ""))
11169               (const_string "alu")
11170            ]
11171            (const_string "ishift")))
11172    (set_attr "mode" "QI,SI,SI")])
11173
11174 (define_insn "*ashlqi3_1"
11175   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11176         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11177                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11178    (clobber (reg:CC FLAGS_REG))]
11179   "TARGET_PARTIAL_REG_STALL
11180    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11181 {
11182   switch (get_attr_type (insn))
11183     {
11184     case TYPE_ALU:
11185       gcc_assert (operands[2] == const1_rtx);
11186       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11187         return "add{l}\t{%k0, %k0|%k0, %k0}";
11188       else
11189         return "add{b}\t{%0, %0|%0, %0}";
11190
11191     default:
11192       if (REG_P (operands[2]))
11193         {
11194           if (get_attr_mode (insn) == MODE_SI)
11195             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11196           else
11197             return "sal{b}\t{%b2, %0|%0, %b2}";
11198         }
11199       else if (operands[2] == const1_rtx
11200                && (TARGET_SHIFT1 || optimize_size))
11201         {
11202           if (get_attr_mode (insn) == MODE_SI)
11203             return "sal{l}\t%0";
11204           else
11205             return "sal{b}\t%0";
11206         }
11207       else
11208         {
11209           if (get_attr_mode (insn) == MODE_SI)
11210             return "sal{l}\t{%2, %k0|%k0, %2}";
11211           else
11212             return "sal{b}\t{%2, %0|%0, %2}";
11213         }
11214     }
11215 }
11216   [(set (attr "type")
11217      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11218                           (const_int 0))
11219                       (match_operand 0 "register_operand" ""))
11220                  (match_operand 2 "const1_operand" ""))
11221               (const_string "alu")
11222            ]
11223            (const_string "ishift")))
11224    (set_attr "mode" "QI,SI")])
11225
11226 ;; This pattern can't accept a variable shift count, since shifts by
11227 ;; zero don't affect the flags.  We assume that shifts by constant
11228 ;; zero are optimized away.
11229 (define_insn "*ashlqi3_cmp"
11230   [(set (reg FLAGS_REG)
11231         (compare
11232           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11233                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11234           (const_int 0)))
11235    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11236         (ashift:QI (match_dup 1) (match_dup 2)))]
11237   "ix86_match_ccmode (insn, CCGOCmode)
11238    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11239    && (optimize_size
11240        || !TARGET_PARTIAL_FLAG_REG_STALL
11241        || (operands[2] == const1_rtx
11242            && (TARGET_SHIFT1
11243                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11244 {
11245   switch (get_attr_type (insn))
11246     {
11247     case TYPE_ALU:
11248       gcc_assert (operands[2] == const1_rtx);
11249       return "add{b}\t{%0, %0|%0, %0}";
11250
11251     default:
11252       if (REG_P (operands[2]))
11253         return "sal{b}\t{%b2, %0|%0, %b2}";
11254       else if (operands[2] == const1_rtx
11255                && (TARGET_SHIFT1 || optimize_size))
11256         return "sal{b}\t%0";
11257       else
11258         return "sal{b}\t{%2, %0|%0, %2}";
11259     }
11260 }
11261   [(set (attr "type")
11262      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11263                           (const_int 0))
11264                       (match_operand 0 "register_operand" ""))
11265                  (match_operand 2 "const1_operand" ""))
11266               (const_string "alu")
11267            ]
11268            (const_string "ishift")))
11269    (set_attr "mode" "QI")])
11270
11271 (define_insn "*ashlqi3_cconly"
11272   [(set (reg FLAGS_REG)
11273         (compare
11274           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11275                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11276           (const_int 0)))
11277    (clobber (match_scratch:QI 0 "=q"))]
11278   "ix86_match_ccmode (insn, CCGOCmode)
11279    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11280    && (optimize_size
11281        || !TARGET_PARTIAL_FLAG_REG_STALL
11282        || (operands[2] == const1_rtx
11283            && (TARGET_SHIFT1
11284                || TARGET_DOUBLE_WITH_ADD)))"
11285 {
11286   switch (get_attr_type (insn))
11287     {
11288     case TYPE_ALU:
11289       gcc_assert (operands[2] == const1_rtx);
11290       return "add{b}\t{%0, %0|%0, %0}";
11291
11292     default:
11293       if (REG_P (operands[2]))
11294         return "sal{b}\t{%b2, %0|%0, %b2}";
11295       else if (operands[2] == const1_rtx
11296                && (TARGET_SHIFT1 || optimize_size))
11297         return "sal{b}\t%0";
11298       else
11299         return "sal{b}\t{%2, %0|%0, %2}";
11300     }
11301 }
11302   [(set (attr "type")
11303      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11304                           (const_int 0))
11305                       (match_operand 0 "register_operand" ""))
11306                  (match_operand 2 "const1_operand" ""))
11307               (const_string "alu")
11308            ]
11309            (const_string "ishift")))
11310    (set_attr "mode" "QI")])
11311
11312 ;; See comment above `ashldi3' about how this works.
11313
11314 (define_expand "ashrti3"
11315   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11316                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11317                                 (match_operand:QI 2 "nonmemory_operand" "")))
11318               (clobber (reg:CC FLAGS_REG))])]
11319   "TARGET_64BIT"
11320 {
11321   if (! immediate_operand (operands[2], QImode))
11322     {
11323       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11324       DONE;
11325     }
11326   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11327   DONE;
11328 })
11329
11330 (define_insn "ashrti3_1"
11331   [(set (match_operand:TI 0 "register_operand" "=r")
11332         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11333                      (match_operand:QI 2 "register_operand" "c")))
11334    (clobber (match_scratch:DI 3 "=&r"))
11335    (clobber (reg:CC FLAGS_REG))]
11336   "TARGET_64BIT"
11337   "#"
11338   [(set_attr "type" "multi")])
11339
11340 (define_insn "*ashrti3_2"
11341   [(set (match_operand:TI 0 "register_operand" "=r")
11342         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11343                      (match_operand:QI 2 "immediate_operand" "O")))
11344    (clobber (reg:CC FLAGS_REG))]
11345   "TARGET_64BIT"
11346   "#"
11347   [(set_attr "type" "multi")])
11348
11349 (define_split
11350   [(set (match_operand:TI 0 "register_operand" "")
11351         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11352                      (match_operand:QI 2 "register_operand" "")))
11353    (clobber (match_scratch:DI 3 ""))
11354    (clobber (reg:CC FLAGS_REG))]
11355   "TARGET_64BIT && reload_completed"
11356   [(const_int 0)]
11357   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11358
11359 (define_split
11360   [(set (match_operand:TI 0 "register_operand" "")
11361         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11362                      (match_operand:QI 2 "immediate_operand" "")))
11363    (clobber (reg:CC FLAGS_REG))]
11364   "TARGET_64BIT && reload_completed"
11365   [(const_int 0)]
11366   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11367
11368 (define_insn "x86_64_shrd"
11369   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11370         (ior:DI (ashiftrt:DI (match_dup 0)
11371                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11372                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11373                   (minus:QI (const_int 64) (match_dup 2)))))
11374    (clobber (reg:CC FLAGS_REG))]
11375   "TARGET_64BIT"
11376   "@
11377    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11378    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11379   [(set_attr "type" "ishift")
11380    (set_attr "prefix_0f" "1")
11381    (set_attr "mode" "DI")
11382    (set_attr "athlon_decode" "vector")
11383    (set_attr "amdfam10_decode" "vector")])   
11384
11385 (define_expand "ashrdi3"
11386   [(set (match_operand:DI 0 "shiftdi_operand" "")
11387         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11388                      (match_operand:QI 2 "nonmemory_operand" "")))]
11389   ""
11390   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11391
11392 (define_insn "*ashrdi3_63_rex64"
11393   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11394         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11395                      (match_operand:DI 2 "const_int_operand" "i,i")))
11396    (clobber (reg:CC FLAGS_REG))]
11397   "TARGET_64BIT && INTVAL (operands[2]) == 63
11398    && (TARGET_USE_CLTD || optimize_size)
11399    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11400   "@
11401    {cqto|cqo}
11402    sar{q}\t{%2, %0|%0, %2}"
11403   [(set_attr "type" "imovx,ishift")
11404    (set_attr "prefix_0f" "0,*")
11405    (set_attr "length_immediate" "0,*")
11406    (set_attr "modrm" "0,1")
11407    (set_attr "mode" "DI")])
11408
11409 (define_insn "*ashrdi3_1_one_bit_rex64"
11410   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11411         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11412                      (match_operand:QI 2 "const1_operand" "")))
11413    (clobber (reg:CC FLAGS_REG))]
11414   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11415    && (TARGET_SHIFT1 || optimize_size)"
11416   "sar{q}\t%0"
11417   [(set_attr "type" "ishift")
11418    (set (attr "length")
11419      (if_then_else (match_operand:DI 0 "register_operand" "")
11420         (const_string "2")
11421         (const_string "*")))])
11422
11423 (define_insn "*ashrdi3_1_rex64"
11424   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11425         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11426                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11427    (clobber (reg:CC FLAGS_REG))]
11428   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11429   "@
11430    sar{q}\t{%2, %0|%0, %2}
11431    sar{q}\t{%b2, %0|%0, %b2}"
11432   [(set_attr "type" "ishift")
11433    (set_attr "mode" "DI")])
11434
11435 ;; This pattern can't accept a variable shift count, since shifts by
11436 ;; zero don't affect the flags.  We assume that shifts by constant
11437 ;; zero are optimized away.
11438 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11439   [(set (reg FLAGS_REG)
11440         (compare
11441           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11442                        (match_operand:QI 2 "const1_operand" ""))
11443           (const_int 0)))
11444    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11445         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11446   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11447    && (TARGET_SHIFT1 || optimize_size)
11448    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11449   "sar{q}\t%0"
11450   [(set_attr "type" "ishift")
11451    (set (attr "length")
11452      (if_then_else (match_operand:DI 0 "register_operand" "")
11453         (const_string "2")
11454         (const_string "*")))])
11455
11456 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11457   [(set (reg FLAGS_REG)
11458         (compare
11459           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11460                        (match_operand:QI 2 "const1_operand" ""))
11461           (const_int 0)))
11462    (clobber (match_scratch:DI 0 "=r"))]
11463   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11464    && (TARGET_SHIFT1 || optimize_size)
11465    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11466   "sar{q}\t%0"
11467   [(set_attr "type" "ishift")
11468    (set_attr "length" "2")])
11469
11470 ;; This pattern can't accept a variable shift count, since shifts by
11471 ;; zero don't affect the flags.  We assume that shifts by constant
11472 ;; zero are optimized away.
11473 (define_insn "*ashrdi3_cmp_rex64"
11474   [(set (reg FLAGS_REG)
11475         (compare
11476           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11477                        (match_operand:QI 2 "const_int_operand" "n"))
11478           (const_int 0)))
11479    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11480         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11481   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11482    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11483    && (optimize_size
11484        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11485   "sar{q}\t{%2, %0|%0, %2}"
11486   [(set_attr "type" "ishift")
11487    (set_attr "mode" "DI")])
11488
11489 (define_insn "*ashrdi3_cconly_rex64"
11490   [(set (reg FLAGS_REG)
11491         (compare
11492           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11493                        (match_operand:QI 2 "const_int_operand" "n"))
11494           (const_int 0)))
11495    (clobber (match_scratch:DI 0 "=r"))]
11496   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11497    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11498    && (optimize_size
11499        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11500   "sar{q}\t{%2, %0|%0, %2}"
11501   [(set_attr "type" "ishift")
11502    (set_attr "mode" "DI")])
11503
11504 (define_insn "*ashrdi3_1"
11505   [(set (match_operand:DI 0 "register_operand" "=r")
11506         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11507                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11508    (clobber (reg:CC FLAGS_REG))]
11509   "!TARGET_64BIT"
11510   "#"
11511   [(set_attr "type" "multi")])
11512
11513 ;; By default we don't ask for a scratch register, because when DImode
11514 ;; values are manipulated, registers are already at a premium.  But if
11515 ;; we have one handy, we won't turn it away.
11516 (define_peephole2
11517   [(match_scratch:SI 3 "r")
11518    (parallel [(set (match_operand:DI 0 "register_operand" "")
11519                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11520                                 (match_operand:QI 2 "nonmemory_operand" "")))
11521               (clobber (reg:CC FLAGS_REG))])
11522    (match_dup 3)]
11523   "!TARGET_64BIT && TARGET_CMOVE"
11524   [(const_int 0)]
11525   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11526
11527 (define_split
11528   [(set (match_operand:DI 0 "register_operand" "")
11529         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11530                      (match_operand:QI 2 "nonmemory_operand" "")))
11531    (clobber (reg:CC FLAGS_REG))]
11532   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11533                      ? flow2_completed : reload_completed)"
11534   [(const_int 0)]
11535   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11536
11537 (define_insn "x86_shrd_1"
11538   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11539         (ior:SI (ashiftrt:SI (match_dup 0)
11540                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11541                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11542                   (minus:QI (const_int 32) (match_dup 2)))))
11543    (clobber (reg:CC FLAGS_REG))]
11544   ""
11545   "@
11546    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11547    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11548   [(set_attr "type" "ishift")
11549    (set_attr "prefix_0f" "1")
11550    (set_attr "pent_pair" "np")
11551    (set_attr "mode" "SI")])
11552
11553 (define_expand "x86_shift_adj_3"
11554   [(use (match_operand:SI 0 "register_operand" ""))
11555    (use (match_operand:SI 1 "register_operand" ""))
11556    (use (match_operand:QI 2 "register_operand" ""))]
11557   ""
11558 {
11559   rtx label = gen_label_rtx ();
11560   rtx tmp;
11561
11562   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11563
11564   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11565   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11566   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11567                               gen_rtx_LABEL_REF (VOIDmode, label),
11568                               pc_rtx);
11569   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11570   JUMP_LABEL (tmp) = label;
11571
11572   emit_move_insn (operands[0], operands[1]);
11573   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11574
11575   emit_label (label);
11576   LABEL_NUSES (label) = 1;
11577
11578   DONE;
11579 })
11580
11581 (define_insn "ashrsi3_31"
11582   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11583         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11584                      (match_operand:SI 2 "const_int_operand" "i,i")))
11585    (clobber (reg:CC FLAGS_REG))]
11586   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11587    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11588   "@
11589    {cltd|cdq}
11590    sar{l}\t{%2, %0|%0, %2}"
11591   [(set_attr "type" "imovx,ishift")
11592    (set_attr "prefix_0f" "0,*")
11593    (set_attr "length_immediate" "0,*")
11594    (set_attr "modrm" "0,1")
11595    (set_attr "mode" "SI")])
11596
11597 (define_insn "*ashrsi3_31_zext"
11598   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11599         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11600                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11601    (clobber (reg:CC FLAGS_REG))]
11602   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11603    && INTVAL (operands[2]) == 31
11604    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11605   "@
11606    {cltd|cdq}
11607    sar{l}\t{%2, %k0|%k0, %2}"
11608   [(set_attr "type" "imovx,ishift")
11609    (set_attr "prefix_0f" "0,*")
11610    (set_attr "length_immediate" "0,*")
11611    (set_attr "modrm" "0,1")
11612    (set_attr "mode" "SI")])
11613
11614 (define_expand "ashrsi3"
11615   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11616         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11617                      (match_operand:QI 2 "nonmemory_operand" "")))
11618    (clobber (reg:CC FLAGS_REG))]
11619   ""
11620   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11621
11622 (define_insn "*ashrsi3_1_one_bit"
11623   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11624         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11625                      (match_operand:QI 2 "const1_operand" "")))
11626    (clobber (reg:CC FLAGS_REG))]
11627   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11628    && (TARGET_SHIFT1 || optimize_size)"
11629   "sar{l}\t%0"
11630   [(set_attr "type" "ishift")
11631    (set (attr "length")
11632      (if_then_else (match_operand:SI 0 "register_operand" "")
11633         (const_string "2")
11634         (const_string "*")))])
11635
11636 (define_insn "*ashrsi3_1_one_bit_zext"
11637   [(set (match_operand:DI 0 "register_operand" "=r")
11638         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11639                                      (match_operand:QI 2 "const1_operand" ""))))
11640    (clobber (reg:CC FLAGS_REG))]
11641   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11642    && (TARGET_SHIFT1 || optimize_size)"
11643   "sar{l}\t%k0"
11644   [(set_attr "type" "ishift")
11645    (set_attr "length" "2")])
11646
11647 (define_insn "*ashrsi3_1"
11648   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11649         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11650                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11651    (clobber (reg:CC FLAGS_REG))]
11652   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11653   "@
11654    sar{l}\t{%2, %0|%0, %2}
11655    sar{l}\t{%b2, %0|%0, %b2}"
11656   [(set_attr "type" "ishift")
11657    (set_attr "mode" "SI")])
11658
11659 (define_insn "*ashrsi3_1_zext"
11660   [(set (match_operand:DI 0 "register_operand" "=r,r")
11661         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11662                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11663    (clobber (reg:CC FLAGS_REG))]
11664   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11665   "@
11666    sar{l}\t{%2, %k0|%k0, %2}
11667    sar{l}\t{%b2, %k0|%k0, %b2}"
11668   [(set_attr "type" "ishift")
11669    (set_attr "mode" "SI")])
11670
11671 ;; This pattern can't accept a variable shift count, since shifts by
11672 ;; zero don't affect the flags.  We assume that shifts by constant
11673 ;; zero are optimized away.
11674 (define_insn "*ashrsi3_one_bit_cmp"
11675   [(set (reg FLAGS_REG)
11676         (compare
11677           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11678                        (match_operand:QI 2 "const1_operand" ""))
11679           (const_int 0)))
11680    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11681         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11682   "ix86_match_ccmode (insn, CCGOCmode)
11683    && (TARGET_SHIFT1 || optimize_size)
11684    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11685   "sar{l}\t%0"
11686   [(set_attr "type" "ishift")
11687    (set (attr "length")
11688      (if_then_else (match_operand:SI 0 "register_operand" "")
11689         (const_string "2")
11690         (const_string "*")))])
11691
11692 (define_insn "*ashrsi3_one_bit_cconly"
11693   [(set (reg FLAGS_REG)
11694         (compare
11695           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11696                        (match_operand:QI 2 "const1_operand" ""))
11697           (const_int 0)))
11698    (clobber (match_scratch:SI 0 "=r"))]
11699   "ix86_match_ccmode (insn, CCGOCmode)
11700    && (TARGET_SHIFT1 || optimize_size)
11701    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11702   "sar{l}\t%0"
11703   [(set_attr "type" "ishift")
11704    (set_attr "length" "2")])
11705
11706 (define_insn "*ashrsi3_one_bit_cmp_zext"
11707   [(set (reg FLAGS_REG)
11708         (compare
11709           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11710                        (match_operand:QI 2 "const1_operand" ""))
11711           (const_int 0)))
11712    (set (match_operand:DI 0 "register_operand" "=r")
11713         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11714   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11715    && (TARGET_SHIFT1 || optimize_size)
11716    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11717   "sar{l}\t%k0"
11718   [(set_attr "type" "ishift")
11719    (set_attr "length" "2")])
11720
11721 ;; This pattern can't accept a variable shift count, since shifts by
11722 ;; zero don't affect the flags.  We assume that shifts by constant
11723 ;; zero are optimized away.
11724 (define_insn "*ashrsi3_cmp"
11725   [(set (reg FLAGS_REG)
11726         (compare
11727           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11728                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11729           (const_int 0)))
11730    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11731         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11732   "ix86_match_ccmode (insn, CCGOCmode)
11733    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11734    && (optimize_size
11735        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11736   "sar{l}\t{%2, %0|%0, %2}"
11737   [(set_attr "type" "ishift")
11738    (set_attr "mode" "SI")])
11739
11740 (define_insn "*ashrsi3_cconly"
11741   [(set (reg FLAGS_REG)
11742         (compare
11743           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11744                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11745           (const_int 0)))
11746    (clobber (match_scratch:SI 0 "=r"))]
11747   "ix86_match_ccmode (insn, CCGOCmode)
11748    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11749    && (optimize_size
11750        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11751   "sar{l}\t{%2, %0|%0, %2}"
11752   [(set_attr "type" "ishift")
11753    (set_attr "mode" "SI")])
11754
11755 (define_insn "*ashrsi3_cmp_zext"
11756   [(set (reg FLAGS_REG)
11757         (compare
11758           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11759                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11760           (const_int 0)))
11761    (set (match_operand:DI 0 "register_operand" "=r")
11762         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11763   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11764    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11765    && (optimize_size
11766        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11767   "sar{l}\t{%2, %k0|%k0, %2}"
11768   [(set_attr "type" "ishift")
11769    (set_attr "mode" "SI")])
11770
11771 (define_expand "ashrhi3"
11772   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11773         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11774                      (match_operand:QI 2 "nonmemory_operand" "")))
11775    (clobber (reg:CC FLAGS_REG))]
11776   "TARGET_HIMODE_MATH"
11777   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11778
11779 (define_insn "*ashrhi3_1_one_bit"
11780   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11781         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11782                      (match_operand:QI 2 "const1_operand" "")))
11783    (clobber (reg:CC FLAGS_REG))]
11784   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11785    && (TARGET_SHIFT1 || optimize_size)"
11786   "sar{w}\t%0"
11787   [(set_attr "type" "ishift")
11788    (set (attr "length")
11789      (if_then_else (match_operand 0 "register_operand" "")
11790         (const_string "2")
11791         (const_string "*")))])
11792
11793 (define_insn "*ashrhi3_1"
11794   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11795         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11796                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11797    (clobber (reg:CC FLAGS_REG))]
11798   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11799   "@
11800    sar{w}\t{%2, %0|%0, %2}
11801    sar{w}\t{%b2, %0|%0, %b2}"
11802   [(set_attr "type" "ishift")
11803    (set_attr "mode" "HI")])
11804
11805 ;; This pattern can't accept a variable shift count, since shifts by
11806 ;; zero don't affect the flags.  We assume that shifts by constant
11807 ;; zero are optimized away.
11808 (define_insn "*ashrhi3_one_bit_cmp"
11809   [(set (reg FLAGS_REG)
11810         (compare
11811           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11812                        (match_operand:QI 2 "const1_operand" ""))
11813           (const_int 0)))
11814    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11815         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11816   "ix86_match_ccmode (insn, CCGOCmode)
11817    && (TARGET_SHIFT1 || optimize_size)
11818    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11819   "sar{w}\t%0"
11820   [(set_attr "type" "ishift")
11821    (set (attr "length")
11822      (if_then_else (match_operand 0 "register_operand" "")
11823         (const_string "2")
11824         (const_string "*")))])
11825
11826 (define_insn "*ashrhi3_one_bit_cconly"
11827   [(set (reg FLAGS_REG)
11828         (compare
11829           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11830                        (match_operand:QI 2 "const1_operand" ""))
11831           (const_int 0)))
11832    (clobber (match_scratch:HI 0 "=r"))]
11833   "ix86_match_ccmode (insn, CCGOCmode)
11834    && (TARGET_SHIFT1 || optimize_size)
11835    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11836   "sar{w}\t%0"
11837   [(set_attr "type" "ishift")
11838    (set_attr "length" "2")])
11839
11840 ;; This pattern can't accept a variable shift count, since shifts by
11841 ;; zero don't affect the flags.  We assume that shifts by constant
11842 ;; zero are optimized away.
11843 (define_insn "*ashrhi3_cmp"
11844   [(set (reg FLAGS_REG)
11845         (compare
11846           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11847                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11848           (const_int 0)))
11849    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11850         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11851   "ix86_match_ccmode (insn, CCGOCmode)
11852    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11853    && (optimize_size
11854        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11855   "sar{w}\t{%2, %0|%0, %2}"
11856   [(set_attr "type" "ishift")
11857    (set_attr "mode" "HI")])
11858
11859 (define_insn "*ashrhi3_cconly"
11860   [(set (reg FLAGS_REG)
11861         (compare
11862           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11863                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11864           (const_int 0)))
11865    (clobber (match_scratch:HI 0 "=r"))]
11866   "ix86_match_ccmode (insn, CCGOCmode)
11867    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11868    && (optimize_size
11869        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11870   "sar{w}\t{%2, %0|%0, %2}"
11871   [(set_attr "type" "ishift")
11872    (set_attr "mode" "HI")])
11873
11874 (define_expand "ashrqi3"
11875   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11876         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11877                      (match_operand:QI 2 "nonmemory_operand" "")))
11878    (clobber (reg:CC FLAGS_REG))]
11879   "TARGET_QIMODE_MATH"
11880   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11881
11882 (define_insn "*ashrqi3_1_one_bit"
11883   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11884         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11885                      (match_operand:QI 2 "const1_operand" "")))
11886    (clobber (reg:CC FLAGS_REG))]
11887   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11888    && (TARGET_SHIFT1 || optimize_size)"
11889   "sar{b}\t%0"
11890   [(set_attr "type" "ishift")
11891    (set (attr "length")
11892      (if_then_else (match_operand 0 "register_operand" "")
11893         (const_string "2")
11894         (const_string "*")))])
11895
11896 (define_insn "*ashrqi3_1_one_bit_slp"
11897   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11898         (ashiftrt:QI (match_dup 0)
11899                      (match_operand:QI 1 "const1_operand" "")))
11900    (clobber (reg:CC FLAGS_REG))]
11901   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11902    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11903    && (TARGET_SHIFT1 || optimize_size)"
11904   "sar{b}\t%0"
11905   [(set_attr "type" "ishift1")
11906    (set (attr "length")
11907      (if_then_else (match_operand 0 "register_operand" "")
11908         (const_string "2")
11909         (const_string "*")))])
11910
11911 (define_insn "*ashrqi3_1"
11912   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11913         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11914                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11915    (clobber (reg:CC FLAGS_REG))]
11916   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11917   "@
11918    sar{b}\t{%2, %0|%0, %2}
11919    sar{b}\t{%b2, %0|%0, %b2}"
11920   [(set_attr "type" "ishift")
11921    (set_attr "mode" "QI")])
11922
11923 (define_insn "*ashrqi3_1_slp"
11924   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11925         (ashiftrt:QI (match_dup 0)
11926                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11927    (clobber (reg:CC FLAGS_REG))]
11928   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11929    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11930   "@
11931    sar{b}\t{%1, %0|%0, %1}
11932    sar{b}\t{%b1, %0|%0, %b1}"
11933   [(set_attr "type" "ishift1")
11934    (set_attr "mode" "QI")])
11935
11936 ;; This pattern can't accept a variable shift count, since shifts by
11937 ;; zero don't affect the flags.  We assume that shifts by constant
11938 ;; zero are optimized away.
11939 (define_insn "*ashrqi3_one_bit_cmp"
11940   [(set (reg FLAGS_REG)
11941         (compare
11942           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11943                        (match_operand:QI 2 "const1_operand" "I"))
11944           (const_int 0)))
11945    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11946         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11947   "ix86_match_ccmode (insn, CCGOCmode)
11948    && (TARGET_SHIFT1 || optimize_size)
11949    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11950   "sar{b}\t%0"
11951   [(set_attr "type" "ishift")
11952    (set (attr "length")
11953      (if_then_else (match_operand 0 "register_operand" "")
11954         (const_string "2")
11955         (const_string "*")))])
11956
11957 (define_insn "*ashrqi3_one_bit_cconly"
11958   [(set (reg FLAGS_REG)
11959         (compare
11960           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11961                        (match_operand:QI 2 "const1_operand" "I"))
11962           (const_int 0)))
11963    (clobber (match_scratch:QI 0 "=q"))]
11964   "ix86_match_ccmode (insn, CCGOCmode)
11965    && (TARGET_SHIFT1 || optimize_size)
11966    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11967   "sar{b}\t%0"
11968   [(set_attr "type" "ishift")
11969    (set_attr "length" "2")])
11970
11971 ;; This pattern can't accept a variable shift count, since shifts by
11972 ;; zero don't affect the flags.  We assume that shifts by constant
11973 ;; zero are optimized away.
11974 (define_insn "*ashrqi3_cmp"
11975   [(set (reg FLAGS_REG)
11976         (compare
11977           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11978                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11979           (const_int 0)))
11980    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11981         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11982   "ix86_match_ccmode (insn, CCGOCmode)
11983    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11984    && (optimize_size
11985        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11986   "sar{b}\t{%2, %0|%0, %2}"
11987   [(set_attr "type" "ishift")
11988    (set_attr "mode" "QI")])
11989
11990 (define_insn "*ashrqi3_cconly"
11991   [(set (reg FLAGS_REG)
11992         (compare
11993           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11994                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11995           (const_int 0)))
11996    (clobber (match_scratch:QI 0 "=q"))]
11997   "ix86_match_ccmode (insn, CCGOCmode)
11998    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11999    && (optimize_size
12000        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12001   "sar{b}\t{%2, %0|%0, %2}"
12002   [(set_attr "type" "ishift")
12003    (set_attr "mode" "QI")])
12004
12005 \f
12006 ;; Logical shift instructions
12007
12008 ;; See comment above `ashldi3' about how this works.
12009
12010 (define_expand "lshrti3"
12011   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12012                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12013                                 (match_operand:QI 2 "nonmemory_operand" "")))
12014               (clobber (reg:CC FLAGS_REG))])]
12015   "TARGET_64BIT"
12016 {
12017   if (! immediate_operand (operands[2], QImode))
12018     {
12019       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12020       DONE;
12021     }
12022   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12023   DONE;
12024 })
12025
12026 (define_insn "lshrti3_1"
12027   [(set (match_operand:TI 0 "register_operand" "=r")
12028         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12029                      (match_operand:QI 2 "register_operand" "c")))
12030    (clobber (match_scratch:DI 3 "=&r"))
12031    (clobber (reg:CC FLAGS_REG))]
12032   "TARGET_64BIT"
12033   "#"
12034   [(set_attr "type" "multi")])
12035
12036 (define_insn "*lshrti3_2"
12037   [(set (match_operand:TI 0 "register_operand" "=r")
12038         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12039                      (match_operand:QI 2 "immediate_operand" "O")))
12040    (clobber (reg:CC FLAGS_REG))]
12041   "TARGET_64BIT"
12042   "#"
12043   [(set_attr "type" "multi")])
12044
12045 (define_split
12046   [(set (match_operand:TI 0 "register_operand" "")
12047         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12048                      (match_operand:QI 2 "register_operand" "")))
12049    (clobber (match_scratch:DI 3 ""))
12050    (clobber (reg:CC FLAGS_REG))]
12051   "TARGET_64BIT && reload_completed"
12052   [(const_int 0)]
12053   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12054
12055 (define_split
12056   [(set (match_operand:TI 0 "register_operand" "")
12057         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12058                      (match_operand:QI 2 "immediate_operand" "")))
12059    (clobber (reg:CC FLAGS_REG))]
12060   "TARGET_64BIT && reload_completed"
12061   [(const_int 0)]
12062   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12063
12064 (define_expand "lshrdi3"
12065   [(set (match_operand:DI 0 "shiftdi_operand" "")
12066         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12067                      (match_operand:QI 2 "nonmemory_operand" "")))]
12068   ""
12069   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12070
12071 (define_insn "*lshrdi3_1_one_bit_rex64"
12072   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12073         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12074                      (match_operand:QI 2 "const1_operand" "")))
12075    (clobber (reg:CC FLAGS_REG))]
12076   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12077    && (TARGET_SHIFT1 || optimize_size)"
12078   "shr{q}\t%0"
12079   [(set_attr "type" "ishift")
12080    (set (attr "length")
12081      (if_then_else (match_operand:DI 0 "register_operand" "")
12082         (const_string "2")
12083         (const_string "*")))])
12084
12085 (define_insn "*lshrdi3_1_rex64"
12086   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12087         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12088                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12089    (clobber (reg:CC FLAGS_REG))]
12090   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12091   "@
12092    shr{q}\t{%2, %0|%0, %2}
12093    shr{q}\t{%b2, %0|%0, %b2}"
12094   [(set_attr "type" "ishift")
12095    (set_attr "mode" "DI")])
12096
12097 ;; This pattern can't accept a variable shift count, since shifts by
12098 ;; zero don't affect the flags.  We assume that shifts by constant
12099 ;; zero are optimized away.
12100 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12101   [(set (reg FLAGS_REG)
12102         (compare
12103           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12104                        (match_operand:QI 2 "const1_operand" ""))
12105           (const_int 0)))
12106    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12107         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12108   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12109    && (TARGET_SHIFT1 || optimize_size)
12110    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12111   "shr{q}\t%0"
12112   [(set_attr "type" "ishift")
12113    (set (attr "length")
12114      (if_then_else (match_operand:DI 0 "register_operand" "")
12115         (const_string "2")
12116         (const_string "*")))])
12117
12118 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12119   [(set (reg FLAGS_REG)
12120         (compare
12121           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12122                        (match_operand:QI 2 "const1_operand" ""))
12123           (const_int 0)))
12124    (clobber (match_scratch:DI 0 "=r"))]
12125   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12126    && (TARGET_SHIFT1 || optimize_size)
12127    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12128   "shr{q}\t%0"
12129   [(set_attr "type" "ishift")
12130    (set_attr "length" "2")])
12131
12132 ;; This pattern can't accept a variable shift count, since shifts by
12133 ;; zero don't affect the flags.  We assume that shifts by constant
12134 ;; zero are optimized away.
12135 (define_insn "*lshrdi3_cmp_rex64"
12136   [(set (reg FLAGS_REG)
12137         (compare
12138           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12139                        (match_operand:QI 2 "const_int_operand" "e"))
12140           (const_int 0)))
12141    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12142         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12143   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12144    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12145    && (optimize_size
12146        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12147   "shr{q}\t{%2, %0|%0, %2}"
12148   [(set_attr "type" "ishift")
12149    (set_attr "mode" "DI")])
12150
12151 (define_insn "*lshrdi3_cconly_rex64"
12152   [(set (reg FLAGS_REG)
12153         (compare
12154           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12155                        (match_operand:QI 2 "const_int_operand" "e"))
12156           (const_int 0)))
12157    (clobber (match_scratch:DI 0 "=r"))]
12158   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12159    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12160    && (optimize_size
12161        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12162   "shr{q}\t{%2, %0|%0, %2}"
12163   [(set_attr "type" "ishift")
12164    (set_attr "mode" "DI")])
12165
12166 (define_insn "*lshrdi3_1"
12167   [(set (match_operand:DI 0 "register_operand" "=r")
12168         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12169                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12170    (clobber (reg:CC FLAGS_REG))]
12171   "!TARGET_64BIT"
12172   "#"
12173   [(set_attr "type" "multi")])
12174
12175 ;; By default we don't ask for a scratch register, because when DImode
12176 ;; values are manipulated, registers are already at a premium.  But if
12177 ;; we have one handy, we won't turn it away.
12178 (define_peephole2
12179   [(match_scratch:SI 3 "r")
12180    (parallel [(set (match_operand:DI 0 "register_operand" "")
12181                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12182                                 (match_operand:QI 2 "nonmemory_operand" "")))
12183               (clobber (reg:CC FLAGS_REG))])
12184    (match_dup 3)]
12185   "!TARGET_64BIT && TARGET_CMOVE"
12186   [(const_int 0)]
12187   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12188
12189 (define_split
12190   [(set (match_operand:DI 0 "register_operand" "")
12191         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12192                      (match_operand:QI 2 "nonmemory_operand" "")))
12193    (clobber (reg:CC FLAGS_REG))]
12194   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12195                      ? flow2_completed : reload_completed)"
12196   [(const_int 0)]
12197   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12198
12199 (define_expand "lshrsi3"
12200   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12201         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12202                      (match_operand:QI 2 "nonmemory_operand" "")))
12203    (clobber (reg:CC FLAGS_REG))]
12204   ""
12205   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12206
12207 (define_insn "*lshrsi3_1_one_bit"
12208   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12209         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12210                      (match_operand:QI 2 "const1_operand" "")))
12211    (clobber (reg:CC FLAGS_REG))]
12212   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12213    && (TARGET_SHIFT1 || optimize_size)"
12214   "shr{l}\t%0"
12215   [(set_attr "type" "ishift")
12216    (set (attr "length")
12217      (if_then_else (match_operand:SI 0 "register_operand" "")
12218         (const_string "2")
12219         (const_string "*")))])
12220
12221 (define_insn "*lshrsi3_1_one_bit_zext"
12222   [(set (match_operand:DI 0 "register_operand" "=r")
12223         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12224                      (match_operand:QI 2 "const1_operand" "")))
12225    (clobber (reg:CC FLAGS_REG))]
12226   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12227    && (TARGET_SHIFT1 || optimize_size)"
12228   "shr{l}\t%k0"
12229   [(set_attr "type" "ishift")
12230    (set_attr "length" "2")])
12231
12232 (define_insn "*lshrsi3_1"
12233   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12234         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12235                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12236    (clobber (reg:CC FLAGS_REG))]
12237   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12238   "@
12239    shr{l}\t{%2, %0|%0, %2}
12240    shr{l}\t{%b2, %0|%0, %b2}"
12241   [(set_attr "type" "ishift")
12242    (set_attr "mode" "SI")])
12243
12244 (define_insn "*lshrsi3_1_zext"
12245   [(set (match_operand:DI 0 "register_operand" "=r,r")
12246         (zero_extend:DI
12247           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12248                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12249    (clobber (reg:CC FLAGS_REG))]
12250   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12251   "@
12252    shr{l}\t{%2, %k0|%k0, %2}
12253    shr{l}\t{%b2, %k0|%k0, %b2}"
12254   [(set_attr "type" "ishift")
12255    (set_attr "mode" "SI")])
12256
12257 ;; This pattern can't accept a variable shift count, since shifts by
12258 ;; zero don't affect the flags.  We assume that shifts by constant
12259 ;; zero are optimized away.
12260 (define_insn "*lshrsi3_one_bit_cmp"
12261   [(set (reg FLAGS_REG)
12262         (compare
12263           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12264                        (match_operand:QI 2 "const1_operand" ""))
12265           (const_int 0)))
12266    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12267         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12268   "ix86_match_ccmode (insn, CCGOCmode)
12269    && (TARGET_SHIFT1 || optimize_size)
12270    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12271   "shr{l}\t%0"
12272   [(set_attr "type" "ishift")
12273    (set (attr "length")
12274      (if_then_else (match_operand:SI 0 "register_operand" "")
12275         (const_string "2")
12276         (const_string "*")))])
12277
12278 (define_insn "*lshrsi3_one_bit_cconly"
12279   [(set (reg FLAGS_REG)
12280         (compare
12281           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12282                        (match_operand:QI 2 "const1_operand" ""))
12283           (const_int 0)))
12284    (clobber (match_scratch:SI 0 "=r"))]
12285   "ix86_match_ccmode (insn, CCGOCmode)
12286    && (TARGET_SHIFT1 || optimize_size)
12287    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12288   "shr{l}\t%0"
12289   [(set_attr "type" "ishift")
12290    (set_attr "length" "2")])
12291
12292 (define_insn "*lshrsi3_cmp_one_bit_zext"
12293   [(set (reg FLAGS_REG)
12294         (compare
12295           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12296                        (match_operand:QI 2 "const1_operand" ""))
12297           (const_int 0)))
12298    (set (match_operand:DI 0 "register_operand" "=r")
12299         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12300   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12301    && (TARGET_SHIFT1 || optimize_size)
12302    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12303   "shr{l}\t%k0"
12304   [(set_attr "type" "ishift")
12305    (set_attr "length" "2")])
12306
12307 ;; This pattern can't accept a variable shift count, since shifts by
12308 ;; zero don't affect the flags.  We assume that shifts by constant
12309 ;; zero are optimized away.
12310 (define_insn "*lshrsi3_cmp"
12311   [(set (reg FLAGS_REG)
12312         (compare
12313           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12314                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12315           (const_int 0)))
12316    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12317         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12318   "ix86_match_ccmode (insn, CCGOCmode)
12319    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12320    && (optimize_size
12321        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12322   "shr{l}\t{%2, %0|%0, %2}"
12323   [(set_attr "type" "ishift")
12324    (set_attr "mode" "SI")])
12325
12326 (define_insn "*lshrsi3_cconly"
12327   [(set (reg FLAGS_REG)
12328       (compare
12329         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12330                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12331         (const_int 0)))
12332    (clobber (match_scratch:SI 0 "=r"))]
12333   "ix86_match_ccmode (insn, CCGOCmode)
12334    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12335    && (optimize_size
12336        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12337   "shr{l}\t{%2, %0|%0, %2}"
12338   [(set_attr "type" "ishift")
12339    (set_attr "mode" "SI")])
12340
12341 (define_insn "*lshrsi3_cmp_zext"
12342   [(set (reg FLAGS_REG)
12343         (compare
12344           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12345                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12346           (const_int 0)))
12347    (set (match_operand:DI 0 "register_operand" "=r")
12348         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12349   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12350    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12351    && (optimize_size
12352        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12353   "shr{l}\t{%2, %k0|%k0, %2}"
12354   [(set_attr "type" "ishift")
12355    (set_attr "mode" "SI")])
12356
12357 (define_expand "lshrhi3"
12358   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12359         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12360                      (match_operand:QI 2 "nonmemory_operand" "")))
12361    (clobber (reg:CC FLAGS_REG))]
12362   "TARGET_HIMODE_MATH"
12363   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12364
12365 (define_insn "*lshrhi3_1_one_bit"
12366   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12367         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368                      (match_operand:QI 2 "const1_operand" "")))
12369    (clobber (reg:CC FLAGS_REG))]
12370   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12371    && (TARGET_SHIFT1 || optimize_size)"
12372   "shr{w}\t%0"
12373   [(set_attr "type" "ishift")
12374    (set (attr "length")
12375      (if_then_else (match_operand 0 "register_operand" "")
12376         (const_string "2")
12377         (const_string "*")))])
12378
12379 (define_insn "*lshrhi3_1"
12380   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12381         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12382                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12383    (clobber (reg:CC FLAGS_REG))]
12384   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12385   "@
12386    shr{w}\t{%2, %0|%0, %2}
12387    shr{w}\t{%b2, %0|%0, %b2}"
12388   [(set_attr "type" "ishift")
12389    (set_attr "mode" "HI")])
12390
12391 ;; This pattern can't accept a variable shift count, since shifts by
12392 ;; zero don't affect the flags.  We assume that shifts by constant
12393 ;; zero are optimized away.
12394 (define_insn "*lshrhi3_one_bit_cmp"
12395   [(set (reg FLAGS_REG)
12396         (compare
12397           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12398                        (match_operand:QI 2 "const1_operand" ""))
12399           (const_int 0)))
12400    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12401         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12402   "ix86_match_ccmode (insn, CCGOCmode)
12403    && (TARGET_SHIFT1 || optimize_size)
12404    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12405   "shr{w}\t%0"
12406   [(set_attr "type" "ishift")
12407    (set (attr "length")
12408      (if_then_else (match_operand:SI 0 "register_operand" "")
12409         (const_string "2")
12410         (const_string "*")))])
12411
12412 (define_insn "*lshrhi3_one_bit_cconly"
12413   [(set (reg FLAGS_REG)
12414         (compare
12415           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12416                        (match_operand:QI 2 "const1_operand" ""))
12417           (const_int 0)))
12418    (clobber (match_scratch:HI 0 "=r"))]
12419   "ix86_match_ccmode (insn, CCGOCmode)
12420    && (TARGET_SHIFT1 || optimize_size)
12421    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12422   "shr{w}\t%0"
12423   [(set_attr "type" "ishift")
12424    (set_attr "length" "2")])
12425
12426 ;; This pattern can't accept a variable shift count, since shifts by
12427 ;; zero don't affect the flags.  We assume that shifts by constant
12428 ;; zero are optimized away.
12429 (define_insn "*lshrhi3_cmp"
12430   [(set (reg FLAGS_REG)
12431         (compare
12432           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12433                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12434           (const_int 0)))
12435    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12436         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12437   "ix86_match_ccmode (insn, CCGOCmode)
12438    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12439    && (optimize_size
12440        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12441   "shr{w}\t{%2, %0|%0, %2}"
12442   [(set_attr "type" "ishift")
12443    (set_attr "mode" "HI")])
12444
12445 (define_insn "*lshrhi3_cconly"
12446   [(set (reg FLAGS_REG)
12447         (compare
12448           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12449                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12450           (const_int 0)))
12451    (clobber (match_scratch:HI 0 "=r"))]
12452   "ix86_match_ccmode (insn, CCGOCmode)
12453    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12454    && (optimize_size
12455        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12456   "shr{w}\t{%2, %0|%0, %2}"
12457   [(set_attr "type" "ishift")
12458    (set_attr "mode" "HI")])
12459
12460 (define_expand "lshrqi3"
12461   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12462         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12463                      (match_operand:QI 2 "nonmemory_operand" "")))
12464    (clobber (reg:CC FLAGS_REG))]
12465   "TARGET_QIMODE_MATH"
12466   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12467
12468 (define_insn "*lshrqi3_1_one_bit"
12469   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12470         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12471                      (match_operand:QI 2 "const1_operand" "")))
12472    (clobber (reg:CC FLAGS_REG))]
12473   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12474    && (TARGET_SHIFT1 || optimize_size)"
12475   "shr{b}\t%0"
12476   [(set_attr "type" "ishift")
12477    (set (attr "length")
12478      (if_then_else (match_operand 0 "register_operand" "")
12479         (const_string "2")
12480         (const_string "*")))])
12481
12482 (define_insn "*lshrqi3_1_one_bit_slp"
12483   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12484         (lshiftrt:QI (match_dup 0)
12485                      (match_operand:QI 1 "const1_operand" "")))
12486    (clobber (reg:CC FLAGS_REG))]
12487   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12488    && (TARGET_SHIFT1 || optimize_size)"
12489   "shr{b}\t%0"
12490   [(set_attr "type" "ishift1")
12491    (set (attr "length")
12492      (if_then_else (match_operand 0 "register_operand" "")
12493         (const_string "2")
12494         (const_string "*")))])
12495
12496 (define_insn "*lshrqi3_1"
12497   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12498         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12499                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12500    (clobber (reg:CC FLAGS_REG))]
12501   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12502   "@
12503    shr{b}\t{%2, %0|%0, %2}
12504    shr{b}\t{%b2, %0|%0, %b2}"
12505   [(set_attr "type" "ishift")
12506    (set_attr "mode" "QI")])
12507
12508 (define_insn "*lshrqi3_1_slp"
12509   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12510         (lshiftrt:QI (match_dup 0)
12511                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12512    (clobber (reg:CC FLAGS_REG))]
12513   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12514    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12515   "@
12516    shr{b}\t{%1, %0|%0, %1}
12517    shr{b}\t{%b1, %0|%0, %b1}"
12518   [(set_attr "type" "ishift1")
12519    (set_attr "mode" "QI")])
12520
12521 ;; This pattern can't accept a variable shift count, since shifts by
12522 ;; zero don't affect the flags.  We assume that shifts by constant
12523 ;; zero are optimized away.
12524 (define_insn "*lshrqi2_one_bit_cmp"
12525   [(set (reg FLAGS_REG)
12526         (compare
12527           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12528                        (match_operand:QI 2 "const1_operand" ""))
12529           (const_int 0)))
12530    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12531         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12532   "ix86_match_ccmode (insn, CCGOCmode)
12533    && (TARGET_SHIFT1 || optimize_size)
12534    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12535   "shr{b}\t%0"
12536   [(set_attr "type" "ishift")
12537    (set (attr "length")
12538      (if_then_else (match_operand:SI 0 "register_operand" "")
12539         (const_string "2")
12540         (const_string "*")))])
12541
12542 (define_insn "*lshrqi2_one_bit_cconly"
12543   [(set (reg FLAGS_REG)
12544         (compare
12545           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12546                        (match_operand:QI 2 "const1_operand" ""))
12547           (const_int 0)))
12548    (clobber (match_scratch:QI 0 "=q"))]
12549   "ix86_match_ccmode (insn, CCGOCmode)
12550    && (TARGET_SHIFT1 || optimize_size)
12551    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12552   "shr{b}\t%0"
12553   [(set_attr "type" "ishift")
12554    (set_attr "length" "2")])
12555
12556 ;; This pattern can't accept a variable shift count, since shifts by
12557 ;; zero don't affect the flags.  We assume that shifts by constant
12558 ;; zero are optimized away.
12559 (define_insn "*lshrqi2_cmp"
12560   [(set (reg FLAGS_REG)
12561         (compare
12562           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12563                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12564           (const_int 0)))
12565    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12566         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12567   "ix86_match_ccmode (insn, CCGOCmode)
12568    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12569    && (optimize_size
12570        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12571   "shr{b}\t{%2, %0|%0, %2}"
12572   [(set_attr "type" "ishift")
12573    (set_attr "mode" "QI")])
12574
12575 (define_insn "*lshrqi2_cconly"
12576   [(set (reg FLAGS_REG)
12577         (compare
12578           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12579                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12580           (const_int 0)))
12581    (clobber (match_scratch:QI 0 "=q"))]
12582   "ix86_match_ccmode (insn, CCGOCmode)
12583    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12584    && (optimize_size
12585        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12586   "shr{b}\t{%2, %0|%0, %2}"
12587   [(set_attr "type" "ishift")
12588    (set_attr "mode" "QI")])
12589 \f
12590 ;; Rotate instructions
12591
12592 (define_expand "rotldi3"
12593   [(set (match_operand:DI 0 "shiftdi_operand" "")
12594         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12595                    (match_operand:QI 2 "nonmemory_operand" "")))
12596    (clobber (reg:CC FLAGS_REG))]
12597  ""
12598 {
12599   if (TARGET_64BIT)
12600     {
12601       ix86_expand_binary_operator (ROTATE, DImode, operands);
12602       DONE;
12603     }
12604   if (!const_1_to_31_operand (operands[2], VOIDmode))
12605     FAIL;
12606   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12607   DONE;
12608 })
12609
12610 ;; Implement rotation using two double-precision shift instructions
12611 ;; and a scratch register.
12612 (define_insn_and_split "ix86_rotldi3"
12613  [(set (match_operand:DI 0 "register_operand" "=r")
12614        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12615                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12616   (clobber (reg:CC FLAGS_REG))
12617   (clobber (match_scratch:SI 3 "=&r"))]
12618  "!TARGET_64BIT"
12619  ""
12620  "&& reload_completed"
12621  [(set (match_dup 3) (match_dup 4))
12622   (parallel
12623    [(set (match_dup 4)
12624          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12625                  (lshiftrt:SI (match_dup 5)
12626                               (minus:QI (const_int 32) (match_dup 2)))))
12627     (clobber (reg:CC FLAGS_REG))])
12628   (parallel
12629    [(set (match_dup 5)
12630          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12631                  (lshiftrt:SI (match_dup 3)
12632                               (minus:QI (const_int 32) (match_dup 2)))))
12633     (clobber (reg:CC FLAGS_REG))])]
12634  "split_di (operands, 1, operands + 4, operands + 5);")
12635
12636 (define_insn "*rotlsi3_1_one_bit_rex64"
12637   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12638         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12639                    (match_operand:QI 2 "const1_operand" "")))
12640    (clobber (reg:CC FLAGS_REG))]
12641   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12642    && (TARGET_SHIFT1 || optimize_size)"
12643   "rol{q}\t%0"
12644   [(set_attr "type" "rotate")
12645    (set (attr "length")
12646      (if_then_else (match_operand:DI 0 "register_operand" "")
12647         (const_string "2")
12648         (const_string "*")))])
12649
12650 (define_insn "*rotldi3_1_rex64"
12651   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12652         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12653                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12654    (clobber (reg:CC FLAGS_REG))]
12655   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12656   "@
12657    rol{q}\t{%2, %0|%0, %2}
12658    rol{q}\t{%b2, %0|%0, %b2}"
12659   [(set_attr "type" "rotate")
12660    (set_attr "mode" "DI")])
12661
12662 (define_expand "rotlsi3"
12663   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12664         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12665                    (match_operand:QI 2 "nonmemory_operand" "")))
12666    (clobber (reg:CC FLAGS_REG))]
12667   ""
12668   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12669
12670 (define_insn "*rotlsi3_1_one_bit"
12671   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12672         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12673                    (match_operand:QI 2 "const1_operand" "")))
12674    (clobber (reg:CC FLAGS_REG))]
12675   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12676    && (TARGET_SHIFT1 || optimize_size)"
12677   "rol{l}\t%0"
12678   [(set_attr "type" "rotate")
12679    (set (attr "length")
12680      (if_then_else (match_operand:SI 0 "register_operand" "")
12681         (const_string "2")
12682         (const_string "*")))])
12683
12684 (define_insn "*rotlsi3_1_one_bit_zext"
12685   [(set (match_operand:DI 0 "register_operand" "=r")
12686         (zero_extend:DI
12687           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12688                      (match_operand:QI 2 "const1_operand" ""))))
12689    (clobber (reg:CC FLAGS_REG))]
12690   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12691    && (TARGET_SHIFT1 || optimize_size)"
12692   "rol{l}\t%k0"
12693   [(set_attr "type" "rotate")
12694    (set_attr "length" "2")])
12695
12696 (define_insn "*rotlsi3_1"
12697   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12698         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12699                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12700    (clobber (reg:CC FLAGS_REG))]
12701   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12702   "@
12703    rol{l}\t{%2, %0|%0, %2}
12704    rol{l}\t{%b2, %0|%0, %b2}"
12705   [(set_attr "type" "rotate")
12706    (set_attr "mode" "SI")])
12707
12708 (define_insn "*rotlsi3_1_zext"
12709   [(set (match_operand:DI 0 "register_operand" "=r,r")
12710         (zero_extend:DI
12711           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12712                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12713    (clobber (reg:CC FLAGS_REG))]
12714   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12715   "@
12716    rol{l}\t{%2, %k0|%k0, %2}
12717    rol{l}\t{%b2, %k0|%k0, %b2}"
12718   [(set_attr "type" "rotate")
12719    (set_attr "mode" "SI")])
12720
12721 (define_expand "rotlhi3"
12722   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12723         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12724                    (match_operand:QI 2 "nonmemory_operand" "")))
12725    (clobber (reg:CC FLAGS_REG))]
12726   "TARGET_HIMODE_MATH"
12727   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12728
12729 (define_insn "*rotlhi3_1_one_bit"
12730   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12731         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12732                    (match_operand:QI 2 "const1_operand" "")))
12733    (clobber (reg:CC FLAGS_REG))]
12734   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12735    && (TARGET_SHIFT1 || optimize_size)"
12736   "rol{w}\t%0"
12737   [(set_attr "type" "rotate")
12738    (set (attr "length")
12739      (if_then_else (match_operand 0 "register_operand" "")
12740         (const_string "2")
12741         (const_string "*")))])
12742
12743 (define_insn "*rotlhi3_1"
12744   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12745         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12746                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12747    (clobber (reg:CC FLAGS_REG))]
12748   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12749   "@
12750    rol{w}\t{%2, %0|%0, %2}
12751    rol{w}\t{%b2, %0|%0, %b2}"
12752   [(set_attr "type" "rotate")
12753    (set_attr "mode" "HI")])
12754
12755 (define_expand "rotlqi3"
12756   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12757         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12758                    (match_operand:QI 2 "nonmemory_operand" "")))
12759    (clobber (reg:CC FLAGS_REG))]
12760   "TARGET_QIMODE_MATH"
12761   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12762
12763 (define_insn "*rotlqi3_1_one_bit_slp"
12764   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12765         (rotate:QI (match_dup 0)
12766                    (match_operand:QI 1 "const1_operand" "")))
12767    (clobber (reg:CC FLAGS_REG))]
12768   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12769    && (TARGET_SHIFT1 || optimize_size)"
12770   "rol{b}\t%0"
12771   [(set_attr "type" "rotate1")
12772    (set (attr "length")
12773      (if_then_else (match_operand 0 "register_operand" "")
12774         (const_string "2")
12775         (const_string "*")))])
12776
12777 (define_insn "*rotlqi3_1_one_bit"
12778   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12779         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12780                    (match_operand:QI 2 "const1_operand" "")))
12781    (clobber (reg:CC FLAGS_REG))]
12782   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12783    && (TARGET_SHIFT1 || optimize_size)"
12784   "rol{b}\t%0"
12785   [(set_attr "type" "rotate")
12786    (set (attr "length")
12787      (if_then_else (match_operand 0 "register_operand" "")
12788         (const_string "2")
12789         (const_string "*")))])
12790
12791 (define_insn "*rotlqi3_1_slp"
12792   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12793         (rotate:QI (match_dup 0)
12794                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12795    (clobber (reg:CC FLAGS_REG))]
12796   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12797    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12798   "@
12799    rol{b}\t{%1, %0|%0, %1}
12800    rol{b}\t{%b1, %0|%0, %b1}"
12801   [(set_attr "type" "rotate1")
12802    (set_attr "mode" "QI")])
12803
12804 (define_insn "*rotlqi3_1"
12805   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12806         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12807                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12808    (clobber (reg:CC FLAGS_REG))]
12809   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12810   "@
12811    rol{b}\t{%2, %0|%0, %2}
12812    rol{b}\t{%b2, %0|%0, %b2}"
12813   [(set_attr "type" "rotate")
12814    (set_attr "mode" "QI")])
12815
12816 (define_expand "rotrdi3"
12817   [(set (match_operand:DI 0 "shiftdi_operand" "")
12818         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12819                    (match_operand:QI 2 "nonmemory_operand" "")))
12820    (clobber (reg:CC FLAGS_REG))]
12821  ""
12822 {
12823   if (TARGET_64BIT)
12824     {
12825       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12826       DONE;
12827     }
12828   if (!const_1_to_31_operand (operands[2], VOIDmode))
12829     FAIL;
12830   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12831   DONE;
12832 })
12833
12834 ;; Implement rotation using two double-precision shift instructions
12835 ;; and a scratch register.
12836 (define_insn_and_split "ix86_rotrdi3"
12837  [(set (match_operand:DI 0 "register_operand" "=r")
12838        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12839                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12840   (clobber (reg:CC FLAGS_REG))
12841   (clobber (match_scratch:SI 3 "=&r"))]
12842  "!TARGET_64BIT"
12843  ""
12844  "&& reload_completed"
12845  [(set (match_dup 3) (match_dup 4))
12846   (parallel
12847    [(set (match_dup 4)
12848          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12849                  (ashift:SI (match_dup 5)
12850                             (minus:QI (const_int 32) (match_dup 2)))))
12851     (clobber (reg:CC FLAGS_REG))])
12852   (parallel
12853    [(set (match_dup 5)
12854          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12855                  (ashift:SI (match_dup 3)
12856                             (minus:QI (const_int 32) (match_dup 2)))))
12857     (clobber (reg:CC FLAGS_REG))])]
12858  "split_di (operands, 1, operands + 4, operands + 5);")
12859
12860 (define_insn "*rotrdi3_1_one_bit_rex64"
12861   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12862         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12863                      (match_operand:QI 2 "const1_operand" "")))
12864    (clobber (reg:CC FLAGS_REG))]
12865   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12866    && (TARGET_SHIFT1 || optimize_size)"
12867   "ror{q}\t%0"
12868   [(set_attr "type" "rotate")
12869    (set (attr "length")
12870      (if_then_else (match_operand:DI 0 "register_operand" "")
12871         (const_string "2")
12872         (const_string "*")))])
12873
12874 (define_insn "*rotrdi3_1_rex64"
12875   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12876         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12877                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12878    (clobber (reg:CC FLAGS_REG))]
12879   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12880   "@
12881    ror{q}\t{%2, %0|%0, %2}
12882    ror{q}\t{%b2, %0|%0, %b2}"
12883   [(set_attr "type" "rotate")
12884    (set_attr "mode" "DI")])
12885
12886 (define_expand "rotrsi3"
12887   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12888         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12889                      (match_operand:QI 2 "nonmemory_operand" "")))
12890    (clobber (reg:CC FLAGS_REG))]
12891   ""
12892   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12893
12894 (define_insn "*rotrsi3_1_one_bit"
12895   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12896         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12897                      (match_operand:QI 2 "const1_operand" "")))
12898    (clobber (reg:CC FLAGS_REG))]
12899   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12900    && (TARGET_SHIFT1 || optimize_size)"
12901   "ror{l}\t%0"
12902   [(set_attr "type" "rotate")
12903    (set (attr "length")
12904      (if_then_else (match_operand:SI 0 "register_operand" "")
12905         (const_string "2")
12906         (const_string "*")))])
12907
12908 (define_insn "*rotrsi3_1_one_bit_zext"
12909   [(set (match_operand:DI 0 "register_operand" "=r")
12910         (zero_extend:DI
12911           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12912                        (match_operand:QI 2 "const1_operand" ""))))
12913    (clobber (reg:CC FLAGS_REG))]
12914   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12915    && (TARGET_SHIFT1 || optimize_size)"
12916   "ror{l}\t%k0"
12917   [(set_attr "type" "rotate")
12918    (set (attr "length")
12919      (if_then_else (match_operand:SI 0 "register_operand" "")
12920         (const_string "2")
12921         (const_string "*")))])
12922
12923 (define_insn "*rotrsi3_1"
12924   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12925         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12926                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12927    (clobber (reg:CC FLAGS_REG))]
12928   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12929   "@
12930    ror{l}\t{%2, %0|%0, %2}
12931    ror{l}\t{%b2, %0|%0, %b2}"
12932   [(set_attr "type" "rotate")
12933    (set_attr "mode" "SI")])
12934
12935 (define_insn "*rotrsi3_1_zext"
12936   [(set (match_operand:DI 0 "register_operand" "=r,r")
12937         (zero_extend:DI
12938           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12939                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12940    (clobber (reg:CC FLAGS_REG))]
12941   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12942   "@
12943    ror{l}\t{%2, %k0|%k0, %2}
12944    ror{l}\t{%b2, %k0|%k0, %b2}"
12945   [(set_attr "type" "rotate")
12946    (set_attr "mode" "SI")])
12947
12948 (define_expand "rotrhi3"
12949   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12950         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12951                      (match_operand:QI 2 "nonmemory_operand" "")))
12952    (clobber (reg:CC FLAGS_REG))]
12953   "TARGET_HIMODE_MATH"
12954   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12955
12956 (define_insn "*rotrhi3_one_bit"
12957   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12958         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12959                      (match_operand:QI 2 "const1_operand" "")))
12960    (clobber (reg:CC FLAGS_REG))]
12961   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12962    && (TARGET_SHIFT1 || optimize_size)"
12963   "ror{w}\t%0"
12964   [(set_attr "type" "rotate")
12965    (set (attr "length")
12966      (if_then_else (match_operand 0 "register_operand" "")
12967         (const_string "2")
12968         (const_string "*")))])
12969
12970 (define_insn "*rotrhi3"
12971   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12972         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12973                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12974    (clobber (reg:CC FLAGS_REG))]
12975   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12976   "@
12977    ror{w}\t{%2, %0|%0, %2}
12978    ror{w}\t{%b2, %0|%0, %b2}"
12979   [(set_attr "type" "rotate")
12980    (set_attr "mode" "HI")])
12981
12982 (define_expand "rotrqi3"
12983   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12984         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12985                      (match_operand:QI 2 "nonmemory_operand" "")))
12986    (clobber (reg:CC FLAGS_REG))]
12987   "TARGET_QIMODE_MATH"
12988   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12989
12990 (define_insn "*rotrqi3_1_one_bit"
12991   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12992         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12993                      (match_operand:QI 2 "const1_operand" "")))
12994    (clobber (reg:CC FLAGS_REG))]
12995   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12996    && (TARGET_SHIFT1 || optimize_size)"
12997   "ror{b}\t%0"
12998   [(set_attr "type" "rotate")
12999    (set (attr "length")
13000      (if_then_else (match_operand 0 "register_operand" "")
13001         (const_string "2")
13002         (const_string "*")))])
13003
13004 (define_insn "*rotrqi3_1_one_bit_slp"
13005   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13006         (rotatert:QI (match_dup 0)
13007                      (match_operand:QI 1 "const1_operand" "")))
13008    (clobber (reg:CC FLAGS_REG))]
13009   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13010    && (TARGET_SHIFT1 || optimize_size)"
13011   "ror{b}\t%0"
13012   [(set_attr "type" "rotate1")
13013    (set (attr "length")
13014      (if_then_else (match_operand 0 "register_operand" "")
13015         (const_string "2")
13016         (const_string "*")))])
13017
13018 (define_insn "*rotrqi3_1"
13019   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13020         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13021                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13022    (clobber (reg:CC FLAGS_REG))]
13023   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13024   "@
13025    ror{b}\t{%2, %0|%0, %2}
13026    ror{b}\t{%b2, %0|%0, %b2}"
13027   [(set_attr "type" "rotate")
13028    (set_attr "mode" "QI")])
13029
13030 (define_insn "*rotrqi3_1_slp"
13031   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13032         (rotatert:QI (match_dup 0)
13033                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13034    (clobber (reg:CC FLAGS_REG))]
13035   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13036    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13037   "@
13038    ror{b}\t{%1, %0|%0, %1}
13039    ror{b}\t{%b1, %0|%0, %b1}"
13040   [(set_attr "type" "rotate1")
13041    (set_attr "mode" "QI")])
13042 \f
13043 ;; Bit set / bit test instructions
13044
13045 (define_expand "extv"
13046   [(set (match_operand:SI 0 "register_operand" "")
13047         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13048                          (match_operand:SI 2 "const8_operand" "")
13049                          (match_operand:SI 3 "const8_operand" "")))]
13050   ""
13051 {
13052   /* Handle extractions from %ah et al.  */
13053   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13054     FAIL;
13055
13056   /* From mips.md: extract_bit_field doesn't verify that our source
13057      matches the predicate, so check it again here.  */
13058   if (! ext_register_operand (operands[1], VOIDmode))
13059     FAIL;
13060 })
13061
13062 (define_expand "extzv"
13063   [(set (match_operand:SI 0 "register_operand" "")
13064         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13065                          (match_operand:SI 2 "const8_operand" "")
13066                          (match_operand:SI 3 "const8_operand" "")))]
13067   ""
13068 {
13069   /* Handle extractions from %ah et al.  */
13070   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13071     FAIL;
13072
13073   /* From mips.md: extract_bit_field doesn't verify that our source
13074      matches the predicate, so check it again here.  */
13075   if (! ext_register_operand (operands[1], VOIDmode))
13076     FAIL;
13077 })
13078
13079 (define_expand "insv"
13080   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13081                       (match_operand 1 "const8_operand" "")
13082                       (match_operand 2 "const8_operand" ""))
13083         (match_operand 3 "register_operand" ""))]
13084   ""
13085 {
13086   /* Handle insertions to %ah et al.  */
13087   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13088     FAIL;
13089
13090   /* From mips.md: insert_bit_field doesn't verify that our source
13091      matches the predicate, so check it again here.  */
13092   if (! ext_register_operand (operands[0], VOIDmode))
13093     FAIL;
13094
13095   if (TARGET_64BIT)
13096     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13097   else
13098     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13099
13100   DONE;
13101 })
13102
13103 ;; %%% bts, btr, btc, bt.
13104 ;; In general these instructions are *slow* when applied to memory,
13105 ;; since they enforce atomic operation.  When applied to registers,
13106 ;; it depends on the cpu implementation.  They're never faster than
13107 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13108 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13109 ;; within the instruction itself, so operating on bits in the high
13110 ;; 32-bits of a register becomes easier.
13111 ;;
13112 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13113 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13114 ;; negdf respectively, so they can never be disabled entirely.
13115
13116 (define_insn "*btsq"
13117   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13118                          (const_int 1)
13119                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13120         (const_int 1))
13121    (clobber (reg:CC FLAGS_REG))]
13122   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13123   "bts{q} %1,%0"
13124   [(set_attr "type" "alu1")])
13125
13126 (define_insn "*btrq"
13127   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13128                          (const_int 1)
13129                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13130         (const_int 0))
13131    (clobber (reg:CC FLAGS_REG))]
13132   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13133   "btr{q} %1,%0"
13134   [(set_attr "type" "alu1")])
13135
13136 (define_insn "*btcq"
13137   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13138                          (const_int 1)
13139                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13140         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13141    (clobber (reg:CC FLAGS_REG))]
13142   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13143   "btc{q} %1,%0"
13144   [(set_attr "type" "alu1")])
13145
13146 ;; Allow Nocona to avoid these instructions if a register is available.
13147
13148 (define_peephole2
13149   [(match_scratch:DI 2 "r")
13150    (parallel [(set (zero_extract:DI
13151                      (match_operand:DI 0 "register_operand" "")
13152                      (const_int 1)
13153                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13154                    (const_int 1))
13155               (clobber (reg:CC FLAGS_REG))])]
13156   "TARGET_64BIT && !TARGET_USE_BT"
13157   [(const_int 0)]
13158 {
13159   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13160   rtx op1;
13161
13162   if (HOST_BITS_PER_WIDE_INT >= 64)
13163     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13164   else if (i < HOST_BITS_PER_WIDE_INT)
13165     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13166   else
13167     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13168
13169   op1 = immed_double_const (lo, hi, DImode);
13170   if (i >= 31)
13171     {
13172       emit_move_insn (operands[2], op1);
13173       op1 = operands[2];
13174     }
13175
13176   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13177   DONE;
13178 })
13179
13180 (define_peephole2
13181   [(match_scratch:DI 2 "r")
13182    (parallel [(set (zero_extract:DI
13183                      (match_operand:DI 0 "register_operand" "")
13184                      (const_int 1)
13185                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13186                    (const_int 0))
13187               (clobber (reg:CC FLAGS_REG))])]
13188   "TARGET_64BIT && !TARGET_USE_BT"
13189   [(const_int 0)]
13190 {
13191   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13192   rtx op1;
13193
13194   if (HOST_BITS_PER_WIDE_INT >= 64)
13195     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13196   else if (i < HOST_BITS_PER_WIDE_INT)
13197     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13198   else
13199     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13200
13201   op1 = immed_double_const (~lo, ~hi, DImode);
13202   if (i >= 32)
13203     {
13204       emit_move_insn (operands[2], op1);
13205       op1 = operands[2];
13206     }
13207
13208   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13209   DONE;
13210 })
13211
13212 (define_peephole2
13213   [(match_scratch:DI 2 "r")
13214    (parallel [(set (zero_extract:DI
13215                      (match_operand:DI 0 "register_operand" "")
13216                      (const_int 1)
13217                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13218               (not:DI (zero_extract:DI
13219                         (match_dup 0) (const_int 1) (match_dup 1))))
13220               (clobber (reg:CC FLAGS_REG))])]
13221   "TARGET_64BIT && !TARGET_USE_BT"
13222   [(const_int 0)]
13223 {
13224   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13225   rtx op1;
13226
13227   if (HOST_BITS_PER_WIDE_INT >= 64)
13228     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13229   else if (i < HOST_BITS_PER_WIDE_INT)
13230     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13231   else
13232     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13233
13234   op1 = immed_double_const (lo, hi, DImode);
13235   if (i >= 31)
13236     {
13237       emit_move_insn (operands[2], op1);
13238       op1 = operands[2];
13239     }
13240
13241   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13242   DONE;
13243 })
13244 \f
13245 ;; Store-flag instructions.
13246
13247 ;; For all sCOND expanders, also expand the compare or test insn that
13248 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13249
13250 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13251 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13252 ;; way, which can later delete the movzx if only QImode is needed.
13253
13254 (define_expand "seq"
13255   [(set (match_operand:QI 0 "register_operand" "")
13256         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257   ""
13258   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13259
13260 (define_expand "sne"
13261   [(set (match_operand:QI 0 "register_operand" "")
13262         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13263   ""
13264   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13265
13266 (define_expand "sgt"
13267   [(set (match_operand:QI 0 "register_operand" "")
13268         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13269   ""
13270   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13271
13272 (define_expand "sgtu"
13273   [(set (match_operand:QI 0 "register_operand" "")
13274         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13275   ""
13276   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13277
13278 (define_expand "slt"
13279   [(set (match_operand:QI 0 "register_operand" "")
13280         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13281   ""
13282   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13283
13284 (define_expand "sltu"
13285   [(set (match_operand:QI 0 "register_operand" "")
13286         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13287   ""
13288   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13289
13290 (define_expand "sge"
13291   [(set (match_operand:QI 0 "register_operand" "")
13292         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13293   ""
13294   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13295
13296 (define_expand "sgeu"
13297   [(set (match_operand:QI 0 "register_operand" "")
13298         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13299   ""
13300   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13301
13302 (define_expand "sle"
13303   [(set (match_operand:QI 0 "register_operand" "")
13304         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13305   ""
13306   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13307
13308 (define_expand "sleu"
13309   [(set (match_operand:QI 0 "register_operand" "")
13310         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13311   ""
13312   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13313
13314 (define_expand "sunordered"
13315   [(set (match_operand:QI 0 "register_operand" "")
13316         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13317   "TARGET_80387 || TARGET_SSE"
13318   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13319
13320 (define_expand "sordered"
13321   [(set (match_operand:QI 0 "register_operand" "")
13322         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13323   "TARGET_80387"
13324   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13325
13326 (define_expand "suneq"
13327   [(set (match_operand:QI 0 "register_operand" "")
13328         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13329   "TARGET_80387 || TARGET_SSE"
13330   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13331
13332 (define_expand "sunge"
13333   [(set (match_operand:QI 0 "register_operand" "")
13334         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13335   "TARGET_80387 || TARGET_SSE"
13336   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13337
13338 (define_expand "sungt"
13339   [(set (match_operand:QI 0 "register_operand" "")
13340         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13341   "TARGET_80387 || TARGET_SSE"
13342   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13343
13344 (define_expand "sunle"
13345   [(set (match_operand:QI 0 "register_operand" "")
13346         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13347   "TARGET_80387 || TARGET_SSE"
13348   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13349
13350 (define_expand "sunlt"
13351   [(set (match_operand:QI 0 "register_operand" "")
13352         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13353   "TARGET_80387 || TARGET_SSE"
13354   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13355
13356 (define_expand "sltgt"
13357   [(set (match_operand:QI 0 "register_operand" "")
13358         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13359   "TARGET_80387 || TARGET_SSE"
13360   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13361
13362 (define_insn "*setcc_1"
13363   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13364         (match_operator:QI 1 "ix86_comparison_operator"
13365           [(reg FLAGS_REG) (const_int 0)]))]
13366   ""
13367   "set%C1\t%0"
13368   [(set_attr "type" "setcc")
13369    (set_attr "mode" "QI")])
13370
13371 (define_insn "*setcc_2"
13372   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13373         (match_operator:QI 1 "ix86_comparison_operator"
13374           [(reg FLAGS_REG) (const_int 0)]))]
13375   ""
13376   "set%C1\t%0"
13377   [(set_attr "type" "setcc")
13378    (set_attr "mode" "QI")])
13379
13380 ;; In general it is not safe to assume too much about CCmode registers,
13381 ;; so simplify-rtx stops when it sees a second one.  Under certain
13382 ;; conditions this is safe on x86, so help combine not create
13383 ;;
13384 ;;      seta    %al
13385 ;;      testb   %al, %al
13386 ;;      sete    %al
13387
13388 (define_split
13389   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13390         (ne:QI (match_operator 1 "ix86_comparison_operator"
13391                  [(reg FLAGS_REG) (const_int 0)])
13392             (const_int 0)))]
13393   ""
13394   [(set (match_dup 0) (match_dup 1))]
13395 {
13396   PUT_MODE (operands[1], QImode);
13397 })
13398
13399 (define_split
13400   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13401         (ne:QI (match_operator 1 "ix86_comparison_operator"
13402                  [(reg FLAGS_REG) (const_int 0)])
13403             (const_int 0)))]
13404   ""
13405   [(set (match_dup 0) (match_dup 1))]
13406 {
13407   PUT_MODE (operands[1], QImode);
13408 })
13409
13410 (define_split
13411   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13412         (eq:QI (match_operator 1 "ix86_comparison_operator"
13413                  [(reg FLAGS_REG) (const_int 0)])
13414             (const_int 0)))]
13415   ""
13416   [(set (match_dup 0) (match_dup 1))]
13417 {
13418   rtx new_op1 = copy_rtx (operands[1]);
13419   operands[1] = new_op1;
13420   PUT_MODE (new_op1, QImode);
13421   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13422                                              GET_MODE (XEXP (new_op1, 0))));
13423
13424   /* Make sure that (a) the CCmode we have for the flags is strong
13425      enough for the reversed compare or (b) we have a valid FP compare.  */
13426   if (! ix86_comparison_operator (new_op1, VOIDmode))
13427     FAIL;
13428 })
13429
13430 (define_split
13431   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13432         (eq:QI (match_operator 1 "ix86_comparison_operator"
13433                  [(reg FLAGS_REG) (const_int 0)])
13434             (const_int 0)))]
13435   ""
13436   [(set (match_dup 0) (match_dup 1))]
13437 {
13438   rtx new_op1 = copy_rtx (operands[1]);
13439   operands[1] = new_op1;
13440   PUT_MODE (new_op1, QImode);
13441   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13442                                              GET_MODE (XEXP (new_op1, 0))));
13443
13444   /* Make sure that (a) the CCmode we have for the flags is strong
13445      enough for the reversed compare or (b) we have a valid FP compare.  */
13446   if (! ix86_comparison_operator (new_op1, VOIDmode))
13447     FAIL;
13448 })
13449
13450 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13451 ;; subsequent logical operations are used to imitate conditional moves.
13452 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13453 ;; it directly.
13454
13455 (define_insn "*sse_setccsf"
13456   [(set (match_operand:SF 0 "register_operand" "=x")
13457         (match_operator:SF 1 "sse_comparison_operator"
13458           [(match_operand:SF 2 "register_operand" "0")
13459            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13460   "TARGET_SSE"
13461   "cmp%D1ss\t{%3, %0|%0, %3}"
13462   [(set_attr "type" "ssecmp")
13463    (set_attr "mode" "SF")])
13464
13465 (define_insn "*sse_setccdf"
13466   [(set (match_operand:DF 0 "register_operand" "=Y")
13467         (match_operator:DF 1 "sse_comparison_operator"
13468           [(match_operand:DF 2 "register_operand" "0")
13469            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13470   "TARGET_SSE2"
13471   "cmp%D1sd\t{%3, %0|%0, %3}"
13472   [(set_attr "type" "ssecmp")
13473    (set_attr "mode" "DF")])
13474 \f
13475 ;; Basic conditional jump instructions.
13476 ;; We ignore the overflow flag for signed branch instructions.
13477
13478 ;; For all bCOND expanders, also expand the compare or test insn that
13479 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13480
13481 (define_expand "beq"
13482   [(set (pc)
13483         (if_then_else (match_dup 1)
13484                       (label_ref (match_operand 0 "" ""))
13485                       (pc)))]
13486   ""
13487   "ix86_expand_branch (EQ, operands[0]); DONE;")
13488
13489 (define_expand "bne"
13490   [(set (pc)
13491         (if_then_else (match_dup 1)
13492                       (label_ref (match_operand 0 "" ""))
13493                       (pc)))]
13494   ""
13495   "ix86_expand_branch (NE, operands[0]); DONE;")
13496
13497 (define_expand "bgt"
13498   [(set (pc)
13499         (if_then_else (match_dup 1)
13500                       (label_ref (match_operand 0 "" ""))
13501                       (pc)))]
13502   ""
13503   "ix86_expand_branch (GT, operands[0]); DONE;")
13504
13505 (define_expand "bgtu"
13506   [(set (pc)
13507         (if_then_else (match_dup 1)
13508                       (label_ref (match_operand 0 "" ""))
13509                       (pc)))]
13510   ""
13511   "ix86_expand_branch (GTU, operands[0]); DONE;")
13512
13513 (define_expand "blt"
13514   [(set (pc)
13515         (if_then_else (match_dup 1)
13516                       (label_ref (match_operand 0 "" ""))
13517                       (pc)))]
13518   ""
13519   "ix86_expand_branch (LT, operands[0]); DONE;")
13520
13521 (define_expand "bltu"
13522   [(set (pc)
13523         (if_then_else (match_dup 1)
13524                       (label_ref (match_operand 0 "" ""))
13525                       (pc)))]
13526   ""
13527   "ix86_expand_branch (LTU, operands[0]); DONE;")
13528
13529 (define_expand "bge"
13530   [(set (pc)
13531         (if_then_else (match_dup 1)
13532                       (label_ref (match_operand 0 "" ""))
13533                       (pc)))]
13534   ""
13535   "ix86_expand_branch (GE, operands[0]); DONE;")
13536
13537 (define_expand "bgeu"
13538   [(set (pc)
13539         (if_then_else (match_dup 1)
13540                       (label_ref (match_operand 0 "" ""))
13541                       (pc)))]
13542   ""
13543   "ix86_expand_branch (GEU, operands[0]); DONE;")
13544
13545 (define_expand "ble"
13546   [(set (pc)
13547         (if_then_else (match_dup 1)
13548                       (label_ref (match_operand 0 "" ""))
13549                       (pc)))]
13550   ""
13551   "ix86_expand_branch (LE, operands[0]); DONE;")
13552
13553 (define_expand "bleu"
13554   [(set (pc)
13555         (if_then_else (match_dup 1)
13556                       (label_ref (match_operand 0 "" ""))
13557                       (pc)))]
13558   ""
13559   "ix86_expand_branch (LEU, operands[0]); DONE;")
13560
13561 (define_expand "bunordered"
13562   [(set (pc)
13563         (if_then_else (match_dup 1)
13564                       (label_ref (match_operand 0 "" ""))
13565                       (pc)))]
13566   "TARGET_80387 || TARGET_SSE_MATH"
13567   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13568
13569 (define_expand "bordered"
13570   [(set (pc)
13571         (if_then_else (match_dup 1)
13572                       (label_ref (match_operand 0 "" ""))
13573                       (pc)))]
13574   "TARGET_80387 || TARGET_SSE_MATH"
13575   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13576
13577 (define_expand "buneq"
13578   [(set (pc)
13579         (if_then_else (match_dup 1)
13580                       (label_ref (match_operand 0 "" ""))
13581                       (pc)))]
13582   "TARGET_80387 || TARGET_SSE_MATH"
13583   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13584
13585 (define_expand "bunge"
13586   [(set (pc)
13587         (if_then_else (match_dup 1)
13588                       (label_ref (match_operand 0 "" ""))
13589                       (pc)))]
13590   "TARGET_80387 || TARGET_SSE_MATH"
13591   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13592
13593 (define_expand "bungt"
13594   [(set (pc)
13595         (if_then_else (match_dup 1)
13596                       (label_ref (match_operand 0 "" ""))
13597                       (pc)))]
13598   "TARGET_80387 || TARGET_SSE_MATH"
13599   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13600
13601 (define_expand "bunle"
13602   [(set (pc)
13603         (if_then_else (match_dup 1)
13604                       (label_ref (match_operand 0 "" ""))
13605                       (pc)))]
13606   "TARGET_80387 || TARGET_SSE_MATH"
13607   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13608
13609 (define_expand "bunlt"
13610   [(set (pc)
13611         (if_then_else (match_dup 1)
13612                       (label_ref (match_operand 0 "" ""))
13613                       (pc)))]
13614   "TARGET_80387 || TARGET_SSE_MATH"
13615   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13616
13617 (define_expand "bltgt"
13618   [(set (pc)
13619         (if_then_else (match_dup 1)
13620                       (label_ref (match_operand 0 "" ""))
13621                       (pc)))]
13622   "TARGET_80387 || TARGET_SSE_MATH"
13623   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13624
13625 (define_insn "*jcc_1"
13626   [(set (pc)
13627         (if_then_else (match_operator 1 "ix86_comparison_operator"
13628                                       [(reg FLAGS_REG) (const_int 0)])
13629                       (label_ref (match_operand 0 "" ""))
13630                       (pc)))]
13631   ""
13632   "%+j%C1\t%l0"
13633   [(set_attr "type" "ibr")
13634    (set_attr "modrm" "0")
13635    (set (attr "length")
13636            (if_then_else (and (ge (minus (match_dup 0) (pc))
13637                                   (const_int -126))
13638                               (lt (minus (match_dup 0) (pc))
13639                                   (const_int 128)))
13640              (const_int 2)
13641              (const_int 6)))])
13642
13643 (define_insn "*jcc_2"
13644   [(set (pc)
13645         (if_then_else (match_operator 1 "ix86_comparison_operator"
13646                                       [(reg FLAGS_REG) (const_int 0)])
13647                       (pc)
13648                       (label_ref (match_operand 0 "" ""))))]
13649   ""
13650   "%+j%c1\t%l0"
13651   [(set_attr "type" "ibr")
13652    (set_attr "modrm" "0")
13653    (set (attr "length")
13654            (if_then_else (and (ge (minus (match_dup 0) (pc))
13655                                   (const_int -126))
13656                               (lt (minus (match_dup 0) (pc))
13657                                   (const_int 128)))
13658              (const_int 2)
13659              (const_int 6)))])
13660
13661 ;; In general it is not safe to assume too much about CCmode registers,
13662 ;; so simplify-rtx stops when it sees a second one.  Under certain
13663 ;; conditions this is safe on x86, so help combine not create
13664 ;;
13665 ;;      seta    %al
13666 ;;      testb   %al, %al
13667 ;;      je      Lfoo
13668
13669 (define_split
13670   [(set (pc)
13671         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13672                                       [(reg FLAGS_REG) (const_int 0)])
13673                           (const_int 0))
13674                       (label_ref (match_operand 1 "" ""))
13675                       (pc)))]
13676   ""
13677   [(set (pc)
13678         (if_then_else (match_dup 0)
13679                       (label_ref (match_dup 1))
13680                       (pc)))]
13681 {
13682   PUT_MODE (operands[0], VOIDmode);
13683 })
13684
13685 (define_split
13686   [(set (pc)
13687         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13688                                       [(reg FLAGS_REG) (const_int 0)])
13689                           (const_int 0))
13690                       (label_ref (match_operand 1 "" ""))
13691                       (pc)))]
13692   ""
13693   [(set (pc)
13694         (if_then_else (match_dup 0)
13695                       (label_ref (match_dup 1))
13696                       (pc)))]
13697 {
13698   rtx new_op0 = copy_rtx (operands[0]);
13699   operands[0] = new_op0;
13700   PUT_MODE (new_op0, VOIDmode);
13701   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13702                                              GET_MODE (XEXP (new_op0, 0))));
13703
13704   /* Make sure that (a) the CCmode we have for the flags is strong
13705      enough for the reversed compare or (b) we have a valid FP compare.  */
13706   if (! ix86_comparison_operator (new_op0, VOIDmode))
13707     FAIL;
13708 })
13709
13710 ;; Define combination compare-and-branch fp compare instructions to use
13711 ;; during early optimization.  Splitting the operation apart early makes
13712 ;; for bad code when we want to reverse the operation.
13713
13714 (define_insn "*fp_jcc_1_mixed"
13715   [(set (pc)
13716         (if_then_else (match_operator 0 "comparison_operator"
13717                         [(match_operand 1 "register_operand" "f,x")
13718                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13719           (label_ref (match_operand 3 "" ""))
13720           (pc)))
13721    (clobber (reg:CCFP FPSR_REG))
13722    (clobber (reg:CCFP FLAGS_REG))]
13723   "TARGET_MIX_SSE_I387
13724    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13725    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13726    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13727   "#")
13728
13729 (define_insn "*fp_jcc_1_sse"
13730   [(set (pc)
13731         (if_then_else (match_operator 0 "comparison_operator"
13732                         [(match_operand 1 "register_operand" "x")
13733                          (match_operand 2 "nonimmediate_operand" "xm")])
13734           (label_ref (match_operand 3 "" ""))
13735           (pc)))
13736    (clobber (reg:CCFP FPSR_REG))
13737    (clobber (reg:CCFP FLAGS_REG))]
13738   "TARGET_SSE_MATH
13739    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13740    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13741    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13742   "#")
13743
13744 (define_insn "*fp_jcc_1_387"
13745   [(set (pc)
13746         (if_then_else (match_operator 0 "comparison_operator"
13747                         [(match_operand 1 "register_operand" "f")
13748                          (match_operand 2 "register_operand" "f")])
13749           (label_ref (match_operand 3 "" ""))
13750           (pc)))
13751    (clobber (reg:CCFP FPSR_REG))
13752    (clobber (reg:CCFP FLAGS_REG))]
13753   "TARGET_CMOVE && TARGET_80387
13754    && FLOAT_MODE_P (GET_MODE (operands[1]))
13755    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13756    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13757   "#")
13758
13759 (define_insn "*fp_jcc_2_mixed"
13760   [(set (pc)
13761         (if_then_else (match_operator 0 "comparison_operator"
13762                         [(match_operand 1 "register_operand" "f,x")
13763                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13764           (pc)
13765           (label_ref (match_operand 3 "" ""))))
13766    (clobber (reg:CCFP FPSR_REG))
13767    (clobber (reg:CCFP FLAGS_REG))]
13768   "TARGET_MIX_SSE_I387
13769    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13770    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13771    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13772   "#")
13773
13774 (define_insn "*fp_jcc_2_sse"
13775   [(set (pc)
13776         (if_then_else (match_operator 0 "comparison_operator"
13777                         [(match_operand 1 "register_operand" "x")
13778                          (match_operand 2 "nonimmediate_operand" "xm")])
13779           (pc)
13780           (label_ref (match_operand 3 "" ""))))
13781    (clobber (reg:CCFP FPSR_REG))
13782    (clobber (reg:CCFP FLAGS_REG))]
13783   "TARGET_SSE_MATH
13784    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13785    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13786    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13787   "#")
13788
13789 (define_insn "*fp_jcc_2_387"
13790   [(set (pc)
13791         (if_then_else (match_operator 0 "comparison_operator"
13792                         [(match_operand 1 "register_operand" "f")
13793                          (match_operand 2 "register_operand" "f")])
13794           (pc)
13795           (label_ref (match_operand 3 "" ""))))
13796    (clobber (reg:CCFP FPSR_REG))
13797    (clobber (reg:CCFP FLAGS_REG))]
13798   "TARGET_CMOVE && TARGET_80387
13799    && FLOAT_MODE_P (GET_MODE (operands[1]))
13800    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13801    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13802   "#")
13803
13804 (define_insn "*fp_jcc_3_387"
13805   [(set (pc)
13806         (if_then_else (match_operator 0 "comparison_operator"
13807                         [(match_operand 1 "register_operand" "f")
13808                          (match_operand 2 "nonimmediate_operand" "fm")])
13809           (label_ref (match_operand 3 "" ""))
13810           (pc)))
13811    (clobber (reg:CCFP FPSR_REG))
13812    (clobber (reg:CCFP FLAGS_REG))
13813    (clobber (match_scratch:HI 4 "=a"))]
13814   "TARGET_80387
13815    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13816    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13817    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13818    && SELECT_CC_MODE (GET_CODE (operands[0]),
13819                       operands[1], operands[2]) == CCFPmode
13820    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13821   "#")
13822
13823 (define_insn "*fp_jcc_4_387"
13824   [(set (pc)
13825         (if_then_else (match_operator 0 "comparison_operator"
13826                         [(match_operand 1 "register_operand" "f")
13827                          (match_operand 2 "nonimmediate_operand" "fm")])
13828           (pc)
13829           (label_ref (match_operand 3 "" ""))))
13830    (clobber (reg:CCFP FPSR_REG))
13831    (clobber (reg:CCFP FLAGS_REG))
13832    (clobber (match_scratch:HI 4 "=a"))]
13833   "TARGET_80387
13834    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13835    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13836    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13837    && SELECT_CC_MODE (GET_CODE (operands[0]),
13838                       operands[1], operands[2]) == CCFPmode
13839    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13840   "#")
13841
13842 (define_insn "*fp_jcc_5_387"
13843   [(set (pc)
13844         (if_then_else (match_operator 0 "comparison_operator"
13845                         [(match_operand 1 "register_operand" "f")
13846                          (match_operand 2 "register_operand" "f")])
13847           (label_ref (match_operand 3 "" ""))
13848           (pc)))
13849    (clobber (reg:CCFP FPSR_REG))
13850    (clobber (reg:CCFP FLAGS_REG))
13851    (clobber (match_scratch:HI 4 "=a"))]
13852   "TARGET_80387
13853    && FLOAT_MODE_P (GET_MODE (operands[1]))
13854    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13855    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13856   "#")
13857
13858 (define_insn "*fp_jcc_6_387"
13859   [(set (pc)
13860         (if_then_else (match_operator 0 "comparison_operator"
13861                         [(match_operand 1 "register_operand" "f")
13862                          (match_operand 2 "register_operand" "f")])
13863           (pc)
13864           (label_ref (match_operand 3 "" ""))))
13865    (clobber (reg:CCFP FPSR_REG))
13866    (clobber (reg:CCFP FLAGS_REG))
13867    (clobber (match_scratch:HI 4 "=a"))]
13868   "TARGET_80387
13869    && FLOAT_MODE_P (GET_MODE (operands[1]))
13870    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13871    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13872   "#")
13873
13874 (define_insn "*fp_jcc_7_387"
13875   [(set (pc)
13876         (if_then_else (match_operator 0 "comparison_operator"
13877                         [(match_operand 1 "register_operand" "f")
13878                          (match_operand 2 "const0_operand" "X")])
13879           (label_ref (match_operand 3 "" ""))
13880           (pc)))
13881    (clobber (reg:CCFP FPSR_REG))
13882    (clobber (reg:CCFP FLAGS_REG))
13883    (clobber (match_scratch:HI 4 "=a"))]
13884   "TARGET_80387
13885    && FLOAT_MODE_P (GET_MODE (operands[1]))
13886    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13887    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13888    && SELECT_CC_MODE (GET_CODE (operands[0]),
13889                       operands[1], operands[2]) == CCFPmode
13890    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13891   "#")
13892
13893 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13894 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13895 ;; with a precedence over other operators and is always put in the first
13896 ;; place. Swap condition and operands to match ficom instruction.
13897
13898 (define_insn "*fp_jcc_8<mode>_387"
13899   [(set (pc)
13900         (if_then_else (match_operator 0 "comparison_operator"
13901                         [(match_operator 1 "float_operator"
13902                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13903                            (match_operand 3 "register_operand" "f,f")])
13904           (label_ref (match_operand 4 "" ""))
13905           (pc)))
13906    (clobber (reg:CCFP FPSR_REG))
13907    (clobber (reg:CCFP FLAGS_REG))
13908    (clobber (match_scratch:HI 5 "=a,a"))]
13909   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13910    && FLOAT_MODE_P (GET_MODE (operands[3]))
13911    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13912    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13913    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13914    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13915   "#")
13916
13917 (define_split
13918   [(set (pc)
13919         (if_then_else (match_operator 0 "comparison_operator"
13920                         [(match_operand 1 "register_operand" "")
13921                          (match_operand 2 "nonimmediate_operand" "")])
13922           (match_operand 3 "" "")
13923           (match_operand 4 "" "")))
13924    (clobber (reg:CCFP FPSR_REG))
13925    (clobber (reg:CCFP FLAGS_REG))]
13926   "reload_completed"
13927   [(const_int 0)]
13928 {
13929   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13930                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13931   DONE;
13932 })
13933
13934 (define_split
13935   [(set (pc)
13936         (if_then_else (match_operator 0 "comparison_operator"
13937                         [(match_operand 1 "register_operand" "")
13938                          (match_operand 2 "general_operand" "")])
13939           (match_operand 3 "" "")
13940           (match_operand 4 "" "")))
13941    (clobber (reg:CCFP FPSR_REG))
13942    (clobber (reg:CCFP FLAGS_REG))
13943    (clobber (match_scratch:HI 5 "=a"))]
13944   "reload_completed"
13945   [(const_int 0)]
13946 {
13947   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13948                         operands[3], operands[4], operands[5], NULL_RTX);
13949   DONE;
13950 })
13951
13952 (define_split
13953   [(set (pc)
13954         (if_then_else (match_operator 0 "comparison_operator"
13955                         [(match_operator 1 "float_operator"
13956                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13957                            (match_operand 3 "register_operand" "")])
13958           (match_operand 4 "" "")
13959           (match_operand 5 "" "")))
13960    (clobber (reg:CCFP FPSR_REG))
13961    (clobber (reg:CCFP FLAGS_REG))
13962    (clobber (match_scratch:HI 6 "=a"))]
13963   "reload_completed"
13964   [(const_int 0)]
13965 {
13966   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13967   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13968                         operands[3], operands[7],
13969                         operands[4], operands[5], operands[6], NULL_RTX);
13970   DONE;
13971 })
13972
13973 ;; %%% Kill this when reload knows how to do it.
13974 (define_split
13975   [(set (pc)
13976         (if_then_else (match_operator 0 "comparison_operator"
13977                         [(match_operator 1 "float_operator"
13978                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13979                            (match_operand 3 "register_operand" "")])
13980           (match_operand 4 "" "")
13981           (match_operand 5 "" "")))
13982    (clobber (reg:CCFP FPSR_REG))
13983    (clobber (reg:CCFP FLAGS_REG))
13984    (clobber (match_scratch:HI 6 "=a"))]
13985   "reload_completed"
13986   [(const_int 0)]
13987 {
13988   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13989   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13990   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13991                         operands[3], operands[7],
13992                         operands[4], operands[5], operands[6], operands[2]);
13993   DONE;
13994 })
13995 \f
13996 ;; Unconditional and other jump instructions
13997
13998 (define_insn "jump"
13999   [(set (pc)
14000         (label_ref (match_operand 0 "" "")))]
14001   ""
14002   "jmp\t%l0"
14003   [(set_attr "type" "ibr")
14004    (set (attr "length")
14005            (if_then_else (and (ge (minus (match_dup 0) (pc))
14006                                   (const_int -126))
14007                               (lt (minus (match_dup 0) (pc))
14008                                   (const_int 128)))
14009              (const_int 2)
14010              (const_int 5)))
14011    (set_attr "modrm" "0")])
14012
14013 (define_expand "indirect_jump"
14014   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14015   ""
14016   "")
14017
14018 (define_insn "*indirect_jump"
14019   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14020   "!TARGET_64BIT"
14021   "jmp\t%A0"
14022   [(set_attr "type" "ibr")
14023    (set_attr "length_immediate" "0")])
14024
14025 (define_insn "*indirect_jump_rtx64"
14026   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14027   "TARGET_64BIT"
14028   "jmp\t%A0"
14029   [(set_attr "type" "ibr")
14030    (set_attr "length_immediate" "0")])
14031
14032 (define_expand "tablejump"
14033   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14034               (use (label_ref (match_operand 1 "" "")))])]
14035   ""
14036 {
14037   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14038      relative.  Convert the relative address to an absolute address.  */
14039   if (flag_pic)
14040     {
14041       rtx op0, op1;
14042       enum rtx_code code;
14043
14044       if (TARGET_64BIT)
14045         {
14046           code = PLUS;
14047           op0 = operands[0];
14048           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14049         }
14050       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14051         {
14052           code = PLUS;
14053           op0 = operands[0];
14054           op1 = pic_offset_table_rtx;
14055         }
14056       else
14057         {
14058           code = MINUS;
14059           op0 = pic_offset_table_rtx;
14060           op1 = operands[0];
14061         }
14062
14063       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14064                                          OPTAB_DIRECT);
14065     }
14066 })
14067
14068 (define_insn "*tablejump_1"
14069   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14070    (use (label_ref (match_operand 1 "" "")))]
14071   "!TARGET_64BIT"
14072   "jmp\t%A0"
14073   [(set_attr "type" "ibr")
14074    (set_attr "length_immediate" "0")])
14075
14076 (define_insn "*tablejump_1_rtx64"
14077   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14078    (use (label_ref (match_operand 1 "" "")))]
14079   "TARGET_64BIT"
14080   "jmp\t%A0"
14081   [(set_attr "type" "ibr")
14082    (set_attr "length_immediate" "0")])
14083 \f
14084 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14085
14086 (define_peephole2
14087   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14088    (set (match_operand:QI 1 "register_operand" "")
14089         (match_operator:QI 2 "ix86_comparison_operator"
14090           [(reg FLAGS_REG) (const_int 0)]))
14091    (set (match_operand 3 "q_regs_operand" "")
14092         (zero_extend (match_dup 1)))]
14093   "(peep2_reg_dead_p (3, operands[1])
14094     || operands_match_p (operands[1], operands[3]))
14095    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14096   [(set (match_dup 4) (match_dup 0))
14097    (set (strict_low_part (match_dup 5))
14098         (match_dup 2))]
14099 {
14100   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14101   operands[5] = gen_lowpart (QImode, operands[3]);
14102   ix86_expand_clear (operands[3]);
14103 })
14104
14105 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14106
14107 (define_peephole2
14108   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14109    (set (match_operand:QI 1 "register_operand" "")
14110         (match_operator:QI 2 "ix86_comparison_operator"
14111           [(reg FLAGS_REG) (const_int 0)]))
14112    (parallel [(set (match_operand 3 "q_regs_operand" "")
14113                    (zero_extend (match_dup 1)))
14114               (clobber (reg:CC FLAGS_REG))])]
14115   "(peep2_reg_dead_p (3, operands[1])
14116     || operands_match_p (operands[1], operands[3]))
14117    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14118   [(set (match_dup 4) (match_dup 0))
14119    (set (strict_low_part (match_dup 5))
14120         (match_dup 2))]
14121 {
14122   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14123   operands[5] = gen_lowpart (QImode, operands[3]);
14124   ix86_expand_clear (operands[3]);
14125 })
14126 \f
14127 ;; Call instructions.
14128
14129 ;; The predicates normally associated with named expanders are not properly
14130 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14131 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14132
14133 ;; Call subroutine returning no value.
14134
14135 (define_expand "call_pop"
14136   [(parallel [(call (match_operand:QI 0 "" "")
14137                     (match_operand:SI 1 "" ""))
14138               (set (reg:SI SP_REG)
14139                    (plus:SI (reg:SI SP_REG)
14140                             (match_operand:SI 3 "" "")))])]
14141   "!TARGET_64BIT"
14142 {
14143   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14144   DONE;
14145 })
14146
14147 (define_insn "*call_pop_0"
14148   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14149          (match_operand:SI 1 "" ""))
14150    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14151                             (match_operand:SI 2 "immediate_operand" "")))]
14152   "!TARGET_64BIT"
14153 {
14154   if (SIBLING_CALL_P (insn))
14155     return "jmp\t%P0";
14156   else
14157     return "call\t%P0";
14158 }
14159   [(set_attr "type" "call")])
14160
14161 (define_insn "*call_pop_1"
14162   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14163          (match_operand:SI 1 "" ""))
14164    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14165                             (match_operand:SI 2 "immediate_operand" "i")))]
14166   "!TARGET_64BIT"
14167 {
14168   if (constant_call_address_operand (operands[0], Pmode))
14169     {
14170       if (SIBLING_CALL_P (insn))
14171         return "jmp\t%P0";
14172       else
14173         return "call\t%P0";
14174     }
14175   if (SIBLING_CALL_P (insn))
14176     return "jmp\t%A0";
14177   else
14178     return "call\t%A0";
14179 }
14180   [(set_attr "type" "call")])
14181
14182 (define_expand "call"
14183   [(call (match_operand:QI 0 "" "")
14184          (match_operand 1 "" ""))
14185    (use (match_operand 2 "" ""))]
14186   ""
14187 {
14188   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14189   DONE;
14190 })
14191
14192 (define_expand "sibcall"
14193   [(call (match_operand:QI 0 "" "")
14194          (match_operand 1 "" ""))
14195    (use (match_operand 2 "" ""))]
14196   ""
14197 {
14198   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14199   DONE;
14200 })
14201
14202 (define_insn "*call_0"
14203   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14204          (match_operand 1 "" ""))]
14205   ""
14206 {
14207   if (SIBLING_CALL_P (insn))
14208     return "jmp\t%P0";
14209   else
14210     return "call\t%P0";
14211 }
14212   [(set_attr "type" "call")])
14213
14214 (define_insn "*call_1"
14215   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14216          (match_operand 1 "" ""))]
14217   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14218 {
14219   if (constant_call_address_operand (operands[0], Pmode))
14220     return "call\t%P0";
14221   return "call\t%A0";
14222 }
14223   [(set_attr "type" "call")])
14224
14225 (define_insn "*sibcall_1"
14226   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14227          (match_operand 1 "" ""))]
14228   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14229 {
14230   if (constant_call_address_operand (operands[0], Pmode))
14231     return "jmp\t%P0";
14232   return "jmp\t%A0";
14233 }
14234   [(set_attr "type" "call")])
14235
14236 (define_insn "*call_1_rex64"
14237   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14238          (match_operand 1 "" ""))]
14239   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14240 {
14241   if (constant_call_address_operand (operands[0], Pmode))
14242     return "call\t%P0";
14243   return "call\t%A0";
14244 }
14245   [(set_attr "type" "call")])
14246
14247 (define_insn "*sibcall_1_rex64"
14248   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14249          (match_operand 1 "" ""))]
14250   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14251   "jmp\t%P0"
14252   [(set_attr "type" "call")])
14253
14254 (define_insn "*sibcall_1_rex64_v"
14255   [(call (mem:QI (reg:DI 40))
14256          (match_operand 0 "" ""))]
14257   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14258   "jmp\t*%%r11"
14259   [(set_attr "type" "call")])
14260
14261
14262 ;; Call subroutine, returning value in operand 0
14263
14264 (define_expand "call_value_pop"
14265   [(parallel [(set (match_operand 0 "" "")
14266                    (call (match_operand:QI 1 "" "")
14267                          (match_operand:SI 2 "" "")))
14268               (set (reg:SI SP_REG)
14269                    (plus:SI (reg:SI SP_REG)
14270                             (match_operand:SI 4 "" "")))])]
14271   "!TARGET_64BIT"
14272 {
14273   ix86_expand_call (operands[0], operands[1], operands[2],
14274                     operands[3], operands[4], 0);
14275   DONE;
14276 })
14277
14278 (define_expand "call_value"
14279   [(set (match_operand 0 "" "")
14280         (call (match_operand:QI 1 "" "")
14281               (match_operand:SI 2 "" "")))
14282    (use (match_operand:SI 3 "" ""))]
14283   ;; Operand 2 not used on the i386.
14284   ""
14285 {
14286   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14287   DONE;
14288 })
14289
14290 (define_expand "sibcall_value"
14291   [(set (match_operand 0 "" "")
14292         (call (match_operand:QI 1 "" "")
14293               (match_operand:SI 2 "" "")))
14294    (use (match_operand:SI 3 "" ""))]
14295   ;; Operand 2 not used on the i386.
14296   ""
14297 {
14298   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14299   DONE;
14300 })
14301
14302 ;; Call subroutine returning any type.
14303
14304 (define_expand "untyped_call"
14305   [(parallel [(call (match_operand 0 "" "")
14306                     (const_int 0))
14307               (match_operand 1 "" "")
14308               (match_operand 2 "" "")])]
14309   ""
14310 {
14311   int i;
14312
14313   /* In order to give reg-stack an easier job in validating two
14314      coprocessor registers as containing a possible return value,
14315      simply pretend the untyped call returns a complex long double
14316      value.  */
14317
14318   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14319                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14320                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14321                     NULL, 0);
14322
14323   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14324     {
14325       rtx set = XVECEXP (operands[2], 0, i);
14326       emit_move_insn (SET_DEST (set), SET_SRC (set));
14327     }
14328
14329   /* The optimizer does not know that the call sets the function value
14330      registers we stored in the result block.  We avoid problems by
14331      claiming that all hard registers are used and clobbered at this
14332      point.  */
14333   emit_insn (gen_blockage (const0_rtx));
14334
14335   DONE;
14336 })
14337 \f
14338 ;; Prologue and epilogue instructions
14339
14340 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14341 ;; all of memory.  This blocks insns from being moved across this point.
14342
14343 (define_insn "blockage"
14344   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14345   ""
14346   ""
14347   [(set_attr "length" "0")])
14348
14349 ;; Insn emitted into the body of a function to return from a function.
14350 ;; This is only done if the function's epilogue is known to be simple.
14351 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14352
14353 (define_expand "return"
14354   [(return)]
14355   "ix86_can_use_return_insn_p ()"
14356 {
14357   if (current_function_pops_args)
14358     {
14359       rtx popc = GEN_INT (current_function_pops_args);
14360       emit_jump_insn (gen_return_pop_internal (popc));
14361       DONE;
14362     }
14363 })
14364
14365 (define_insn "return_internal"
14366   [(return)]
14367   "reload_completed"
14368   "ret"
14369   [(set_attr "length" "1")
14370    (set_attr "length_immediate" "0")
14371    (set_attr "modrm" "0")])
14372
14373 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14374 ;; instruction Athlon and K8 have.
14375
14376 (define_insn "return_internal_long"
14377   [(return)
14378    (unspec [(const_int 0)] UNSPEC_REP)]
14379   "reload_completed"
14380   "rep {;} ret"
14381   [(set_attr "length" "1")
14382    (set_attr "length_immediate" "0")
14383    (set_attr "prefix_rep" "1")
14384    (set_attr "modrm" "0")])
14385
14386 (define_insn "return_pop_internal"
14387   [(return)
14388    (use (match_operand:SI 0 "const_int_operand" ""))]
14389   "reload_completed"
14390   "ret\t%0"
14391   [(set_attr "length" "3")
14392    (set_attr "length_immediate" "2")
14393    (set_attr "modrm" "0")])
14394
14395 (define_insn "return_indirect_internal"
14396   [(return)
14397    (use (match_operand:SI 0 "register_operand" "r"))]
14398   "reload_completed"
14399   "jmp\t%A0"
14400   [(set_attr "type" "ibr")
14401    (set_attr "length_immediate" "0")])
14402
14403 (define_insn "nop"
14404   [(const_int 0)]
14405   ""
14406   "nop"
14407   [(set_attr "length" "1")
14408    (set_attr "length_immediate" "0")
14409    (set_attr "modrm" "0")])
14410
14411 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14412 ;; branch prediction penalty for the third jump in a 16-byte
14413 ;; block on K8.
14414
14415 (define_insn "align"
14416   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14417   ""
14418 {
14419 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14420   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14421 #else
14422   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14423      The align insn is used to avoid 3 jump instructions in the row to improve
14424      branch prediction and the benefits hardly outweigh the cost of extra 8
14425      nops on the average inserted by full alignment pseudo operation.  */
14426 #endif
14427   return "";
14428 }
14429   [(set_attr "length" "16")])
14430
14431 (define_expand "prologue"
14432   [(const_int 1)]
14433   ""
14434   "ix86_expand_prologue (); DONE;")
14435
14436 (define_insn "set_got"
14437   [(set (match_operand:SI 0 "register_operand" "=r")
14438         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14439    (clobber (reg:CC FLAGS_REG))]
14440   "!TARGET_64BIT"
14441   { return output_set_got (operands[0], NULL_RTX); }
14442   [(set_attr "type" "multi")
14443    (set_attr "length" "12")])
14444
14445 (define_insn "set_got_labelled"
14446   [(set (match_operand:SI 0 "register_operand" "=r")
14447         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14448          UNSPEC_SET_GOT))
14449    (clobber (reg:CC FLAGS_REG))]
14450   "!TARGET_64BIT"
14451   { return output_set_got (operands[0], operands[1]); }
14452   [(set_attr "type" "multi")
14453    (set_attr "length" "12")])
14454
14455 (define_insn "set_got_rex64"
14456   [(set (match_operand:DI 0 "register_operand" "=r")
14457         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14458   "TARGET_64BIT"
14459   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14460   [(set_attr "type" "lea")
14461    (set_attr "length" "6")])
14462
14463 (define_expand "epilogue"
14464   [(const_int 1)]
14465   ""
14466   "ix86_expand_epilogue (1); DONE;")
14467
14468 (define_expand "sibcall_epilogue"
14469   [(const_int 1)]
14470   ""
14471   "ix86_expand_epilogue (0); DONE;")
14472
14473 (define_expand "eh_return"
14474   [(use (match_operand 0 "register_operand" ""))]
14475   ""
14476 {
14477   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14478
14479   /* Tricky bit: we write the address of the handler to which we will
14480      be returning into someone else's stack frame, one word below the
14481      stack address we wish to restore.  */
14482   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14483   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14484   tmp = gen_rtx_MEM (Pmode, tmp);
14485   emit_move_insn (tmp, ra);
14486
14487   if (Pmode == SImode)
14488     emit_jump_insn (gen_eh_return_si (sa));
14489   else
14490     emit_jump_insn (gen_eh_return_di (sa));
14491   emit_barrier ();
14492   DONE;
14493 })
14494
14495 (define_insn_and_split "eh_return_si"
14496   [(set (pc)
14497         (unspec [(match_operand:SI 0 "register_operand" "c")]
14498                  UNSPEC_EH_RETURN))]
14499   "!TARGET_64BIT"
14500   "#"
14501   "reload_completed"
14502   [(const_int 1)]
14503   "ix86_expand_epilogue (2); DONE;")
14504
14505 (define_insn_and_split "eh_return_di"
14506   [(set (pc)
14507         (unspec [(match_operand:DI 0 "register_operand" "c")]
14508                  UNSPEC_EH_RETURN))]
14509   "TARGET_64BIT"
14510   "#"
14511   "reload_completed"
14512   [(const_int 1)]
14513   "ix86_expand_epilogue (2); DONE;")
14514
14515 (define_insn "leave"
14516   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14517    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14518    (clobber (mem:BLK (scratch)))]
14519   "!TARGET_64BIT"
14520   "leave"
14521   [(set_attr "type" "leave")])
14522
14523 (define_insn "leave_rex64"
14524   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14525    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14526    (clobber (mem:BLK (scratch)))]
14527   "TARGET_64BIT"
14528   "leave"
14529   [(set_attr "type" "leave")])
14530 \f
14531 (define_expand "ffssi2"
14532   [(parallel
14533      [(set (match_operand:SI 0 "register_operand" "")
14534            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14535       (clobber (match_scratch:SI 2 ""))
14536       (clobber (reg:CC FLAGS_REG))])]
14537   ""
14538   "")
14539
14540 (define_insn_and_split "*ffs_cmove"
14541   [(set (match_operand:SI 0 "register_operand" "=r")
14542         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14543    (clobber (match_scratch:SI 2 "=&r"))
14544    (clobber (reg:CC FLAGS_REG))]
14545   "TARGET_CMOVE"
14546   "#"
14547   "&& reload_completed"
14548   [(set (match_dup 2) (const_int -1))
14549    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14550               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14551    (set (match_dup 0) (if_then_else:SI
14552                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14553                         (match_dup 2)
14554                         (match_dup 0)))
14555    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14556               (clobber (reg:CC FLAGS_REG))])]
14557   "")
14558
14559 (define_insn_and_split "*ffs_no_cmove"
14560   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14561         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14562    (clobber (match_scratch:SI 2 "=&q"))
14563    (clobber (reg:CC FLAGS_REG))]
14564   ""
14565   "#"
14566   "reload_completed"
14567   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14568               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14569    (set (strict_low_part (match_dup 3))
14570         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14571    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14572               (clobber (reg:CC FLAGS_REG))])
14573    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14574               (clobber (reg:CC FLAGS_REG))])
14575    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14576               (clobber (reg:CC FLAGS_REG))])]
14577 {
14578   operands[3] = gen_lowpart (QImode, operands[2]);
14579   ix86_expand_clear (operands[2]);
14580 })
14581
14582 (define_insn "*ffssi_1"
14583   [(set (reg:CCZ FLAGS_REG)
14584         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14585                      (const_int 0)))
14586    (set (match_operand:SI 0 "register_operand" "=r")
14587         (ctz:SI (match_dup 1)))]
14588   ""
14589   "bsf{l}\t{%1, %0|%0, %1}"
14590   [(set_attr "prefix_0f" "1")])
14591
14592 (define_expand "ffsdi2"
14593   [(parallel
14594      [(set (match_operand:DI 0 "register_operand" "")
14595            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14596       (clobber (match_scratch:DI 2 ""))
14597       (clobber (reg:CC FLAGS_REG))])]
14598   "TARGET_64BIT && TARGET_CMOVE"
14599   "")
14600
14601 (define_insn_and_split "*ffs_rex64"
14602   [(set (match_operand:DI 0 "register_operand" "=r")
14603         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14604    (clobber (match_scratch:DI 2 "=&r"))
14605    (clobber (reg:CC FLAGS_REG))]
14606   "TARGET_64BIT && TARGET_CMOVE"
14607   "#"
14608   "&& reload_completed"
14609   [(set (match_dup 2) (const_int -1))
14610    (parallel [(set (reg:CCZ FLAGS_REG)
14611                    (compare:CCZ (match_dup 1) (const_int 0)))
14612               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14613    (set (match_dup 0) (if_then_else:DI
14614                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14615                         (match_dup 2)
14616                         (match_dup 0)))
14617    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14618               (clobber (reg:CC FLAGS_REG))])]
14619   "")
14620
14621 (define_insn "*ffsdi_1"
14622   [(set (reg:CCZ FLAGS_REG)
14623         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14624                      (const_int 0)))
14625    (set (match_operand:DI 0 "register_operand" "=r")
14626         (ctz:DI (match_dup 1)))]
14627   "TARGET_64BIT"
14628   "bsf{q}\t{%1, %0|%0, %1}"
14629   [(set_attr "prefix_0f" "1")])
14630
14631 (define_insn "ctzsi2"
14632   [(set (match_operand:SI 0 "register_operand" "=r")
14633         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14634    (clobber (reg:CC FLAGS_REG))]
14635   ""
14636   "bsf{l}\t{%1, %0|%0, %1}"
14637   [(set_attr "prefix_0f" "1")])
14638
14639 (define_insn "ctzdi2"
14640   [(set (match_operand:DI 0 "register_operand" "=r")
14641         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14642    (clobber (reg:CC FLAGS_REG))]
14643   "TARGET_64BIT"
14644   "bsf{q}\t{%1, %0|%0, %1}"
14645   [(set_attr "prefix_0f" "1")])
14646
14647 (define_expand "clzsi2"
14648   [(parallel
14649      [(set (match_operand:SI 0 "register_operand" "")
14650            (minus:SI (const_int 31)
14651                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14652       (clobber (reg:CC FLAGS_REG))])
14653    (parallel
14654      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14655       (clobber (reg:CC FLAGS_REG))])]
14656   ""
14657 {
14658   if (TARGET_ABM)
14659     {
14660       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14661       DONE;
14662     }
14663 })
14664
14665 (define_insn "clzsi2_abm"
14666   [(set (match_operand:SI 0 "register_operand" "=r")
14667         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14668    (clobber (reg:CC FLAGS_REG))]
14669   "TARGET_ABM"
14670   "lzcnt{l}\t{%1, %0|%0, %1}"
14671   [(set_attr "prefix_rep" "1")
14672    (set_attr "type" "bitmanip")
14673    (set_attr "mode" "SI")])
14674
14675 (define_insn "*bsr"
14676   [(set (match_operand:SI 0 "register_operand" "=r")
14677         (minus:SI (const_int 31)
14678                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14679    (clobber (reg:CC FLAGS_REG))]
14680   ""
14681   "bsr{l}\t{%1, %0|%0, %1}"
14682   [(set_attr "prefix_0f" "1")
14683    (set_attr "mode" "SI")])
14684
14685 (define_insn "popcountsi2"
14686   [(set (match_operand:SI 0 "register_operand" "=r")
14687         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14688    (clobber (reg:CC FLAGS_REG))]
14689   "TARGET_POPCNT"
14690   "popcnt{l}\t{%1, %0|%0, %1}"
14691   [(set_attr "prefix_rep" "1")
14692    (set_attr "type" "bitmanip")
14693    (set_attr "mode" "SI")])
14694
14695 (define_insn "*popcountsi2_cmp"
14696   [(set (reg FLAGS_REG)
14697         (compare
14698           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14699           (const_int 0)))
14700    (set (match_operand:SI 0 "register_operand" "=r")
14701         (popcount:SI (match_dup 1)))]
14702   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14703   "popcnt{l}\t{%1, %0|%0, %1}"
14704   [(set_attr "prefix_rep" "1")
14705    (set_attr "type" "bitmanip")
14706    (set_attr "mode" "SI")])
14707
14708 (define_insn "*popcountsi2_cmp_zext"
14709   [(set (reg FLAGS_REG)
14710         (compare
14711           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14712           (const_int 0)))
14713    (set (match_operand:DI 0 "register_operand" "=r")
14714         (zero_extend:DI(popcount:SI (match_dup 1))))]
14715   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14716   "popcnt{l}\t{%1, %0|%0, %1}"
14717   [(set_attr "prefix_rep" "1")
14718    (set_attr "type" "bitmanip")
14719    (set_attr "mode" "SI")])
14720
14721 (define_insn "bswapsi2"
14722   [(set (match_operand:SI 0 "register_operand" "=r")
14723         (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14724    (clobber (reg:CC FLAGS_REG))]
14725   "TARGET_BSWAP"
14726   "bswap\t%k0"
14727   [(set_attr "prefix_0f" "1")
14728    (set_attr "length" "2")])
14729
14730 (define_insn "bswapdi2"
14731   [(set (match_operand:DI 0 "register_operand" "=r")
14732         (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14733    (clobber (reg:CC FLAGS_REG))]
14734   "TARGET_64BIT && TARGET_BSWAP"
14735   "bswap\t%0"
14736   [(set_attr "prefix_0f" "1")
14737    (set_attr "length" "3")])
14738
14739 (define_expand "clzdi2"
14740   [(parallel
14741      [(set (match_operand:DI 0 "register_operand" "")
14742            (minus:DI (const_int 63)
14743                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14744       (clobber (reg:CC FLAGS_REG))])
14745    (parallel
14746      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14747       (clobber (reg:CC FLAGS_REG))])]
14748   "TARGET_64BIT"
14749 {
14750   if (TARGET_ABM)
14751     {
14752       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14753       DONE;
14754     }
14755 })
14756
14757 (define_insn "clzdi2_abm"
14758   [(set (match_operand:DI 0 "register_operand" "=r")
14759         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14760    (clobber (reg:CC FLAGS_REG))]
14761   "TARGET_64BIT && TARGET_ABM"
14762   "lzcnt{q}\t{%1, %0|%0, %1}"
14763   [(set_attr "prefix_rep" "1")
14764    (set_attr "type" "bitmanip")
14765    (set_attr "mode" "DI")])
14766
14767 (define_insn "*bsr_rex64"
14768   [(set (match_operand:DI 0 "register_operand" "=r")
14769         (minus:DI (const_int 63)
14770                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14771    (clobber (reg:CC FLAGS_REG))]
14772   "TARGET_64BIT"
14773   "bsr{q}\t{%1, %0|%0, %1}"
14774   [(set_attr "prefix_0f" "1")
14775    (set_attr "mode" "DI")])
14776
14777 (define_insn "popcountdi2"
14778   [(set (match_operand:DI 0 "register_operand" "=r")
14779         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14780    (clobber (reg:CC FLAGS_REG))]
14781   "TARGET_64BIT && TARGET_POPCNT"
14782   "popcnt{q}\t{%1, %0|%0, %1}"
14783   [(set_attr "prefix_rep" "1")
14784    (set_attr "type" "bitmanip")
14785    (set_attr "mode" "DI")])
14786
14787 (define_insn "*popcountdi2_cmp"
14788   [(set (reg FLAGS_REG)
14789         (compare
14790           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14791           (const_int 0)))
14792    (set (match_operand:DI 0 "register_operand" "=r")
14793         (popcount:DI (match_dup 1)))]
14794   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14795   "popcnt{q}\t{%1, %0|%0, %1}"
14796   [(set_attr "prefix_rep" "1")
14797    (set_attr "type" "bitmanip")
14798    (set_attr "mode" "DI")])
14799
14800 (define_expand "clzhi2"
14801   [(parallel
14802      [(set (match_operand:HI 0 "register_operand" "")
14803            (minus:HI (const_int 15)
14804                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14805       (clobber (reg:CC FLAGS_REG))])
14806    (parallel
14807      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14808       (clobber (reg:CC FLAGS_REG))])]
14809   ""
14810 {
14811   if (TARGET_ABM)
14812     {
14813       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14814       DONE;
14815     }
14816 })
14817
14818 (define_insn "clzhi2_abm"
14819   [(set (match_operand:HI 0 "register_operand" "=r")
14820         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14821    (clobber (reg:CC FLAGS_REG))]
14822   "TARGET_ABM"
14823   "lzcnt{w}\t{%1, %0|%0, %1}"
14824   [(set_attr "prefix_rep" "1")
14825    (set_attr "type" "bitmanip")
14826    (set_attr "mode" "HI")])
14827
14828 (define_insn "*bsrhi"
14829   [(set (match_operand:HI 0 "register_operand" "=r")
14830         (minus:HI (const_int 15)
14831                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14832    (clobber (reg:CC FLAGS_REG))]
14833   ""
14834   "bsr{w}\t{%1, %0|%0, %1}"
14835   [(set_attr "prefix_0f" "1")
14836    (set_attr "mode" "HI")])
14837
14838 (define_insn "popcounthi2"
14839   [(set (match_operand:HI 0 "register_operand" "=r")
14840         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14841    (clobber (reg:CC FLAGS_REG))]
14842   "TARGET_POPCNT"
14843   "popcnt{w}\t{%1, %0|%0, %1}"
14844   [(set_attr "prefix_rep" "1")
14845    (set_attr "type" "bitmanip")
14846    (set_attr "mode" "HI")])
14847
14848 (define_insn "*popcounthi2_cmp"
14849   [(set (reg FLAGS_REG)
14850         (compare
14851           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14852           (const_int 0)))
14853    (set (match_operand:HI 0 "register_operand" "=r")
14854         (popcount:HI (match_dup 1)))]
14855   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14856   "popcnt{w}\t{%1, %0|%0, %1}"
14857   [(set_attr "prefix_rep" "1")
14858    (set_attr "type" "bitmanip")
14859    (set_attr "mode" "HI")])
14860 \f
14861 ;; Thread-local storage patterns for ELF.
14862 ;;
14863 ;; Note that these code sequences must appear exactly as shown
14864 ;; in order to allow linker relaxation.
14865
14866 (define_insn "*tls_global_dynamic_32_gnu"
14867   [(set (match_operand:SI 0 "register_operand" "=a")
14868         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14869                     (match_operand:SI 2 "tls_symbolic_operand" "")
14870                     (match_operand:SI 3 "call_insn_operand" "")]
14871                     UNSPEC_TLS_GD))
14872    (clobber (match_scratch:SI 4 "=d"))
14873    (clobber (match_scratch:SI 5 "=c"))
14874    (clobber (reg:CC FLAGS_REG))]
14875   "!TARGET_64BIT && TARGET_GNU_TLS"
14876   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14877   [(set_attr "type" "multi")
14878    (set_attr "length" "12")])
14879
14880 (define_insn "*tls_global_dynamic_32_sun"
14881   [(set (match_operand:SI 0 "register_operand" "=a")
14882         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14883                     (match_operand:SI 2 "tls_symbolic_operand" "")
14884                     (match_operand:SI 3 "call_insn_operand" "")]
14885                     UNSPEC_TLS_GD))
14886    (clobber (match_scratch:SI 4 "=d"))
14887    (clobber (match_scratch:SI 5 "=c"))
14888    (clobber (reg:CC FLAGS_REG))]
14889   "!TARGET_64BIT && TARGET_SUN_TLS"
14890   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14891         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14892   [(set_attr "type" "multi")
14893    (set_attr "length" "14")])
14894
14895 (define_expand "tls_global_dynamic_32"
14896   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14897                    (unspec:SI
14898                     [(match_dup 2)
14899                      (match_operand:SI 1 "tls_symbolic_operand" "")
14900                      (match_dup 3)]
14901                     UNSPEC_TLS_GD))
14902               (clobber (match_scratch:SI 4 ""))
14903               (clobber (match_scratch:SI 5 ""))
14904               (clobber (reg:CC FLAGS_REG))])]
14905   ""
14906 {
14907   if (flag_pic)
14908     operands[2] = pic_offset_table_rtx;
14909   else
14910     {
14911       operands[2] = gen_reg_rtx (Pmode);
14912       emit_insn (gen_set_got (operands[2]));
14913     }
14914   if (TARGET_GNU2_TLS)
14915     {
14916        emit_insn (gen_tls_dynamic_gnu2_32
14917                   (operands[0], operands[1], operands[2]));
14918        DONE;
14919     }
14920   operands[3] = ix86_tls_get_addr ();
14921 })
14922
14923 (define_insn "*tls_global_dynamic_64"
14924   [(set (match_operand:DI 0 "register_operand" "=a")
14925         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14926                  (match_operand:DI 3 "" "")))
14927    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14928               UNSPEC_TLS_GD)]
14929   "TARGET_64BIT"
14930   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14931   [(set_attr "type" "multi")
14932    (set_attr "length" "16")])
14933
14934 (define_expand "tls_global_dynamic_64"
14935   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14936                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14937               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14938                          UNSPEC_TLS_GD)])]
14939   ""
14940 {
14941   if (TARGET_GNU2_TLS)
14942     {
14943        emit_insn (gen_tls_dynamic_gnu2_64
14944                   (operands[0], operands[1]));
14945        DONE;
14946     }
14947   operands[2] = ix86_tls_get_addr ();
14948 })
14949
14950 (define_insn "*tls_local_dynamic_base_32_gnu"
14951   [(set (match_operand:SI 0 "register_operand" "=a")
14952         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14953                     (match_operand:SI 2 "call_insn_operand" "")]
14954                    UNSPEC_TLS_LD_BASE))
14955    (clobber (match_scratch:SI 3 "=d"))
14956    (clobber (match_scratch:SI 4 "=c"))
14957    (clobber (reg:CC FLAGS_REG))]
14958   "!TARGET_64BIT && TARGET_GNU_TLS"
14959   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14960   [(set_attr "type" "multi")
14961    (set_attr "length" "11")])
14962
14963 (define_insn "*tls_local_dynamic_base_32_sun"
14964   [(set (match_operand:SI 0 "register_operand" "=a")
14965         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14966                     (match_operand:SI 2 "call_insn_operand" "")]
14967                    UNSPEC_TLS_LD_BASE))
14968    (clobber (match_scratch:SI 3 "=d"))
14969    (clobber (match_scratch:SI 4 "=c"))
14970    (clobber (reg:CC FLAGS_REG))]
14971   "!TARGET_64BIT && TARGET_SUN_TLS"
14972   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14973         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14974   [(set_attr "type" "multi")
14975    (set_attr "length" "13")])
14976
14977 (define_expand "tls_local_dynamic_base_32"
14978   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14979                    (unspec:SI [(match_dup 1) (match_dup 2)]
14980                               UNSPEC_TLS_LD_BASE))
14981               (clobber (match_scratch:SI 3 ""))
14982               (clobber (match_scratch:SI 4 ""))
14983               (clobber (reg:CC FLAGS_REG))])]
14984   ""
14985 {
14986   if (flag_pic)
14987     operands[1] = pic_offset_table_rtx;
14988   else
14989     {
14990       operands[1] = gen_reg_rtx (Pmode);
14991       emit_insn (gen_set_got (operands[1]));
14992     }
14993   if (TARGET_GNU2_TLS)
14994     {
14995        emit_insn (gen_tls_dynamic_gnu2_32
14996                   (operands[0], ix86_tls_module_base (), operands[1]));
14997        DONE;
14998     }
14999   operands[2] = ix86_tls_get_addr ();
15000 })
15001
15002 (define_insn "*tls_local_dynamic_base_64"
15003   [(set (match_operand:DI 0 "register_operand" "=a")
15004         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15005                  (match_operand:DI 2 "" "")))
15006    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15007   "TARGET_64BIT"
15008   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15009   [(set_attr "type" "multi")
15010    (set_attr "length" "12")])
15011
15012 (define_expand "tls_local_dynamic_base_64"
15013   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15014                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15015               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15016   ""
15017 {
15018   if (TARGET_GNU2_TLS)
15019     {
15020        emit_insn (gen_tls_dynamic_gnu2_64
15021                   (operands[0], ix86_tls_module_base ()));
15022        DONE;
15023     }
15024   operands[1] = ix86_tls_get_addr ();
15025 })
15026
15027 ;; Local dynamic of a single variable is a lose.  Show combine how
15028 ;; to convert that back to global dynamic.
15029
15030 (define_insn_and_split "*tls_local_dynamic_32_once"
15031   [(set (match_operand:SI 0 "register_operand" "=a")
15032         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15033                              (match_operand:SI 2 "call_insn_operand" "")]
15034                             UNSPEC_TLS_LD_BASE)
15035                  (const:SI (unspec:SI
15036                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15037                             UNSPEC_DTPOFF))))
15038    (clobber (match_scratch:SI 4 "=d"))
15039    (clobber (match_scratch:SI 5 "=c"))
15040    (clobber (reg:CC FLAGS_REG))]
15041   ""
15042   "#"
15043   ""
15044   [(parallel [(set (match_dup 0)
15045                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15046                               UNSPEC_TLS_GD))
15047               (clobber (match_dup 4))
15048               (clobber (match_dup 5))
15049               (clobber (reg:CC FLAGS_REG))])]
15050   "")
15051
15052 ;; Load and add the thread base pointer from %gs:0.
15053
15054 (define_insn "*load_tp_si"
15055   [(set (match_operand:SI 0 "register_operand" "=r")
15056         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15057   "!TARGET_64BIT"
15058   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15059   [(set_attr "type" "imov")
15060    (set_attr "modrm" "0")
15061    (set_attr "length" "7")
15062    (set_attr "memory" "load")
15063    (set_attr "imm_disp" "false")])
15064
15065 (define_insn "*add_tp_si"
15066   [(set (match_operand:SI 0 "register_operand" "=r")
15067         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15068                  (match_operand:SI 1 "register_operand" "0")))
15069    (clobber (reg:CC FLAGS_REG))]
15070   "!TARGET_64BIT"
15071   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15072   [(set_attr "type" "alu")
15073    (set_attr "modrm" "0")
15074    (set_attr "length" "7")
15075    (set_attr "memory" "load")
15076    (set_attr "imm_disp" "false")])
15077
15078 (define_insn "*load_tp_di"
15079   [(set (match_operand:DI 0 "register_operand" "=r")
15080         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15081   "TARGET_64BIT"
15082   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15083   [(set_attr "type" "imov")
15084    (set_attr "modrm" "0")
15085    (set_attr "length" "7")
15086    (set_attr "memory" "load")
15087    (set_attr "imm_disp" "false")])
15088
15089 (define_insn "*add_tp_di"
15090   [(set (match_operand:DI 0 "register_operand" "=r")
15091         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15092                  (match_operand:DI 1 "register_operand" "0")))
15093    (clobber (reg:CC FLAGS_REG))]
15094   "TARGET_64BIT"
15095   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15096   [(set_attr "type" "alu")
15097    (set_attr "modrm" "0")
15098    (set_attr "length" "7")
15099    (set_attr "memory" "load")
15100    (set_attr "imm_disp" "false")])
15101
15102 ;; GNU2 TLS patterns can be split.
15103
15104 (define_expand "tls_dynamic_gnu2_32"
15105   [(set (match_dup 3)
15106         (plus:SI (match_operand:SI 2 "register_operand" "")
15107                  (const:SI
15108                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15109                              UNSPEC_TLSDESC))))
15110    (parallel
15111     [(set (match_operand:SI 0 "register_operand" "")
15112           (unspec:SI [(match_dup 1) (match_dup 3)
15113                       (match_dup 2) (reg:SI SP_REG)]
15114                       UNSPEC_TLSDESC))
15115      (clobber (reg:CC FLAGS_REG))])]
15116   "!TARGET_64BIT && TARGET_GNU2_TLS"
15117 {
15118   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15119   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15120 })
15121
15122 (define_insn "*tls_dynamic_lea_32"
15123   [(set (match_operand:SI 0 "register_operand" "=r")
15124         (plus:SI (match_operand:SI 1 "register_operand" "b")
15125                  (const:SI
15126                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15127                               UNSPEC_TLSDESC))))]
15128   "!TARGET_64BIT && TARGET_GNU2_TLS"
15129   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15130   [(set_attr "type" "lea")
15131    (set_attr "mode" "SI")
15132    (set_attr "length" "6")
15133    (set_attr "length_address" "4")])
15134
15135 (define_insn "*tls_dynamic_call_32"
15136   [(set (match_operand:SI 0 "register_operand" "=a")
15137         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15138                     (match_operand:SI 2 "register_operand" "0")
15139                     ;; we have to make sure %ebx still points to the GOT
15140                     (match_operand:SI 3 "register_operand" "b")
15141                     (reg:SI SP_REG)]
15142                    UNSPEC_TLSDESC))
15143    (clobber (reg:CC FLAGS_REG))]
15144   "!TARGET_64BIT && TARGET_GNU2_TLS"
15145   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15146   [(set_attr "type" "call")
15147    (set_attr "length" "2")
15148    (set_attr "length_address" "0")])
15149
15150 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15151   [(set (match_operand:SI 0 "register_operand" "=&a")
15152         (plus:SI
15153          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15154                      (match_operand:SI 4 "" "")
15155                      (match_operand:SI 2 "register_operand" "b")
15156                      (reg:SI SP_REG)]
15157                     UNSPEC_TLSDESC)
15158          (const:SI (unspec:SI
15159                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15160                     UNSPEC_DTPOFF))))
15161    (clobber (reg:CC FLAGS_REG))]
15162   "!TARGET_64BIT && TARGET_GNU2_TLS"
15163   "#"
15164   ""
15165   [(set (match_dup 0) (match_dup 5))]
15166 {
15167   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15168   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15169 })
15170
15171 (define_expand "tls_dynamic_gnu2_64"
15172   [(set (match_dup 2)
15173         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15174                    UNSPEC_TLSDESC))
15175    (parallel
15176     [(set (match_operand:DI 0 "register_operand" "")
15177           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15178                      UNSPEC_TLSDESC))
15179      (clobber (reg:CC FLAGS_REG))])]
15180   "TARGET_64BIT && TARGET_GNU2_TLS"
15181 {
15182   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15183   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15184 })
15185
15186 (define_insn "*tls_dynamic_lea_64"
15187   [(set (match_operand:DI 0 "register_operand" "=r")
15188         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15189                    UNSPEC_TLSDESC))]
15190   "TARGET_64BIT && TARGET_GNU2_TLS"
15191   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15192   [(set_attr "type" "lea")
15193    (set_attr "mode" "DI")
15194    (set_attr "length" "7")
15195    (set_attr "length_address" "4")])
15196
15197 (define_insn "*tls_dynamic_call_64"
15198   [(set (match_operand:DI 0 "register_operand" "=a")
15199         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15200                     (match_operand:DI 2 "register_operand" "0")
15201                     (reg:DI SP_REG)]
15202                    UNSPEC_TLSDESC))
15203    (clobber (reg:CC FLAGS_REG))]
15204   "TARGET_64BIT && TARGET_GNU2_TLS"
15205   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15206   [(set_attr "type" "call")
15207    (set_attr "length" "2")
15208    (set_attr "length_address" "0")])
15209
15210 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15211   [(set (match_operand:DI 0 "register_operand" "=&a")
15212         (plus:DI
15213          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15214                      (match_operand:DI 3 "" "")
15215                      (reg:DI SP_REG)]
15216                     UNSPEC_TLSDESC)
15217          (const:DI (unspec:DI
15218                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15219                     UNSPEC_DTPOFF))))
15220    (clobber (reg:CC FLAGS_REG))]
15221   "TARGET_64BIT && TARGET_GNU2_TLS"
15222   "#"
15223   ""
15224   [(set (match_dup 0) (match_dup 4))]
15225 {
15226   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15227   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15228 })
15229
15230 ;;
15231 \f
15232 ;; These patterns match the binary 387 instructions for addM3, subM3,
15233 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15234 ;; SFmode.  The first is the normal insn, the second the same insn but
15235 ;; with one operand a conversion, and the third the same insn but with
15236 ;; the other operand a conversion.  The conversion may be SFmode or
15237 ;; SImode if the target mode DFmode, but only SImode if the target mode
15238 ;; is SFmode.
15239
15240 ;; Gcc is slightly more smart about handling normal two address instructions
15241 ;; so use special patterns for add and mull.
15242
15243 (define_insn "*fop_sf_comm_mixed"
15244   [(set (match_operand:SF 0 "register_operand" "=f,x")
15245         (match_operator:SF 3 "binary_fp_operator"
15246                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15247                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15248   "TARGET_MIX_SSE_I387
15249    && COMMUTATIVE_ARITH_P (operands[3])
15250    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15251   "* return output_387_binary_op (insn, operands);"
15252   [(set (attr "type")
15253         (if_then_else (eq_attr "alternative" "1")
15254            (if_then_else (match_operand:SF 3 "mult_operator" "")
15255               (const_string "ssemul")
15256               (const_string "sseadd"))
15257            (if_then_else (match_operand:SF 3 "mult_operator" "")
15258               (const_string "fmul")
15259               (const_string "fop"))))
15260    (set_attr "mode" "SF")])
15261
15262 (define_insn "*fop_sf_comm_sse"
15263   [(set (match_operand:SF 0 "register_operand" "=x")
15264         (match_operator:SF 3 "binary_fp_operator"
15265                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15266                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15267   "TARGET_SSE_MATH
15268    && COMMUTATIVE_ARITH_P (operands[3])
15269    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15270   "* return output_387_binary_op (insn, operands);"
15271   [(set (attr "type")
15272         (if_then_else (match_operand:SF 3 "mult_operator" "")
15273            (const_string "ssemul")
15274            (const_string "sseadd")))
15275    (set_attr "mode" "SF")])
15276
15277 (define_insn "*fop_sf_comm_i387"
15278   [(set (match_operand:SF 0 "register_operand" "=f")
15279         (match_operator:SF 3 "binary_fp_operator"
15280                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15281                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15282   "TARGET_80387
15283    && COMMUTATIVE_ARITH_P (operands[3])
15284    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15285   "* return output_387_binary_op (insn, operands);"
15286   [(set (attr "type")
15287         (if_then_else (match_operand:SF 3 "mult_operator" "")
15288            (const_string "fmul")
15289            (const_string "fop")))
15290    (set_attr "mode" "SF")])
15291
15292 (define_insn "*fop_sf_1_mixed"
15293   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15294         (match_operator:SF 3 "binary_fp_operator"
15295                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15296                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15297   "TARGET_MIX_SSE_I387
15298    && !COMMUTATIVE_ARITH_P (operands[3])
15299    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15300   "* return output_387_binary_op (insn, operands);"
15301   [(set (attr "type")
15302         (cond [(and (eq_attr "alternative" "2")
15303                     (match_operand:SF 3 "mult_operator" ""))
15304                  (const_string "ssemul")
15305                (and (eq_attr "alternative" "2")
15306                     (match_operand:SF 3 "div_operator" ""))
15307                  (const_string "ssediv")
15308                (eq_attr "alternative" "2")
15309                  (const_string "sseadd")
15310                (match_operand:SF 3 "mult_operator" "")
15311                  (const_string "fmul")
15312                (match_operand:SF 3 "div_operator" "")
15313                  (const_string "fdiv")
15314               ]
15315               (const_string "fop")))
15316    (set_attr "mode" "SF")])
15317
15318 (define_insn "*fop_sf_1_sse"
15319   [(set (match_operand:SF 0 "register_operand" "=x")
15320         (match_operator:SF 3 "binary_fp_operator"
15321                         [(match_operand:SF 1 "register_operand" "0")
15322                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15323   "TARGET_SSE_MATH
15324    && !COMMUTATIVE_ARITH_P (operands[3])"
15325   "* return output_387_binary_op (insn, operands);"
15326   [(set (attr "type")
15327         (cond [(match_operand:SF 3 "mult_operator" "")
15328                  (const_string "ssemul")
15329                (match_operand:SF 3 "div_operator" "")
15330                  (const_string "ssediv")
15331               ]
15332               (const_string "sseadd")))
15333    (set_attr "mode" "SF")])
15334
15335 ;; This pattern is not fully shadowed by the pattern above.
15336 (define_insn "*fop_sf_1_i387"
15337   [(set (match_operand:SF 0 "register_operand" "=f,f")
15338         (match_operator:SF 3 "binary_fp_operator"
15339                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15340                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15341   "TARGET_80387 && !TARGET_SSE_MATH
15342    && !COMMUTATIVE_ARITH_P (operands[3])
15343    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15344   "* return output_387_binary_op (insn, operands);"
15345   [(set (attr "type")
15346         (cond [(match_operand:SF 3 "mult_operator" "")
15347                  (const_string "fmul")
15348                (match_operand:SF 3 "div_operator" "")
15349                  (const_string "fdiv")
15350               ]
15351               (const_string "fop")))
15352    (set_attr "mode" "SF")])
15353
15354 ;; ??? Add SSE splitters for these!
15355 (define_insn "*fop_sf_2<mode>_i387"
15356   [(set (match_operand:SF 0 "register_operand" "=f,f")
15357         (match_operator:SF 3 "binary_fp_operator"
15358           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15359            (match_operand:SF 2 "register_operand" "0,0")]))]
15360   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15361   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15362   [(set (attr "type")
15363         (cond [(match_operand:SF 3 "mult_operator" "")
15364                  (const_string "fmul")
15365                (match_operand:SF 3 "div_operator" "")
15366                  (const_string "fdiv")
15367               ]
15368               (const_string "fop")))
15369    (set_attr "fp_int_src" "true")
15370    (set_attr "mode" "<MODE>")])
15371
15372 (define_insn "*fop_sf_3<mode>_i387"
15373   [(set (match_operand:SF 0 "register_operand" "=f,f")
15374         (match_operator:SF 3 "binary_fp_operator"
15375           [(match_operand:SF 1 "register_operand" "0,0")
15376            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15377   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15378   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15379   [(set (attr "type")
15380         (cond [(match_operand:SF 3 "mult_operator" "")
15381                  (const_string "fmul")
15382                (match_operand:SF 3 "div_operator" "")
15383                  (const_string "fdiv")
15384               ]
15385               (const_string "fop")))
15386    (set_attr "fp_int_src" "true")
15387    (set_attr "mode" "<MODE>")])
15388
15389 (define_insn "*fop_df_comm_mixed"
15390   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15391         (match_operator:DF 3 "binary_fp_operator"
15392                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15393                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15394   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15395    && COMMUTATIVE_ARITH_P (operands[3])
15396    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15397   "* return output_387_binary_op (insn, operands);"
15398   [(set (attr "type")
15399         (if_then_else (eq_attr "alternative" "1")
15400            (if_then_else (match_operand:DF 3 "mult_operator" "")
15401               (const_string "ssemul")
15402               (const_string "sseadd"))
15403            (if_then_else (match_operand:DF 3 "mult_operator" "")
15404               (const_string "fmul")
15405               (const_string "fop"))))
15406    (set_attr "mode" "DF")])
15407
15408 (define_insn "*fop_df_comm_sse"
15409   [(set (match_operand:DF 0 "register_operand" "=Y")
15410         (match_operator:DF 3 "binary_fp_operator"
15411                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15412                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15413   "TARGET_SSE2 && TARGET_SSE_MATH
15414    && COMMUTATIVE_ARITH_P (operands[3])
15415    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15416   "* return output_387_binary_op (insn, operands);"
15417   [(set (attr "type")
15418         (if_then_else (match_operand:DF 3 "mult_operator" "")
15419            (const_string "ssemul")
15420            (const_string "sseadd")))
15421    (set_attr "mode" "DF")])
15422
15423 (define_insn "*fop_df_comm_i387"
15424   [(set (match_operand:DF 0 "register_operand" "=f")
15425         (match_operator:DF 3 "binary_fp_operator"
15426                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15427                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15428   "TARGET_80387
15429    && COMMUTATIVE_ARITH_P (operands[3])
15430    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15431   "* return output_387_binary_op (insn, operands);"
15432   [(set (attr "type")
15433         (if_then_else (match_operand:DF 3 "mult_operator" "")
15434            (const_string "fmul")
15435            (const_string "fop")))
15436    (set_attr "mode" "DF")])
15437
15438 (define_insn "*fop_df_1_mixed"
15439   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15440         (match_operator:DF 3 "binary_fp_operator"
15441                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15442                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15443   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15444    && !COMMUTATIVE_ARITH_P (operands[3])
15445    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15446   "* return output_387_binary_op (insn, operands);"
15447   [(set (attr "type")
15448         (cond [(and (eq_attr "alternative" "2")
15449                     (match_operand:DF 3 "mult_operator" ""))
15450                  (const_string "ssemul")
15451                (and (eq_attr "alternative" "2")
15452                     (match_operand:DF 3 "div_operator" ""))
15453                  (const_string "ssediv")
15454                (eq_attr "alternative" "2")
15455                  (const_string "sseadd")
15456                (match_operand:DF 3 "mult_operator" "")
15457                  (const_string "fmul")
15458                (match_operand:DF 3 "div_operator" "")
15459                  (const_string "fdiv")
15460               ]
15461               (const_string "fop")))
15462    (set_attr "mode" "DF")])
15463
15464 (define_insn "*fop_df_1_sse"
15465   [(set (match_operand:DF 0 "register_operand" "=Y")
15466         (match_operator:DF 3 "binary_fp_operator"
15467                         [(match_operand:DF 1 "register_operand" "0")
15468                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15469   "TARGET_SSE2 && TARGET_SSE_MATH
15470    && !COMMUTATIVE_ARITH_P (operands[3])"
15471   "* return output_387_binary_op (insn, operands);"
15472   [(set_attr "mode" "DF")
15473    (set (attr "type")
15474         (cond [(match_operand:DF 3 "mult_operator" "")
15475                  (const_string "ssemul")
15476                (match_operand:DF 3 "div_operator" "")
15477                  (const_string "ssediv")
15478               ]
15479               (const_string "sseadd")))])
15480
15481 ;; This pattern is not fully shadowed by the pattern above.
15482 (define_insn "*fop_df_1_i387"
15483   [(set (match_operand:DF 0 "register_operand" "=f,f")
15484         (match_operator:DF 3 "binary_fp_operator"
15485                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15486                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15487   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15488    && !COMMUTATIVE_ARITH_P (operands[3])
15489    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15490   "* return output_387_binary_op (insn, operands);"
15491   [(set (attr "type")
15492         (cond [(match_operand:DF 3 "mult_operator" "")
15493                  (const_string "fmul")
15494                (match_operand:DF 3 "div_operator" "")
15495                  (const_string "fdiv")
15496               ]
15497               (const_string "fop")))
15498    (set_attr "mode" "DF")])
15499
15500 ;; ??? Add SSE splitters for these!
15501 (define_insn "*fop_df_2<mode>_i387"
15502   [(set (match_operand:DF 0 "register_operand" "=f,f")
15503         (match_operator:DF 3 "binary_fp_operator"
15504            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15505             (match_operand:DF 2 "register_operand" "0,0")]))]
15506   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15507    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15508   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15509   [(set (attr "type")
15510         (cond [(match_operand:DF 3 "mult_operator" "")
15511                  (const_string "fmul")
15512                (match_operand:DF 3 "div_operator" "")
15513                  (const_string "fdiv")
15514               ]
15515               (const_string "fop")))
15516    (set_attr "fp_int_src" "true")
15517    (set_attr "mode" "<MODE>")])
15518
15519 (define_insn "*fop_df_3<mode>_i387"
15520   [(set (match_operand:DF 0 "register_operand" "=f,f")
15521         (match_operator:DF 3 "binary_fp_operator"
15522            [(match_operand:DF 1 "register_operand" "0,0")
15523             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15524   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15525    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15526   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15527   [(set (attr "type")
15528         (cond [(match_operand:DF 3 "mult_operator" "")
15529                  (const_string "fmul")
15530                (match_operand:DF 3 "div_operator" "")
15531                  (const_string "fdiv")
15532               ]
15533               (const_string "fop")))
15534    (set_attr "fp_int_src" "true")
15535    (set_attr "mode" "<MODE>")])
15536
15537 (define_insn "*fop_df_4_i387"
15538   [(set (match_operand:DF 0 "register_operand" "=f,f")
15539         (match_operator:DF 3 "binary_fp_operator"
15540            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15541             (match_operand:DF 2 "register_operand" "0,f")]))]
15542   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15543    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15544   "* return output_387_binary_op (insn, operands);"
15545   [(set (attr "type")
15546         (cond [(match_operand:DF 3 "mult_operator" "")
15547                  (const_string "fmul")
15548                (match_operand:DF 3 "div_operator" "")
15549                  (const_string "fdiv")
15550               ]
15551               (const_string "fop")))
15552    (set_attr "mode" "SF")])
15553
15554 (define_insn "*fop_df_5_i387"
15555   [(set (match_operand:DF 0 "register_operand" "=f,f")
15556         (match_operator:DF 3 "binary_fp_operator"
15557           [(match_operand:DF 1 "register_operand" "0,f")
15558            (float_extend:DF
15559             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15560   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15561   "* return output_387_binary_op (insn, operands);"
15562   [(set (attr "type")
15563         (cond [(match_operand:DF 3 "mult_operator" "")
15564                  (const_string "fmul")
15565                (match_operand:DF 3 "div_operator" "")
15566                  (const_string "fdiv")
15567               ]
15568               (const_string "fop")))
15569    (set_attr "mode" "SF")])
15570
15571 (define_insn "*fop_df_6_i387"
15572   [(set (match_operand:DF 0 "register_operand" "=f,f")
15573         (match_operator:DF 3 "binary_fp_operator"
15574           [(float_extend:DF
15575             (match_operand:SF 1 "register_operand" "0,f"))
15576            (float_extend:DF
15577             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15578   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15579   "* return output_387_binary_op (insn, operands);"
15580   [(set (attr "type")
15581         (cond [(match_operand:DF 3 "mult_operator" "")
15582                  (const_string "fmul")
15583                (match_operand:DF 3 "div_operator" "")
15584                  (const_string "fdiv")
15585               ]
15586               (const_string "fop")))
15587    (set_attr "mode" "SF")])
15588
15589 (define_insn "*fop_xf_comm_i387"
15590   [(set (match_operand:XF 0 "register_operand" "=f")
15591         (match_operator:XF 3 "binary_fp_operator"
15592                         [(match_operand:XF 1 "register_operand" "%0")
15593                          (match_operand:XF 2 "register_operand" "f")]))]
15594   "TARGET_80387
15595    && COMMUTATIVE_ARITH_P (operands[3])"
15596   "* return output_387_binary_op (insn, operands);"
15597   [(set (attr "type")
15598         (if_then_else (match_operand:XF 3 "mult_operator" "")
15599            (const_string "fmul")
15600            (const_string "fop")))
15601    (set_attr "mode" "XF")])
15602
15603 (define_insn "*fop_xf_1_i387"
15604   [(set (match_operand:XF 0 "register_operand" "=f,f")
15605         (match_operator:XF 3 "binary_fp_operator"
15606                         [(match_operand:XF 1 "register_operand" "0,f")
15607                          (match_operand:XF 2 "register_operand" "f,0")]))]
15608   "TARGET_80387
15609    && !COMMUTATIVE_ARITH_P (operands[3])"
15610   "* return output_387_binary_op (insn, operands);"
15611   [(set (attr "type")
15612         (cond [(match_operand:XF 3 "mult_operator" "")
15613                  (const_string "fmul")
15614                (match_operand:XF 3 "div_operator" "")
15615                  (const_string "fdiv")
15616               ]
15617               (const_string "fop")))
15618    (set_attr "mode" "XF")])
15619
15620 (define_insn "*fop_xf_2<mode>_i387"
15621   [(set (match_operand:XF 0 "register_operand" "=f,f")
15622         (match_operator:XF 3 "binary_fp_operator"
15623            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15624             (match_operand:XF 2 "register_operand" "0,0")]))]
15625   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15626   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15627   [(set (attr "type")
15628         (cond [(match_operand:XF 3 "mult_operator" "")
15629                  (const_string "fmul")
15630                (match_operand:XF 3 "div_operator" "")
15631                  (const_string "fdiv")
15632               ]
15633               (const_string "fop")))
15634    (set_attr "fp_int_src" "true")
15635    (set_attr "mode" "<MODE>")])
15636
15637 (define_insn "*fop_xf_3<mode>_i387"
15638   [(set (match_operand:XF 0 "register_operand" "=f,f")
15639         (match_operator:XF 3 "binary_fp_operator"
15640           [(match_operand:XF 1 "register_operand" "0,0")
15641            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15642   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15643   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15644   [(set (attr "type")
15645         (cond [(match_operand:XF 3 "mult_operator" "")
15646                  (const_string "fmul")
15647                (match_operand:XF 3 "div_operator" "")
15648                  (const_string "fdiv")
15649               ]
15650               (const_string "fop")))
15651    (set_attr "fp_int_src" "true")
15652    (set_attr "mode" "<MODE>")])
15653
15654 (define_insn "*fop_xf_4_i387"
15655   [(set (match_operand:XF 0 "register_operand" "=f,f")
15656         (match_operator:XF 3 "binary_fp_operator"
15657            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15658             (match_operand:XF 2 "register_operand" "0,f")]))]
15659   "TARGET_80387"
15660   "* return output_387_binary_op (insn, operands);"
15661   [(set (attr "type")
15662         (cond [(match_operand:XF 3 "mult_operator" "")
15663                  (const_string "fmul")
15664                (match_operand:XF 3 "div_operator" "")
15665                  (const_string "fdiv")
15666               ]
15667               (const_string "fop")))
15668    (set_attr "mode" "SF")])
15669
15670 (define_insn "*fop_xf_5_i387"
15671   [(set (match_operand:XF 0 "register_operand" "=f,f")
15672         (match_operator:XF 3 "binary_fp_operator"
15673           [(match_operand:XF 1 "register_operand" "0,f")
15674            (float_extend:XF
15675             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15676   "TARGET_80387"
15677   "* return output_387_binary_op (insn, operands);"
15678   [(set (attr "type")
15679         (cond [(match_operand:XF 3 "mult_operator" "")
15680                  (const_string "fmul")
15681                (match_operand:XF 3 "div_operator" "")
15682                  (const_string "fdiv")
15683               ]
15684               (const_string "fop")))
15685    (set_attr "mode" "SF")])
15686
15687 (define_insn "*fop_xf_6_i387"
15688   [(set (match_operand:XF 0 "register_operand" "=f,f")
15689         (match_operator:XF 3 "binary_fp_operator"
15690           [(float_extend:XF
15691             (match_operand 1 "register_operand" "0,f"))
15692            (float_extend:XF
15693             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15694   "TARGET_80387"
15695   "* return output_387_binary_op (insn, operands);"
15696   [(set (attr "type")
15697         (cond [(match_operand:XF 3 "mult_operator" "")
15698                  (const_string "fmul")
15699                (match_operand:XF 3 "div_operator" "")
15700                  (const_string "fdiv")
15701               ]
15702               (const_string "fop")))
15703    (set_attr "mode" "SF")])
15704
15705 (define_split
15706   [(set (match_operand 0 "register_operand" "")
15707         (match_operator 3 "binary_fp_operator"
15708            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15709             (match_operand 2 "register_operand" "")]))]
15710   "TARGET_80387 && reload_completed
15711    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15712   [(const_int 0)]
15713 {
15714   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15715   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15716   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15717                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15718                                           GET_MODE (operands[3]),
15719                                           operands[4],
15720                                           operands[2])));
15721   ix86_free_from_memory (GET_MODE (operands[1]));
15722   DONE;
15723 })
15724
15725 (define_split
15726   [(set (match_operand 0 "register_operand" "")
15727         (match_operator 3 "binary_fp_operator"
15728            [(match_operand 1 "register_operand" "")
15729             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15730   "TARGET_80387 && reload_completed
15731    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15732   [(const_int 0)]
15733 {
15734   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15735   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15736   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15737                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15738                                           GET_MODE (operands[3]),
15739                                           operands[1],
15740                                           operands[4])));
15741   ix86_free_from_memory (GET_MODE (operands[2]));
15742   DONE;
15743 })
15744 \f
15745 ;; FPU special functions.
15746
15747 (define_expand "sqrtsf2"
15748   [(set (match_operand:SF 0 "register_operand" "")
15749         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15750   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15751 {
15752   if (!TARGET_SSE_MATH)
15753     operands[1] = force_reg (SFmode, operands[1]);
15754 })
15755
15756 (define_insn "*sqrtsf2_mixed"
15757   [(set (match_operand:SF 0 "register_operand" "=f,x")
15758         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15759   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15760   "@
15761    fsqrt
15762    sqrtss\t{%1, %0|%0, %1}"
15763   [(set_attr "type" "fpspc,sse")
15764    (set_attr "mode" "SF,SF")
15765    (set_attr "athlon_decode" "direct,*")
15766    (set_attr "amdfam10_decode" "direct,*")])
15767
15768 (define_insn "*sqrtsf2_sse"
15769   [(set (match_operand:SF 0 "register_operand" "=x")
15770         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15771   "TARGET_SSE_MATH"
15772   "sqrtss\t{%1, %0|%0, %1}"
15773   [(set_attr "type" "sse")
15774    (set_attr "mode" "SF")
15775    (set_attr "athlon_decode" "*")
15776    (set_attr "amdfam10_decode" "*")])
15777
15778 (define_insn "*sqrtsf2_i387"
15779   [(set (match_operand:SF 0 "register_operand" "=f")
15780         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15781   "TARGET_USE_FANCY_MATH_387"
15782   "fsqrt"
15783   [(set_attr "type" "fpspc")
15784    (set_attr "mode" "SF")
15785    (set_attr "athlon_decode" "direct")
15786    (set_attr "amdfam10_decode" "direct")])
15787
15788 (define_expand "sqrtdf2"
15789   [(set (match_operand:DF 0 "register_operand" "")
15790         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15791   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15792 {
15793   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15794     operands[1] = force_reg (DFmode, operands[1]);
15795 })
15796
15797 (define_insn "*sqrtdf2_mixed"
15798   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15799         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15800   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15801   "@
15802    fsqrt
15803    sqrtsd\t{%1, %0|%0, %1}"
15804   [(set_attr "type" "fpspc,sse")
15805    (set_attr "mode" "DF,DF")
15806    (set_attr "athlon_decode" "direct,*")
15807    (set_attr "amdfam10_decode" "direct,*")])
15808
15809 (define_insn "*sqrtdf2_sse"
15810   [(set (match_operand:DF 0 "register_operand" "=Y")
15811         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15812   "TARGET_SSE2 && TARGET_SSE_MATH"
15813   "sqrtsd\t{%1, %0|%0, %1}"
15814   [(set_attr "type" "sse")
15815    (set_attr "mode" "DF")
15816    (set_attr "athlon_decode" "*")
15817    (set_attr "amdfam10_decode" "*")])
15818
15819 (define_insn "*sqrtdf2_i387"
15820   [(set (match_operand:DF 0 "register_operand" "=f")
15821         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15822   "TARGET_USE_FANCY_MATH_387"
15823   "fsqrt"
15824   [(set_attr "type" "fpspc")
15825    (set_attr "mode" "DF")
15826    (set_attr "athlon_decode" "direct")
15827    (set_attr "amdfam10_decode" "direct")])
15828
15829 (define_insn "*sqrtextendsfdf2_i387"
15830   [(set (match_operand:DF 0 "register_operand" "=f")
15831         (sqrt:DF (float_extend:DF
15832                   (match_operand:SF 1 "register_operand" "0"))))]
15833   "TARGET_USE_FANCY_MATH_387
15834    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15835   "fsqrt"
15836   [(set_attr "type" "fpspc")
15837    (set_attr "mode" "DF")
15838    (set_attr "athlon_decode" "direct")
15839    (set_attr "amdfam10_decode" "direct")])
15840
15841 (define_insn "sqrtxf2"
15842   [(set (match_operand:XF 0 "register_operand" "=f")
15843         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15844   "TARGET_USE_FANCY_MATH_387"
15845   "fsqrt"
15846   [(set_attr "type" "fpspc")
15847    (set_attr "mode" "XF")
15848    (set_attr "athlon_decode" "direct")
15849    (set_attr "amdfam10_decode" "direct")])
15850
15851 (define_insn "*sqrtextendsfxf2_i387"
15852   [(set (match_operand:XF 0 "register_operand" "=f")
15853         (sqrt:XF (float_extend:XF
15854                   (match_operand:SF 1 "register_operand" "0"))))]
15855   "TARGET_USE_FANCY_MATH_387"
15856   "fsqrt"
15857   [(set_attr "type" "fpspc")
15858    (set_attr "mode" "XF")
15859    (set_attr "athlon_decode" "direct")
15860    (set_attr "amdfam10_decode" "direct")])
15861
15862 (define_insn "*sqrtextenddfxf2_i387"
15863   [(set (match_operand:XF 0 "register_operand" "=f")
15864         (sqrt:XF (float_extend:XF
15865                   (match_operand:DF 1 "register_operand" "0"))))]
15866   "TARGET_USE_FANCY_MATH_387"
15867   "fsqrt"
15868   [(set_attr "type" "fpspc")
15869    (set_attr "mode" "XF")
15870    (set_attr "athlon_decode" "direct")
15871    (set_attr "amdfam10_decode" "direct")])
15872
15873 (define_insn "fpremxf4"
15874   [(set (match_operand:XF 0 "register_operand" "=f")
15875         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15876                     (match_operand:XF 3 "register_operand" "1")]
15877                    UNSPEC_FPREM_F))
15878    (set (match_operand:XF 1 "register_operand" "=u")
15879         (unspec:XF [(match_dup 2) (match_dup 3)]
15880                    UNSPEC_FPREM_U))
15881    (set (reg:CCFP FPSR_REG)
15882         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15883   "TARGET_USE_FANCY_MATH_387
15884    && flag_unsafe_math_optimizations"
15885   "fprem"
15886   [(set_attr "type" "fpspc")
15887    (set_attr "mode" "XF")])
15888
15889 (define_expand "fmodsf3"
15890   [(use (match_operand:SF 0 "register_operand" ""))
15891    (use (match_operand:SF 1 "register_operand" ""))
15892    (use (match_operand:SF 2 "register_operand" ""))]
15893   "TARGET_USE_FANCY_MATH_387
15894    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15895    && flag_unsafe_math_optimizations"
15896 {
15897   rtx label = gen_label_rtx ();
15898
15899   rtx op1 = gen_reg_rtx (XFmode);
15900   rtx op2 = gen_reg_rtx (XFmode);
15901
15902   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15903   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15904
15905   emit_label (label);
15906
15907   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15908   ix86_emit_fp_unordered_jump (label);
15909
15910   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15911   DONE;
15912 })
15913
15914 (define_expand "fmoddf3"
15915   [(use (match_operand:DF 0 "register_operand" ""))
15916    (use (match_operand:DF 1 "register_operand" ""))
15917    (use (match_operand:DF 2 "register_operand" ""))]
15918   "TARGET_USE_FANCY_MATH_387
15919    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15920    && flag_unsafe_math_optimizations"
15921 {
15922   rtx label = gen_label_rtx ();
15923
15924   rtx op1 = gen_reg_rtx (XFmode);
15925   rtx op2 = gen_reg_rtx (XFmode);
15926
15927   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15928   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15929
15930   emit_label (label);
15931
15932   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15933   ix86_emit_fp_unordered_jump (label);
15934
15935   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15936   DONE;
15937 })
15938
15939 (define_expand "fmodxf3"
15940   [(use (match_operand:XF 0 "register_operand" ""))
15941    (use (match_operand:XF 1 "register_operand" ""))
15942    (use (match_operand:XF 2 "register_operand" ""))]
15943   "TARGET_USE_FANCY_MATH_387
15944    && flag_unsafe_math_optimizations"
15945 {
15946   rtx label = gen_label_rtx ();
15947
15948   emit_label (label);
15949
15950   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15951                            operands[1], operands[2]));
15952   ix86_emit_fp_unordered_jump (label);
15953
15954   emit_move_insn (operands[0], operands[1]);
15955   DONE;
15956 })
15957
15958 (define_insn "fprem1xf4"
15959   [(set (match_operand:XF 0 "register_operand" "=f")
15960         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15961                     (match_operand:XF 3 "register_operand" "1")]
15962                    UNSPEC_FPREM1_F))
15963    (set (match_operand:XF 1 "register_operand" "=u")
15964         (unspec:XF [(match_dup 2) (match_dup 3)]
15965                    UNSPEC_FPREM1_U))
15966    (set (reg:CCFP FPSR_REG)
15967         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15968   "TARGET_USE_FANCY_MATH_387
15969    && flag_unsafe_math_optimizations"
15970   "fprem1"
15971   [(set_attr "type" "fpspc")
15972    (set_attr "mode" "XF")])
15973
15974 (define_expand "dremsf3"
15975   [(use (match_operand:SF 0 "register_operand" ""))
15976    (use (match_operand:SF 1 "register_operand" ""))
15977    (use (match_operand:SF 2 "register_operand" ""))]
15978   "TARGET_USE_FANCY_MATH_387
15979    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15980    && flag_unsafe_math_optimizations"
15981 {
15982   rtx label = gen_label_rtx ();
15983
15984   rtx op1 = gen_reg_rtx (XFmode);
15985   rtx op2 = gen_reg_rtx (XFmode);
15986
15987   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15988   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15989
15990   emit_label (label);
15991
15992   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15993   ix86_emit_fp_unordered_jump (label);
15994
15995   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15996   DONE;
15997 })
15998
15999 (define_expand "dremdf3"
16000   [(use (match_operand:DF 0 "register_operand" ""))
16001    (use (match_operand:DF 1 "register_operand" ""))
16002    (use (match_operand:DF 2 "register_operand" ""))]
16003   "TARGET_USE_FANCY_MATH_387
16004    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16005    && flag_unsafe_math_optimizations"
16006 {
16007   rtx label = gen_label_rtx ();
16008
16009   rtx op1 = gen_reg_rtx (XFmode);
16010   rtx op2 = gen_reg_rtx (XFmode);
16011
16012   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16013   emit_insn (gen_extenddfxf2 (op2, operands[2]));
16014
16015   emit_label (label);
16016
16017   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
16018   ix86_emit_fp_unordered_jump (label);
16019
16020   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
16021   DONE;
16022 })
16023
16024 (define_expand "dremxf3"
16025   [(use (match_operand:XF 0 "register_operand" ""))
16026    (use (match_operand:XF 1 "register_operand" ""))
16027    (use (match_operand:XF 2 "register_operand" ""))]
16028   "TARGET_USE_FANCY_MATH_387
16029    && flag_unsafe_math_optimizations"
16030 {
16031   rtx label = gen_label_rtx ();
16032
16033   emit_label (label);
16034
16035   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
16036                             operands[1], operands[2]));
16037   ix86_emit_fp_unordered_jump (label);
16038
16039   emit_move_insn (operands[0], operands[1]);
16040   DONE;
16041 })
16042
16043 (define_insn "*sindf2"
16044   [(set (match_operand:DF 0 "register_operand" "=f")
16045         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
16046   "TARGET_USE_FANCY_MATH_387
16047    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16048    && flag_unsafe_math_optimizations"
16049   "fsin"
16050   [(set_attr "type" "fpspc")
16051    (set_attr "mode" "DF")])
16052
16053 (define_insn "*sinsf2"
16054   [(set (match_operand:SF 0 "register_operand" "=f")
16055         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
16056   "TARGET_USE_FANCY_MATH_387
16057    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16058    && flag_unsafe_math_optimizations"
16059   "fsin"
16060   [(set_attr "type" "fpspc")
16061    (set_attr "mode" "SF")])
16062
16063 (define_insn "*sinextendsfdf2"
16064   [(set (match_operand:DF 0 "register_operand" "=f")
16065         (unspec:DF [(float_extend:DF
16066                      (match_operand:SF 1 "register_operand" "0"))]
16067                    UNSPEC_SIN))]
16068   "TARGET_USE_FANCY_MATH_387
16069    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16070    && flag_unsafe_math_optimizations"
16071   "fsin"
16072   [(set_attr "type" "fpspc")
16073    (set_attr "mode" "DF")])
16074
16075 (define_insn "*sinxf2"
16076   [(set (match_operand:XF 0 "register_operand" "=f")
16077         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16078   "TARGET_USE_FANCY_MATH_387
16079    && flag_unsafe_math_optimizations"
16080   "fsin"
16081   [(set_attr "type" "fpspc")
16082    (set_attr "mode" "XF")])
16083
16084 (define_insn "*cosdf2"
16085   [(set (match_operand:DF 0 "register_operand" "=f")
16086         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
16087   "TARGET_USE_FANCY_MATH_387
16088    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16089    && flag_unsafe_math_optimizations"
16090   "fcos"
16091   [(set_attr "type" "fpspc")
16092    (set_attr "mode" "DF")])
16093
16094 (define_insn "*cossf2"
16095   [(set (match_operand:SF 0 "register_operand" "=f")
16096         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
16097   "TARGET_USE_FANCY_MATH_387
16098    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16099    && flag_unsafe_math_optimizations"
16100   "fcos"
16101   [(set_attr "type" "fpspc")
16102    (set_attr "mode" "SF")])
16103
16104 (define_insn "*cosextendsfdf2"
16105   [(set (match_operand:DF 0 "register_operand" "=f")
16106         (unspec:DF [(float_extend:DF
16107                      (match_operand:SF 1 "register_operand" "0"))]
16108                    UNSPEC_COS))]
16109   "TARGET_USE_FANCY_MATH_387
16110    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16111    && flag_unsafe_math_optimizations"
16112   "fcos"
16113   [(set_attr "type" "fpspc")
16114    (set_attr "mode" "DF")])
16115
16116 (define_insn "*cosxf2"
16117   [(set (match_operand:XF 0 "register_operand" "=f")
16118         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16119   "TARGET_USE_FANCY_MATH_387
16120    && flag_unsafe_math_optimizations"
16121   "fcos"
16122   [(set_attr "type" "fpspc")
16123    (set_attr "mode" "XF")])
16124
16125 ;; With sincos pattern defined, sin and cos builtin function will be
16126 ;; expanded to sincos pattern with one of its outputs left unused.
16127 ;; Cse pass  will detected, if two sincos patterns can be combined,
16128 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16129 ;; depending on the unused output.
16130
16131 (define_insn "sincosdf3"
16132   [(set (match_operand:DF 0 "register_operand" "=f")
16133         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16134                    UNSPEC_SINCOS_COS))
16135    (set (match_operand:DF 1 "register_operand" "=u")
16136         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16137   "TARGET_USE_FANCY_MATH_387
16138    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16139    && flag_unsafe_math_optimizations"
16140   "fsincos"
16141   [(set_attr "type" "fpspc")
16142    (set_attr "mode" "DF")])
16143
16144 (define_split
16145   [(set (match_operand:DF 0 "register_operand" "")
16146         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16147                    UNSPEC_SINCOS_COS))
16148    (set (match_operand:DF 1 "register_operand" "")
16149         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16150   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16151    && !reload_completed && !reload_in_progress"
16152   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
16153   "")
16154
16155 (define_split
16156   [(set (match_operand:DF 0 "register_operand" "")
16157         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16158                    UNSPEC_SINCOS_COS))
16159    (set (match_operand:DF 1 "register_operand" "")
16160         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16161   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16162    && !reload_completed && !reload_in_progress"
16163   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
16164   "")
16165
16166 (define_insn "sincossf3"
16167   [(set (match_operand:SF 0 "register_operand" "=f")
16168         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16169                    UNSPEC_SINCOS_COS))
16170    (set (match_operand:SF 1 "register_operand" "=u")
16171         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16172   "TARGET_USE_FANCY_MATH_387
16173    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16174    && flag_unsafe_math_optimizations"
16175   "fsincos"
16176   [(set_attr "type" "fpspc")
16177    (set_attr "mode" "SF")])
16178
16179 (define_split
16180   [(set (match_operand:SF 0 "register_operand" "")
16181         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16182                    UNSPEC_SINCOS_COS))
16183    (set (match_operand:SF 1 "register_operand" "")
16184         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16185   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16186    && !reload_completed && !reload_in_progress"
16187   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
16188   "")
16189
16190 (define_split
16191   [(set (match_operand:SF 0 "register_operand" "")
16192         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16193                    UNSPEC_SINCOS_COS))
16194    (set (match_operand:SF 1 "register_operand" "")
16195         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16196   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16197    && !reload_completed && !reload_in_progress"
16198   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
16199   "")
16200
16201 (define_insn "*sincosextendsfdf3"
16202   [(set (match_operand:DF 0 "register_operand" "=f")
16203         (unspec:DF [(float_extend:DF
16204                      (match_operand:SF 2 "register_operand" "0"))]
16205                    UNSPEC_SINCOS_COS))
16206    (set (match_operand:DF 1 "register_operand" "=u")
16207         (unspec:DF [(float_extend:DF
16208                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
16209   "TARGET_USE_FANCY_MATH_387
16210    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16211    && flag_unsafe_math_optimizations"
16212   "fsincos"
16213   [(set_attr "type" "fpspc")
16214    (set_attr "mode" "DF")])
16215
16216 (define_split
16217   [(set (match_operand:DF 0 "register_operand" "")
16218         (unspec:DF [(float_extend:DF
16219                      (match_operand:SF 2 "register_operand" ""))]
16220                    UNSPEC_SINCOS_COS))
16221    (set (match_operand:DF 1 "register_operand" "")
16222         (unspec:DF [(float_extend:DF
16223                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
16224   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16225    && !reload_completed && !reload_in_progress"
16226   [(set (match_dup 1) (unspec:DF [(float_extend:DF
16227                                    (match_dup 2))] UNSPEC_SIN))]
16228   "")
16229
16230 (define_split
16231   [(set (match_operand:DF 0 "register_operand" "")
16232         (unspec:DF [(float_extend:DF
16233                      (match_operand:SF 2 "register_operand" ""))]
16234                    UNSPEC_SINCOS_COS))
16235    (set (match_operand:DF 1 "register_operand" "")
16236         (unspec:DF [(float_extend:DF
16237                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
16238   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16239    && !reload_completed && !reload_in_progress"
16240   [(set (match_dup 0) (unspec:DF [(float_extend:DF
16241                                    (match_dup 2))] UNSPEC_COS))]
16242   "")
16243
16244 (define_insn "sincosxf3"
16245   [(set (match_operand:XF 0 "register_operand" "=f")
16246         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16247                    UNSPEC_SINCOS_COS))
16248    (set (match_operand:XF 1 "register_operand" "=u")
16249         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16250   "TARGET_USE_FANCY_MATH_387
16251    && flag_unsafe_math_optimizations"
16252   "fsincos"
16253   [(set_attr "type" "fpspc")
16254    (set_attr "mode" "XF")])
16255
16256 (define_split
16257   [(set (match_operand:XF 0 "register_operand" "")
16258         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16259                    UNSPEC_SINCOS_COS))
16260    (set (match_operand:XF 1 "register_operand" "")
16261         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16262   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16263    && !reload_completed && !reload_in_progress"
16264   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16265   "")
16266
16267 (define_split
16268   [(set (match_operand:XF 0 "register_operand" "")
16269         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16270                    UNSPEC_SINCOS_COS))
16271    (set (match_operand:XF 1 "register_operand" "")
16272         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16273   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16274    && !reload_completed && !reload_in_progress"
16275   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16276   "")
16277
16278 (define_insn "*tandf3_1"
16279   [(set (match_operand:DF 0 "register_operand" "=f")
16280         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16281                    UNSPEC_TAN_ONE))
16282    (set (match_operand:DF 1 "register_operand" "=u")
16283         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16284   "TARGET_USE_FANCY_MATH_387
16285    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16286    && flag_unsafe_math_optimizations"
16287   "fptan"
16288   [(set_attr "type" "fpspc")
16289    (set_attr "mode" "DF")])
16290
16291 ;; optimize sequence: fptan
16292 ;;                    fstp    %st(0)
16293 ;;                    fld1
16294 ;; into fptan insn.
16295
16296 (define_peephole2
16297   [(parallel[(set (match_operand:DF 0 "register_operand" "")
16298                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16299                              UNSPEC_TAN_ONE))
16300              (set (match_operand:DF 1 "register_operand" "")
16301                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16302    (set (match_dup 0)
16303         (match_operand:DF 3 "immediate_operand" ""))]
16304   "standard_80387_constant_p (operands[3]) == 2"
16305   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16306              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16307   "")
16308
16309 (define_expand "tandf2"
16310   [(parallel [(set (match_dup 2)
16311                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16312                               UNSPEC_TAN_ONE))
16313               (set (match_operand:DF 0 "register_operand" "")
16314                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16315   "TARGET_USE_FANCY_MATH_387
16316    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16317    && flag_unsafe_math_optimizations"
16318 {
16319   operands[2] = gen_reg_rtx (DFmode);
16320 })
16321
16322 (define_insn "*tansf3_1"
16323   [(set (match_operand:SF 0 "register_operand" "=f")
16324         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16325                    UNSPEC_TAN_ONE))
16326    (set (match_operand:SF 1 "register_operand" "=u")
16327         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16328   "TARGET_USE_FANCY_MATH_387
16329    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16330    && flag_unsafe_math_optimizations"
16331   "fptan"
16332   [(set_attr "type" "fpspc")
16333    (set_attr "mode" "SF")])
16334
16335 ;; optimize sequence: fptan
16336 ;;                    fstp    %st(0)
16337 ;;                    fld1
16338 ;; into fptan insn.
16339
16340 (define_peephole2
16341   [(parallel[(set (match_operand:SF 0 "register_operand" "")
16342                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16343                              UNSPEC_TAN_ONE))
16344              (set (match_operand:SF 1 "register_operand" "")
16345                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16346    (set (match_dup 0)
16347         (match_operand:SF 3 "immediate_operand" ""))]
16348   "standard_80387_constant_p (operands[3]) == 2"
16349   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16350              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16351   "")
16352
16353 (define_expand "tansf2"
16354   [(parallel [(set (match_dup 2)
16355                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16356                               UNSPEC_TAN_ONE))
16357               (set (match_operand:SF 0 "register_operand" "")
16358                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16359   "TARGET_USE_FANCY_MATH_387
16360    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16361    && flag_unsafe_math_optimizations"
16362 {
16363   operands[2] = gen_reg_rtx (SFmode);
16364 })
16365
16366 (define_insn "*tanxf3_1"
16367   [(set (match_operand:XF 0 "register_operand" "=f")
16368         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16369                    UNSPEC_TAN_ONE))
16370    (set (match_operand:XF 1 "register_operand" "=u")
16371         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16372   "TARGET_USE_FANCY_MATH_387
16373    && flag_unsafe_math_optimizations"
16374   "fptan"
16375   [(set_attr "type" "fpspc")
16376    (set_attr "mode" "XF")])
16377
16378 ;; optimize sequence: fptan
16379 ;;                    fstp    %st(0)
16380 ;;                    fld1
16381 ;; into fptan insn.
16382
16383 (define_peephole2
16384   [(parallel[(set (match_operand:XF 0 "register_operand" "")
16385                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16386                              UNSPEC_TAN_ONE))
16387              (set (match_operand:XF 1 "register_operand" "")
16388                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16389    (set (match_dup 0)
16390         (match_operand:XF 3 "immediate_operand" ""))]
16391   "standard_80387_constant_p (operands[3]) == 2"
16392   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16393              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16394   "")
16395
16396 (define_expand "tanxf2"
16397   [(parallel [(set (match_dup 2)
16398                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16399                               UNSPEC_TAN_ONE))
16400               (set (match_operand:XF 0 "register_operand" "")
16401                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16402   "TARGET_USE_FANCY_MATH_387
16403    && flag_unsafe_math_optimizations"
16404 {
16405   operands[2] = gen_reg_rtx (XFmode);
16406 })
16407
16408 (define_insn "atan2df3_1"
16409   [(set (match_operand:DF 0 "register_operand" "=f")
16410         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16411                     (match_operand:DF 1 "register_operand" "u")]
16412                    UNSPEC_FPATAN))
16413    (clobber (match_scratch:DF 3 "=1"))]
16414   "TARGET_USE_FANCY_MATH_387
16415    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16416    && flag_unsafe_math_optimizations"
16417   "fpatan"
16418   [(set_attr "type" "fpspc")
16419    (set_attr "mode" "DF")])
16420
16421 (define_expand "atan2df3"
16422   [(use (match_operand:DF 0 "register_operand" ""))
16423    (use (match_operand:DF 2 "register_operand" ""))
16424    (use (match_operand:DF 1 "register_operand" ""))]
16425   "TARGET_USE_FANCY_MATH_387
16426    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16427    && flag_unsafe_math_optimizations"
16428 {
16429   rtx copy = gen_reg_rtx (DFmode);
16430   emit_move_insn (copy, operands[1]);
16431   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16432   DONE;
16433 })
16434
16435 (define_expand "atandf2"
16436   [(parallel [(set (match_operand:DF 0 "register_operand" "")
16437                    (unspec:DF [(match_dup 2)
16438                                (match_operand:DF 1 "register_operand" "")]
16439                     UNSPEC_FPATAN))
16440               (clobber (match_scratch:DF 3 ""))])]
16441   "TARGET_USE_FANCY_MATH_387
16442    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16443    && flag_unsafe_math_optimizations"
16444 {
16445   operands[2] = gen_reg_rtx (DFmode);
16446   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16447 })
16448
16449 (define_insn "atan2sf3_1"
16450   [(set (match_operand:SF 0 "register_operand" "=f")
16451         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16452                     (match_operand:SF 1 "register_operand" "u")]
16453                    UNSPEC_FPATAN))
16454    (clobber (match_scratch:SF 3 "=1"))]
16455   "TARGET_USE_FANCY_MATH_387
16456    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16457    && flag_unsafe_math_optimizations"
16458   "fpatan"
16459   [(set_attr "type" "fpspc")
16460    (set_attr "mode" "SF")])
16461
16462 (define_expand "atan2sf3"
16463   [(use (match_operand:SF 0 "register_operand" ""))
16464    (use (match_operand:SF 2 "register_operand" ""))
16465    (use (match_operand:SF 1 "register_operand" ""))]
16466   "TARGET_USE_FANCY_MATH_387
16467    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16468    && flag_unsafe_math_optimizations"
16469 {
16470   rtx copy = gen_reg_rtx (SFmode);
16471   emit_move_insn (copy, operands[1]);
16472   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16473   DONE;
16474 })
16475
16476 (define_expand "atansf2"
16477   [(parallel [(set (match_operand:SF 0 "register_operand" "")
16478                    (unspec:SF [(match_dup 2)
16479                                (match_operand:SF 1 "register_operand" "")]
16480                     UNSPEC_FPATAN))
16481               (clobber (match_scratch:SF 3 ""))])]
16482   "TARGET_USE_FANCY_MATH_387
16483    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16484    && flag_unsafe_math_optimizations"
16485 {
16486   operands[2] = gen_reg_rtx (SFmode);
16487   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16488 })
16489
16490 (define_insn "atan2xf3_1"
16491   [(set (match_operand:XF 0 "register_operand" "=f")
16492         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16493                     (match_operand:XF 1 "register_operand" "u")]
16494                    UNSPEC_FPATAN))
16495    (clobber (match_scratch:XF 3 "=1"))]
16496   "TARGET_USE_FANCY_MATH_387
16497    && flag_unsafe_math_optimizations"
16498   "fpatan"
16499   [(set_attr "type" "fpspc")
16500    (set_attr "mode" "XF")])
16501
16502 (define_expand "atan2xf3"
16503   [(use (match_operand:XF 0 "register_operand" ""))
16504    (use (match_operand:XF 2 "register_operand" ""))
16505    (use (match_operand:XF 1 "register_operand" ""))]
16506   "TARGET_USE_FANCY_MATH_387
16507    && flag_unsafe_math_optimizations"
16508 {
16509   rtx copy = gen_reg_rtx (XFmode);
16510   emit_move_insn (copy, operands[1]);
16511   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16512   DONE;
16513 })
16514
16515 (define_expand "atanxf2"
16516   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16517                    (unspec:XF [(match_dup 2)
16518                                (match_operand:XF 1 "register_operand" "")]
16519                     UNSPEC_FPATAN))
16520               (clobber (match_scratch:XF 3 ""))])]
16521   "TARGET_USE_FANCY_MATH_387
16522    && flag_unsafe_math_optimizations"
16523 {
16524   operands[2] = gen_reg_rtx (XFmode);
16525   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16526 })
16527
16528 (define_expand "asindf2"
16529   [(set (match_dup 2)
16530         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16531    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16532    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16533    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16534    (parallel [(set (match_dup 7)
16535                    (unspec:XF [(match_dup 6) (match_dup 2)]
16536                               UNSPEC_FPATAN))
16537               (clobber (match_scratch:XF 8 ""))])
16538    (set (match_operand:DF 0 "register_operand" "")
16539         (float_truncate:DF (match_dup 7)))]
16540   "TARGET_USE_FANCY_MATH_387
16541    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16542    && flag_unsafe_math_optimizations"
16543 {
16544   int i;
16545
16546   for (i=2; i<8; i++)
16547     operands[i] = gen_reg_rtx (XFmode);
16548
16549   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16550 })
16551
16552 (define_expand "asinsf2"
16553   [(set (match_dup 2)
16554         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16555    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16556    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16557    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16558    (parallel [(set (match_dup 7)
16559                    (unspec:XF [(match_dup 6) (match_dup 2)]
16560                               UNSPEC_FPATAN))
16561               (clobber (match_scratch:XF 8 ""))])
16562    (set (match_operand:SF 0 "register_operand" "")
16563         (float_truncate:SF (match_dup 7)))]
16564   "TARGET_USE_FANCY_MATH_387
16565    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16566    && flag_unsafe_math_optimizations"
16567 {
16568   int i;
16569
16570   for (i=2; i<8; i++)
16571     operands[i] = gen_reg_rtx (XFmode);
16572
16573   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16574 })
16575
16576 (define_expand "asinxf2"
16577   [(set (match_dup 2)
16578         (mult:XF (match_operand:XF 1 "register_operand" "")
16579                  (match_dup 1)))
16580    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16581    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16582    (parallel [(set (match_operand:XF 0 "register_operand" "")
16583                    (unspec:XF [(match_dup 5) (match_dup 1)]
16584                               UNSPEC_FPATAN))
16585               (clobber (match_scratch:XF 6 ""))])]
16586   "TARGET_USE_FANCY_MATH_387
16587    && flag_unsafe_math_optimizations"
16588 {
16589   int i;
16590
16591   for (i=2; i<6; i++)
16592     operands[i] = gen_reg_rtx (XFmode);
16593
16594   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16595 })
16596
16597 (define_expand "acosdf2"
16598   [(set (match_dup 2)
16599         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16600    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16601    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16602    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16603    (parallel [(set (match_dup 7)
16604                    (unspec:XF [(match_dup 2) (match_dup 6)]
16605                               UNSPEC_FPATAN))
16606               (clobber (match_scratch:XF 8 ""))])
16607    (set (match_operand:DF 0 "register_operand" "")
16608         (float_truncate:DF (match_dup 7)))]
16609   "TARGET_USE_FANCY_MATH_387
16610    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16611    && flag_unsafe_math_optimizations"
16612 {
16613   int i;
16614
16615   for (i=2; i<8; i++)
16616     operands[i] = gen_reg_rtx (XFmode);
16617
16618   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16619 })
16620
16621 (define_expand "acossf2"
16622   [(set (match_dup 2)
16623         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16624    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16625    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16626    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16627    (parallel [(set (match_dup 7)
16628                    (unspec:XF [(match_dup 2) (match_dup 6)]
16629                               UNSPEC_FPATAN))
16630               (clobber (match_scratch:XF 8 ""))])
16631    (set (match_operand:SF 0 "register_operand" "")
16632         (float_truncate:SF (match_dup 7)))]
16633   "TARGET_USE_FANCY_MATH_387
16634    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16635    && flag_unsafe_math_optimizations"
16636 {
16637   int i;
16638
16639   for (i=2; i<8; i++)
16640     operands[i] = gen_reg_rtx (XFmode);
16641
16642   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16643 })
16644
16645 (define_expand "acosxf2"
16646   [(set (match_dup 2)
16647         (mult:XF (match_operand:XF 1 "register_operand" "")
16648                  (match_dup 1)))
16649    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16650    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16651    (parallel [(set (match_operand:XF 0 "register_operand" "")
16652                    (unspec:XF [(match_dup 1) (match_dup 5)]
16653                               UNSPEC_FPATAN))
16654               (clobber (match_scratch:XF 6 ""))])]
16655   "TARGET_USE_FANCY_MATH_387
16656    && flag_unsafe_math_optimizations"
16657 {
16658   int i;
16659
16660   for (i=2; i<6; i++)
16661     operands[i] = gen_reg_rtx (XFmode);
16662
16663   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16664 })
16665
16666 (define_insn "fyl2x_xf3"
16667   [(set (match_operand:XF 0 "register_operand" "=f")
16668         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16669                     (match_operand:XF 1 "register_operand" "u")]
16670                    UNSPEC_FYL2X))
16671    (clobber (match_scratch:XF 3 "=1"))]
16672   "TARGET_USE_FANCY_MATH_387
16673    && flag_unsafe_math_optimizations"
16674   "fyl2x"
16675   [(set_attr "type" "fpspc")
16676    (set_attr "mode" "XF")])
16677
16678 (define_expand "logsf2"
16679   [(set (match_dup 2)
16680         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16681    (parallel [(set (match_dup 4)
16682                    (unspec:XF [(match_dup 2)
16683                                (match_dup 3)] UNSPEC_FYL2X))
16684               (clobber (match_scratch:XF 5 ""))])
16685    (set (match_operand:SF 0 "register_operand" "")
16686         (float_truncate:SF (match_dup 4)))]
16687   "TARGET_USE_FANCY_MATH_387
16688    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16689    && flag_unsafe_math_optimizations"
16690 {
16691   rtx temp;
16692
16693   operands[2] = gen_reg_rtx (XFmode);
16694   operands[3] = gen_reg_rtx (XFmode);
16695   operands[4] = gen_reg_rtx (XFmode);
16696
16697   temp = standard_80387_constant_rtx (4); /* fldln2 */
16698   emit_move_insn (operands[3], temp);
16699 })
16700
16701 (define_expand "logdf2"
16702   [(set (match_dup 2)
16703         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16704    (parallel [(set (match_dup 4)
16705                    (unspec:XF [(match_dup 2)
16706                                (match_dup 3)] UNSPEC_FYL2X))
16707               (clobber (match_scratch:XF 5 ""))])
16708    (set (match_operand:DF 0 "register_operand" "")
16709         (float_truncate:DF (match_dup 4)))]
16710   "TARGET_USE_FANCY_MATH_387
16711    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16712    && flag_unsafe_math_optimizations"
16713 {
16714   rtx temp;
16715
16716   operands[2] = gen_reg_rtx (XFmode);
16717   operands[3] = gen_reg_rtx (XFmode);
16718   operands[4] = gen_reg_rtx (XFmode);
16719
16720   temp = standard_80387_constant_rtx (4); /* fldln2 */
16721   emit_move_insn (operands[3], temp);
16722 })
16723
16724 (define_expand "logxf2"
16725   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16726                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16727                                (match_dup 2)] UNSPEC_FYL2X))
16728               (clobber (match_scratch:XF 3 ""))])]
16729   "TARGET_USE_FANCY_MATH_387
16730    && flag_unsafe_math_optimizations"
16731 {
16732   rtx temp;
16733
16734   operands[2] = gen_reg_rtx (XFmode);
16735   temp = standard_80387_constant_rtx (4); /* fldln2 */
16736   emit_move_insn (operands[2], temp);
16737 })
16738
16739 (define_expand "log10sf2"
16740   [(set (match_dup 2)
16741         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16742    (parallel [(set (match_dup 4)
16743                    (unspec:XF [(match_dup 2)
16744                                (match_dup 3)] UNSPEC_FYL2X))
16745               (clobber (match_scratch:XF 5 ""))])
16746    (set (match_operand:SF 0 "register_operand" "")
16747         (float_truncate:SF (match_dup 4)))]
16748   "TARGET_USE_FANCY_MATH_387
16749    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16750    && flag_unsafe_math_optimizations"
16751 {
16752   rtx temp;
16753
16754   operands[2] = gen_reg_rtx (XFmode);
16755   operands[3] = gen_reg_rtx (XFmode);
16756   operands[4] = gen_reg_rtx (XFmode);
16757
16758   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16759   emit_move_insn (operands[3], temp);
16760 })
16761
16762 (define_expand "log10df2"
16763   [(set (match_dup 2)
16764         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16765    (parallel [(set (match_dup 4)
16766                    (unspec:XF [(match_dup 2)
16767                                (match_dup 3)] UNSPEC_FYL2X))
16768               (clobber (match_scratch:XF 5 ""))])
16769    (set (match_operand:DF 0 "register_operand" "")
16770         (float_truncate:DF (match_dup 4)))]
16771   "TARGET_USE_FANCY_MATH_387
16772    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16773    && flag_unsafe_math_optimizations"
16774 {
16775   rtx temp;
16776
16777   operands[2] = gen_reg_rtx (XFmode);
16778   operands[3] = gen_reg_rtx (XFmode);
16779   operands[4] = gen_reg_rtx (XFmode);
16780
16781   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16782   emit_move_insn (operands[3], temp);
16783 })
16784
16785 (define_expand "log10xf2"
16786   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16787                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16788                                (match_dup 2)] UNSPEC_FYL2X))
16789               (clobber (match_scratch:XF 3 ""))])]
16790   "TARGET_USE_FANCY_MATH_387
16791    && flag_unsafe_math_optimizations"
16792 {
16793   rtx temp;
16794
16795   operands[2] = gen_reg_rtx (XFmode);
16796   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16797   emit_move_insn (operands[2], temp);
16798 })
16799
16800 (define_expand "log2sf2"
16801   [(set (match_dup 2)
16802         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16803    (parallel [(set (match_dup 4)
16804                    (unspec:XF [(match_dup 2)
16805                                (match_dup 3)] UNSPEC_FYL2X))
16806               (clobber (match_scratch:XF 5 ""))])
16807    (set (match_operand:SF 0 "register_operand" "")
16808         (float_truncate:SF (match_dup 4)))]
16809   "TARGET_USE_FANCY_MATH_387
16810    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16811    && flag_unsafe_math_optimizations"
16812 {
16813   operands[2] = gen_reg_rtx (XFmode);
16814   operands[3] = gen_reg_rtx (XFmode);
16815   operands[4] = gen_reg_rtx (XFmode);
16816
16817   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16818 })
16819
16820 (define_expand "log2df2"
16821   [(set (match_dup 2)
16822         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16823    (parallel [(set (match_dup 4)
16824                    (unspec:XF [(match_dup 2)
16825                                (match_dup 3)] UNSPEC_FYL2X))
16826               (clobber (match_scratch:XF 5 ""))])
16827    (set (match_operand:DF 0 "register_operand" "")
16828         (float_truncate:DF (match_dup 4)))]
16829   "TARGET_USE_FANCY_MATH_387
16830    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16831    && flag_unsafe_math_optimizations"
16832 {
16833   operands[2] = gen_reg_rtx (XFmode);
16834   operands[3] = gen_reg_rtx (XFmode);
16835   operands[4] = gen_reg_rtx (XFmode);
16836
16837   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16838 })
16839
16840 (define_expand "log2xf2"
16841   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16842                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16843                                (match_dup 2)] UNSPEC_FYL2X))
16844               (clobber (match_scratch:XF 3 ""))])]
16845   "TARGET_USE_FANCY_MATH_387
16846    && flag_unsafe_math_optimizations"
16847 {
16848   operands[2] = gen_reg_rtx (XFmode);
16849   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16850 })
16851
16852 (define_insn "fyl2xp1_xf3"
16853   [(set (match_operand:XF 0 "register_operand" "=f")
16854         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16855                     (match_operand:XF 1 "register_operand" "u")]
16856                    UNSPEC_FYL2XP1))
16857    (clobber (match_scratch:XF 3 "=1"))]
16858   "TARGET_USE_FANCY_MATH_387
16859    && flag_unsafe_math_optimizations"
16860   "fyl2xp1"
16861   [(set_attr "type" "fpspc")
16862    (set_attr "mode" "XF")])
16863
16864 (define_expand "log1psf2"
16865   [(use (match_operand:SF 0 "register_operand" ""))
16866    (use (match_operand:SF 1 "register_operand" ""))]
16867   "TARGET_USE_FANCY_MATH_387
16868    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16869    && flag_unsafe_math_optimizations"
16870 {
16871   rtx op0 = gen_reg_rtx (XFmode);
16872   rtx op1 = gen_reg_rtx (XFmode);
16873
16874   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16875   ix86_emit_i387_log1p (op0, op1);
16876   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16877   DONE;
16878 })
16879
16880 (define_expand "log1pdf2"
16881   [(use (match_operand:DF 0 "register_operand" ""))
16882    (use (match_operand:DF 1 "register_operand" ""))]
16883   "TARGET_USE_FANCY_MATH_387
16884    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16885    && flag_unsafe_math_optimizations"
16886 {
16887   rtx op0 = gen_reg_rtx (XFmode);
16888   rtx op1 = gen_reg_rtx (XFmode);
16889
16890   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16891   ix86_emit_i387_log1p (op0, op1);
16892   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16893   DONE;
16894 })
16895
16896 (define_expand "log1pxf2"
16897   [(use (match_operand:XF 0 "register_operand" ""))
16898    (use (match_operand:XF 1 "register_operand" ""))]
16899   "TARGET_USE_FANCY_MATH_387
16900    && flag_unsafe_math_optimizations"
16901 {
16902   ix86_emit_i387_log1p (operands[0], operands[1]);
16903   DONE;
16904 })
16905
16906 (define_insn "*fxtractxf3"
16907   [(set (match_operand:XF 0 "register_operand" "=f")
16908         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16909                    UNSPEC_XTRACT_FRACT))
16910    (set (match_operand:XF 1 "register_operand" "=u")
16911         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16912   "TARGET_USE_FANCY_MATH_387
16913    && flag_unsafe_math_optimizations"
16914   "fxtract"
16915   [(set_attr "type" "fpspc")
16916    (set_attr "mode" "XF")])
16917
16918 (define_expand "logbsf2"
16919   [(set (match_dup 2)
16920         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16921    (parallel [(set (match_dup 3)
16922                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16923               (set (match_dup 4)
16924                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16925    (set (match_operand:SF 0 "register_operand" "")
16926         (float_truncate:SF (match_dup 4)))]
16927   "TARGET_USE_FANCY_MATH_387
16928    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16929    && flag_unsafe_math_optimizations"
16930 {
16931   operands[2] = gen_reg_rtx (XFmode);
16932   operands[3] = gen_reg_rtx (XFmode);
16933   operands[4] = gen_reg_rtx (XFmode);
16934 })
16935
16936 (define_expand "logbdf2"
16937   [(set (match_dup 2)
16938         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16939    (parallel [(set (match_dup 3)
16940                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16941               (set (match_dup 4)
16942                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16943    (set (match_operand:DF 0 "register_operand" "")
16944         (float_truncate:DF (match_dup 4)))]
16945   "TARGET_USE_FANCY_MATH_387
16946    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16947    && flag_unsafe_math_optimizations"
16948 {
16949   operands[2] = gen_reg_rtx (XFmode);
16950   operands[3] = gen_reg_rtx (XFmode);
16951   operands[4] = gen_reg_rtx (XFmode);
16952 })
16953
16954 (define_expand "logbxf2"
16955   [(parallel [(set (match_dup 2)
16956                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16957                               UNSPEC_XTRACT_FRACT))
16958               (set (match_operand:XF 0 "register_operand" "")
16959                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16960   "TARGET_USE_FANCY_MATH_387
16961    && flag_unsafe_math_optimizations"
16962 {
16963   operands[2] = gen_reg_rtx (XFmode);
16964 })
16965
16966 (define_expand "ilogbsi2"
16967   [(parallel [(set (match_dup 2)
16968                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16969                               UNSPEC_XTRACT_FRACT))
16970               (set (match_operand:XF 3 "register_operand" "")
16971                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16972    (parallel [(set (match_operand:SI 0 "register_operand" "")
16973                    (fix:SI (match_dup 3)))
16974               (clobber (reg:CC FLAGS_REG))])]
16975   "TARGET_USE_FANCY_MATH_387
16976    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16977    && flag_unsafe_math_optimizations"
16978 {
16979   operands[2] = gen_reg_rtx (XFmode);
16980   operands[3] = gen_reg_rtx (XFmode);
16981 })
16982
16983 (define_insn "*f2xm1xf2"
16984   [(set (match_operand:XF 0 "register_operand" "=f")
16985         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16986          UNSPEC_F2XM1))]
16987   "TARGET_USE_FANCY_MATH_387
16988    && flag_unsafe_math_optimizations"
16989   "f2xm1"
16990   [(set_attr "type" "fpspc")
16991    (set_attr "mode" "XF")])
16992
16993 (define_insn "*fscalexf4"
16994   [(set (match_operand:XF 0 "register_operand" "=f")
16995         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16996                     (match_operand:XF 3 "register_operand" "1")]
16997                    UNSPEC_FSCALE_FRACT))
16998    (set (match_operand:XF 1 "register_operand" "=u")
16999         (unspec:XF [(match_dup 2) (match_dup 3)]
17000                    UNSPEC_FSCALE_EXP))]
17001   "TARGET_USE_FANCY_MATH_387
17002    && flag_unsafe_math_optimizations"
17003   "fscale"
17004   [(set_attr "type" "fpspc")
17005    (set_attr "mode" "XF")])
17006
17007 (define_expand "expsf2"
17008   [(set (match_dup 2)
17009         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17010    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17011    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17012    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17013    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17014    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17015    (parallel [(set (match_dup 10)
17016                    (unspec:XF [(match_dup 9) (match_dup 5)]
17017                               UNSPEC_FSCALE_FRACT))
17018               (set (match_dup 11)
17019                    (unspec:XF [(match_dup 9) (match_dup 5)]
17020                               UNSPEC_FSCALE_EXP))])
17021    (set (match_operand:SF 0 "register_operand" "")
17022         (float_truncate:SF (match_dup 10)))]
17023   "TARGET_USE_FANCY_MATH_387
17024    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17025    && flag_unsafe_math_optimizations"
17026 {
17027   rtx temp;
17028   int i;
17029
17030   for (i=2; i<12; i++)
17031     operands[i] = gen_reg_rtx (XFmode);
17032   temp = standard_80387_constant_rtx (5); /* fldl2e */
17033   emit_move_insn (operands[3], temp);
17034   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17035 })
17036
17037 (define_expand "expdf2"
17038   [(set (match_dup 2)
17039         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17040    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17041    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17042    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17043    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17044    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17045    (parallel [(set (match_dup 10)
17046                    (unspec:XF [(match_dup 9) (match_dup 5)]
17047                               UNSPEC_FSCALE_FRACT))
17048               (set (match_dup 11)
17049                    (unspec:XF [(match_dup 9) (match_dup 5)]
17050                               UNSPEC_FSCALE_EXP))])
17051    (set (match_operand:DF 0 "register_operand" "")
17052         (float_truncate:DF (match_dup 10)))]
17053   "TARGET_USE_FANCY_MATH_387
17054    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17055    && flag_unsafe_math_optimizations"
17056 {
17057   rtx temp;
17058   int i;
17059
17060   for (i=2; i<12; i++)
17061     operands[i] = gen_reg_rtx (XFmode);
17062   temp = standard_80387_constant_rtx (5); /* fldl2e */
17063   emit_move_insn (operands[3], temp);
17064   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17065 })
17066
17067 (define_expand "expxf2"
17068   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17069                                (match_dup 2)))
17070    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17071    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17072    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17073    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17074    (parallel [(set (match_operand:XF 0 "register_operand" "")
17075                    (unspec:XF [(match_dup 8) (match_dup 4)]
17076                               UNSPEC_FSCALE_FRACT))
17077               (set (match_dup 9)
17078                    (unspec:XF [(match_dup 8) (match_dup 4)]
17079                               UNSPEC_FSCALE_EXP))])]
17080   "TARGET_USE_FANCY_MATH_387
17081    && flag_unsafe_math_optimizations"
17082 {
17083   rtx temp;
17084   int i;
17085
17086   for (i=2; i<10; i++)
17087     operands[i] = gen_reg_rtx (XFmode);
17088   temp = standard_80387_constant_rtx (5); /* fldl2e */
17089   emit_move_insn (operands[2], temp);
17090   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17091 })
17092
17093 (define_expand "exp10sf2"
17094   [(set (match_dup 2)
17095         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17096    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17097    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17098    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17099    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17100    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17101    (parallel [(set (match_dup 10)
17102                    (unspec:XF [(match_dup 9) (match_dup 5)]
17103                               UNSPEC_FSCALE_FRACT))
17104               (set (match_dup 11)
17105                    (unspec:XF [(match_dup 9) (match_dup 5)]
17106                               UNSPEC_FSCALE_EXP))])
17107    (set (match_operand:SF 0 "register_operand" "")
17108         (float_truncate:SF (match_dup 10)))]
17109   "TARGET_USE_FANCY_MATH_387
17110    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17111    && flag_unsafe_math_optimizations"
17112 {
17113   rtx temp;
17114   int i;
17115
17116   for (i=2; i<12; i++)
17117     operands[i] = gen_reg_rtx (XFmode);
17118   temp = standard_80387_constant_rtx (6); /* fldl2t */
17119   emit_move_insn (operands[3], temp);
17120   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17121 })
17122
17123 (define_expand "exp10df2"
17124   [(set (match_dup 2)
17125         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17126    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17127    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17128    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17129    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17130    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17131    (parallel [(set (match_dup 10)
17132                    (unspec:XF [(match_dup 9) (match_dup 5)]
17133                               UNSPEC_FSCALE_FRACT))
17134               (set (match_dup 11)
17135                    (unspec:XF [(match_dup 9) (match_dup 5)]
17136                               UNSPEC_FSCALE_EXP))])
17137    (set (match_operand:DF 0 "register_operand" "")
17138         (float_truncate:DF (match_dup 10)))]
17139   "TARGET_USE_FANCY_MATH_387
17140    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17141    && flag_unsafe_math_optimizations"
17142 {
17143   rtx temp;
17144   int i;
17145
17146   for (i=2; i<12; i++)
17147     operands[i] = gen_reg_rtx (XFmode);
17148   temp = standard_80387_constant_rtx (6); /* fldl2t */
17149   emit_move_insn (operands[3], temp);
17150   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17151 })
17152
17153 (define_expand "exp10xf2"
17154   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17155                                (match_dup 2)))
17156    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17157    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17158    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17159    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17160    (parallel [(set (match_operand:XF 0 "register_operand" "")
17161                    (unspec:XF [(match_dup 8) (match_dup 4)]
17162                               UNSPEC_FSCALE_FRACT))
17163               (set (match_dup 9)
17164                    (unspec:XF [(match_dup 8) (match_dup 4)]
17165                               UNSPEC_FSCALE_EXP))])]
17166   "TARGET_USE_FANCY_MATH_387
17167    && flag_unsafe_math_optimizations"
17168 {
17169   rtx temp;
17170   int i;
17171
17172   for (i=2; i<10; i++)
17173     operands[i] = gen_reg_rtx (XFmode);
17174   temp = standard_80387_constant_rtx (6); /* fldl2t */
17175   emit_move_insn (operands[2], temp);
17176   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17177 })
17178
17179 (define_expand "exp2sf2"
17180   [(set (match_dup 2)
17181         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17182    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17183    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17184    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17185    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17186    (parallel [(set (match_dup 8)
17187                    (unspec:XF [(match_dup 7) (match_dup 3)]
17188                               UNSPEC_FSCALE_FRACT))
17189               (set (match_dup 9)
17190                    (unspec:XF [(match_dup 7) (match_dup 3)]
17191                               UNSPEC_FSCALE_EXP))])
17192    (set (match_operand:SF 0 "register_operand" "")
17193         (float_truncate:SF (match_dup 8)))]
17194   "TARGET_USE_FANCY_MATH_387
17195    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17196    && flag_unsafe_math_optimizations"
17197 {
17198   int i;
17199
17200   for (i=2; i<10; i++)
17201     operands[i] = gen_reg_rtx (XFmode);
17202   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17203 })
17204
17205 (define_expand "exp2df2"
17206   [(set (match_dup 2)
17207         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17208    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17209    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17210    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17211    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17212    (parallel [(set (match_dup 8)
17213                    (unspec:XF [(match_dup 7) (match_dup 3)]
17214                               UNSPEC_FSCALE_FRACT))
17215               (set (match_dup 9)
17216                    (unspec:XF [(match_dup 7) (match_dup 3)]
17217                               UNSPEC_FSCALE_EXP))])
17218    (set (match_operand:DF 0 "register_operand" "")
17219         (float_truncate:DF (match_dup 8)))]
17220   "TARGET_USE_FANCY_MATH_387
17221    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17222    && flag_unsafe_math_optimizations"
17223 {
17224   int i;
17225
17226   for (i=2; i<10; i++)
17227     operands[i] = gen_reg_rtx (XFmode);
17228   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17229 })
17230
17231 (define_expand "exp2xf2"
17232   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
17233    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17234    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17235    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17236    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17237    (parallel [(set (match_operand:XF 0 "register_operand" "")
17238                    (unspec:XF [(match_dup 7) (match_dup 3)]
17239                               UNSPEC_FSCALE_FRACT))
17240               (set (match_dup 8)
17241                    (unspec:XF [(match_dup 7) (match_dup 3)]
17242                               UNSPEC_FSCALE_EXP))])]
17243   "TARGET_USE_FANCY_MATH_387
17244    && flag_unsafe_math_optimizations"
17245 {
17246   int i;
17247
17248   for (i=2; i<9; i++)
17249     operands[i] = gen_reg_rtx (XFmode);
17250   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17251 })
17252
17253 (define_expand "expm1df2"
17254   [(set (match_dup 2)
17255         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17256    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17257    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17258    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17259    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17260    (parallel [(set (match_dup 8)
17261                    (unspec:XF [(match_dup 7) (match_dup 5)]
17262                               UNSPEC_FSCALE_FRACT))
17263                    (set (match_dup 9)
17264                    (unspec:XF [(match_dup 7) (match_dup 5)]
17265                               UNSPEC_FSCALE_EXP))])
17266    (parallel [(set (match_dup 11)
17267                    (unspec:XF [(match_dup 10) (match_dup 9)]
17268                               UNSPEC_FSCALE_FRACT))
17269               (set (match_dup 12)
17270                    (unspec:XF [(match_dup 10) (match_dup 9)]
17271                               UNSPEC_FSCALE_EXP))])
17272    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17273    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17274    (set (match_operand:DF 0 "register_operand" "")
17275         (float_truncate:DF (match_dup 14)))]
17276   "TARGET_USE_FANCY_MATH_387
17277    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17278    && flag_unsafe_math_optimizations"
17279 {
17280   rtx temp;
17281   int i;
17282
17283   for (i=2; i<15; i++)
17284     operands[i] = gen_reg_rtx (XFmode);
17285   temp = standard_80387_constant_rtx (5); /* fldl2e */
17286   emit_move_insn (operands[3], temp);
17287   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17288 })
17289
17290 (define_expand "expm1sf2"
17291   [(set (match_dup 2)
17292         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17293    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17294    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17295    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17296    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17297    (parallel [(set (match_dup 8)
17298                    (unspec:XF [(match_dup 7) (match_dup 5)]
17299                               UNSPEC_FSCALE_FRACT))
17300                    (set (match_dup 9)
17301                    (unspec:XF [(match_dup 7) (match_dup 5)]
17302                               UNSPEC_FSCALE_EXP))])
17303    (parallel [(set (match_dup 11)
17304                    (unspec:XF [(match_dup 10) (match_dup 9)]
17305                               UNSPEC_FSCALE_FRACT))
17306               (set (match_dup 12)
17307                    (unspec:XF [(match_dup 10) (match_dup 9)]
17308                               UNSPEC_FSCALE_EXP))])
17309    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17310    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17311    (set (match_operand:SF 0 "register_operand" "")
17312         (float_truncate:SF (match_dup 14)))]
17313   "TARGET_USE_FANCY_MATH_387
17314    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17315    && flag_unsafe_math_optimizations"
17316 {
17317   rtx temp;
17318   int i;
17319
17320   for (i=2; i<15; i++)
17321     operands[i] = gen_reg_rtx (XFmode);
17322   temp = standard_80387_constant_rtx (5); /* fldl2e */
17323   emit_move_insn (operands[3], temp);
17324   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17325 })
17326
17327 (define_expand "expm1xf2"
17328   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17329                                (match_dup 2)))
17330    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17331    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17332    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17333    (parallel [(set (match_dup 7)
17334                    (unspec:XF [(match_dup 6) (match_dup 4)]
17335                               UNSPEC_FSCALE_FRACT))
17336                    (set (match_dup 8)
17337                    (unspec:XF [(match_dup 6) (match_dup 4)]
17338                               UNSPEC_FSCALE_EXP))])
17339    (parallel [(set (match_dup 10)
17340                    (unspec:XF [(match_dup 9) (match_dup 8)]
17341                               UNSPEC_FSCALE_FRACT))
17342               (set (match_dup 11)
17343                    (unspec:XF [(match_dup 9) (match_dup 8)]
17344                               UNSPEC_FSCALE_EXP))])
17345    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17346    (set (match_operand:XF 0 "register_operand" "")
17347         (plus:XF (match_dup 12) (match_dup 7)))]
17348   "TARGET_USE_FANCY_MATH_387
17349    && flag_unsafe_math_optimizations"
17350 {
17351   rtx temp;
17352   int i;
17353
17354   for (i=2; i<13; i++)
17355     operands[i] = gen_reg_rtx (XFmode);
17356   temp = standard_80387_constant_rtx (5); /* fldl2e */
17357   emit_move_insn (operands[2], temp);
17358   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17359 })
17360
17361 (define_expand "ldexpdf3"
17362   [(set (match_dup 3)
17363         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17364    (set (match_dup 4)
17365         (float:XF (match_operand:SI 2 "register_operand" "")))
17366    (parallel [(set (match_dup 5)
17367                    (unspec:XF [(match_dup 3) (match_dup 4)]
17368                               UNSPEC_FSCALE_FRACT))
17369               (set (match_dup 6)
17370                    (unspec:XF [(match_dup 3) (match_dup 4)]
17371                               UNSPEC_FSCALE_EXP))])
17372    (set (match_operand:DF 0 "register_operand" "")
17373         (float_truncate:DF (match_dup 5)))]
17374   "TARGET_USE_FANCY_MATH_387
17375    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17376    && flag_unsafe_math_optimizations"
17377 {
17378   int i;
17379
17380   for (i=3; i<7; i++)
17381     operands[i] = gen_reg_rtx (XFmode);
17382 })
17383
17384 (define_expand "ldexpsf3"
17385   [(set (match_dup 3)
17386         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17387    (set (match_dup 4)
17388         (float:XF (match_operand:SI 2 "register_operand" "")))
17389    (parallel [(set (match_dup 5)
17390                    (unspec:XF [(match_dup 3) (match_dup 4)]
17391                               UNSPEC_FSCALE_FRACT))
17392               (set (match_dup 6)
17393                    (unspec:XF [(match_dup 3) (match_dup 4)]
17394                               UNSPEC_FSCALE_EXP))])
17395    (set (match_operand:SF 0 "register_operand" "")
17396         (float_truncate:SF (match_dup 5)))]
17397   "TARGET_USE_FANCY_MATH_387
17398    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17399    && flag_unsafe_math_optimizations"
17400 {
17401   int i;
17402
17403   for (i=3; i<7; i++)
17404     operands[i] = gen_reg_rtx (XFmode);
17405 })
17406
17407 (define_expand "ldexpxf3"
17408   [(set (match_dup 3)
17409         (float:XF (match_operand:SI 2 "register_operand" "")))
17410    (parallel [(set (match_operand:XF 0 " register_operand" "")
17411                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17412                                (match_dup 3)]
17413                               UNSPEC_FSCALE_FRACT))
17414               (set (match_dup 4)
17415                    (unspec:XF [(match_dup 1) (match_dup 3)]
17416                               UNSPEC_FSCALE_EXP))])]
17417   "TARGET_USE_FANCY_MATH_387
17418    && flag_unsafe_math_optimizations"
17419 {
17420   int i;
17421
17422   for (i=3; i<5; i++)
17423     operands[i] = gen_reg_rtx (XFmode);
17424 })
17425 \f
17426
17427 (define_insn "frndintxf2"
17428   [(set (match_operand:XF 0 "register_operand" "=f")
17429         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17430          UNSPEC_FRNDINT))]
17431   "TARGET_USE_FANCY_MATH_387
17432    && flag_unsafe_math_optimizations"
17433   "frndint"
17434   [(set_attr "type" "fpspc")
17435    (set_attr "mode" "XF")])
17436
17437 (define_expand "rintdf2"
17438   [(use (match_operand:DF 0 "register_operand" ""))
17439    (use (match_operand:DF 1 "register_operand" ""))]
17440   "TARGET_USE_FANCY_MATH_387
17441    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17442    && flag_unsafe_math_optimizations"
17443 {
17444   rtx op0 = gen_reg_rtx (XFmode);
17445   rtx op1 = gen_reg_rtx (XFmode);
17446
17447   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17448   emit_insn (gen_frndintxf2 (op0, op1));
17449
17450   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17451   DONE;
17452 })
17453
17454 (define_expand "rintsf2"
17455   [(use (match_operand:SF 0 "register_operand" ""))
17456    (use (match_operand:SF 1 "register_operand" ""))]
17457   "TARGET_USE_FANCY_MATH_387
17458    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17459    && flag_unsafe_math_optimizations"
17460 {
17461   rtx op0 = gen_reg_rtx (XFmode);
17462   rtx op1 = gen_reg_rtx (XFmode);
17463
17464   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17465   emit_insn (gen_frndintxf2 (op0, op1));
17466
17467   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17468   DONE;
17469 })
17470
17471 (define_expand "rintxf2"
17472   [(use (match_operand:XF 0 "register_operand" ""))
17473    (use (match_operand:XF 1 "register_operand" ""))]
17474   "TARGET_USE_FANCY_MATH_387
17475    && flag_unsafe_math_optimizations"
17476 {
17477   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17478   DONE;
17479 })
17480
17481 (define_insn_and_split "*fistdi2_1"
17482   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17483         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17484          UNSPEC_FIST))]
17485   "TARGET_USE_FANCY_MATH_387
17486    && flag_unsafe_math_optimizations
17487    && !(reload_completed || reload_in_progress)"
17488   "#"
17489   "&& 1"
17490   [(const_int 0)]
17491 {
17492   if (memory_operand (operands[0], VOIDmode))
17493     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17494   else
17495     {
17496       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17497       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17498                                          operands[2]));
17499     }
17500   DONE;
17501 }
17502   [(set_attr "type" "fpspc")
17503    (set_attr "mode" "DI")])
17504
17505 (define_insn "fistdi2"
17506   [(set (match_operand:DI 0 "memory_operand" "=m")
17507         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17508          UNSPEC_FIST))
17509    (clobber (match_scratch:XF 2 "=&1f"))]
17510   "TARGET_USE_FANCY_MATH_387
17511    && flag_unsafe_math_optimizations"
17512   "* return output_fix_trunc (insn, operands, 0);"
17513   [(set_attr "type" "fpspc")
17514    (set_attr "mode" "DI")])
17515
17516 (define_insn "fistdi2_with_temp"
17517   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17518         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17519          UNSPEC_FIST))
17520    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17521    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17522   "TARGET_USE_FANCY_MATH_387
17523    && flag_unsafe_math_optimizations"
17524   "#"
17525   [(set_attr "type" "fpspc")
17526    (set_attr "mode" "DI")])
17527
17528 (define_split
17529   [(set (match_operand:DI 0 "register_operand" "")
17530         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17531          UNSPEC_FIST))
17532    (clobber (match_operand:DI 2 "memory_operand" ""))
17533    (clobber (match_scratch 3 ""))]
17534   "reload_completed"
17535   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17536               (clobber (match_dup 3))])
17537    (set (match_dup 0) (match_dup 2))]
17538   "")
17539
17540 (define_split
17541   [(set (match_operand:DI 0 "memory_operand" "")
17542         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17543          UNSPEC_FIST))
17544    (clobber (match_operand:DI 2 "memory_operand" ""))
17545    (clobber (match_scratch 3 ""))]
17546   "reload_completed"
17547   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17548               (clobber (match_dup 3))])]
17549   "")
17550
17551 (define_insn_and_split "*fist<mode>2_1"
17552   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17553         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17554          UNSPEC_FIST))]
17555   "TARGET_USE_FANCY_MATH_387
17556    && flag_unsafe_math_optimizations
17557    && !(reload_completed || reload_in_progress)"
17558   "#"
17559   "&& 1"
17560   [(const_int 0)]
17561 {
17562   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17563   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17564                                         operands[2]));
17565   DONE;
17566 }
17567   [(set_attr "type" "fpspc")
17568    (set_attr "mode" "<MODE>")])
17569
17570 (define_insn "fist<mode>2"
17571   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17572         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17573          UNSPEC_FIST))]
17574   "TARGET_USE_FANCY_MATH_387
17575    && flag_unsafe_math_optimizations"
17576   "* return output_fix_trunc (insn, operands, 0);"
17577   [(set_attr "type" "fpspc")
17578    (set_attr "mode" "<MODE>")])
17579
17580 (define_insn "fist<mode>2_with_temp"
17581   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17582         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17583          UNSPEC_FIST))
17584    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17585   "TARGET_USE_FANCY_MATH_387
17586    && flag_unsafe_math_optimizations"
17587   "#"
17588   [(set_attr "type" "fpspc")
17589    (set_attr "mode" "<MODE>")])
17590
17591 (define_split
17592   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17593         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17594          UNSPEC_FIST))
17595    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17596   "reload_completed"
17597   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17598                        UNSPEC_FIST))
17599    (set (match_dup 0) (match_dup 2))]
17600   "")
17601
17602 (define_split
17603   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17604         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17605          UNSPEC_FIST))
17606    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17607   "reload_completed"
17608   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17609                        UNSPEC_FIST))]
17610   "")
17611
17612 (define_expand "lrint<mode>2"
17613   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17614         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17615          UNSPEC_FIST))]
17616   "TARGET_USE_FANCY_MATH_387
17617    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17618    && flag_unsafe_math_optimizations"
17619   "")
17620
17621 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17622 (define_insn_and_split "frndintxf2_floor"
17623   [(set (match_operand:XF 0 "register_operand" "=f")
17624         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17625          UNSPEC_FRNDINT_FLOOR))
17626    (clobber (reg:CC FLAGS_REG))]
17627   "TARGET_USE_FANCY_MATH_387
17628    && flag_unsafe_math_optimizations
17629    && !(reload_completed || reload_in_progress)"
17630   "#"
17631   "&& 1"
17632   [(const_int 0)]
17633 {
17634   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17635
17636   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17637   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17638
17639   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17640                                         operands[2], operands[3]));
17641   DONE;
17642 }
17643   [(set_attr "type" "frndint")
17644    (set_attr "i387_cw" "floor")
17645    (set_attr "mode" "XF")])
17646
17647 (define_insn "frndintxf2_floor_i387"
17648   [(set (match_operand:XF 0 "register_operand" "=f")
17649         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17650          UNSPEC_FRNDINT_FLOOR))
17651    (use (match_operand:HI 2 "memory_operand" "m"))
17652    (use (match_operand:HI 3 "memory_operand" "m"))]
17653   "TARGET_USE_FANCY_MATH_387
17654    && flag_unsafe_math_optimizations"
17655   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17656   [(set_attr "type" "frndint")
17657    (set_attr "i387_cw" "floor")
17658    (set_attr "mode" "XF")])
17659
17660 (define_expand "floorxf2"
17661   [(use (match_operand:XF 0 "register_operand" ""))
17662    (use (match_operand:XF 1 "register_operand" ""))]
17663   "TARGET_USE_FANCY_MATH_387
17664    && flag_unsafe_math_optimizations"
17665 {
17666   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17667   DONE;
17668 })
17669
17670 (define_expand "floordf2"
17671   [(use (match_operand:DF 0 "register_operand" ""))
17672    (use (match_operand:DF 1 "register_operand" ""))]
17673   "TARGET_USE_FANCY_MATH_387
17674    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17675    && flag_unsafe_math_optimizations"
17676 {
17677   rtx op0 = gen_reg_rtx (XFmode);
17678   rtx op1 = gen_reg_rtx (XFmode);
17679
17680   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17681   emit_insn (gen_frndintxf2_floor (op0, op1));
17682
17683   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17684   DONE;
17685 })
17686
17687 (define_expand "floorsf2"
17688   [(use (match_operand:SF 0 "register_operand" ""))
17689    (use (match_operand:SF 1 "register_operand" ""))]
17690   "TARGET_USE_FANCY_MATH_387
17691    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17692    && flag_unsafe_math_optimizations"
17693 {
17694   rtx op0 = gen_reg_rtx (XFmode);
17695   rtx op1 = gen_reg_rtx (XFmode);
17696
17697   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17698   emit_insn (gen_frndintxf2_floor (op0, op1));
17699
17700   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17701   DONE;
17702 })
17703
17704 (define_insn_and_split "*fist<mode>2_floor_1"
17705   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17706         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17707          UNSPEC_FIST_FLOOR))
17708    (clobber (reg:CC FLAGS_REG))]
17709   "TARGET_USE_FANCY_MATH_387
17710    && flag_unsafe_math_optimizations
17711    && !(reload_completed || reload_in_progress)"
17712   "#"
17713   "&& 1"
17714   [(const_int 0)]
17715 {
17716   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17717
17718   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17719   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17720   if (memory_operand (operands[0], VOIDmode))
17721     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17722                                       operands[2], operands[3]));
17723   else
17724     {
17725       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17726       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17727                                                   operands[2], operands[3],
17728                                                   operands[4]));
17729     }
17730   DONE;
17731 }
17732   [(set_attr "type" "fistp")
17733    (set_attr "i387_cw" "floor")
17734    (set_attr "mode" "<MODE>")])
17735
17736 (define_insn "fistdi2_floor"
17737   [(set (match_operand:DI 0 "memory_operand" "=m")
17738         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17739          UNSPEC_FIST_FLOOR))
17740    (use (match_operand:HI 2 "memory_operand" "m"))
17741    (use (match_operand:HI 3 "memory_operand" "m"))
17742    (clobber (match_scratch:XF 4 "=&1f"))]
17743   "TARGET_USE_FANCY_MATH_387
17744    && flag_unsafe_math_optimizations"
17745   "* return output_fix_trunc (insn, operands, 0);"
17746   [(set_attr "type" "fistp")
17747    (set_attr "i387_cw" "floor")
17748    (set_attr "mode" "DI")])
17749
17750 (define_insn "fistdi2_floor_with_temp"
17751   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17752         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17753          UNSPEC_FIST_FLOOR))
17754    (use (match_operand:HI 2 "memory_operand" "m,m"))
17755    (use (match_operand:HI 3 "memory_operand" "m,m"))
17756    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17757    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17758   "TARGET_USE_FANCY_MATH_387
17759    && flag_unsafe_math_optimizations"
17760   "#"
17761   [(set_attr "type" "fistp")
17762    (set_attr "i387_cw" "floor")
17763    (set_attr "mode" "DI")])
17764
17765 (define_split
17766   [(set (match_operand:DI 0 "register_operand" "")
17767         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17768          UNSPEC_FIST_FLOOR))
17769    (use (match_operand:HI 2 "memory_operand" ""))
17770    (use (match_operand:HI 3 "memory_operand" ""))
17771    (clobber (match_operand:DI 4 "memory_operand" ""))
17772    (clobber (match_scratch 5 ""))]
17773   "reload_completed"
17774   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17775               (use (match_dup 2))
17776               (use (match_dup 3))
17777               (clobber (match_dup 5))])
17778    (set (match_dup 0) (match_dup 4))]
17779   "")
17780
17781 (define_split
17782   [(set (match_operand:DI 0 "memory_operand" "")
17783         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17784          UNSPEC_FIST_FLOOR))
17785    (use (match_operand:HI 2 "memory_operand" ""))
17786    (use (match_operand:HI 3 "memory_operand" ""))
17787    (clobber (match_operand:DI 4 "memory_operand" ""))
17788    (clobber (match_scratch 5 ""))]
17789   "reload_completed"
17790   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17791               (use (match_dup 2))
17792               (use (match_dup 3))
17793               (clobber (match_dup 5))])]
17794   "")
17795
17796 (define_insn "fist<mode>2_floor"
17797   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17798         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17799          UNSPEC_FIST_FLOOR))
17800    (use (match_operand:HI 2 "memory_operand" "m"))
17801    (use (match_operand:HI 3 "memory_operand" "m"))]
17802   "TARGET_USE_FANCY_MATH_387
17803    && flag_unsafe_math_optimizations"
17804   "* return output_fix_trunc (insn, operands, 0);"
17805   [(set_attr "type" "fistp")
17806    (set_attr "i387_cw" "floor")
17807    (set_attr "mode" "<MODE>")])
17808
17809 (define_insn "fist<mode>2_floor_with_temp"
17810   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17811         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17812          UNSPEC_FIST_FLOOR))
17813    (use (match_operand:HI 2 "memory_operand" "m,m"))
17814    (use (match_operand:HI 3 "memory_operand" "m,m"))
17815    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17816   "TARGET_USE_FANCY_MATH_387
17817    && flag_unsafe_math_optimizations"
17818   "#"
17819   [(set_attr "type" "fistp")
17820    (set_attr "i387_cw" "floor")
17821    (set_attr "mode" "<MODE>")])
17822
17823 (define_split
17824   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17825         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17826          UNSPEC_FIST_FLOOR))
17827    (use (match_operand:HI 2 "memory_operand" ""))
17828    (use (match_operand:HI 3 "memory_operand" ""))
17829    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17830   "reload_completed"
17831   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17832                                   UNSPEC_FIST_FLOOR))
17833               (use (match_dup 2))
17834               (use (match_dup 3))])
17835    (set (match_dup 0) (match_dup 4))]
17836   "")
17837
17838 (define_split
17839   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17840         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17841          UNSPEC_FIST_FLOOR))
17842    (use (match_operand:HI 2 "memory_operand" ""))
17843    (use (match_operand:HI 3 "memory_operand" ""))
17844    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17845   "reload_completed"
17846   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17847                                   UNSPEC_FIST_FLOOR))
17848               (use (match_dup 2))
17849               (use (match_dup 3))])]
17850   "")
17851
17852 (define_expand "lfloor<mode>2"
17853   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17854                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17855                     UNSPEC_FIST_FLOOR))
17856               (clobber (reg:CC FLAGS_REG))])]
17857   "TARGET_USE_FANCY_MATH_387
17858    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17859    && flag_unsafe_math_optimizations"
17860   "")
17861
17862 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17863 (define_insn_and_split "frndintxf2_ceil"
17864   [(set (match_operand:XF 0 "register_operand" "=f")
17865         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17866          UNSPEC_FRNDINT_CEIL))
17867    (clobber (reg:CC FLAGS_REG))]
17868   "TARGET_USE_FANCY_MATH_387
17869    && flag_unsafe_math_optimizations
17870    && !(reload_completed || reload_in_progress)"
17871   "#"
17872   "&& 1"
17873   [(const_int 0)]
17874 {
17875   ix86_optimize_mode_switching[I387_CEIL] = 1;
17876
17877   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17878   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17879
17880   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17881                                        operands[2], operands[3]));
17882   DONE;
17883 }
17884   [(set_attr "type" "frndint")
17885    (set_attr "i387_cw" "ceil")
17886    (set_attr "mode" "XF")])
17887
17888 (define_insn "frndintxf2_ceil_i387"
17889   [(set (match_operand:XF 0 "register_operand" "=f")
17890         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17891          UNSPEC_FRNDINT_CEIL))
17892    (use (match_operand:HI 2 "memory_operand" "m"))
17893    (use (match_operand:HI 3 "memory_operand" "m"))]
17894   "TARGET_USE_FANCY_MATH_387
17895    && flag_unsafe_math_optimizations"
17896   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17897   [(set_attr "type" "frndint")
17898    (set_attr "i387_cw" "ceil")
17899    (set_attr "mode" "XF")])
17900
17901 (define_expand "ceilxf2"
17902   [(use (match_operand:XF 0 "register_operand" ""))
17903    (use (match_operand:XF 1 "register_operand" ""))]
17904   "TARGET_USE_FANCY_MATH_387
17905    && flag_unsafe_math_optimizations"
17906 {
17907   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17908   DONE;
17909 })
17910
17911 (define_expand "ceildf2"
17912   [(use (match_operand:DF 0 "register_operand" ""))
17913    (use (match_operand:DF 1 "register_operand" ""))]
17914   "TARGET_USE_FANCY_MATH_387
17915    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17916    && flag_unsafe_math_optimizations"
17917 {
17918   rtx op0 = gen_reg_rtx (XFmode);
17919   rtx op1 = gen_reg_rtx (XFmode);
17920
17921   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17922   emit_insn (gen_frndintxf2_ceil (op0, op1));
17923
17924   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17925   DONE;
17926 })
17927
17928 (define_expand "ceilsf2"
17929   [(use (match_operand:SF 0 "register_operand" ""))
17930    (use (match_operand:SF 1 "register_operand" ""))]
17931   "TARGET_USE_FANCY_MATH_387
17932    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17933    && flag_unsafe_math_optimizations"
17934 {
17935   rtx op0 = gen_reg_rtx (XFmode);
17936   rtx op1 = gen_reg_rtx (XFmode);
17937
17938   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17939   emit_insn (gen_frndintxf2_ceil (op0, op1));
17940
17941   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17942   DONE;
17943 })
17944
17945 (define_insn_and_split "*fist<mode>2_ceil_1"
17946   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17947         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17948          UNSPEC_FIST_CEIL))
17949    (clobber (reg:CC FLAGS_REG))]
17950   "TARGET_USE_FANCY_MATH_387
17951    && flag_unsafe_math_optimizations
17952    && !(reload_completed || reload_in_progress)"
17953   "#"
17954   "&& 1"
17955   [(const_int 0)]
17956 {
17957   ix86_optimize_mode_switching[I387_CEIL] = 1;
17958
17959   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17960   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17961   if (memory_operand (operands[0], VOIDmode))
17962     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17963                                      operands[2], operands[3]));
17964   else
17965     {
17966       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17967       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17968                                                  operands[2], operands[3],
17969                                                  operands[4]));
17970     }
17971   DONE;
17972 }
17973   [(set_attr "type" "fistp")
17974    (set_attr "i387_cw" "ceil")
17975    (set_attr "mode" "<MODE>")])
17976
17977 (define_insn "fistdi2_ceil"
17978   [(set (match_operand:DI 0 "memory_operand" "=m")
17979         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17980          UNSPEC_FIST_CEIL))
17981    (use (match_operand:HI 2 "memory_operand" "m"))
17982    (use (match_operand:HI 3 "memory_operand" "m"))
17983    (clobber (match_scratch:XF 4 "=&1f"))]
17984   "TARGET_USE_FANCY_MATH_387
17985    && flag_unsafe_math_optimizations"
17986   "* return output_fix_trunc (insn, operands, 0);"
17987   [(set_attr "type" "fistp")
17988    (set_attr "i387_cw" "ceil")
17989    (set_attr "mode" "DI")])
17990
17991 (define_insn "fistdi2_ceil_with_temp"
17992   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17993         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17994          UNSPEC_FIST_CEIL))
17995    (use (match_operand:HI 2 "memory_operand" "m,m"))
17996    (use (match_operand:HI 3 "memory_operand" "m,m"))
17997    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17998    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17999   "TARGET_USE_FANCY_MATH_387
18000    && flag_unsafe_math_optimizations"
18001   "#"
18002   [(set_attr "type" "fistp")
18003    (set_attr "i387_cw" "ceil")
18004    (set_attr "mode" "DI")])
18005
18006 (define_split
18007   [(set (match_operand:DI 0 "register_operand" "")
18008         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18009          UNSPEC_FIST_CEIL))
18010    (use (match_operand:HI 2 "memory_operand" ""))
18011    (use (match_operand:HI 3 "memory_operand" ""))
18012    (clobber (match_operand:DI 4 "memory_operand" ""))
18013    (clobber (match_scratch 5 ""))]
18014   "reload_completed"
18015   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18016               (use (match_dup 2))
18017               (use (match_dup 3))
18018               (clobber (match_dup 5))])
18019    (set (match_dup 0) (match_dup 4))]
18020   "")
18021
18022 (define_split
18023   [(set (match_operand:DI 0 "memory_operand" "")
18024         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18025          UNSPEC_FIST_CEIL))
18026    (use (match_operand:HI 2 "memory_operand" ""))
18027    (use (match_operand:HI 3 "memory_operand" ""))
18028    (clobber (match_operand:DI 4 "memory_operand" ""))
18029    (clobber (match_scratch 5 ""))]
18030   "reload_completed"
18031   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18032               (use (match_dup 2))
18033               (use (match_dup 3))
18034               (clobber (match_dup 5))])]
18035   "")
18036
18037 (define_insn "fist<mode>2_ceil"
18038   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18039         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18040          UNSPEC_FIST_CEIL))
18041    (use (match_operand:HI 2 "memory_operand" "m"))
18042    (use (match_operand:HI 3 "memory_operand" "m"))]
18043   "TARGET_USE_FANCY_MATH_387
18044    && flag_unsafe_math_optimizations"
18045   "* return output_fix_trunc (insn, operands, 0);"
18046   [(set_attr "type" "fistp")
18047    (set_attr "i387_cw" "ceil")
18048    (set_attr "mode" "<MODE>")])
18049
18050 (define_insn "fist<mode>2_ceil_with_temp"
18051   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18052         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18053          UNSPEC_FIST_CEIL))
18054    (use (match_operand:HI 2 "memory_operand" "m,m"))
18055    (use (match_operand:HI 3 "memory_operand" "m,m"))
18056    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18057   "TARGET_USE_FANCY_MATH_387
18058    && flag_unsafe_math_optimizations"
18059   "#"
18060   [(set_attr "type" "fistp")
18061    (set_attr "i387_cw" "ceil")
18062    (set_attr "mode" "<MODE>")])
18063
18064 (define_split
18065   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18066         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18067          UNSPEC_FIST_CEIL))
18068    (use (match_operand:HI 2 "memory_operand" ""))
18069    (use (match_operand:HI 3 "memory_operand" ""))
18070    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18071   "reload_completed"
18072   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18073                                   UNSPEC_FIST_CEIL))
18074               (use (match_dup 2))
18075               (use (match_dup 3))])
18076    (set (match_dup 0) (match_dup 4))]
18077   "")
18078
18079 (define_split
18080   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18081         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18082          UNSPEC_FIST_CEIL))
18083    (use (match_operand:HI 2 "memory_operand" ""))
18084    (use (match_operand:HI 3 "memory_operand" ""))
18085    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18086   "reload_completed"
18087   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18088                                   UNSPEC_FIST_CEIL))
18089               (use (match_dup 2))
18090               (use (match_dup 3))])]
18091   "")
18092
18093 (define_expand "lceil<mode>2"
18094   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18095                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18096                     UNSPEC_FIST_CEIL))
18097               (clobber (reg:CC FLAGS_REG))])]
18098   "TARGET_USE_FANCY_MATH_387
18099    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18100    && flag_unsafe_math_optimizations"
18101   "")
18102
18103 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18104 (define_insn_and_split "frndintxf2_trunc"
18105   [(set (match_operand:XF 0 "register_operand" "=f")
18106         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18107          UNSPEC_FRNDINT_TRUNC))
18108    (clobber (reg:CC FLAGS_REG))]
18109   "TARGET_USE_FANCY_MATH_387
18110    && flag_unsafe_math_optimizations
18111    && !(reload_completed || reload_in_progress)"
18112   "#"
18113   "&& 1"
18114   [(const_int 0)]
18115 {
18116   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18117
18118   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18119   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18120
18121   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18122                                         operands[2], operands[3]));
18123   DONE;
18124 }
18125   [(set_attr "type" "frndint")
18126    (set_attr "i387_cw" "trunc")
18127    (set_attr "mode" "XF")])
18128
18129 (define_insn "frndintxf2_trunc_i387"
18130   [(set (match_operand:XF 0 "register_operand" "=f")
18131         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18132          UNSPEC_FRNDINT_TRUNC))
18133    (use (match_operand:HI 2 "memory_operand" "m"))
18134    (use (match_operand:HI 3 "memory_operand" "m"))]
18135   "TARGET_USE_FANCY_MATH_387
18136    && flag_unsafe_math_optimizations"
18137   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18138   [(set_attr "type" "frndint")
18139    (set_attr "i387_cw" "trunc")
18140    (set_attr "mode" "XF")])
18141
18142 (define_expand "btruncxf2"
18143   [(use (match_operand:XF 0 "register_operand" ""))
18144    (use (match_operand:XF 1 "register_operand" ""))]
18145   "TARGET_USE_FANCY_MATH_387
18146    && flag_unsafe_math_optimizations"
18147 {
18148   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18149   DONE;
18150 })
18151
18152 (define_expand "btruncdf2"
18153   [(use (match_operand:DF 0 "register_operand" ""))
18154    (use (match_operand:DF 1 "register_operand" ""))]
18155   "TARGET_USE_FANCY_MATH_387
18156    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18157    && flag_unsafe_math_optimizations"
18158 {
18159   rtx op0 = gen_reg_rtx (XFmode);
18160   rtx op1 = gen_reg_rtx (XFmode);
18161
18162   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18163   emit_insn (gen_frndintxf2_trunc (op0, op1));
18164
18165   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18166   DONE;
18167 })
18168
18169 (define_expand "btruncsf2"
18170   [(use (match_operand:SF 0 "register_operand" ""))
18171    (use (match_operand:SF 1 "register_operand" ""))]
18172   "TARGET_USE_FANCY_MATH_387
18173    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18174    && flag_unsafe_math_optimizations"
18175 {
18176   rtx op0 = gen_reg_rtx (XFmode);
18177   rtx op1 = gen_reg_rtx (XFmode);
18178
18179   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18180   emit_insn (gen_frndintxf2_trunc (op0, op1));
18181
18182   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18183   DONE;
18184 })
18185
18186 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18187 (define_insn_and_split "frndintxf2_mask_pm"
18188   [(set (match_operand:XF 0 "register_operand" "=f")
18189         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18190          UNSPEC_FRNDINT_MASK_PM))
18191    (clobber (reg:CC FLAGS_REG))]
18192   "TARGET_USE_FANCY_MATH_387
18193    && flag_unsafe_math_optimizations
18194    && !(reload_completed || reload_in_progress)"
18195   "#"
18196   "&& 1"
18197   [(const_int 0)]
18198 {
18199   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18200
18201   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18202   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18203
18204   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18205                                           operands[2], operands[3]));
18206   DONE;
18207 }
18208   [(set_attr "type" "frndint")
18209    (set_attr "i387_cw" "mask_pm")
18210    (set_attr "mode" "XF")])
18211
18212 (define_insn "frndintxf2_mask_pm_i387"
18213   [(set (match_operand:XF 0 "register_operand" "=f")
18214         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18215          UNSPEC_FRNDINT_MASK_PM))
18216    (use (match_operand:HI 2 "memory_operand" "m"))
18217    (use (match_operand:HI 3 "memory_operand" "m"))]
18218   "TARGET_USE_FANCY_MATH_387
18219    && flag_unsafe_math_optimizations"
18220   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18221   [(set_attr "type" "frndint")
18222    (set_attr "i387_cw" "mask_pm")
18223    (set_attr "mode" "XF")])
18224
18225 (define_expand "nearbyintxf2"
18226   [(use (match_operand:XF 0 "register_operand" ""))
18227    (use (match_operand:XF 1 "register_operand" ""))]
18228   "TARGET_USE_FANCY_MATH_387
18229    && flag_unsafe_math_optimizations"
18230 {
18231   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18232
18233   DONE;
18234 })
18235
18236 (define_expand "nearbyintdf2"
18237   [(use (match_operand:DF 0 "register_operand" ""))
18238    (use (match_operand:DF 1 "register_operand" ""))]
18239   "TARGET_USE_FANCY_MATH_387
18240    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18241    && flag_unsafe_math_optimizations"
18242 {
18243   rtx op0 = gen_reg_rtx (XFmode);
18244   rtx op1 = gen_reg_rtx (XFmode);
18245
18246   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18247   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18248
18249   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18250   DONE;
18251 })
18252
18253 (define_expand "nearbyintsf2"
18254   [(use (match_operand:SF 0 "register_operand" ""))
18255    (use (match_operand:SF 1 "register_operand" ""))]
18256   "TARGET_USE_FANCY_MATH_387
18257    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18258    && flag_unsafe_math_optimizations"
18259 {
18260   rtx op0 = gen_reg_rtx (XFmode);
18261   rtx op1 = gen_reg_rtx (XFmode);
18262
18263   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18264   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18265
18266   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18267   DONE;
18268 })
18269
18270 \f
18271 ;; Block operation instructions
18272
18273 (define_insn "cld"
18274  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18275  ""
18276  "cld"
18277   [(set_attr "type" "cld")])
18278
18279 (define_expand "movmemsi"
18280   [(use (match_operand:BLK 0 "memory_operand" ""))
18281    (use (match_operand:BLK 1 "memory_operand" ""))
18282    (use (match_operand:SI 2 "nonmemory_operand" ""))
18283    (use (match_operand:SI 3 "const_int_operand" ""))]
18284   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18285 {
18286  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18287    DONE;
18288  else
18289    FAIL;
18290 })
18291
18292 (define_expand "movmemdi"
18293   [(use (match_operand:BLK 0 "memory_operand" ""))
18294    (use (match_operand:BLK 1 "memory_operand" ""))
18295    (use (match_operand:DI 2 "nonmemory_operand" ""))
18296    (use (match_operand:DI 3 "const_int_operand" ""))]
18297   "TARGET_64BIT"
18298 {
18299  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18300    DONE;
18301  else
18302    FAIL;
18303 })
18304
18305 ;; Most CPUs don't like single string operations
18306 ;; Handle this case here to simplify previous expander.
18307
18308 (define_expand "strmov"
18309   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18310    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18311    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18312               (clobber (reg:CC FLAGS_REG))])
18313    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18314               (clobber (reg:CC FLAGS_REG))])]
18315   ""
18316 {
18317   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18318
18319   /* If .md ever supports :P for Pmode, these can be directly
18320      in the pattern above.  */
18321   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18322   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18323
18324   if (TARGET_SINGLE_STRINGOP || optimize_size)
18325     {
18326       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18327                                       operands[2], operands[3],
18328                                       operands[5], operands[6]));
18329       DONE;
18330     }
18331
18332   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18333 })
18334
18335 (define_expand "strmov_singleop"
18336   [(parallel [(set (match_operand 1 "memory_operand" "")
18337                    (match_operand 3 "memory_operand" ""))
18338               (set (match_operand 0 "register_operand" "")
18339                    (match_operand 4 "" ""))
18340               (set (match_operand 2 "register_operand" "")
18341                    (match_operand 5 "" ""))
18342               (use (reg:SI DIRFLAG_REG))])]
18343   "TARGET_SINGLE_STRINGOP || optimize_size"
18344   "")
18345
18346 (define_insn "*strmovdi_rex_1"
18347   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18348         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18349    (set (match_operand:DI 0 "register_operand" "=D")
18350         (plus:DI (match_dup 2)
18351                  (const_int 8)))
18352    (set (match_operand:DI 1 "register_operand" "=S")
18353         (plus:DI (match_dup 3)
18354                  (const_int 8)))
18355    (use (reg:SI DIRFLAG_REG))]
18356   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18357   "movsq"
18358   [(set_attr "type" "str")
18359    (set_attr "mode" "DI")
18360    (set_attr "memory" "both")])
18361
18362 (define_insn "*strmovsi_1"
18363   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18364         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18365    (set (match_operand:SI 0 "register_operand" "=D")
18366         (plus:SI (match_dup 2)
18367                  (const_int 4)))
18368    (set (match_operand:SI 1 "register_operand" "=S")
18369         (plus:SI (match_dup 3)
18370                  (const_int 4)))
18371    (use (reg:SI DIRFLAG_REG))]
18372   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18373   "{movsl|movsd}"
18374   [(set_attr "type" "str")
18375    (set_attr "mode" "SI")
18376    (set_attr "memory" "both")])
18377
18378 (define_insn "*strmovsi_rex_1"
18379   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18380         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18381    (set (match_operand:DI 0 "register_operand" "=D")
18382         (plus:DI (match_dup 2)
18383                  (const_int 4)))
18384    (set (match_operand:DI 1 "register_operand" "=S")
18385         (plus:DI (match_dup 3)
18386                  (const_int 4)))
18387    (use (reg:SI DIRFLAG_REG))]
18388   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18389   "{movsl|movsd}"
18390   [(set_attr "type" "str")
18391    (set_attr "mode" "SI")
18392    (set_attr "memory" "both")])
18393
18394 (define_insn "*strmovhi_1"
18395   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18396         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18397    (set (match_operand:SI 0 "register_operand" "=D")
18398         (plus:SI (match_dup 2)
18399                  (const_int 2)))
18400    (set (match_operand:SI 1 "register_operand" "=S")
18401         (plus:SI (match_dup 3)
18402                  (const_int 2)))
18403    (use (reg:SI DIRFLAG_REG))]
18404   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18405   "movsw"
18406   [(set_attr "type" "str")
18407    (set_attr "memory" "both")
18408    (set_attr "mode" "HI")])
18409
18410 (define_insn "*strmovhi_rex_1"
18411   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18412         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18413    (set (match_operand:DI 0 "register_operand" "=D")
18414         (plus:DI (match_dup 2)
18415                  (const_int 2)))
18416    (set (match_operand:DI 1 "register_operand" "=S")
18417         (plus:DI (match_dup 3)
18418                  (const_int 2)))
18419    (use (reg:SI DIRFLAG_REG))]
18420   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18421   "movsw"
18422   [(set_attr "type" "str")
18423    (set_attr "memory" "both")
18424    (set_attr "mode" "HI")])
18425
18426 (define_insn "*strmovqi_1"
18427   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18428         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18429    (set (match_operand:SI 0 "register_operand" "=D")
18430         (plus:SI (match_dup 2)
18431                  (const_int 1)))
18432    (set (match_operand:SI 1 "register_operand" "=S")
18433         (plus:SI (match_dup 3)
18434                  (const_int 1)))
18435    (use (reg:SI DIRFLAG_REG))]
18436   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18437   "movsb"
18438   [(set_attr "type" "str")
18439    (set_attr "memory" "both")
18440    (set_attr "mode" "QI")])
18441
18442 (define_insn "*strmovqi_rex_1"
18443   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18444         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18445    (set (match_operand:DI 0 "register_operand" "=D")
18446         (plus:DI (match_dup 2)
18447                  (const_int 1)))
18448    (set (match_operand:DI 1 "register_operand" "=S")
18449         (plus:DI (match_dup 3)
18450                  (const_int 1)))
18451    (use (reg:SI DIRFLAG_REG))]
18452   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18453   "movsb"
18454   [(set_attr "type" "str")
18455    (set_attr "memory" "both")
18456    (set_attr "mode" "QI")])
18457
18458 (define_expand "rep_mov"
18459   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18460               (set (match_operand 0 "register_operand" "")
18461                    (match_operand 5 "" ""))
18462               (set (match_operand 2 "register_operand" "")
18463                    (match_operand 6 "" ""))
18464               (set (match_operand 1 "memory_operand" "")
18465                    (match_operand 3 "memory_operand" ""))
18466               (use (match_dup 4))
18467               (use (reg:SI DIRFLAG_REG))])]
18468   ""
18469   "")
18470
18471 (define_insn "*rep_movdi_rex64"
18472   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18473    (set (match_operand:DI 0 "register_operand" "=D")
18474         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18475                             (const_int 3))
18476                  (match_operand:DI 3 "register_operand" "0")))
18477    (set (match_operand:DI 1 "register_operand" "=S")
18478         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18479                  (match_operand:DI 4 "register_operand" "1")))
18480    (set (mem:BLK (match_dup 3))
18481         (mem:BLK (match_dup 4)))
18482    (use (match_dup 5))
18483    (use (reg:SI DIRFLAG_REG))]
18484   "TARGET_64BIT"
18485   "{rep\;movsq|rep movsq}"
18486   [(set_attr "type" "str")
18487    (set_attr "prefix_rep" "1")
18488    (set_attr "memory" "both")
18489    (set_attr "mode" "DI")])
18490
18491 (define_insn "*rep_movsi"
18492   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18493    (set (match_operand:SI 0 "register_operand" "=D")
18494         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18495                             (const_int 2))
18496                  (match_operand:SI 3 "register_operand" "0")))
18497    (set (match_operand:SI 1 "register_operand" "=S")
18498         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18499                  (match_operand:SI 4 "register_operand" "1")))
18500    (set (mem:BLK (match_dup 3))
18501         (mem:BLK (match_dup 4)))
18502    (use (match_dup 5))
18503    (use (reg:SI DIRFLAG_REG))]
18504   "!TARGET_64BIT"
18505   "{rep\;movsl|rep movsd}"
18506   [(set_attr "type" "str")
18507    (set_attr "prefix_rep" "1")
18508    (set_attr "memory" "both")
18509    (set_attr "mode" "SI")])
18510
18511 (define_insn "*rep_movsi_rex64"
18512   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18513    (set (match_operand:DI 0 "register_operand" "=D")
18514         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18515                             (const_int 2))
18516                  (match_operand:DI 3 "register_operand" "0")))
18517    (set (match_operand:DI 1 "register_operand" "=S")
18518         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18519                  (match_operand:DI 4 "register_operand" "1")))
18520    (set (mem:BLK (match_dup 3))
18521         (mem:BLK (match_dup 4)))
18522    (use (match_dup 5))
18523    (use (reg:SI DIRFLAG_REG))]
18524   "TARGET_64BIT"
18525   "{rep\;movsl|rep movsd}"
18526   [(set_attr "type" "str")
18527    (set_attr "prefix_rep" "1")
18528    (set_attr "memory" "both")
18529    (set_attr "mode" "SI")])
18530
18531 (define_insn "*rep_movqi"
18532   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18533    (set (match_operand:SI 0 "register_operand" "=D")
18534         (plus:SI (match_operand:SI 3 "register_operand" "0")
18535                  (match_operand:SI 5 "register_operand" "2")))
18536    (set (match_operand:SI 1 "register_operand" "=S")
18537         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18538    (set (mem:BLK (match_dup 3))
18539         (mem:BLK (match_dup 4)))
18540    (use (match_dup 5))
18541    (use (reg:SI DIRFLAG_REG))]
18542   "!TARGET_64BIT"
18543   "{rep\;movsb|rep movsb}"
18544   [(set_attr "type" "str")
18545    (set_attr "prefix_rep" "1")
18546    (set_attr "memory" "both")
18547    (set_attr "mode" "SI")])
18548
18549 (define_insn "*rep_movqi_rex64"
18550   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18551    (set (match_operand:DI 0 "register_operand" "=D")
18552         (plus:DI (match_operand:DI 3 "register_operand" "0")
18553                  (match_operand:DI 5 "register_operand" "2")))
18554    (set (match_operand:DI 1 "register_operand" "=S")
18555         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18556    (set (mem:BLK (match_dup 3))
18557         (mem:BLK (match_dup 4)))
18558    (use (match_dup 5))
18559    (use (reg:SI DIRFLAG_REG))]
18560   "TARGET_64BIT"
18561   "{rep\;movsb|rep movsb}"
18562   [(set_attr "type" "str")
18563    (set_attr "prefix_rep" "1")
18564    (set_attr "memory" "both")
18565    (set_attr "mode" "SI")])
18566
18567 (define_expand "setmemsi"
18568    [(use (match_operand:BLK 0 "memory_operand" ""))
18569     (use (match_operand:SI 1 "nonmemory_operand" ""))
18570     (use (match_operand 2 "const_int_operand" ""))
18571     (use (match_operand 3 "const_int_operand" ""))]
18572   ""
18573 {
18574  /* If value to set is not zero, use the library routine.  */
18575  if (operands[2] != const0_rtx)
18576    FAIL;
18577
18578  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18579    DONE;
18580  else
18581    FAIL;
18582 })
18583
18584 (define_expand "setmemdi"
18585    [(use (match_operand:BLK 0 "memory_operand" ""))
18586     (use (match_operand:DI 1 "nonmemory_operand" ""))
18587     (use (match_operand 2 "const_int_operand" ""))
18588     (use (match_operand 3 "const_int_operand" ""))]
18589   "TARGET_64BIT"
18590 {
18591  /* If value to set is not zero, use the library routine.  */
18592  if (operands[2] != const0_rtx)
18593    FAIL;
18594
18595  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18596    DONE;
18597  else
18598    FAIL;
18599 })
18600
18601 ;; Most CPUs don't like single string operations
18602 ;; Handle this case here to simplify previous expander.
18603
18604 (define_expand "strset"
18605   [(set (match_operand 1 "memory_operand" "")
18606         (match_operand 2 "register_operand" ""))
18607    (parallel [(set (match_operand 0 "register_operand" "")
18608                    (match_dup 3))
18609               (clobber (reg:CC FLAGS_REG))])]
18610   ""
18611 {
18612   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18613     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18614
18615   /* If .md ever supports :P for Pmode, this can be directly
18616      in the pattern above.  */
18617   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18618                               GEN_INT (GET_MODE_SIZE (GET_MODE
18619                                                       (operands[2]))));
18620   if (TARGET_SINGLE_STRINGOP || optimize_size)
18621     {
18622       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18623                                       operands[3]));
18624       DONE;
18625     }
18626 })
18627
18628 (define_expand "strset_singleop"
18629   [(parallel [(set (match_operand 1 "memory_operand" "")
18630                    (match_operand 2 "register_operand" ""))
18631               (set (match_operand 0 "register_operand" "")
18632                    (match_operand 3 "" ""))
18633               (use (reg:SI DIRFLAG_REG))])]
18634   "TARGET_SINGLE_STRINGOP || optimize_size"
18635   "")
18636
18637 (define_insn "*strsetdi_rex_1"
18638   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18639         (match_operand:DI 2 "register_operand" "a"))
18640    (set (match_operand:DI 0 "register_operand" "=D")
18641         (plus:DI (match_dup 1)
18642                  (const_int 8)))
18643    (use (reg:SI DIRFLAG_REG))]
18644   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18645   "stosq"
18646   [(set_attr "type" "str")
18647    (set_attr "memory" "store")
18648    (set_attr "mode" "DI")])
18649
18650 (define_insn "*strsetsi_1"
18651   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18652         (match_operand:SI 2 "register_operand" "a"))
18653    (set (match_operand:SI 0 "register_operand" "=D")
18654         (plus:SI (match_dup 1)
18655                  (const_int 4)))
18656    (use (reg:SI DIRFLAG_REG))]
18657   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18658   "{stosl|stosd}"
18659   [(set_attr "type" "str")
18660    (set_attr "memory" "store")
18661    (set_attr "mode" "SI")])
18662
18663 (define_insn "*strsetsi_rex_1"
18664   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18665         (match_operand:SI 2 "register_operand" "a"))
18666    (set (match_operand:DI 0 "register_operand" "=D")
18667         (plus:DI (match_dup 1)
18668                  (const_int 4)))
18669    (use (reg:SI DIRFLAG_REG))]
18670   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18671   "{stosl|stosd}"
18672   [(set_attr "type" "str")
18673    (set_attr "memory" "store")
18674    (set_attr "mode" "SI")])
18675
18676 (define_insn "*strsethi_1"
18677   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18678         (match_operand:HI 2 "register_operand" "a"))
18679    (set (match_operand:SI 0 "register_operand" "=D")
18680         (plus:SI (match_dup 1)
18681                  (const_int 2)))
18682    (use (reg:SI DIRFLAG_REG))]
18683   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18684   "stosw"
18685   [(set_attr "type" "str")
18686    (set_attr "memory" "store")
18687    (set_attr "mode" "HI")])
18688
18689 (define_insn "*strsethi_rex_1"
18690   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18691         (match_operand:HI 2 "register_operand" "a"))
18692    (set (match_operand:DI 0 "register_operand" "=D")
18693         (plus:DI (match_dup 1)
18694                  (const_int 2)))
18695    (use (reg:SI DIRFLAG_REG))]
18696   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18697   "stosw"
18698   [(set_attr "type" "str")
18699    (set_attr "memory" "store")
18700    (set_attr "mode" "HI")])
18701
18702 (define_insn "*strsetqi_1"
18703   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18704         (match_operand:QI 2 "register_operand" "a"))
18705    (set (match_operand:SI 0 "register_operand" "=D")
18706         (plus:SI (match_dup 1)
18707                  (const_int 1)))
18708    (use (reg:SI DIRFLAG_REG))]
18709   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18710   "stosb"
18711   [(set_attr "type" "str")
18712    (set_attr "memory" "store")
18713    (set_attr "mode" "QI")])
18714
18715 (define_insn "*strsetqi_rex_1"
18716   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18717         (match_operand:QI 2 "register_operand" "a"))
18718    (set (match_operand:DI 0 "register_operand" "=D")
18719         (plus:DI (match_dup 1)
18720                  (const_int 1)))
18721    (use (reg:SI DIRFLAG_REG))]
18722   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18723   "stosb"
18724   [(set_attr "type" "str")
18725    (set_attr "memory" "store")
18726    (set_attr "mode" "QI")])
18727
18728 (define_expand "rep_stos"
18729   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18730               (set (match_operand 0 "register_operand" "")
18731                    (match_operand 4 "" ""))
18732               (set (match_operand 2 "memory_operand" "") (const_int 0))
18733               (use (match_operand 3 "register_operand" ""))
18734               (use (match_dup 1))
18735               (use (reg:SI DIRFLAG_REG))])]
18736   ""
18737   "")
18738
18739 (define_insn "*rep_stosdi_rex64"
18740   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18741    (set (match_operand:DI 0 "register_operand" "=D")
18742         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18743                             (const_int 3))
18744                  (match_operand:DI 3 "register_operand" "0")))
18745    (set (mem:BLK (match_dup 3))
18746         (const_int 0))
18747    (use (match_operand:DI 2 "register_operand" "a"))
18748    (use (match_dup 4))
18749    (use (reg:SI DIRFLAG_REG))]
18750   "TARGET_64BIT"
18751   "{rep\;stosq|rep stosq}"
18752   [(set_attr "type" "str")
18753    (set_attr "prefix_rep" "1")
18754    (set_attr "memory" "store")
18755    (set_attr "mode" "DI")])
18756
18757 (define_insn "*rep_stossi"
18758   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18759    (set (match_operand:SI 0 "register_operand" "=D")
18760         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18761                             (const_int 2))
18762                  (match_operand:SI 3 "register_operand" "0")))
18763    (set (mem:BLK (match_dup 3))
18764         (const_int 0))
18765    (use (match_operand:SI 2 "register_operand" "a"))
18766    (use (match_dup 4))
18767    (use (reg:SI DIRFLAG_REG))]
18768   "!TARGET_64BIT"
18769   "{rep\;stosl|rep stosd}"
18770   [(set_attr "type" "str")
18771    (set_attr "prefix_rep" "1")
18772    (set_attr "memory" "store")
18773    (set_attr "mode" "SI")])
18774
18775 (define_insn "*rep_stossi_rex64"
18776   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18777    (set (match_operand:DI 0 "register_operand" "=D")
18778         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18779                             (const_int 2))
18780                  (match_operand:DI 3 "register_operand" "0")))
18781    (set (mem:BLK (match_dup 3))
18782         (const_int 0))
18783    (use (match_operand:SI 2 "register_operand" "a"))
18784    (use (match_dup 4))
18785    (use (reg:SI DIRFLAG_REG))]
18786   "TARGET_64BIT"
18787   "{rep\;stosl|rep stosd}"
18788   [(set_attr "type" "str")
18789    (set_attr "prefix_rep" "1")
18790    (set_attr "memory" "store")
18791    (set_attr "mode" "SI")])
18792
18793 (define_insn "*rep_stosqi"
18794   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18795    (set (match_operand:SI 0 "register_operand" "=D")
18796         (plus:SI (match_operand:SI 3 "register_operand" "0")
18797                  (match_operand:SI 4 "register_operand" "1")))
18798    (set (mem:BLK (match_dup 3))
18799         (const_int 0))
18800    (use (match_operand:QI 2 "register_operand" "a"))
18801    (use (match_dup 4))
18802    (use (reg:SI DIRFLAG_REG))]
18803   "!TARGET_64BIT"
18804   "{rep\;stosb|rep stosb}"
18805   [(set_attr "type" "str")
18806    (set_attr "prefix_rep" "1")
18807    (set_attr "memory" "store")
18808    (set_attr "mode" "QI")])
18809
18810 (define_insn "*rep_stosqi_rex64"
18811   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18812    (set (match_operand:DI 0 "register_operand" "=D")
18813         (plus:DI (match_operand:DI 3 "register_operand" "0")
18814                  (match_operand:DI 4 "register_operand" "1")))
18815    (set (mem:BLK (match_dup 3))
18816         (const_int 0))
18817    (use (match_operand:QI 2 "register_operand" "a"))
18818    (use (match_dup 4))
18819    (use (reg:SI DIRFLAG_REG))]
18820   "TARGET_64BIT"
18821   "{rep\;stosb|rep stosb}"
18822   [(set_attr "type" "str")
18823    (set_attr "prefix_rep" "1")
18824    (set_attr "memory" "store")
18825    (set_attr "mode" "QI")])
18826
18827 (define_expand "cmpstrnsi"
18828   [(set (match_operand:SI 0 "register_operand" "")
18829         (compare:SI (match_operand:BLK 1 "general_operand" "")
18830                     (match_operand:BLK 2 "general_operand" "")))
18831    (use (match_operand 3 "general_operand" ""))
18832    (use (match_operand 4 "immediate_operand" ""))]
18833   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18834 {
18835   rtx addr1, addr2, out, outlow, count, countreg, align;
18836
18837   /* Can't use this if the user has appropriated esi or edi.  */
18838   if (global_regs[4] || global_regs[5])
18839     FAIL;
18840
18841   out = operands[0];
18842   if (GET_CODE (out) != REG)
18843     out = gen_reg_rtx (SImode);
18844
18845   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18846   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18847   if (addr1 != XEXP (operands[1], 0))
18848     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18849   if (addr2 != XEXP (operands[2], 0))
18850     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18851
18852   count = operands[3];
18853   countreg = ix86_zero_extend_to_Pmode (count);
18854
18855   /* %%% Iff we are testing strict equality, we can use known alignment
18856      to good advantage.  This may be possible with combine, particularly
18857      once cc0 is dead.  */
18858   align = operands[4];
18859
18860   emit_insn (gen_cld ());
18861   if (GET_CODE (count) == CONST_INT)
18862     {
18863       if (INTVAL (count) == 0)
18864         {
18865           emit_move_insn (operands[0], const0_rtx);
18866           DONE;
18867         }
18868       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18869                                      operands[1], operands[2]));
18870     }
18871   else
18872     {
18873       if (TARGET_64BIT)
18874         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18875       else
18876         emit_insn (gen_cmpsi_1 (countreg, countreg));
18877       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18878                                   operands[1], operands[2]));
18879     }
18880
18881   outlow = gen_lowpart (QImode, out);
18882   emit_insn (gen_cmpintqi (outlow));
18883   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18884
18885   if (operands[0] != out)
18886     emit_move_insn (operands[0], out);
18887
18888   DONE;
18889 })
18890
18891 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18892
18893 (define_expand "cmpintqi"
18894   [(set (match_dup 1)
18895         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18896    (set (match_dup 2)
18897         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18898    (parallel [(set (match_operand:QI 0 "register_operand" "")
18899                    (minus:QI (match_dup 1)
18900                              (match_dup 2)))
18901               (clobber (reg:CC FLAGS_REG))])]
18902   ""
18903   "operands[1] = gen_reg_rtx (QImode);
18904    operands[2] = gen_reg_rtx (QImode);")
18905
18906 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18907 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18908
18909 (define_expand "cmpstrnqi_nz_1"
18910   [(parallel [(set (reg:CC FLAGS_REG)
18911                    (compare:CC (match_operand 4 "memory_operand" "")
18912                                (match_operand 5 "memory_operand" "")))
18913               (use (match_operand 2 "register_operand" ""))
18914               (use (match_operand:SI 3 "immediate_operand" ""))
18915               (use (reg:SI DIRFLAG_REG))
18916               (clobber (match_operand 0 "register_operand" ""))
18917               (clobber (match_operand 1 "register_operand" ""))
18918               (clobber (match_dup 2))])]
18919   ""
18920   "")
18921
18922 (define_insn "*cmpstrnqi_nz_1"
18923   [(set (reg:CC FLAGS_REG)
18924         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18925                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18926    (use (match_operand:SI 6 "register_operand" "2"))
18927    (use (match_operand:SI 3 "immediate_operand" "i"))
18928    (use (reg:SI DIRFLAG_REG))
18929    (clobber (match_operand:SI 0 "register_operand" "=S"))
18930    (clobber (match_operand:SI 1 "register_operand" "=D"))
18931    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18932   "!TARGET_64BIT"
18933   "repz{\;| }cmpsb"
18934   [(set_attr "type" "str")
18935    (set_attr "mode" "QI")
18936    (set_attr "prefix_rep" "1")])
18937
18938 (define_insn "*cmpstrnqi_nz_rex_1"
18939   [(set (reg:CC FLAGS_REG)
18940         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18941                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18942    (use (match_operand:DI 6 "register_operand" "2"))
18943    (use (match_operand:SI 3 "immediate_operand" "i"))
18944    (use (reg:SI DIRFLAG_REG))
18945    (clobber (match_operand:DI 0 "register_operand" "=S"))
18946    (clobber (match_operand:DI 1 "register_operand" "=D"))
18947    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18948   "TARGET_64BIT"
18949   "repz{\;| }cmpsb"
18950   [(set_attr "type" "str")
18951    (set_attr "mode" "QI")
18952    (set_attr "prefix_rep" "1")])
18953
18954 ;; The same, but the count is not known to not be zero.
18955
18956 (define_expand "cmpstrnqi_1"
18957   [(parallel [(set (reg:CC FLAGS_REG)
18958                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18959                                      (const_int 0))
18960                   (compare:CC (match_operand 4 "memory_operand" "")
18961                               (match_operand 5 "memory_operand" ""))
18962                   (const_int 0)))
18963               (use (match_operand:SI 3 "immediate_operand" ""))
18964               (use (reg:CC FLAGS_REG))
18965               (use (reg:SI DIRFLAG_REG))
18966               (clobber (match_operand 0 "register_operand" ""))
18967               (clobber (match_operand 1 "register_operand" ""))
18968               (clobber (match_dup 2))])]
18969   ""
18970   "")
18971
18972 (define_insn "*cmpstrnqi_1"
18973   [(set (reg:CC FLAGS_REG)
18974         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18975                              (const_int 0))
18976           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18977                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18978           (const_int 0)))
18979    (use (match_operand:SI 3 "immediate_operand" "i"))
18980    (use (reg:CC FLAGS_REG))
18981    (use (reg:SI DIRFLAG_REG))
18982    (clobber (match_operand:SI 0 "register_operand" "=S"))
18983    (clobber (match_operand:SI 1 "register_operand" "=D"))
18984    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18985   "!TARGET_64BIT"
18986   "repz{\;| }cmpsb"
18987   [(set_attr "type" "str")
18988    (set_attr "mode" "QI")
18989    (set_attr "prefix_rep" "1")])
18990
18991 (define_insn "*cmpstrnqi_rex_1"
18992   [(set (reg:CC FLAGS_REG)
18993         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18994                              (const_int 0))
18995           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18996                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18997           (const_int 0)))
18998    (use (match_operand:SI 3 "immediate_operand" "i"))
18999    (use (reg:CC FLAGS_REG))
19000    (use (reg:SI DIRFLAG_REG))
19001    (clobber (match_operand:DI 0 "register_operand" "=S"))
19002    (clobber (match_operand:DI 1 "register_operand" "=D"))
19003    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19004   "TARGET_64BIT"
19005   "repz{\;| }cmpsb"
19006   [(set_attr "type" "str")
19007    (set_attr "mode" "QI")
19008    (set_attr "prefix_rep" "1")])
19009
19010 (define_expand "strlensi"
19011   [(set (match_operand:SI 0 "register_operand" "")
19012         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19013                     (match_operand:QI 2 "immediate_operand" "")
19014                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19015   ""
19016 {
19017  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19018    DONE;
19019  else
19020    FAIL;
19021 })
19022
19023 (define_expand "strlendi"
19024   [(set (match_operand:DI 0 "register_operand" "")
19025         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19026                     (match_operand:QI 2 "immediate_operand" "")
19027                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19028   ""
19029 {
19030  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19031    DONE;
19032  else
19033    FAIL;
19034 })
19035
19036 (define_expand "strlenqi_1"
19037   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19038               (use (reg:SI DIRFLAG_REG))
19039               (clobber (match_operand 1 "register_operand" ""))
19040               (clobber (reg:CC FLAGS_REG))])]
19041   ""
19042   "")
19043
19044 (define_insn "*strlenqi_1"
19045   [(set (match_operand:SI 0 "register_operand" "=&c")
19046         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19047                     (match_operand:QI 2 "register_operand" "a")
19048                     (match_operand:SI 3 "immediate_operand" "i")
19049                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19050    (use (reg:SI DIRFLAG_REG))
19051    (clobber (match_operand:SI 1 "register_operand" "=D"))
19052    (clobber (reg:CC FLAGS_REG))]
19053   "!TARGET_64BIT"
19054   "repnz{\;| }scasb"
19055   [(set_attr "type" "str")
19056    (set_attr "mode" "QI")
19057    (set_attr "prefix_rep" "1")])
19058
19059 (define_insn "*strlenqi_rex_1"
19060   [(set (match_operand:DI 0 "register_operand" "=&c")
19061         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19062                     (match_operand:QI 2 "register_operand" "a")
19063                     (match_operand:DI 3 "immediate_operand" "i")
19064                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19065    (use (reg:SI DIRFLAG_REG))
19066    (clobber (match_operand:DI 1 "register_operand" "=D"))
19067    (clobber (reg:CC FLAGS_REG))]
19068   "TARGET_64BIT"
19069   "repnz{\;| }scasb"
19070   [(set_attr "type" "str")
19071    (set_attr "mode" "QI")
19072    (set_attr "prefix_rep" "1")])
19073
19074 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19075 ;; handled in combine, but it is not currently up to the task.
19076 ;; When used for their truth value, the cmpstrn* expanders generate
19077 ;; code like this:
19078 ;;
19079 ;;   repz cmpsb
19080 ;;   seta       %al
19081 ;;   setb       %dl
19082 ;;   cmpb       %al, %dl
19083 ;;   jcc        label
19084 ;;
19085 ;; The intermediate three instructions are unnecessary.
19086
19087 ;; This one handles cmpstrn*_nz_1...
19088 (define_peephole2
19089   [(parallel[
19090      (set (reg:CC FLAGS_REG)
19091           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19092                       (mem:BLK (match_operand 5 "register_operand" ""))))
19093      (use (match_operand 6 "register_operand" ""))
19094      (use (match_operand:SI 3 "immediate_operand" ""))
19095      (use (reg:SI DIRFLAG_REG))
19096      (clobber (match_operand 0 "register_operand" ""))
19097      (clobber (match_operand 1 "register_operand" ""))
19098      (clobber (match_operand 2 "register_operand" ""))])
19099    (set (match_operand:QI 7 "register_operand" "")
19100         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19101    (set (match_operand:QI 8 "register_operand" "")
19102         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19103    (set (reg FLAGS_REG)
19104         (compare (match_dup 7) (match_dup 8)))
19105   ]
19106   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19107   [(parallel[
19108      (set (reg:CC FLAGS_REG)
19109           (compare:CC (mem:BLK (match_dup 4))
19110                       (mem:BLK (match_dup 5))))
19111      (use (match_dup 6))
19112      (use (match_dup 3))
19113      (use (reg:SI DIRFLAG_REG))
19114      (clobber (match_dup 0))
19115      (clobber (match_dup 1))
19116      (clobber (match_dup 2))])]
19117   "")
19118
19119 ;; ...and this one handles cmpstrn*_1.
19120 (define_peephole2
19121   [(parallel[
19122      (set (reg:CC FLAGS_REG)
19123           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19124                                (const_int 0))
19125             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19126                         (mem:BLK (match_operand 5 "register_operand" "")))
19127             (const_int 0)))
19128      (use (match_operand:SI 3 "immediate_operand" ""))
19129      (use (reg:CC FLAGS_REG))
19130      (use (reg:SI DIRFLAG_REG))
19131      (clobber (match_operand 0 "register_operand" ""))
19132      (clobber (match_operand 1 "register_operand" ""))
19133      (clobber (match_operand 2 "register_operand" ""))])
19134    (set (match_operand:QI 7 "register_operand" "")
19135         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19136    (set (match_operand:QI 8 "register_operand" "")
19137         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19138    (set (reg FLAGS_REG)
19139         (compare (match_dup 7) (match_dup 8)))
19140   ]
19141   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19142   [(parallel[
19143      (set (reg:CC FLAGS_REG)
19144           (if_then_else:CC (ne (match_dup 6)
19145                                (const_int 0))
19146             (compare:CC (mem:BLK (match_dup 4))
19147                         (mem:BLK (match_dup 5)))
19148             (const_int 0)))
19149      (use (match_dup 3))
19150      (use (reg:CC FLAGS_REG))
19151      (use (reg:SI DIRFLAG_REG))
19152      (clobber (match_dup 0))
19153      (clobber (match_dup 1))
19154      (clobber (match_dup 2))])]
19155   "")
19156
19157
19158 \f
19159 ;; Conditional move instructions.
19160
19161 (define_expand "movdicc"
19162   [(set (match_operand:DI 0 "register_operand" "")
19163         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19164                          (match_operand:DI 2 "general_operand" "")
19165                          (match_operand:DI 3 "general_operand" "")))]
19166   "TARGET_64BIT"
19167   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19168
19169 (define_insn "x86_movdicc_0_m1_rex64"
19170   [(set (match_operand:DI 0 "register_operand" "=r")
19171         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19172           (const_int -1)
19173           (const_int 0)))
19174    (clobber (reg:CC FLAGS_REG))]
19175   "TARGET_64BIT"
19176   "sbb{q}\t%0, %0"
19177   ; Since we don't have the proper number of operands for an alu insn,
19178   ; fill in all the blanks.
19179   [(set_attr "type" "alu")
19180    (set_attr "pent_pair" "pu")
19181    (set_attr "memory" "none")
19182    (set_attr "imm_disp" "false")
19183    (set_attr "mode" "DI")
19184    (set_attr "length_immediate" "0")])
19185
19186 (define_insn "*movdicc_c_rex64"
19187   [(set (match_operand:DI 0 "register_operand" "=r,r")
19188         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19189                                 [(reg FLAGS_REG) (const_int 0)])
19190                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19191                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19192   "TARGET_64BIT && TARGET_CMOVE
19193    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19194   "@
19195    cmov%O2%C1\t{%2, %0|%0, %2}
19196    cmov%O2%c1\t{%3, %0|%0, %3}"
19197   [(set_attr "type" "icmov")
19198    (set_attr "mode" "DI")])
19199
19200 (define_expand "movsicc"
19201   [(set (match_operand:SI 0 "register_operand" "")
19202         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19203                          (match_operand:SI 2 "general_operand" "")
19204                          (match_operand:SI 3 "general_operand" "")))]
19205   ""
19206   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19207
19208 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19209 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19210 ;; So just document what we're doing explicitly.
19211
19212 (define_insn "x86_movsicc_0_m1"
19213   [(set (match_operand:SI 0 "register_operand" "=r")
19214         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19215           (const_int -1)
19216           (const_int 0)))
19217    (clobber (reg:CC FLAGS_REG))]
19218   ""
19219   "sbb{l}\t%0, %0"
19220   ; Since we don't have the proper number of operands for an alu insn,
19221   ; fill in all the blanks.
19222   [(set_attr "type" "alu")
19223    (set_attr "pent_pair" "pu")
19224    (set_attr "memory" "none")
19225    (set_attr "imm_disp" "false")
19226    (set_attr "mode" "SI")
19227    (set_attr "length_immediate" "0")])
19228
19229 (define_insn "*movsicc_noc"
19230   [(set (match_operand:SI 0 "register_operand" "=r,r")
19231         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19232                                 [(reg FLAGS_REG) (const_int 0)])
19233                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19234                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19235   "TARGET_CMOVE
19236    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19237   "@
19238    cmov%O2%C1\t{%2, %0|%0, %2}
19239    cmov%O2%c1\t{%3, %0|%0, %3}"
19240   [(set_attr "type" "icmov")
19241    (set_attr "mode" "SI")])
19242
19243 (define_expand "movhicc"
19244   [(set (match_operand:HI 0 "register_operand" "")
19245         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19246                          (match_operand:HI 2 "general_operand" "")
19247                          (match_operand:HI 3 "general_operand" "")))]
19248   "TARGET_HIMODE_MATH"
19249   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19250
19251 (define_insn "*movhicc_noc"
19252   [(set (match_operand:HI 0 "register_operand" "=r,r")
19253         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19254                                 [(reg FLAGS_REG) (const_int 0)])
19255                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19256                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19257   "TARGET_CMOVE
19258    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19259   "@
19260    cmov%O2%C1\t{%2, %0|%0, %2}
19261    cmov%O2%c1\t{%3, %0|%0, %3}"
19262   [(set_attr "type" "icmov")
19263    (set_attr "mode" "HI")])
19264
19265 (define_expand "movqicc"
19266   [(set (match_operand:QI 0 "register_operand" "")
19267         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19268                          (match_operand:QI 2 "general_operand" "")
19269                          (match_operand:QI 3 "general_operand" "")))]
19270   "TARGET_QIMODE_MATH"
19271   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19272
19273 (define_insn_and_split "*movqicc_noc"
19274   [(set (match_operand:QI 0 "register_operand" "=r,r")
19275         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19276                                 [(match_operand 4 "flags_reg_operand" "")
19277                                  (const_int 0)])
19278                       (match_operand:QI 2 "register_operand" "r,0")
19279                       (match_operand:QI 3 "register_operand" "0,r")))]
19280   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19281   "#"
19282   "&& reload_completed"
19283   [(set (match_dup 0)
19284         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19285                       (match_dup 2)
19286                       (match_dup 3)))]
19287   "operands[0] = gen_lowpart (SImode, operands[0]);
19288    operands[2] = gen_lowpart (SImode, operands[2]);
19289    operands[3] = gen_lowpart (SImode, operands[3]);"
19290   [(set_attr "type" "icmov")
19291    (set_attr "mode" "SI")])
19292
19293 (define_expand "movsfcc"
19294   [(set (match_operand:SF 0 "register_operand" "")
19295         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19296                          (match_operand:SF 2 "register_operand" "")
19297                          (match_operand:SF 3 "register_operand" "")))]
19298   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19299   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19300
19301 (define_insn "*movsfcc_1_387"
19302   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19303         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19304                                 [(reg FLAGS_REG) (const_int 0)])
19305                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19306                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19307   "TARGET_80387 && TARGET_CMOVE
19308    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19309   "@
19310    fcmov%F1\t{%2, %0|%0, %2}
19311    fcmov%f1\t{%3, %0|%0, %3}
19312    cmov%O2%C1\t{%2, %0|%0, %2}
19313    cmov%O2%c1\t{%3, %0|%0, %3}"
19314   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19315    (set_attr "mode" "SF,SF,SI,SI")])
19316
19317 (define_expand "movdfcc"
19318   [(set (match_operand:DF 0 "register_operand" "")
19319         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19320                          (match_operand:DF 2 "register_operand" "")
19321                          (match_operand:DF 3 "register_operand" "")))]
19322   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19323   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19324
19325 (define_insn "*movdfcc_1"
19326   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19327         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19328                                 [(reg FLAGS_REG) (const_int 0)])
19329                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19330                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19331   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19332    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19333   "@
19334    fcmov%F1\t{%2, %0|%0, %2}
19335    fcmov%f1\t{%3, %0|%0, %3}
19336    #
19337    #"
19338   [(set_attr "type" "fcmov,fcmov,multi,multi")
19339    (set_attr "mode" "DF")])
19340
19341 (define_insn "*movdfcc_1_rex64"
19342   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19343         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19344                                 [(reg FLAGS_REG) (const_int 0)])
19345                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19346                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19347   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19348    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19349   "@
19350    fcmov%F1\t{%2, %0|%0, %2}
19351    fcmov%f1\t{%3, %0|%0, %3}
19352    cmov%O2%C1\t{%2, %0|%0, %2}
19353    cmov%O2%c1\t{%3, %0|%0, %3}"
19354   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19355    (set_attr "mode" "DF")])
19356
19357 (define_split
19358   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19359         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19360                                 [(match_operand 4 "flags_reg_operand" "")
19361                                  (const_int 0)])
19362                       (match_operand:DF 2 "nonimmediate_operand" "")
19363                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19364   "!TARGET_64BIT && reload_completed"
19365   [(set (match_dup 2)
19366         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19367                       (match_dup 5)
19368                       (match_dup 7)))
19369    (set (match_dup 3)
19370         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19371                       (match_dup 6)
19372                       (match_dup 8)))]
19373   "split_di (operands+2, 1, operands+5, operands+6);
19374    split_di (operands+3, 1, operands+7, operands+8);
19375    split_di (operands, 1, operands+2, operands+3);")
19376
19377 (define_expand "movxfcc"
19378   [(set (match_operand:XF 0 "register_operand" "")
19379         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19380                          (match_operand:XF 2 "register_operand" "")
19381                          (match_operand:XF 3 "register_operand" "")))]
19382   "TARGET_80387 && TARGET_CMOVE"
19383   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19384
19385 (define_insn "*movxfcc_1"
19386   [(set (match_operand:XF 0 "register_operand" "=f,f")
19387         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19388                                 [(reg FLAGS_REG) (const_int 0)])
19389                       (match_operand:XF 2 "register_operand" "f,0")
19390                       (match_operand:XF 3 "register_operand" "0,f")))]
19391   "TARGET_80387 && TARGET_CMOVE"
19392   "@
19393    fcmov%F1\t{%2, %0|%0, %2}
19394    fcmov%f1\t{%3, %0|%0, %3}"
19395   [(set_attr "type" "fcmov")
19396    (set_attr "mode" "XF")])
19397
19398 ;; These versions of the min/max patterns are intentionally ignorant of
19399 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19400 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19401 ;; are undefined in this condition, we're certain this is correct.
19402
19403 (define_insn "sminsf3"
19404   [(set (match_operand:SF 0 "register_operand" "=x")
19405         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19406                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19407   "TARGET_SSE_MATH"
19408   "minss\t{%2, %0|%0, %2}"
19409   [(set_attr "type" "sseadd")
19410    (set_attr "mode" "SF")])
19411
19412 (define_insn "smaxsf3"
19413   [(set (match_operand:SF 0 "register_operand" "=x")
19414         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19415                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19416   "TARGET_SSE_MATH"
19417   "maxss\t{%2, %0|%0, %2}"
19418   [(set_attr "type" "sseadd")
19419    (set_attr "mode" "SF")])
19420
19421 (define_insn "smindf3"
19422   [(set (match_operand:DF 0 "register_operand" "=x")
19423         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19424                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19425   "TARGET_SSE2 && TARGET_SSE_MATH"
19426   "minsd\t{%2, %0|%0, %2}"
19427   [(set_attr "type" "sseadd")
19428    (set_attr "mode" "DF")])
19429
19430 (define_insn "smaxdf3"
19431   [(set (match_operand:DF 0 "register_operand" "=x")
19432         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19433                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19434   "TARGET_SSE2 && TARGET_SSE_MATH"
19435   "maxsd\t{%2, %0|%0, %2}"
19436   [(set_attr "type" "sseadd")
19437    (set_attr "mode" "DF")])
19438
19439 ;; These versions of the min/max patterns implement exactly the operations
19440 ;;   min = (op1 < op2 ? op1 : op2)
19441 ;;   max = (!(op1 < op2) ? op1 : op2)
19442 ;; Their operands are not commutative, and thus they may be used in the
19443 ;; presence of -0.0 and NaN.
19444
19445 (define_insn "*ieee_sminsf3"
19446   [(set (match_operand:SF 0 "register_operand" "=x")
19447         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19448                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19449                    UNSPEC_IEEE_MIN))]
19450   "TARGET_SSE_MATH"
19451   "minss\t{%2, %0|%0, %2}"
19452   [(set_attr "type" "sseadd")
19453    (set_attr "mode" "SF")])
19454
19455 (define_insn "*ieee_smaxsf3"
19456   [(set (match_operand:SF 0 "register_operand" "=x")
19457         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19458                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19459                    UNSPEC_IEEE_MAX))]
19460   "TARGET_SSE_MATH"
19461   "maxss\t{%2, %0|%0, %2}"
19462   [(set_attr "type" "sseadd")
19463    (set_attr "mode" "SF")])
19464
19465 (define_insn "*ieee_smindf3"
19466   [(set (match_operand:DF 0 "register_operand" "=x")
19467         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19468                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19469                    UNSPEC_IEEE_MIN))]
19470   "TARGET_SSE2 && TARGET_SSE_MATH"
19471   "minsd\t{%2, %0|%0, %2}"
19472   [(set_attr "type" "sseadd")
19473    (set_attr "mode" "DF")])
19474
19475 (define_insn "*ieee_smaxdf3"
19476   [(set (match_operand:DF 0 "register_operand" "=x")
19477         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19478                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19479                    UNSPEC_IEEE_MAX))]
19480   "TARGET_SSE2 && TARGET_SSE_MATH"
19481   "maxsd\t{%2, %0|%0, %2}"
19482   [(set_attr "type" "sseadd")
19483    (set_attr "mode" "DF")])
19484
19485 ;; Make two stack loads independent:
19486 ;;   fld aa              fld aa
19487 ;;   fld %st(0)     ->   fld bb
19488 ;;   fmul bb             fmul %st(1), %st
19489 ;;
19490 ;; Actually we only match the last two instructions for simplicity.
19491 (define_peephole2
19492   [(set (match_operand 0 "fp_register_operand" "")
19493         (match_operand 1 "fp_register_operand" ""))
19494    (set (match_dup 0)
19495         (match_operator 2 "binary_fp_operator"
19496            [(match_dup 0)
19497             (match_operand 3 "memory_operand" "")]))]
19498   "REGNO (operands[0]) != REGNO (operands[1])"
19499   [(set (match_dup 0) (match_dup 3))
19500    (set (match_dup 0) (match_dup 4))]
19501
19502   ;; The % modifier is not operational anymore in peephole2's, so we have to
19503   ;; swap the operands manually in the case of addition and multiplication.
19504   "if (COMMUTATIVE_ARITH_P (operands[2]))
19505      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19506                                  operands[0], operands[1]);
19507    else
19508      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19509                                  operands[1], operands[0]);")
19510
19511 ;; Conditional addition patterns
19512 (define_expand "addqicc"
19513   [(match_operand:QI 0 "register_operand" "")
19514    (match_operand 1 "comparison_operator" "")
19515    (match_operand:QI 2 "register_operand" "")
19516    (match_operand:QI 3 "const_int_operand" "")]
19517   ""
19518   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19519
19520 (define_expand "addhicc"
19521   [(match_operand:HI 0 "register_operand" "")
19522    (match_operand 1 "comparison_operator" "")
19523    (match_operand:HI 2 "register_operand" "")
19524    (match_operand:HI 3 "const_int_operand" "")]
19525   ""
19526   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19527
19528 (define_expand "addsicc"
19529   [(match_operand:SI 0 "register_operand" "")
19530    (match_operand 1 "comparison_operator" "")
19531    (match_operand:SI 2 "register_operand" "")
19532    (match_operand:SI 3 "const_int_operand" "")]
19533   ""
19534   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19535
19536 (define_expand "adddicc"
19537   [(match_operand:DI 0 "register_operand" "")
19538    (match_operand 1 "comparison_operator" "")
19539    (match_operand:DI 2 "register_operand" "")
19540    (match_operand:DI 3 "const_int_operand" "")]
19541   "TARGET_64BIT"
19542   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19543
19544 \f
19545 ;; Misc patterns (?)
19546
19547 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19548 ;; Otherwise there will be nothing to keep
19549 ;;
19550 ;; [(set (reg ebp) (reg esp))]
19551 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19552 ;;  (clobber (eflags)]
19553 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19554 ;;
19555 ;; in proper program order.
19556 (define_insn "pro_epilogue_adjust_stack_1"
19557   [(set (match_operand:SI 0 "register_operand" "=r,r")
19558         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19559                  (match_operand:SI 2 "immediate_operand" "i,i")))
19560    (clobber (reg:CC FLAGS_REG))
19561    (clobber (mem:BLK (scratch)))]
19562   "!TARGET_64BIT"
19563 {
19564   switch (get_attr_type (insn))
19565     {
19566     case TYPE_IMOV:
19567       return "mov{l}\t{%1, %0|%0, %1}";
19568
19569     case TYPE_ALU:
19570       if (GET_CODE (operands[2]) == CONST_INT
19571           && (INTVAL (operands[2]) == 128
19572               || (INTVAL (operands[2]) < 0
19573                   && INTVAL (operands[2]) != -128)))
19574         {
19575           operands[2] = GEN_INT (-INTVAL (operands[2]));
19576           return "sub{l}\t{%2, %0|%0, %2}";
19577         }
19578       return "add{l}\t{%2, %0|%0, %2}";
19579
19580     case TYPE_LEA:
19581       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19582       return "lea{l}\t{%a2, %0|%0, %a2}";
19583
19584     default:
19585       gcc_unreachable ();
19586     }
19587 }
19588   [(set (attr "type")
19589         (cond [(eq_attr "alternative" "0")
19590                  (const_string "alu")
19591                (match_operand:SI 2 "const0_operand" "")
19592                  (const_string "imov")
19593               ]
19594               (const_string "lea")))
19595    (set_attr "mode" "SI")])
19596
19597 (define_insn "pro_epilogue_adjust_stack_rex64"
19598   [(set (match_operand:DI 0 "register_operand" "=r,r")
19599         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19600                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19601    (clobber (reg:CC FLAGS_REG))
19602    (clobber (mem:BLK (scratch)))]
19603   "TARGET_64BIT"
19604 {
19605   switch (get_attr_type (insn))
19606     {
19607     case TYPE_IMOV:
19608       return "mov{q}\t{%1, %0|%0, %1}";
19609
19610     case TYPE_ALU:
19611       if (GET_CODE (operands[2]) == CONST_INT
19612           /* Avoid overflows.  */
19613           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19614           && (INTVAL (operands[2]) == 128
19615               || (INTVAL (operands[2]) < 0
19616                   && INTVAL (operands[2]) != -128)))
19617         {
19618           operands[2] = GEN_INT (-INTVAL (operands[2]));
19619           return "sub{q}\t{%2, %0|%0, %2}";
19620         }
19621       return "add{q}\t{%2, %0|%0, %2}";
19622
19623     case TYPE_LEA:
19624       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19625       return "lea{q}\t{%a2, %0|%0, %a2}";
19626
19627     default:
19628       gcc_unreachable ();
19629     }
19630 }
19631   [(set (attr "type")
19632         (cond [(eq_attr "alternative" "0")
19633                  (const_string "alu")
19634                (match_operand:DI 2 "const0_operand" "")
19635                  (const_string "imov")
19636               ]
19637               (const_string "lea")))
19638    (set_attr "mode" "DI")])
19639
19640 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19641   [(set (match_operand:DI 0 "register_operand" "=r,r")
19642         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19643                  (match_operand:DI 3 "immediate_operand" "i,i")))
19644    (use (match_operand:DI 2 "register_operand" "r,r"))
19645    (clobber (reg:CC FLAGS_REG))
19646    (clobber (mem:BLK (scratch)))]
19647   "TARGET_64BIT"
19648 {
19649   switch (get_attr_type (insn))
19650     {
19651     case TYPE_ALU:
19652       return "add{q}\t{%2, %0|%0, %2}";
19653
19654     case TYPE_LEA:
19655       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19656       return "lea{q}\t{%a2, %0|%0, %a2}";
19657
19658     default:
19659       gcc_unreachable ();
19660     }
19661 }
19662   [(set_attr "type" "alu,lea")
19663    (set_attr "mode" "DI")])
19664
19665 (define_expand "allocate_stack_worker"
19666   [(match_operand:SI 0 "register_operand" "")]
19667   "TARGET_STACK_PROBE"
19668 {
19669   if (reload_completed)
19670     {
19671       if (TARGET_64BIT)
19672         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19673       else
19674         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19675     }
19676   else
19677     {
19678       if (TARGET_64BIT)
19679         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19680       else
19681         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19682     }
19683   DONE;
19684 })
19685
19686 (define_insn "allocate_stack_worker_1"
19687   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19688     UNSPECV_STACK_PROBE)
19689    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19690    (clobber (match_scratch:SI 1 "=0"))
19691    (clobber (reg:CC FLAGS_REG))]
19692   "!TARGET_64BIT && TARGET_STACK_PROBE"
19693   "call\t__alloca"
19694   [(set_attr "type" "multi")
19695    (set_attr "length" "5")])
19696
19697 (define_expand "allocate_stack_worker_postreload"
19698   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19699                                     UNSPECV_STACK_PROBE)
19700               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19701               (clobber (match_dup 0))
19702               (clobber (reg:CC FLAGS_REG))])]
19703   ""
19704   "")
19705
19706 (define_insn "allocate_stack_worker_rex64"
19707   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19708     UNSPECV_STACK_PROBE)
19709    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19710    (clobber (match_scratch:DI 1 "=0"))
19711    (clobber (reg:CC FLAGS_REG))]
19712   "TARGET_64BIT && TARGET_STACK_PROBE"
19713   "call\t__alloca"
19714   [(set_attr "type" "multi")
19715    (set_attr "length" "5")])
19716
19717 (define_expand "allocate_stack_worker_rex64_postreload"
19718   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19719                                     UNSPECV_STACK_PROBE)
19720               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19721               (clobber (match_dup 0))
19722               (clobber (reg:CC FLAGS_REG))])]
19723   ""
19724   "")
19725
19726 (define_expand "allocate_stack"
19727   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19728                    (minus:SI (reg:SI SP_REG)
19729                              (match_operand:SI 1 "general_operand" "")))
19730               (clobber (reg:CC FLAGS_REG))])
19731    (parallel [(set (reg:SI SP_REG)
19732                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19733               (clobber (reg:CC FLAGS_REG))])]
19734   "TARGET_STACK_PROBE"
19735 {
19736 #ifdef CHECK_STACK_LIMIT
19737   if (GET_CODE (operands[1]) == CONST_INT
19738       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19739     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19740                            operands[1]));
19741   else
19742 #endif
19743     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19744                                                             operands[1])));
19745
19746   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19747   DONE;
19748 })
19749
19750 (define_expand "builtin_setjmp_receiver"
19751   [(label_ref (match_operand 0 "" ""))]
19752   "!TARGET_64BIT && flag_pic"
19753 {
19754   if (TARGET_MACHO)
19755     {
19756       rtx xops[3];
19757       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19758       rtx label_rtx = gen_label_rtx ();
19759       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19760       xops[0] = xops[1] = picreg;
19761       xops[2] = gen_rtx_CONST (SImode,
19762                   gen_rtx_MINUS (SImode,
19763                     gen_rtx_LABEL_REF (SImode, label_rtx),
19764                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19765       ix86_expand_binary_operator (MINUS, SImode, xops);
19766     }
19767   else
19768     emit_insn (gen_set_got (pic_offset_table_rtx));
19769   DONE;
19770 })
19771 \f
19772 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19773
19774 (define_split
19775   [(set (match_operand 0 "register_operand" "")
19776         (match_operator 3 "promotable_binary_operator"
19777            [(match_operand 1 "register_operand" "")
19778             (match_operand 2 "aligned_operand" "")]))
19779    (clobber (reg:CC FLAGS_REG))]
19780   "! TARGET_PARTIAL_REG_STALL && reload_completed
19781    && ((GET_MODE (operands[0]) == HImode
19782         && ((!optimize_size && !TARGET_FAST_PREFIX)
19783             /* ??? next two lines just !satisfies_constraint_K (...) */
19784             || GET_CODE (operands[2]) != CONST_INT
19785             || satisfies_constraint_K (operands[2])))
19786        || (GET_MODE (operands[0]) == QImode
19787            && (TARGET_PROMOTE_QImode || optimize_size)))"
19788   [(parallel [(set (match_dup 0)
19789                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19790               (clobber (reg:CC FLAGS_REG))])]
19791   "operands[0] = gen_lowpart (SImode, operands[0]);
19792    operands[1] = gen_lowpart (SImode, operands[1]);
19793    if (GET_CODE (operands[3]) != ASHIFT)
19794      operands[2] = gen_lowpart (SImode, operands[2]);
19795    PUT_MODE (operands[3], SImode);")
19796
19797 ; Promote the QImode tests, as i386 has encoding of the AND
19798 ; instruction with 32-bit sign-extended immediate and thus the
19799 ; instruction size is unchanged, except in the %eax case for
19800 ; which it is increased by one byte, hence the ! optimize_size.
19801 (define_split
19802   [(set (match_operand 0 "flags_reg_operand" "")
19803         (match_operator 2 "compare_operator"
19804           [(and (match_operand 3 "aligned_operand" "")
19805                 (match_operand 4 "const_int_operand" ""))
19806            (const_int 0)]))
19807    (set (match_operand 1 "register_operand" "")
19808         (and (match_dup 3) (match_dup 4)))]
19809   "! TARGET_PARTIAL_REG_STALL && reload_completed
19810    /* Ensure that the operand will remain sign-extended immediate.  */
19811    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19812    && ! optimize_size
19813    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19814        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19815   [(parallel [(set (match_dup 0)
19816                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19817                                     (const_int 0)]))
19818               (set (match_dup 1)
19819                    (and:SI (match_dup 3) (match_dup 4)))])]
19820 {
19821   operands[4]
19822     = gen_int_mode (INTVAL (operands[4])
19823                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19824   operands[1] = gen_lowpart (SImode, operands[1]);
19825   operands[3] = gen_lowpart (SImode, operands[3]);
19826 })
19827
19828 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19829 ; the TEST instruction with 32-bit sign-extended immediate and thus
19830 ; the instruction size would at least double, which is not what we
19831 ; want even with ! optimize_size.
19832 (define_split
19833   [(set (match_operand 0 "flags_reg_operand" "")
19834         (match_operator 1 "compare_operator"
19835           [(and (match_operand:HI 2 "aligned_operand" "")
19836                 (match_operand:HI 3 "const_int_operand" ""))
19837            (const_int 0)]))]
19838   "! TARGET_PARTIAL_REG_STALL && reload_completed
19839    /* Ensure that the operand will remain sign-extended immediate.  */
19840    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19841    && ! TARGET_FAST_PREFIX
19842    && ! optimize_size"
19843   [(set (match_dup 0)
19844         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19845                          (const_int 0)]))]
19846 {
19847   operands[3]
19848     = gen_int_mode (INTVAL (operands[3])
19849                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19850   operands[2] = gen_lowpart (SImode, operands[2]);
19851 })
19852
19853 (define_split
19854   [(set (match_operand 0 "register_operand" "")
19855         (neg (match_operand 1 "register_operand" "")))
19856    (clobber (reg:CC FLAGS_REG))]
19857   "! TARGET_PARTIAL_REG_STALL && reload_completed
19858    && (GET_MODE (operands[0]) == HImode
19859        || (GET_MODE (operands[0]) == QImode
19860            && (TARGET_PROMOTE_QImode || optimize_size)))"
19861   [(parallel [(set (match_dup 0)
19862                    (neg:SI (match_dup 1)))
19863               (clobber (reg:CC FLAGS_REG))])]
19864   "operands[0] = gen_lowpart (SImode, operands[0]);
19865    operands[1] = gen_lowpart (SImode, operands[1]);")
19866
19867 (define_split
19868   [(set (match_operand 0 "register_operand" "")
19869         (not (match_operand 1 "register_operand" "")))]
19870   "! TARGET_PARTIAL_REG_STALL && reload_completed
19871    && (GET_MODE (operands[0]) == HImode
19872        || (GET_MODE (operands[0]) == QImode
19873            && (TARGET_PROMOTE_QImode || optimize_size)))"
19874   [(set (match_dup 0)
19875         (not:SI (match_dup 1)))]
19876   "operands[0] = gen_lowpart (SImode, operands[0]);
19877    operands[1] = gen_lowpart (SImode, operands[1]);")
19878
19879 (define_split
19880   [(set (match_operand 0 "register_operand" "")
19881         (if_then_else (match_operator 1 "comparison_operator"
19882                                 [(reg FLAGS_REG) (const_int 0)])
19883                       (match_operand 2 "register_operand" "")
19884                       (match_operand 3 "register_operand" "")))]
19885   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19886    && (GET_MODE (operands[0]) == HImode
19887        || (GET_MODE (operands[0]) == QImode
19888            && (TARGET_PROMOTE_QImode || optimize_size)))"
19889   [(set (match_dup 0)
19890         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19891   "operands[0] = gen_lowpart (SImode, operands[0]);
19892    operands[2] = gen_lowpart (SImode, operands[2]);
19893    operands[3] = gen_lowpart (SImode, operands[3]);")
19894
19895 \f
19896 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19897 ;; transform a complex memory operation into two memory to register operations.
19898
19899 ;; Don't push memory operands
19900 (define_peephole2
19901   [(set (match_operand:SI 0 "push_operand" "")
19902         (match_operand:SI 1 "memory_operand" ""))
19903    (match_scratch:SI 2 "r")]
19904   "!optimize_size && !TARGET_PUSH_MEMORY
19905    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19906   [(set (match_dup 2) (match_dup 1))
19907    (set (match_dup 0) (match_dup 2))]
19908   "")
19909
19910 (define_peephole2
19911   [(set (match_operand:DI 0 "push_operand" "")
19912         (match_operand:DI 1 "memory_operand" ""))
19913    (match_scratch:DI 2 "r")]
19914   "!optimize_size && !TARGET_PUSH_MEMORY
19915    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19916   [(set (match_dup 2) (match_dup 1))
19917    (set (match_dup 0) (match_dup 2))]
19918   "")
19919
19920 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19921 ;; SImode pushes.
19922 (define_peephole2
19923   [(set (match_operand:SF 0 "push_operand" "")
19924         (match_operand:SF 1 "memory_operand" ""))
19925    (match_scratch:SF 2 "r")]
19926   "!optimize_size && !TARGET_PUSH_MEMORY
19927    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19928   [(set (match_dup 2) (match_dup 1))
19929    (set (match_dup 0) (match_dup 2))]
19930   "")
19931
19932 (define_peephole2
19933   [(set (match_operand:HI 0 "push_operand" "")
19934         (match_operand:HI 1 "memory_operand" ""))
19935    (match_scratch:HI 2 "r")]
19936   "!optimize_size && !TARGET_PUSH_MEMORY
19937    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19938   [(set (match_dup 2) (match_dup 1))
19939    (set (match_dup 0) (match_dup 2))]
19940   "")
19941
19942 (define_peephole2
19943   [(set (match_operand:QI 0 "push_operand" "")
19944         (match_operand:QI 1 "memory_operand" ""))
19945    (match_scratch:QI 2 "q")]
19946   "!optimize_size && !TARGET_PUSH_MEMORY
19947    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19948   [(set (match_dup 2) (match_dup 1))
19949    (set (match_dup 0) (match_dup 2))]
19950   "")
19951
19952 ;; Don't move an immediate directly to memory when the instruction
19953 ;; gets too big.
19954 (define_peephole2
19955   [(match_scratch:SI 1 "r")
19956    (set (match_operand:SI 0 "memory_operand" "")
19957         (const_int 0))]
19958   "! optimize_size
19959    && ! TARGET_USE_MOV0
19960    && TARGET_SPLIT_LONG_MOVES
19961    && get_attr_length (insn) >= ix86_cost->large_insn
19962    && peep2_regno_dead_p (0, FLAGS_REG)"
19963   [(parallel [(set (match_dup 1) (const_int 0))
19964               (clobber (reg:CC FLAGS_REG))])
19965    (set (match_dup 0) (match_dup 1))]
19966   "")
19967
19968 (define_peephole2
19969   [(match_scratch:HI 1 "r")
19970    (set (match_operand:HI 0 "memory_operand" "")
19971         (const_int 0))]
19972   "! optimize_size
19973    && ! TARGET_USE_MOV0
19974    && TARGET_SPLIT_LONG_MOVES
19975    && get_attr_length (insn) >= ix86_cost->large_insn
19976    && peep2_regno_dead_p (0, FLAGS_REG)"
19977   [(parallel [(set (match_dup 2) (const_int 0))
19978               (clobber (reg:CC FLAGS_REG))])
19979    (set (match_dup 0) (match_dup 1))]
19980   "operands[2] = gen_lowpart (SImode, operands[1]);")
19981
19982 (define_peephole2
19983   [(match_scratch:QI 1 "q")
19984    (set (match_operand:QI 0 "memory_operand" "")
19985         (const_int 0))]
19986   "! optimize_size
19987    && ! TARGET_USE_MOV0
19988    && TARGET_SPLIT_LONG_MOVES
19989    && get_attr_length (insn) >= ix86_cost->large_insn
19990    && peep2_regno_dead_p (0, FLAGS_REG)"
19991   [(parallel [(set (match_dup 2) (const_int 0))
19992               (clobber (reg:CC FLAGS_REG))])
19993    (set (match_dup 0) (match_dup 1))]
19994   "operands[2] = gen_lowpart (SImode, operands[1]);")
19995
19996 (define_peephole2
19997   [(match_scratch:SI 2 "r")
19998    (set (match_operand:SI 0 "memory_operand" "")
19999         (match_operand:SI 1 "immediate_operand" ""))]
20000   "! optimize_size
20001    && get_attr_length (insn) >= ix86_cost->large_insn
20002    && TARGET_SPLIT_LONG_MOVES"
20003   [(set (match_dup 2) (match_dup 1))
20004    (set (match_dup 0) (match_dup 2))]
20005   "")
20006
20007 (define_peephole2
20008   [(match_scratch:HI 2 "r")
20009    (set (match_operand:HI 0 "memory_operand" "")
20010         (match_operand:HI 1 "immediate_operand" ""))]
20011   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20012   && TARGET_SPLIT_LONG_MOVES"
20013   [(set (match_dup 2) (match_dup 1))
20014    (set (match_dup 0) (match_dup 2))]
20015   "")
20016
20017 (define_peephole2
20018   [(match_scratch:QI 2 "q")
20019    (set (match_operand:QI 0 "memory_operand" "")
20020         (match_operand:QI 1 "immediate_operand" ""))]
20021   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20022   && TARGET_SPLIT_LONG_MOVES"
20023   [(set (match_dup 2) (match_dup 1))
20024    (set (match_dup 0) (match_dup 2))]
20025   "")
20026
20027 ;; Don't compare memory with zero, load and use a test instead.
20028 (define_peephole2
20029   [(set (match_operand 0 "flags_reg_operand" "")
20030         (match_operator 1 "compare_operator"
20031           [(match_operand:SI 2 "memory_operand" "")
20032            (const_int 0)]))
20033    (match_scratch:SI 3 "r")]
20034   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
20035   [(set (match_dup 3) (match_dup 2))
20036    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20037   "")
20038
20039 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20040 ;; Don't split NOTs with a displacement operand, because resulting XOR
20041 ;; will not be pairable anyway.
20042 ;;
20043 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20044 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20045 ;; so this split helps here as well.
20046 ;;
20047 ;; Note: Can't do this as a regular split because we can't get proper
20048 ;; lifetime information then.
20049
20050 (define_peephole2
20051   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20052         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20053   "!optimize_size
20054    && peep2_regno_dead_p (0, FLAGS_REG)
20055    && ((TARGET_PENTIUM
20056         && (GET_CODE (operands[0]) != MEM
20057             || !memory_displacement_operand (operands[0], SImode)))
20058        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20059   [(parallel [(set (match_dup 0)
20060                    (xor:SI (match_dup 1) (const_int -1)))
20061               (clobber (reg:CC FLAGS_REG))])]
20062   "")
20063
20064 (define_peephole2
20065   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20066         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20067   "!optimize_size
20068    && peep2_regno_dead_p (0, FLAGS_REG)
20069    && ((TARGET_PENTIUM
20070         && (GET_CODE (operands[0]) != MEM
20071             || !memory_displacement_operand (operands[0], HImode)))
20072        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20073   [(parallel [(set (match_dup 0)
20074                    (xor:HI (match_dup 1) (const_int -1)))
20075               (clobber (reg:CC FLAGS_REG))])]
20076   "")
20077
20078 (define_peephole2
20079   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20080         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20081   "!optimize_size
20082    && peep2_regno_dead_p (0, FLAGS_REG)
20083    && ((TARGET_PENTIUM
20084         && (GET_CODE (operands[0]) != MEM
20085             || !memory_displacement_operand (operands[0], QImode)))
20086        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20087   [(parallel [(set (match_dup 0)
20088                    (xor:QI (match_dup 1) (const_int -1)))
20089               (clobber (reg:CC FLAGS_REG))])]
20090   "")
20091
20092 ;; Non pairable "test imm, reg" instructions can be translated to
20093 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20094 ;; byte opcode instead of two, have a short form for byte operands),
20095 ;; so do it for other CPUs as well.  Given that the value was dead,
20096 ;; this should not create any new dependencies.  Pass on the sub-word
20097 ;; versions if we're concerned about partial register stalls.
20098
20099 (define_peephole2
20100   [(set (match_operand 0 "flags_reg_operand" "")
20101         (match_operator 1 "compare_operator"
20102           [(and:SI (match_operand:SI 2 "register_operand" "")
20103                    (match_operand:SI 3 "immediate_operand" ""))
20104            (const_int 0)]))]
20105   "ix86_match_ccmode (insn, CCNOmode)
20106    && (true_regnum (operands[2]) != 0
20107        || satisfies_constraint_K (operands[3]))
20108    && peep2_reg_dead_p (1, operands[2])"
20109   [(parallel
20110      [(set (match_dup 0)
20111            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20112                             (const_int 0)]))
20113       (set (match_dup 2)
20114            (and:SI (match_dup 2) (match_dup 3)))])]
20115   "")
20116
20117 ;; We don't need to handle HImode case, because it will be promoted to SImode
20118 ;; on ! TARGET_PARTIAL_REG_STALL
20119
20120 (define_peephole2
20121   [(set (match_operand 0 "flags_reg_operand" "")
20122         (match_operator 1 "compare_operator"
20123           [(and:QI (match_operand:QI 2 "register_operand" "")
20124                    (match_operand:QI 3 "immediate_operand" ""))
20125            (const_int 0)]))]
20126   "! TARGET_PARTIAL_REG_STALL
20127    && ix86_match_ccmode (insn, CCNOmode)
20128    && true_regnum (operands[2]) != 0
20129    && peep2_reg_dead_p (1, operands[2])"
20130   [(parallel
20131      [(set (match_dup 0)
20132            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20133                             (const_int 0)]))
20134       (set (match_dup 2)
20135            (and:QI (match_dup 2) (match_dup 3)))])]
20136   "")
20137
20138 (define_peephole2
20139   [(set (match_operand 0 "flags_reg_operand" "")
20140         (match_operator 1 "compare_operator"
20141           [(and:SI
20142              (zero_extract:SI
20143                (match_operand 2 "ext_register_operand" "")
20144                (const_int 8)
20145                (const_int 8))
20146              (match_operand 3 "const_int_operand" ""))
20147            (const_int 0)]))]
20148   "! TARGET_PARTIAL_REG_STALL
20149    && ix86_match_ccmode (insn, CCNOmode)
20150    && true_regnum (operands[2]) != 0
20151    && peep2_reg_dead_p (1, operands[2])"
20152   [(parallel [(set (match_dup 0)
20153                    (match_op_dup 1
20154                      [(and:SI
20155                         (zero_extract:SI
20156                           (match_dup 2)
20157                           (const_int 8)
20158                           (const_int 8))
20159                         (match_dup 3))
20160                       (const_int 0)]))
20161               (set (zero_extract:SI (match_dup 2)
20162                                     (const_int 8)
20163                                     (const_int 8))
20164                    (and:SI
20165                      (zero_extract:SI
20166                        (match_dup 2)
20167                        (const_int 8)
20168                        (const_int 8))
20169                      (match_dup 3)))])]
20170   "")
20171
20172 ;; Don't do logical operations with memory inputs.
20173 (define_peephole2
20174   [(match_scratch:SI 2 "r")
20175    (parallel [(set (match_operand:SI 0 "register_operand" "")
20176                    (match_operator:SI 3 "arith_or_logical_operator"
20177                      [(match_dup 0)
20178                       (match_operand:SI 1 "memory_operand" "")]))
20179               (clobber (reg:CC FLAGS_REG))])]
20180   "! optimize_size && ! TARGET_READ_MODIFY"
20181   [(set (match_dup 2) (match_dup 1))
20182    (parallel [(set (match_dup 0)
20183                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20184               (clobber (reg:CC FLAGS_REG))])]
20185   "")
20186
20187 (define_peephole2
20188   [(match_scratch:SI 2 "r")
20189    (parallel [(set (match_operand:SI 0 "register_operand" "")
20190                    (match_operator:SI 3 "arith_or_logical_operator"
20191                      [(match_operand:SI 1 "memory_operand" "")
20192                       (match_dup 0)]))
20193               (clobber (reg:CC FLAGS_REG))])]
20194   "! optimize_size && ! TARGET_READ_MODIFY"
20195   [(set (match_dup 2) (match_dup 1))
20196    (parallel [(set (match_dup 0)
20197                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20198               (clobber (reg:CC FLAGS_REG))])]
20199   "")
20200
20201 ; Don't do logical operations with memory outputs
20202 ;
20203 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20204 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20205 ; the same decoder scheduling characteristics as the original.
20206
20207 (define_peephole2
20208   [(match_scratch:SI 2 "r")
20209    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20210                    (match_operator:SI 3 "arith_or_logical_operator"
20211                      [(match_dup 0)
20212                       (match_operand:SI 1 "nonmemory_operand" "")]))
20213               (clobber (reg:CC FLAGS_REG))])]
20214   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20215   [(set (match_dup 2) (match_dup 0))
20216    (parallel [(set (match_dup 2)
20217                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20218               (clobber (reg:CC FLAGS_REG))])
20219    (set (match_dup 0) (match_dup 2))]
20220   "")
20221
20222 (define_peephole2
20223   [(match_scratch:SI 2 "r")
20224    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20225                    (match_operator:SI 3 "arith_or_logical_operator"
20226                      [(match_operand:SI 1 "nonmemory_operand" "")
20227                       (match_dup 0)]))
20228               (clobber (reg:CC FLAGS_REG))])]
20229   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20230   [(set (match_dup 2) (match_dup 0))
20231    (parallel [(set (match_dup 2)
20232                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20233               (clobber (reg:CC FLAGS_REG))])
20234    (set (match_dup 0) (match_dup 2))]
20235   "")
20236
20237 ;; Attempt to always use XOR for zeroing registers.
20238 (define_peephole2
20239   [(set (match_operand 0 "register_operand" "")
20240         (match_operand 1 "const0_operand" ""))]
20241   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20242    && (! TARGET_USE_MOV0 || optimize_size)
20243    && GENERAL_REG_P (operands[0])
20244    && peep2_regno_dead_p (0, FLAGS_REG)"
20245   [(parallel [(set (match_dup 0) (const_int 0))
20246               (clobber (reg:CC FLAGS_REG))])]
20247 {
20248   operands[0] = gen_lowpart (word_mode, operands[0]);
20249 })
20250
20251 (define_peephole2
20252   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20253         (const_int 0))]
20254   "(GET_MODE (operands[0]) == QImode
20255     || GET_MODE (operands[0]) == HImode)
20256    && (! TARGET_USE_MOV0 || optimize_size)
20257    && peep2_regno_dead_p (0, FLAGS_REG)"
20258   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20259               (clobber (reg:CC FLAGS_REG))])])
20260
20261 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20262 (define_peephole2
20263   [(set (match_operand 0 "register_operand" "")
20264         (const_int -1))]
20265   "(GET_MODE (operands[0]) == HImode
20266     || GET_MODE (operands[0]) == SImode
20267     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20268    && (optimize_size || TARGET_PENTIUM)
20269    && peep2_regno_dead_p (0, FLAGS_REG)"
20270   [(parallel [(set (match_dup 0) (const_int -1))
20271               (clobber (reg:CC FLAGS_REG))])]
20272   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20273                               operands[0]);")
20274
20275 ;; Attempt to convert simple leas to adds. These can be created by
20276 ;; move expanders.
20277 (define_peephole2
20278   [(set (match_operand:SI 0 "register_operand" "")
20279         (plus:SI (match_dup 0)
20280                  (match_operand:SI 1 "nonmemory_operand" "")))]
20281   "peep2_regno_dead_p (0, FLAGS_REG)"
20282   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20283               (clobber (reg:CC FLAGS_REG))])]
20284   "")
20285
20286 (define_peephole2
20287   [(set (match_operand:SI 0 "register_operand" "")
20288         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20289                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20290   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20291   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20292               (clobber (reg:CC FLAGS_REG))])]
20293   "operands[2] = gen_lowpart (SImode, operands[2]);")
20294
20295 (define_peephole2
20296   [(set (match_operand:DI 0 "register_operand" "")
20297         (plus:DI (match_dup 0)
20298                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20299   "peep2_regno_dead_p (0, FLAGS_REG)"
20300   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20301               (clobber (reg:CC FLAGS_REG))])]
20302   "")
20303
20304 (define_peephole2
20305   [(set (match_operand:SI 0 "register_operand" "")
20306         (mult:SI (match_dup 0)
20307                  (match_operand:SI 1 "const_int_operand" "")))]
20308   "exact_log2 (INTVAL (operands[1])) >= 0
20309    && peep2_regno_dead_p (0, FLAGS_REG)"
20310   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20311               (clobber (reg:CC FLAGS_REG))])]
20312   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20313
20314 (define_peephole2
20315   [(set (match_operand:DI 0 "register_operand" "")
20316         (mult:DI (match_dup 0)
20317                  (match_operand:DI 1 "const_int_operand" "")))]
20318   "exact_log2 (INTVAL (operands[1])) >= 0
20319    && peep2_regno_dead_p (0, FLAGS_REG)"
20320   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20321               (clobber (reg:CC FLAGS_REG))])]
20322   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20323
20324 (define_peephole2
20325   [(set (match_operand:SI 0 "register_operand" "")
20326         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20327                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20328   "exact_log2 (INTVAL (operands[2])) >= 0
20329    && REGNO (operands[0]) == REGNO (operands[1])
20330    && peep2_regno_dead_p (0, FLAGS_REG)"
20331   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20332               (clobber (reg:CC FLAGS_REG))])]
20333   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20334
20335 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20336 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20337 ;; many CPUs it is also faster, since special hardware to avoid esp
20338 ;; dependencies is present.
20339
20340 ;; While some of these conversions may be done using splitters, we use peepholes
20341 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20342
20343 ;; Convert prologue esp subtractions to push.
20344 ;; We need register to push.  In order to keep verify_flow_info happy we have
20345 ;; two choices
20346 ;; - use scratch and clobber it in order to avoid dependencies
20347 ;; - use already live register
20348 ;; We can't use the second way right now, since there is no reliable way how to
20349 ;; verify that given register is live.  First choice will also most likely in
20350 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20351 ;; call clobbered registers are dead.  We may want to use base pointer as an
20352 ;; alternative when no register is available later.
20353
20354 (define_peephole2
20355   [(match_scratch:SI 0 "r")
20356    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20357               (clobber (reg:CC FLAGS_REG))
20358               (clobber (mem:BLK (scratch)))])]
20359   "optimize_size || !TARGET_SUB_ESP_4"
20360   [(clobber (match_dup 0))
20361    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20362               (clobber (mem:BLK (scratch)))])])
20363
20364 (define_peephole2
20365   [(match_scratch:SI 0 "r")
20366    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20367               (clobber (reg:CC FLAGS_REG))
20368               (clobber (mem:BLK (scratch)))])]
20369   "optimize_size || !TARGET_SUB_ESP_8"
20370   [(clobber (match_dup 0))
20371    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20372    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20373               (clobber (mem:BLK (scratch)))])])
20374
20375 ;; Convert esp subtractions to push.
20376 (define_peephole2
20377   [(match_scratch:SI 0 "r")
20378    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20379               (clobber (reg:CC FLAGS_REG))])]
20380   "optimize_size || !TARGET_SUB_ESP_4"
20381   [(clobber (match_dup 0))
20382    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20383
20384 (define_peephole2
20385   [(match_scratch:SI 0 "r")
20386    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20387               (clobber (reg:CC FLAGS_REG))])]
20388   "optimize_size || !TARGET_SUB_ESP_8"
20389   [(clobber (match_dup 0))
20390    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20391    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20392
20393 ;; Convert epilogue deallocator to pop.
20394 (define_peephole2
20395   [(match_scratch:SI 0 "r")
20396    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20397               (clobber (reg:CC FLAGS_REG))
20398               (clobber (mem:BLK (scratch)))])]
20399   "optimize_size || !TARGET_ADD_ESP_4"
20400   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20401               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20402               (clobber (mem:BLK (scratch)))])]
20403   "")
20404
20405 ;; Two pops case is tricky, since pop causes dependency on destination register.
20406 ;; We use two registers if available.
20407 (define_peephole2
20408   [(match_scratch:SI 0 "r")
20409    (match_scratch:SI 1 "r")
20410    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20411               (clobber (reg:CC FLAGS_REG))
20412               (clobber (mem:BLK (scratch)))])]
20413   "optimize_size || !TARGET_ADD_ESP_8"
20414   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20415               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20416               (clobber (mem:BLK (scratch)))])
20417    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20418               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20419   "")
20420
20421 (define_peephole2
20422   [(match_scratch:SI 0 "r")
20423    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20424               (clobber (reg:CC FLAGS_REG))
20425               (clobber (mem:BLK (scratch)))])]
20426   "optimize_size"
20427   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20428               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20429               (clobber (mem:BLK (scratch)))])
20430    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20431               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20432   "")
20433
20434 ;; Convert esp additions to pop.
20435 (define_peephole2
20436   [(match_scratch:SI 0 "r")
20437    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20438               (clobber (reg:CC FLAGS_REG))])]
20439   ""
20440   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20441               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20442   "")
20443
20444 ;; Two pops case is tricky, since pop causes dependency on destination register.
20445 ;; We use two registers if available.
20446 (define_peephole2
20447   [(match_scratch:SI 0 "r")
20448    (match_scratch:SI 1 "r")
20449    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20450               (clobber (reg:CC FLAGS_REG))])]
20451   ""
20452   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20453               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20454    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20455               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20456   "")
20457
20458 (define_peephole2
20459   [(match_scratch:SI 0 "r")
20460    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20461               (clobber (reg:CC FLAGS_REG))])]
20462   "optimize_size"
20463   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20464               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20465    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20466               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20467   "")
20468 \f
20469 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20470 ;; required and register dies.  Similarly for 128 to plus -128.
20471 (define_peephole2
20472   [(set (match_operand 0 "flags_reg_operand" "")
20473         (match_operator 1 "compare_operator"
20474           [(match_operand 2 "register_operand" "")
20475            (match_operand 3 "const_int_operand" "")]))]
20476   "(INTVAL (operands[3]) == -1
20477     || INTVAL (operands[3]) == 1
20478     || INTVAL (operands[3]) == 128)
20479    && ix86_match_ccmode (insn, CCGCmode)
20480    && peep2_reg_dead_p (1, operands[2])"
20481   [(parallel [(set (match_dup 0)
20482                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20483               (clobber (match_dup 2))])]
20484   "")
20485 \f
20486 (define_peephole2
20487   [(match_scratch:DI 0 "r")
20488    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20489               (clobber (reg:CC FLAGS_REG))
20490               (clobber (mem:BLK (scratch)))])]
20491   "optimize_size || !TARGET_SUB_ESP_4"
20492   [(clobber (match_dup 0))
20493    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20494               (clobber (mem:BLK (scratch)))])])
20495
20496 (define_peephole2
20497   [(match_scratch:DI 0 "r")
20498    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20499               (clobber (reg:CC FLAGS_REG))
20500               (clobber (mem:BLK (scratch)))])]
20501   "optimize_size || !TARGET_SUB_ESP_8"
20502   [(clobber (match_dup 0))
20503    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20504    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20505               (clobber (mem:BLK (scratch)))])])
20506
20507 ;; Convert esp subtractions to push.
20508 (define_peephole2
20509   [(match_scratch:DI 0 "r")
20510    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20511               (clobber (reg:CC FLAGS_REG))])]
20512   "optimize_size || !TARGET_SUB_ESP_4"
20513   [(clobber (match_dup 0))
20514    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20515
20516 (define_peephole2
20517   [(match_scratch:DI 0 "r")
20518    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20519               (clobber (reg:CC FLAGS_REG))])]
20520   "optimize_size || !TARGET_SUB_ESP_8"
20521   [(clobber (match_dup 0))
20522    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20523    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20524
20525 ;; Convert epilogue deallocator to pop.
20526 (define_peephole2
20527   [(match_scratch:DI 0 "r")
20528    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20529               (clobber (reg:CC FLAGS_REG))
20530               (clobber (mem:BLK (scratch)))])]
20531   "optimize_size || !TARGET_ADD_ESP_4"
20532   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20533               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20534               (clobber (mem:BLK (scratch)))])]
20535   "")
20536
20537 ;; Two pops case is tricky, since pop causes dependency on destination register.
20538 ;; We use two registers if available.
20539 (define_peephole2
20540   [(match_scratch:DI 0 "r")
20541    (match_scratch:DI 1 "r")
20542    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20543               (clobber (reg:CC FLAGS_REG))
20544               (clobber (mem:BLK (scratch)))])]
20545   "optimize_size || !TARGET_ADD_ESP_8"
20546   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20547               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20548               (clobber (mem:BLK (scratch)))])
20549    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20550               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20551   "")
20552
20553 (define_peephole2
20554   [(match_scratch:DI 0 "r")
20555    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20556               (clobber (reg:CC FLAGS_REG))
20557               (clobber (mem:BLK (scratch)))])]
20558   "optimize_size"
20559   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20560               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20561               (clobber (mem:BLK (scratch)))])
20562    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20563               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20564   "")
20565
20566 ;; Convert esp additions to pop.
20567 (define_peephole2
20568   [(match_scratch:DI 0 "r")
20569    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20570               (clobber (reg:CC FLAGS_REG))])]
20571   ""
20572   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20573               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20574   "")
20575
20576 ;; Two pops case is tricky, since pop causes dependency on destination register.
20577 ;; We use two registers if available.
20578 (define_peephole2
20579   [(match_scratch:DI 0 "r")
20580    (match_scratch:DI 1 "r")
20581    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20582               (clobber (reg:CC FLAGS_REG))])]
20583   ""
20584   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20585               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20586    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20587               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20588   "")
20589
20590 (define_peephole2
20591   [(match_scratch:DI 0 "r")
20592    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20593               (clobber (reg:CC FLAGS_REG))])]
20594   "optimize_size"
20595   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20596               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20597    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20598               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20599   "")
20600 \f
20601 ;; Convert imul by three, five and nine into lea
20602 (define_peephole2
20603   [(parallel
20604     [(set (match_operand:SI 0 "register_operand" "")
20605           (mult:SI (match_operand:SI 1 "register_operand" "")
20606                    (match_operand:SI 2 "const_int_operand" "")))
20607      (clobber (reg:CC FLAGS_REG))])]
20608   "INTVAL (operands[2]) == 3
20609    || INTVAL (operands[2]) == 5
20610    || INTVAL (operands[2]) == 9"
20611   [(set (match_dup 0)
20612         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20613                  (match_dup 1)))]
20614   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20615
20616 (define_peephole2
20617   [(parallel
20618     [(set (match_operand:SI 0 "register_operand" "")
20619           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20620                    (match_operand:SI 2 "const_int_operand" "")))
20621      (clobber (reg:CC FLAGS_REG))])]
20622   "!optimize_size
20623    && (INTVAL (operands[2]) == 3
20624        || INTVAL (operands[2]) == 5
20625        || INTVAL (operands[2]) == 9)"
20626   [(set (match_dup 0) (match_dup 1))
20627    (set (match_dup 0)
20628         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20629                  (match_dup 0)))]
20630   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20631
20632 (define_peephole2
20633   [(parallel
20634     [(set (match_operand:DI 0 "register_operand" "")
20635           (mult:DI (match_operand:DI 1 "register_operand" "")
20636                    (match_operand:DI 2 "const_int_operand" "")))
20637      (clobber (reg:CC FLAGS_REG))])]
20638   "TARGET_64BIT
20639    && (INTVAL (operands[2]) == 3
20640        || INTVAL (operands[2]) == 5
20641        || INTVAL (operands[2]) == 9)"
20642   [(set (match_dup 0)
20643         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20644                  (match_dup 1)))]
20645   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20646
20647 (define_peephole2
20648   [(parallel
20649     [(set (match_operand:DI 0 "register_operand" "")
20650           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20651                    (match_operand:DI 2 "const_int_operand" "")))
20652      (clobber (reg:CC FLAGS_REG))])]
20653   "TARGET_64BIT
20654    && !optimize_size
20655    && (INTVAL (operands[2]) == 3
20656        || INTVAL (operands[2]) == 5
20657        || INTVAL (operands[2]) == 9)"
20658   [(set (match_dup 0) (match_dup 1))
20659    (set (match_dup 0)
20660         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20661                  (match_dup 0)))]
20662   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20663
20664 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20665 ;; imul $32bit_imm, reg, reg is direct decoded.
20666 (define_peephole2
20667   [(match_scratch:DI 3 "r")
20668    (parallel [(set (match_operand:DI 0 "register_operand" "")
20669                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20670                             (match_operand:DI 2 "immediate_operand" "")))
20671               (clobber (reg:CC FLAGS_REG))])]
20672   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20673    && !satisfies_constraint_K (operands[2])"
20674   [(set (match_dup 3) (match_dup 1))
20675    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20676               (clobber (reg:CC FLAGS_REG))])]
20677 "")
20678
20679 (define_peephole2
20680   [(match_scratch:SI 3 "r")
20681    (parallel [(set (match_operand:SI 0 "register_operand" "")
20682                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20683                             (match_operand:SI 2 "immediate_operand" "")))
20684               (clobber (reg:CC FLAGS_REG))])]
20685   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20686    && !satisfies_constraint_K (operands[2])"
20687   [(set (match_dup 3) (match_dup 1))
20688    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20689               (clobber (reg:CC FLAGS_REG))])]
20690 "")
20691
20692 (define_peephole2
20693   [(match_scratch:SI 3 "r")
20694    (parallel [(set (match_operand:DI 0 "register_operand" "")
20695                    (zero_extend:DI
20696                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20697                               (match_operand:SI 2 "immediate_operand" ""))))
20698               (clobber (reg:CC FLAGS_REG))])]
20699   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20700    && !satisfies_constraint_K (operands[2])"
20701   [(set (match_dup 3) (match_dup 1))
20702    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20703               (clobber (reg:CC FLAGS_REG))])]
20704 "")
20705
20706 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20707 ;; Convert it into imul reg, reg
20708 ;; It would be better to force assembler to encode instruction using long
20709 ;; immediate, but there is apparently no way to do so.
20710 (define_peephole2
20711   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20712                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20713                             (match_operand:DI 2 "const_int_operand" "")))
20714               (clobber (reg:CC FLAGS_REG))])
20715    (match_scratch:DI 3 "r")]
20716   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20717    && satisfies_constraint_K (operands[2])"
20718   [(set (match_dup 3) (match_dup 2))
20719    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20720               (clobber (reg:CC FLAGS_REG))])]
20721 {
20722   if (!rtx_equal_p (operands[0], operands[1]))
20723     emit_move_insn (operands[0], operands[1]);
20724 })
20725
20726 (define_peephole2
20727   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20728                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20729                             (match_operand:SI 2 "const_int_operand" "")))
20730               (clobber (reg:CC FLAGS_REG))])
20731    (match_scratch:SI 3 "r")]
20732   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20733    && satisfies_constraint_K (operands[2])"
20734   [(set (match_dup 3) (match_dup 2))
20735    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20736               (clobber (reg:CC FLAGS_REG))])]
20737 {
20738   if (!rtx_equal_p (operands[0], operands[1]))
20739     emit_move_insn (operands[0], operands[1]);
20740 })
20741
20742 (define_peephole2
20743   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20744                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20745                             (match_operand:HI 2 "immediate_operand" "")))
20746               (clobber (reg:CC FLAGS_REG))])
20747    (match_scratch:HI 3 "r")]
20748   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20749   [(set (match_dup 3) (match_dup 2))
20750    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20751               (clobber (reg:CC FLAGS_REG))])]
20752 {
20753   if (!rtx_equal_p (operands[0], operands[1]))
20754     emit_move_insn (operands[0], operands[1]);
20755 })
20756
20757 ;; After splitting up read-modify operations, array accesses with memory
20758 ;; operands might end up in form:
20759 ;;  sall    $2, %eax
20760 ;;  movl    4(%esp), %edx
20761 ;;  addl    %edx, %eax
20762 ;; instead of pre-splitting:
20763 ;;  sall    $2, %eax
20764 ;;  addl    4(%esp), %eax
20765 ;; Turn it into:
20766 ;;  movl    4(%esp), %edx
20767 ;;  leal    (%edx,%eax,4), %eax
20768
20769 (define_peephole2
20770   [(parallel [(set (match_operand 0 "register_operand" "")
20771                    (ashift (match_operand 1 "register_operand" "")
20772                            (match_operand 2 "const_int_operand" "")))
20773                (clobber (reg:CC FLAGS_REG))])
20774    (set (match_operand 3 "register_operand")
20775         (match_operand 4 "x86_64_general_operand" ""))
20776    (parallel [(set (match_operand 5 "register_operand" "")
20777                    (plus (match_operand 6 "register_operand" "")
20778                          (match_operand 7 "register_operand" "")))
20779                    (clobber (reg:CC FLAGS_REG))])]
20780   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20781    /* Validate MODE for lea.  */
20782    && ((!TARGET_PARTIAL_REG_STALL
20783         && (GET_MODE (operands[0]) == QImode
20784             || GET_MODE (operands[0]) == HImode))
20785        || GET_MODE (operands[0]) == SImode
20786        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20787    /* We reorder load and the shift.  */
20788    && !rtx_equal_p (operands[1], operands[3])
20789    && !reg_overlap_mentioned_p (operands[0], operands[4])
20790    /* Last PLUS must consist of operand 0 and 3.  */
20791    && !rtx_equal_p (operands[0], operands[3])
20792    && (rtx_equal_p (operands[3], operands[6])
20793        || rtx_equal_p (operands[3], operands[7]))
20794    && (rtx_equal_p (operands[0], operands[6])
20795        || rtx_equal_p (operands[0], operands[7]))
20796    /* The intermediate operand 0 must die or be same as output.  */
20797    && (rtx_equal_p (operands[0], operands[5])
20798        || peep2_reg_dead_p (3, operands[0]))"
20799   [(set (match_dup 3) (match_dup 4))
20800    (set (match_dup 0) (match_dup 1))]
20801 {
20802   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20803   int scale = 1 << INTVAL (operands[2]);
20804   rtx index = gen_lowpart (Pmode, operands[1]);
20805   rtx base = gen_lowpart (Pmode, operands[3]);
20806   rtx dest = gen_lowpart (mode, operands[5]);
20807
20808   operands[1] = gen_rtx_PLUS (Pmode, base,
20809                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20810   if (mode != Pmode)
20811     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20812   operands[0] = dest;
20813 })
20814 \f
20815 ;; Call-value patterns last so that the wildcard operand does not
20816 ;; disrupt insn-recog's switch tables.
20817
20818 (define_insn "*call_value_pop_0"
20819   [(set (match_operand 0 "" "")
20820         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20821               (match_operand:SI 2 "" "")))
20822    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20823                             (match_operand:SI 3 "immediate_operand" "")))]
20824   "!TARGET_64BIT"
20825 {
20826   if (SIBLING_CALL_P (insn))
20827     return "jmp\t%P1";
20828   else
20829     return "call\t%P1";
20830 }
20831   [(set_attr "type" "callv")])
20832
20833 (define_insn "*call_value_pop_1"
20834   [(set (match_operand 0 "" "")
20835         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20836               (match_operand:SI 2 "" "")))
20837    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20838                             (match_operand:SI 3 "immediate_operand" "i")))]
20839   "!TARGET_64BIT"
20840 {
20841   if (constant_call_address_operand (operands[1], Pmode))
20842     {
20843       if (SIBLING_CALL_P (insn))
20844         return "jmp\t%P1";
20845       else
20846         return "call\t%P1";
20847     }
20848   if (SIBLING_CALL_P (insn))
20849     return "jmp\t%A1";
20850   else
20851     return "call\t%A1";
20852 }
20853   [(set_attr "type" "callv")])
20854
20855 (define_insn "*call_value_0"
20856   [(set (match_operand 0 "" "")
20857         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20858               (match_operand:SI 2 "" "")))]
20859   "!TARGET_64BIT"
20860 {
20861   if (SIBLING_CALL_P (insn))
20862     return "jmp\t%P1";
20863   else
20864     return "call\t%P1";
20865 }
20866   [(set_attr "type" "callv")])
20867
20868 (define_insn "*call_value_0_rex64"
20869   [(set (match_operand 0 "" "")
20870         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20871               (match_operand:DI 2 "const_int_operand" "")))]
20872   "TARGET_64BIT"
20873 {
20874   if (SIBLING_CALL_P (insn))
20875     return "jmp\t%P1";
20876   else
20877     return "call\t%P1";
20878 }
20879   [(set_attr "type" "callv")])
20880
20881 (define_insn "*call_value_1"
20882   [(set (match_operand 0 "" "")
20883         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20884               (match_operand:SI 2 "" "")))]
20885   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20886 {
20887   if (constant_call_address_operand (operands[1], Pmode))
20888     return "call\t%P1";
20889   return "call\t%A1";
20890 }
20891   [(set_attr "type" "callv")])
20892
20893 (define_insn "*sibcall_value_1"
20894   [(set (match_operand 0 "" "")
20895         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20896               (match_operand:SI 2 "" "")))]
20897   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20898 {
20899   if (constant_call_address_operand (operands[1], Pmode))
20900     return "jmp\t%P1";
20901   return "jmp\t%A1";
20902 }
20903   [(set_attr "type" "callv")])
20904
20905 (define_insn "*call_value_1_rex64"
20906   [(set (match_operand 0 "" "")
20907         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20908               (match_operand:DI 2 "" "")))]
20909   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20910 {
20911   if (constant_call_address_operand (operands[1], Pmode))
20912     return "call\t%P1";
20913   return "call\t%A1";
20914 }
20915   [(set_attr "type" "callv")])
20916
20917 (define_insn "*sibcall_value_1_rex64"
20918   [(set (match_operand 0 "" "")
20919         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20920               (match_operand:DI 2 "" "")))]
20921   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20922   "jmp\t%P1"
20923   [(set_attr "type" "callv")])
20924
20925 (define_insn "*sibcall_value_1_rex64_v"
20926   [(set (match_operand 0 "" "")
20927         (call (mem:QI (reg:DI 40))
20928               (match_operand:DI 1 "" "")))]
20929   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20930   "jmp\t*%%r11"
20931   [(set_attr "type" "callv")])
20932 \f
20933 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20934 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20935 ;; caught for use by garbage collectors and the like.  Using an insn that
20936 ;; maps to SIGILL makes it more likely the program will rightfully die.
20937 ;; Keeping with tradition, "6" is in honor of #UD.
20938 (define_insn "trap"
20939   [(trap_if (const_int 1) (const_int 6))]
20940   ""
20941   { return ASM_SHORT "0x0b0f"; }
20942   [(set_attr "length" "2")])
20943
20944 (define_expand "sse_prologue_save"
20945   [(parallel [(set (match_operand:BLK 0 "" "")
20946                    (unspec:BLK [(reg:DI 21)
20947                                 (reg:DI 22)
20948                                 (reg:DI 23)
20949                                 (reg:DI 24)
20950                                 (reg:DI 25)
20951                                 (reg:DI 26)
20952                                 (reg:DI 27)
20953                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20954               (use (match_operand:DI 1 "register_operand" ""))
20955               (use (match_operand:DI 2 "immediate_operand" ""))
20956               (use (label_ref:DI (match_operand 3 "" "")))])]
20957   "TARGET_64BIT"
20958   "")
20959
20960 (define_insn "*sse_prologue_save_insn"
20961   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20962                           (match_operand:DI 4 "const_int_operand" "n")))
20963         (unspec:BLK [(reg:DI 21)
20964                      (reg:DI 22)
20965                      (reg:DI 23)
20966                      (reg:DI 24)
20967                      (reg:DI 25)
20968                      (reg:DI 26)
20969                      (reg:DI 27)
20970                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20971    (use (match_operand:DI 1 "register_operand" "r"))
20972    (use (match_operand:DI 2 "const_int_operand" "i"))
20973    (use (label_ref:DI (match_operand 3 "" "X")))]
20974   "TARGET_64BIT
20975    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20976    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20977   "*
20978 {
20979   int i;
20980   operands[0] = gen_rtx_MEM (Pmode,
20981                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20982   output_asm_insn (\"jmp\\t%A1\", operands);
20983   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20984     {
20985       operands[4] = adjust_address (operands[0], DImode, i*16);
20986       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20987       PUT_MODE (operands[4], TImode);
20988       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20989         output_asm_insn (\"rex\", operands);
20990       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20991     }
20992   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20993                              CODE_LABEL_NUMBER (operands[3]));
20994   RET;
20995 }
20996   "
20997   [(set_attr "type" "other")
20998    (set_attr "length_immediate" "0")
20999    (set_attr "length_address" "0")
21000    (set_attr "length" "135")
21001    (set_attr "memory" "store")
21002    (set_attr "modrm" "0")
21003    (set_attr "mode" "DI")])
21004
21005 (define_expand "prefetch"
21006   [(prefetch (match_operand 0 "address_operand" "")
21007              (match_operand:SI 1 "const_int_operand" "")
21008              (match_operand:SI 2 "const_int_operand" ""))]
21009   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21010 {
21011   int rw = INTVAL (operands[1]);
21012   int locality = INTVAL (operands[2]);
21013
21014   gcc_assert (rw == 0 || rw == 1);
21015   gcc_assert (locality >= 0 && locality <= 3);
21016   gcc_assert (GET_MODE (operands[0]) == Pmode
21017               || GET_MODE (operands[0]) == VOIDmode);
21018
21019   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21020      supported by SSE counterpart or the SSE prefetch is not available
21021      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21022      of locality.  */
21023   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21024     operands[2] = GEN_INT (3);
21025   else
21026     operands[1] = const0_rtx;
21027 })
21028
21029 (define_insn "*prefetch_sse"
21030   [(prefetch (match_operand:SI 0 "address_operand" "p")
21031              (const_int 0)
21032              (match_operand:SI 1 "const_int_operand" ""))]
21033   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21034 {
21035   static const char * const patterns[4] = {
21036    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21037   };
21038
21039   int locality = INTVAL (operands[1]);
21040   gcc_assert (locality >= 0 && locality <= 3);
21041
21042   return patterns[locality];
21043 }
21044   [(set_attr "type" "sse")
21045    (set_attr "memory" "none")])
21046
21047 (define_insn "*prefetch_sse_rex"
21048   [(prefetch (match_operand:DI 0 "address_operand" "p")
21049              (const_int 0)
21050              (match_operand:SI 1 "const_int_operand" ""))]
21051   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21052 {
21053   static const char * const patterns[4] = {
21054    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21055   };
21056
21057   int locality = INTVAL (operands[1]);
21058   gcc_assert (locality >= 0 && locality <= 3);
21059
21060   return patterns[locality];
21061 }
21062   [(set_attr "type" "sse")
21063    (set_attr "memory" "none")])
21064
21065 (define_insn "*prefetch_3dnow"
21066   [(prefetch (match_operand:SI 0 "address_operand" "p")
21067              (match_operand:SI 1 "const_int_operand" "n")
21068              (const_int 3))]
21069   "TARGET_3DNOW && !TARGET_64BIT"
21070 {
21071   if (INTVAL (operands[1]) == 0)
21072     return "prefetch\t%a0";
21073   else
21074     return "prefetchw\t%a0";
21075 }
21076   [(set_attr "type" "mmx")
21077    (set_attr "memory" "none")])
21078
21079 (define_insn "*prefetch_3dnow_rex"
21080   [(prefetch (match_operand:DI 0 "address_operand" "p")
21081              (match_operand:SI 1 "const_int_operand" "n")
21082              (const_int 3))]
21083   "TARGET_3DNOW && TARGET_64BIT"
21084 {
21085   if (INTVAL (operands[1]) == 0)
21086     return "prefetch\t%a0";
21087   else
21088     return "prefetchw\t%a0";
21089 }
21090   [(set_attr "type" "mmx")
21091    (set_attr "memory" "none")])
21092
21093 (define_expand "stack_protect_set"
21094   [(match_operand 0 "memory_operand" "")
21095    (match_operand 1 "memory_operand" "")]
21096   ""
21097 {
21098 #ifdef TARGET_THREAD_SSP_OFFSET
21099   if (TARGET_64BIT)
21100     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21101                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21102   else
21103     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21104                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21105 #else
21106   if (TARGET_64BIT)
21107     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21108   else
21109     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21110 #endif
21111   DONE;
21112 })
21113
21114 (define_insn "stack_protect_set_si"
21115   [(set (match_operand:SI 0 "memory_operand" "=m")
21116         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21117    (set (match_scratch:SI 2 "=&r") (const_int 0))
21118    (clobber (reg:CC FLAGS_REG))]
21119   ""
21120   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21121   [(set_attr "type" "multi")])
21122
21123 (define_insn "stack_protect_set_di"
21124   [(set (match_operand:DI 0 "memory_operand" "=m")
21125         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21126    (set (match_scratch:DI 2 "=&r") (const_int 0))
21127    (clobber (reg:CC FLAGS_REG))]
21128   "TARGET_64BIT"
21129   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21130   [(set_attr "type" "multi")])
21131
21132 (define_insn "stack_tls_protect_set_si"
21133   [(set (match_operand:SI 0 "memory_operand" "=m")
21134         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21135    (set (match_scratch:SI 2 "=&r") (const_int 0))
21136    (clobber (reg:CC FLAGS_REG))]
21137   ""
21138   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21139   [(set_attr "type" "multi")])
21140
21141 (define_insn "stack_tls_protect_set_di"
21142   [(set (match_operand:DI 0 "memory_operand" "=m")
21143         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21144    (set (match_scratch:DI 2 "=&r") (const_int 0))
21145    (clobber (reg:CC FLAGS_REG))]
21146   "TARGET_64BIT"
21147   {
21148      /* The kernel uses a different segment register for performance reasons; a
21149         system call would not have to trash the userspace segment register,
21150         which would be expensive */
21151      if (ix86_cmodel != CM_KERNEL)
21152         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21153      else
21154         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21155   }
21156   [(set_attr "type" "multi")])
21157
21158 (define_expand "stack_protect_test"
21159   [(match_operand 0 "memory_operand" "")
21160    (match_operand 1 "memory_operand" "")
21161    (match_operand 2 "" "")]
21162   ""
21163 {
21164   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21165   ix86_compare_op0 = operands[0];
21166   ix86_compare_op1 = operands[1];
21167   ix86_compare_emitted = flags;
21168
21169 #ifdef TARGET_THREAD_SSP_OFFSET
21170   if (TARGET_64BIT)
21171     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21172                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21173   else
21174     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21175                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21176 #else
21177   if (TARGET_64BIT)
21178     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21179   else
21180     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21181 #endif
21182   emit_jump_insn (gen_beq (operands[2]));
21183   DONE;
21184 })
21185
21186 (define_insn "stack_protect_test_si"
21187   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21188         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21189                      (match_operand:SI 2 "memory_operand" "m")]
21190                     UNSPEC_SP_TEST))
21191    (clobber (match_scratch:SI 3 "=&r"))]
21192   ""
21193   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21194   [(set_attr "type" "multi")])
21195
21196 (define_insn "stack_protect_test_di"
21197   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21198         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21199                      (match_operand:DI 2 "memory_operand" "m")]
21200                     UNSPEC_SP_TEST))
21201    (clobber (match_scratch:DI 3 "=&r"))]
21202   "TARGET_64BIT"
21203   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21204   [(set_attr "type" "multi")])
21205
21206 (define_insn "stack_tls_protect_test_si"
21207   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21208         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21209                      (match_operand:SI 2 "const_int_operand" "i")]
21210                     UNSPEC_SP_TLS_TEST))
21211    (clobber (match_scratch:SI 3 "=r"))]
21212   ""
21213   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21214   [(set_attr "type" "multi")])
21215
21216 (define_insn "stack_tls_protect_test_di"
21217   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21218         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21219                      (match_operand:DI 2 "const_int_operand" "i")]
21220                     UNSPEC_SP_TLS_TEST))
21221    (clobber (match_scratch:DI 3 "=r"))]
21222   "TARGET_64BIT"
21223   {
21224      /* The kernel uses a different segment register for performance reasons; a
21225         system call would not have to trash the userspace segment register,
21226         which would be expensive */
21227      if (ix86_cmodel != CM_KERNEL)
21228         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21229      else
21230         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21231   }
21232   [(set_attr "type" "multi")])
21233
21234 (include "mmx.md")
21235 (include "sse.md")
21236 (include "sync.md")