OSDN Git Service

config/i386/i386.md (UNSPEC_TRUNC_NOOP): New unspec definition.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
71
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76    (UNSPEC_TLSDESC              19)
77
78    ; Other random patterns
79    (UNSPEC_SCAS                 20)
80    (UNSPEC_FNSTSW               21)
81    (UNSPEC_SAHF                 22)
82    (UNSPEC_FSTCW                23)
83    (UNSPEC_ADD_CARRY            24)
84    (UNSPEC_FLDCW                25)
85    (UNSPEC_REP                  26)
86    (UNSPEC_EH_RETURN            27)
87    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
88    (UNSPEC_TRUNC_NOOP           29)
89
90    ; For SSE/MMX support:
91    (UNSPEC_FIX_NOTRUNC          30)
92    (UNSPEC_MASKMOV              31)
93    (UNSPEC_MOVMSK               32)
94    (UNSPEC_MOVNT                33)
95    (UNSPEC_MOVU                 34)
96    (UNSPEC_RCP                  35)
97    (UNSPEC_RSQRT                36)
98    (UNSPEC_SFENCE               37)
99    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
100    (UNSPEC_PFRCP                39)
101    (UNSPEC_PFRCPIT1             40)
102    (UNSPEC_PFRCPIT2             41)
103    (UNSPEC_PFRSQRT              42)
104    (UNSPEC_PFRSQIT1             43)
105    (UNSPEC_MFENCE               44)
106    (UNSPEC_LFENCE               45)
107    (UNSPEC_PSADBW               46)
108    (UNSPEC_LDDQU                47)
109
110    ; Generic math support
111    (UNSPEC_COPYSIGN             50)
112    (UNSPEC_IEEE_MIN             51)     ; not commutative
113    (UNSPEC_IEEE_MAX             52)     ; not commutative
114
115    ; x87 Floating point
116    (UNSPEC_SIN                  60)
117    (UNSPEC_COS                  61)
118    (UNSPEC_FPATAN               62)
119    (UNSPEC_FYL2X                63)
120    (UNSPEC_FYL2XP1              64)
121    (UNSPEC_FRNDINT              65)
122    (UNSPEC_FIST                 66)
123    (UNSPEC_F2XM1                67)
124
125    ; x87 Rounding
126    (UNSPEC_FRNDINT_FLOOR        70)
127    (UNSPEC_FRNDINT_CEIL         71)
128    (UNSPEC_FRNDINT_TRUNC        72)
129    (UNSPEC_FRNDINT_MASK_PM      73)
130    (UNSPEC_FIST_FLOOR           74)
131    (UNSPEC_FIST_CEIL            75)
132
133    ; x87 Double output FP
134    (UNSPEC_SINCOS_COS           80)
135    (UNSPEC_SINCOS_SIN           81)
136    (UNSPEC_TAN_ONE              82)
137    (UNSPEC_TAN_TAN              83)
138    (UNSPEC_XTRACT_FRACT         84)
139    (UNSPEC_XTRACT_EXP           85)
140    (UNSPEC_FSCALE_FRACT         86)
141    (UNSPEC_FSCALE_EXP           87)
142    (UNSPEC_FPREM_F              88)
143    (UNSPEC_FPREM_U              89)
144    (UNSPEC_FPREM1_F             90)
145    (UNSPEC_FPREM1_U             91)
146
147    ; SSP patterns
148    (UNSPEC_SP_SET               100)
149    (UNSPEC_SP_TEST              101)
150    (UNSPEC_SP_TLS_SET           102)
151    (UNSPEC_SP_TLS_TEST          103)
152
153    ; SSSE3
154    (UNSPEC_PSHUFB               120)
155    (UNSPEC_PSIGN                121)
156    (UNSPEC_PALIGNR              122)
157   ])
158
159 (define_constants
160   [(UNSPECV_BLOCKAGE            0)
161    (UNSPECV_STACK_PROBE         1)
162    (UNSPECV_EMMS                2)
163    (UNSPECV_LDMXCSR             3)
164    (UNSPECV_STMXCSR             4)
165    (UNSPECV_FEMMS               5)
166    (UNSPECV_CLFLUSH             6)
167    (UNSPECV_ALIGN               7)
168    (UNSPECV_MONITOR             8)
169    (UNSPECV_MWAIT               9)
170    (UNSPECV_CMPXCHG_1           10)
171    (UNSPECV_CMPXCHG_2           11)
172    (UNSPECV_XCHG                12)
173    (UNSPECV_LOCK                13)
174   ])
175
176 ;; Registers by name.
177 (define_constants
178   [(BP_REG                       6)
179    (SP_REG                       7)
180    (FLAGS_REG                   17)
181    (FPSR_REG                    18)
182    (FPCR_REG                    19)
183    (DIRFLAG_REG                 20)
184    (R11_REG                     41)
185   ])
186
187 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
188 ;; from i386.c.
189
190 ;; In C guard expressions, put expressions which may be compile-time
191 ;; constants first.  This allows for better optimization.  For
192 ;; example, write "TARGET_64BIT && reload_completed", not
193 ;; "reload_completed && TARGET_64BIT".
194
195 \f
196 ;; Processor type.  This attribute must exactly match the processor_type
197 ;; enumeration in i386.h.
198 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
199   (const (symbol_ref "ix86_tune")))
200
201 ;; A basic instruction type.  Refinements due to arguments to be
202 ;; provided in other attributes.
203 (define_attr "type"
204   "other,multi,
205    alu,alu1,negnot,imov,imovx,lea,
206    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
207    icmp,test,ibr,setcc,icmov,
208    push,pop,call,callv,leave,
209    str,cld,
210    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
211    sselog,sselog1,sseiadd,sseishft,sseimul,
212    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
213    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
214   (const_string "other"))
215
216 ;; Main data type used by the insn
217 (define_attr "mode"
218   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
219   (const_string "unknown"))
220
221 ;; The CPU unit operations uses.
222 (define_attr "unit" "integer,i387,sse,mmx,unknown"
223   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
224            (const_string "i387")
225          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
226                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
227            (const_string "sse")
228          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
229            (const_string "mmx")
230          (eq_attr "type" "other")
231            (const_string "unknown")]
232          (const_string "integer")))
233
234 ;; The (bounding maximum) length of an instruction immediate.
235 (define_attr "length_immediate" ""
236   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
237            (const_int 0)
238          (eq_attr "unit" "i387,sse,mmx")
239            (const_int 0)
240          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
241                           imul,icmp,push,pop")
242            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
243          (eq_attr "type" "imov,test")
244            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
245          (eq_attr "type" "call")
246            (if_then_else (match_operand 0 "constant_call_address_operand" "")
247              (const_int 4)
248              (const_int 0))
249          (eq_attr "type" "callv")
250            (if_then_else (match_operand 1 "constant_call_address_operand" "")
251              (const_int 4)
252              (const_int 0))
253          ;; We don't know the size before shorten_branches.  Expect
254          ;; the instruction to fit for better scheduling.
255          (eq_attr "type" "ibr")
256            (const_int 1)
257          ]
258          (symbol_ref "/* Update immediate_length and other attributes! */
259                       gcc_unreachable (),1")))
260
261 ;; The (bounding maximum) length of an instruction address.
262 (define_attr "length_address" ""
263   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
264            (const_int 0)
265          (and (eq_attr "type" "call")
266               (match_operand 0 "constant_call_address_operand" ""))
267              (const_int 0)
268          (and (eq_attr "type" "callv")
269               (match_operand 1 "constant_call_address_operand" ""))
270              (const_int 0)
271          ]
272          (symbol_ref "ix86_attr_length_address_default (insn)")))
273
274 ;; Set when length prefix is used.
275 (define_attr "prefix_data16" ""
276   (if_then_else (ior (eq_attr "mode" "HI")
277                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
278     (const_int 1)
279     (const_int 0)))
280
281 ;; Set when string REP prefix is used.
282 (define_attr "prefix_rep" ""
283   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
284     (const_int 1)
285     (const_int 0)))
286
287 ;; Set when 0f opcode prefix is used.
288 (define_attr "prefix_0f" ""
289   (if_then_else
290     (ior (eq_attr "type" "imovx,setcc,icmov")
291          (eq_attr "unit" "sse,mmx"))
292     (const_int 1)
293     (const_int 0)))
294
295 ;; Set when REX opcode prefix is used.
296 (define_attr "prefix_rex" ""
297   (cond [(and (eq_attr "mode" "DI")
298               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
299            (const_int 1)
300          (and (eq_attr "mode" "QI")
301               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
302                   (const_int 0)))
303            (const_int 1)
304          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
305              (const_int 0))
306            (const_int 1)
307         ]
308         (const_int 0)))
309
310 ;; Set when modrm byte is used.
311 (define_attr "modrm" ""
312   (cond [(eq_attr "type" "str,cld,leave")
313            (const_int 0)
314          (eq_attr "unit" "i387")
315            (const_int 0)
316          (and (eq_attr "type" "incdec")
317               (ior (match_operand:SI 1 "register_operand" "")
318                    (match_operand:HI 1 "register_operand" "")))
319            (const_int 0)
320          (and (eq_attr "type" "push")
321               (not (match_operand 1 "memory_operand" "")))
322            (const_int 0)
323          (and (eq_attr "type" "pop")
324               (not (match_operand 0 "memory_operand" "")))
325            (const_int 0)
326          (and (eq_attr "type" "imov")
327               (ior (and (match_operand 0 "register_operand" "")
328                         (match_operand 1 "immediate_operand" ""))
329                    (ior (and (match_operand 0 "ax_reg_operand" "")
330                              (match_operand 1 "memory_displacement_only_operand" ""))
331                         (and (match_operand 0 "memory_displacement_only_operand" "")
332                              (match_operand 1 "ax_reg_operand" "")))))
333            (const_int 0)
334          (and (eq_attr "type" "call")
335               (match_operand 0 "constant_call_address_operand" ""))
336              (const_int 0)
337          (and (eq_attr "type" "callv")
338               (match_operand 1 "constant_call_address_operand" ""))
339              (const_int 0)
340          ]
341          (const_int 1)))
342
343 ;; The (bounding maximum) length of an instruction in bytes.
344 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
345 ;; Later we may want to split them and compute proper length as for
346 ;; other insns.
347 (define_attr "length" ""
348   (cond [(eq_attr "type" "other,multi,fistp,frndint")
349            (const_int 16)
350          (eq_attr "type" "fcmp")
351            (const_int 4)
352          (eq_attr "unit" "i387")
353            (plus (const_int 2)
354                  (plus (attr "prefix_data16")
355                        (attr "length_address")))]
356          (plus (plus (attr "modrm")
357                      (plus (attr "prefix_0f")
358                            (plus (attr "prefix_rex")
359                                  (const_int 1))))
360                (plus (attr "prefix_rep")
361                      (plus (attr "prefix_data16")
362                            (plus (attr "length_immediate")
363                                  (attr "length_address")))))))
364
365 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
366 ;; `store' if there is a simple memory reference therein, or `unknown'
367 ;; if the instruction is complex.
368
369 (define_attr "memory" "none,load,store,both,unknown"
370   (cond [(eq_attr "type" "other,multi,str")
371            (const_string "unknown")
372          (eq_attr "type" "lea,fcmov,fpspc,cld")
373            (const_string "none")
374          (eq_attr "type" "fistp,leave")
375            (const_string "both")
376          (eq_attr "type" "frndint")
377            (const_string "load")
378          (eq_attr "type" "push")
379            (if_then_else (match_operand 1 "memory_operand" "")
380              (const_string "both")
381              (const_string "store"))
382          (eq_attr "type" "pop")
383            (if_then_else (match_operand 0 "memory_operand" "")
384              (const_string "both")
385              (const_string "load"))
386          (eq_attr "type" "setcc")
387            (if_then_else (match_operand 0 "memory_operand" "")
388              (const_string "store")
389              (const_string "none"))
390          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
391            (if_then_else (ior (match_operand 0 "memory_operand" "")
392                               (match_operand 1 "memory_operand" ""))
393              (const_string "load")
394              (const_string "none"))
395          (eq_attr "type" "ibr")
396            (if_then_else (match_operand 0 "memory_operand" "")
397              (const_string "load")
398              (const_string "none"))
399          (eq_attr "type" "call")
400            (if_then_else (match_operand 0 "constant_call_address_operand" "")
401              (const_string "none")
402              (const_string "load"))
403          (eq_attr "type" "callv")
404            (if_then_else (match_operand 1 "constant_call_address_operand" "")
405              (const_string "none")
406              (const_string "load"))
407          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
408               (match_operand 1 "memory_operand" ""))
409            (const_string "both")
410          (and (match_operand 0 "memory_operand" "")
411               (match_operand 1 "memory_operand" ""))
412            (const_string "both")
413          (match_operand 0 "memory_operand" "")
414            (const_string "store")
415          (match_operand 1 "memory_operand" "")
416            (const_string "load")
417          (and (eq_attr "type"
418                  "!alu1,negnot,ishift1,
419                    imov,imovx,icmp,test,
420                    fmov,fcmp,fsgn,
421                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
422                    mmx,mmxmov,mmxcmp,mmxcvt")
423               (match_operand 2 "memory_operand" ""))
424            (const_string "load")
425          (and (eq_attr "type" "icmov")
426               (match_operand 3 "memory_operand" ""))
427            (const_string "load")
428         ]
429         (const_string "none")))
430
431 ;; Indicates if an instruction has both an immediate and a displacement.
432
433 (define_attr "imm_disp" "false,true,unknown"
434   (cond [(eq_attr "type" "other,multi")
435            (const_string "unknown")
436          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
437               (and (match_operand 0 "memory_displacement_operand" "")
438                    (match_operand 1 "immediate_operand" "")))
439            (const_string "true")
440          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
441               (and (match_operand 0 "memory_displacement_operand" "")
442                    (match_operand 2 "immediate_operand" "")))
443            (const_string "true")
444         ]
445         (const_string "false")))
446
447 ;; Indicates if an FP operation has an integer source.
448
449 (define_attr "fp_int_src" "false,true"
450   (const_string "false"))
451
452 ;; Defines rounding mode of an FP operation.
453
454 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
455   (const_string "any"))
456
457 ;; Describe a user's asm statement.
458 (define_asm_attributes
459   [(set_attr "length" "128")
460    (set_attr "type" "multi")])
461
462 ;; All x87 floating point modes
463 (define_mode_macro X87MODEF [SF DF XF])
464
465 ;; x87 SFmode and DFMode floating point modes
466 (define_mode_macro X87MODEF12 [SF DF])
467
468 ;; All integer modes handled by x87 fisttp operator.
469 (define_mode_macro X87MODEI [HI SI DI])
470
471 ;; All integer modes handled by integer x87 operators.
472 (define_mode_macro X87MODEI12 [HI SI])
473
474 ;; All SSE floating point modes
475 (define_mode_macro SSEMODEF [SF DF])
476
477 ;; All integer modes handled by SSE cvtts?2si* operators.
478 (define_mode_macro SSEMODEI24 [SI DI])
479
480 ;; SSE asm suffix for floating point modes
481 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
482
483 \f
484 ;; Scheduling descriptions
485
486 (include "pentium.md")
487 (include "ppro.md")
488 (include "k6.md")
489 (include "athlon.md")
490 (include "geode.md")
491
492 \f
493 ;; Operand and operator predicates and constraints
494
495 (include "predicates.md")
496 (include "constraints.md")
497
498 \f
499 ;; Compare instructions.
500
501 ;; All compare insns have expanders that save the operands away without
502 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
503 ;; after the cmp) will actually emit the cmpM.
504
505 (define_expand "cmpti"
506   [(set (reg:CC FLAGS_REG)
507         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
508                     (match_operand:TI 1 "x86_64_general_operand" "")))]
509   "TARGET_64BIT"
510 {
511   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
512     operands[0] = force_reg (TImode, operands[0]);
513   ix86_compare_op0 = operands[0];
514   ix86_compare_op1 = operands[1];
515   DONE;
516 })
517
518 (define_expand "cmpdi"
519   [(set (reg:CC FLAGS_REG)
520         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
521                     (match_operand:DI 1 "x86_64_general_operand" "")))]
522   ""
523 {
524   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
525     operands[0] = force_reg (DImode, operands[0]);
526   ix86_compare_op0 = operands[0];
527   ix86_compare_op1 = operands[1];
528   DONE;
529 })
530
531 (define_expand "cmpsi"
532   [(set (reg:CC FLAGS_REG)
533         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
534                     (match_operand:SI 1 "general_operand" "")))]
535   ""
536 {
537   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
538     operands[0] = force_reg (SImode, operands[0]);
539   ix86_compare_op0 = operands[0];
540   ix86_compare_op1 = operands[1];
541   DONE;
542 })
543
544 (define_expand "cmphi"
545   [(set (reg:CC FLAGS_REG)
546         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
547                     (match_operand:HI 1 "general_operand" "")))]
548   ""
549 {
550   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
551     operands[0] = force_reg (HImode, operands[0]);
552   ix86_compare_op0 = operands[0];
553   ix86_compare_op1 = operands[1];
554   DONE;
555 })
556
557 (define_expand "cmpqi"
558   [(set (reg:CC FLAGS_REG)
559         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
560                     (match_operand:QI 1 "general_operand" "")))]
561   "TARGET_QIMODE_MATH"
562 {
563   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
564     operands[0] = force_reg (QImode, operands[0]);
565   ix86_compare_op0 = operands[0];
566   ix86_compare_op1 = operands[1];
567   DONE;
568 })
569
570 (define_insn "cmpdi_ccno_1_rex64"
571   [(set (reg FLAGS_REG)
572         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
573                  (match_operand:DI 1 "const0_operand" "n,n")))]
574   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
575   "@
576    test{q}\t{%0, %0|%0, %0}
577    cmp{q}\t{%1, %0|%0, %1}"
578   [(set_attr "type" "test,icmp")
579    (set_attr "length_immediate" "0,1")
580    (set_attr "mode" "DI")])
581
582 (define_insn "*cmpdi_minus_1_rex64"
583   [(set (reg FLAGS_REG)
584         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
585                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
586                  (const_int 0)))]
587   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
588   "cmp{q}\t{%1, %0|%0, %1}"
589   [(set_attr "type" "icmp")
590    (set_attr "mode" "DI")])
591
592 (define_expand "cmpdi_1_rex64"
593   [(set (reg:CC FLAGS_REG)
594         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
595                     (match_operand:DI 1 "general_operand" "")))]
596   "TARGET_64BIT"
597   "")
598
599 (define_insn "cmpdi_1_insn_rex64"
600   [(set (reg FLAGS_REG)
601         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
602                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
603   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
604   "cmp{q}\t{%1, %0|%0, %1}"
605   [(set_attr "type" "icmp")
606    (set_attr "mode" "DI")])
607
608
609 (define_insn "*cmpsi_ccno_1"
610   [(set (reg FLAGS_REG)
611         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
612                  (match_operand:SI 1 "const0_operand" "n,n")))]
613   "ix86_match_ccmode (insn, CCNOmode)"
614   "@
615    test{l}\t{%0, %0|%0, %0}
616    cmp{l}\t{%1, %0|%0, %1}"
617   [(set_attr "type" "test,icmp")
618    (set_attr "length_immediate" "0,1")
619    (set_attr "mode" "SI")])
620
621 (define_insn "*cmpsi_minus_1"
622   [(set (reg FLAGS_REG)
623         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
624                            (match_operand:SI 1 "general_operand" "ri,mr"))
625                  (const_int 0)))]
626   "ix86_match_ccmode (insn, CCGOCmode)"
627   "cmp{l}\t{%1, %0|%0, %1}"
628   [(set_attr "type" "icmp")
629    (set_attr "mode" "SI")])
630
631 (define_expand "cmpsi_1"
632   [(set (reg:CC FLAGS_REG)
633         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
634                     (match_operand:SI 1 "general_operand" "ri,mr")))]
635   ""
636   "")
637
638 (define_insn "*cmpsi_1_insn"
639   [(set (reg FLAGS_REG)
640         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
641                  (match_operand:SI 1 "general_operand" "ri,mr")))]
642   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
643     && ix86_match_ccmode (insn, CCmode)"
644   "cmp{l}\t{%1, %0|%0, %1}"
645   [(set_attr "type" "icmp")
646    (set_attr "mode" "SI")])
647
648 (define_insn "*cmphi_ccno_1"
649   [(set (reg FLAGS_REG)
650         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
651                  (match_operand:HI 1 "const0_operand" "n,n")))]
652   "ix86_match_ccmode (insn, CCNOmode)"
653   "@
654    test{w}\t{%0, %0|%0, %0}
655    cmp{w}\t{%1, %0|%0, %1}"
656   [(set_attr "type" "test,icmp")
657    (set_attr "length_immediate" "0,1")
658    (set_attr "mode" "HI")])
659
660 (define_insn "*cmphi_minus_1"
661   [(set (reg FLAGS_REG)
662         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
663                            (match_operand:HI 1 "general_operand" "ri,mr"))
664                  (const_int 0)))]
665   "ix86_match_ccmode (insn, CCGOCmode)"
666   "cmp{w}\t{%1, %0|%0, %1}"
667   [(set_attr "type" "icmp")
668    (set_attr "mode" "HI")])
669
670 (define_insn "*cmphi_1"
671   [(set (reg FLAGS_REG)
672         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
673                  (match_operand:HI 1 "general_operand" "ri,mr")))]
674   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
675    && ix86_match_ccmode (insn, CCmode)"
676   "cmp{w}\t{%1, %0|%0, %1}"
677   [(set_attr "type" "icmp")
678    (set_attr "mode" "HI")])
679
680 (define_insn "*cmpqi_ccno_1"
681   [(set (reg FLAGS_REG)
682         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
683                  (match_operand:QI 1 "const0_operand" "n,n")))]
684   "ix86_match_ccmode (insn, CCNOmode)"
685   "@
686    test{b}\t{%0, %0|%0, %0}
687    cmp{b}\t{$0, %0|%0, 0}"
688   [(set_attr "type" "test,icmp")
689    (set_attr "length_immediate" "0,1")
690    (set_attr "mode" "QI")])
691
692 (define_insn "*cmpqi_1"
693   [(set (reg FLAGS_REG)
694         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
695                  (match_operand:QI 1 "general_operand" "qi,mq")))]
696   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
697     && ix86_match_ccmode (insn, CCmode)"
698   "cmp{b}\t{%1, %0|%0, %1}"
699   [(set_attr "type" "icmp")
700    (set_attr "mode" "QI")])
701
702 (define_insn "*cmpqi_minus_1"
703   [(set (reg FLAGS_REG)
704         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
705                            (match_operand:QI 1 "general_operand" "qi,mq"))
706                  (const_int 0)))]
707   "ix86_match_ccmode (insn, CCGOCmode)"
708   "cmp{b}\t{%1, %0|%0, %1}"
709   [(set_attr "type" "icmp")
710    (set_attr "mode" "QI")])
711
712 (define_insn "*cmpqi_ext_1"
713   [(set (reg FLAGS_REG)
714         (compare
715           (match_operand:QI 0 "general_operand" "Qm")
716           (subreg:QI
717             (zero_extract:SI
718               (match_operand 1 "ext_register_operand" "Q")
719               (const_int 8)
720               (const_int 8)) 0)))]
721   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
722   "cmp{b}\t{%h1, %0|%0, %h1}"
723   [(set_attr "type" "icmp")
724    (set_attr "mode" "QI")])
725
726 (define_insn "*cmpqi_ext_1_rex64"
727   [(set (reg FLAGS_REG)
728         (compare
729           (match_operand:QI 0 "register_operand" "Q")
730           (subreg:QI
731             (zero_extract:SI
732               (match_operand 1 "ext_register_operand" "Q")
733               (const_int 8)
734               (const_int 8)) 0)))]
735   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
736   "cmp{b}\t{%h1, %0|%0, %h1}"
737   [(set_attr "type" "icmp")
738    (set_attr "mode" "QI")])
739
740 (define_insn "*cmpqi_ext_2"
741   [(set (reg FLAGS_REG)
742         (compare
743           (subreg:QI
744             (zero_extract:SI
745               (match_operand 0 "ext_register_operand" "Q")
746               (const_int 8)
747               (const_int 8)) 0)
748           (match_operand:QI 1 "const0_operand" "n")))]
749   "ix86_match_ccmode (insn, CCNOmode)"
750   "test{b}\t%h0, %h0"
751   [(set_attr "type" "test")
752    (set_attr "length_immediate" "0")
753    (set_attr "mode" "QI")])
754
755 (define_expand "cmpqi_ext_3"
756   [(set (reg:CC FLAGS_REG)
757         (compare:CC
758           (subreg:QI
759             (zero_extract:SI
760               (match_operand 0 "ext_register_operand" "")
761               (const_int 8)
762               (const_int 8)) 0)
763           (match_operand:QI 1 "general_operand" "")))]
764   ""
765   "")
766
767 (define_insn "cmpqi_ext_3_insn"
768   [(set (reg FLAGS_REG)
769         (compare
770           (subreg:QI
771             (zero_extract:SI
772               (match_operand 0 "ext_register_operand" "Q")
773               (const_int 8)
774               (const_int 8)) 0)
775           (match_operand:QI 1 "general_operand" "Qmn")))]
776   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
777   "cmp{b}\t{%1, %h0|%h0, %1}"
778   [(set_attr "type" "icmp")
779    (set_attr "mode" "QI")])
780
781 (define_insn "cmpqi_ext_3_insn_rex64"
782   [(set (reg FLAGS_REG)
783         (compare
784           (subreg:QI
785             (zero_extract:SI
786               (match_operand 0 "ext_register_operand" "Q")
787               (const_int 8)
788               (const_int 8)) 0)
789           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
790   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
791   "cmp{b}\t{%1, %h0|%h0, %1}"
792   [(set_attr "type" "icmp")
793    (set_attr "mode" "QI")])
794
795 (define_insn "*cmpqi_ext_4"
796   [(set (reg FLAGS_REG)
797         (compare
798           (subreg:QI
799             (zero_extract:SI
800               (match_operand 0 "ext_register_operand" "Q")
801               (const_int 8)
802               (const_int 8)) 0)
803           (subreg:QI
804             (zero_extract:SI
805               (match_operand 1 "ext_register_operand" "Q")
806               (const_int 8)
807               (const_int 8)) 0)))]
808   "ix86_match_ccmode (insn, CCmode)"
809   "cmp{b}\t{%h1, %h0|%h0, %h1}"
810   [(set_attr "type" "icmp")
811    (set_attr "mode" "QI")])
812
813 ;; These implement float point compares.
814 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
815 ;; which would allow mix and match FP modes on the compares.  Which is what
816 ;; the old patterns did, but with many more of them.
817
818 (define_expand "cmpxf"
819   [(set (reg:CC FLAGS_REG)
820         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
821                     (match_operand:XF 1 "nonmemory_operand" "")))]
822   "TARGET_80387"
823 {
824   ix86_compare_op0 = operands[0];
825   ix86_compare_op1 = operands[1];
826   DONE;
827 })
828
829 (define_expand "cmpdf"
830   [(set (reg:CC FLAGS_REG)
831         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
832                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
833   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
834 {
835   ix86_compare_op0 = operands[0];
836   ix86_compare_op1 = operands[1];
837   DONE;
838 })
839
840 (define_expand "cmpsf"
841   [(set (reg:CC FLAGS_REG)
842         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
843                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
844   "TARGET_80387 || TARGET_SSE_MATH"
845 {
846   ix86_compare_op0 = operands[0];
847   ix86_compare_op1 = operands[1];
848   DONE;
849 })
850
851 ;; FP compares, step 1:
852 ;; Set the FP condition codes.
853 ;;
854 ;; CCFPmode     compare with exceptions
855 ;; CCFPUmode    compare with no exceptions
856
857 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
858 ;; used to manage the reg stack popping would not be preserved.
859
860 (define_insn "*cmpfp_0"
861   [(set (match_operand:HI 0 "register_operand" "=a")
862         (unspec:HI
863           [(compare:CCFP
864              (match_operand 1 "register_operand" "f")
865              (match_operand 2 "const0_operand" "X"))]
866         UNSPEC_FNSTSW))]
867   "TARGET_80387
868    && FLOAT_MODE_P (GET_MODE (operands[1]))
869    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
870   "* return output_fp_compare (insn, operands, 0, 0);"
871   [(set_attr "type" "multi")
872    (set_attr "unit" "i387")
873    (set (attr "mode")
874      (cond [(match_operand:SF 1 "" "")
875               (const_string "SF")
876             (match_operand:DF 1 "" "")
877               (const_string "DF")
878            ]
879            (const_string "XF")))])
880
881 (define_insn "*cmpfp_sf"
882   [(set (match_operand:HI 0 "register_operand" "=a")
883         (unspec:HI
884           [(compare:CCFP
885              (match_operand:SF 1 "register_operand" "f")
886              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
887           UNSPEC_FNSTSW))]
888   "TARGET_80387"
889   "* return output_fp_compare (insn, operands, 0, 0);"
890   [(set_attr "type" "multi")
891    (set_attr "unit" "i387")
892    (set_attr "mode" "SF")])
893
894 (define_insn "*cmpfp_df"
895   [(set (match_operand:HI 0 "register_operand" "=a")
896         (unspec:HI
897           [(compare:CCFP
898              (match_operand:DF 1 "register_operand" "f")
899              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
900           UNSPEC_FNSTSW))]
901   "TARGET_80387"
902   "* return output_fp_compare (insn, operands, 0, 0);"
903   [(set_attr "type" "multi")
904    (set_attr "unit" "i387")
905    (set_attr "mode" "DF")])
906
907 (define_insn "*cmpfp_xf"
908   [(set (match_operand:HI 0 "register_operand" "=a")
909         (unspec:HI
910           [(compare:CCFP
911              (match_operand:XF 1 "register_operand" "f")
912              (match_operand:XF 2 "register_operand" "f"))]
913           UNSPEC_FNSTSW))]
914   "TARGET_80387"
915   "* return output_fp_compare (insn, operands, 0, 0);"
916   [(set_attr "type" "multi")
917    (set_attr "unit" "i387")
918    (set_attr "mode" "XF")])
919
920 (define_insn "*cmpfp_u"
921   [(set (match_operand:HI 0 "register_operand" "=a")
922         (unspec:HI
923           [(compare:CCFPU
924              (match_operand 1 "register_operand" "f")
925              (match_operand 2 "register_operand" "f"))]
926           UNSPEC_FNSTSW))]
927   "TARGET_80387
928    && FLOAT_MODE_P (GET_MODE (operands[1]))
929    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
930   "* return output_fp_compare (insn, operands, 0, 1);"
931   [(set_attr "type" "multi")
932    (set_attr "unit" "i387")
933    (set (attr "mode")
934      (cond [(match_operand:SF 1 "" "")
935               (const_string "SF")
936             (match_operand:DF 1 "" "")
937               (const_string "DF")
938            ]
939            (const_string "XF")))])
940
941 (define_insn "*cmpfp_<mode>"
942   [(set (match_operand:HI 0 "register_operand" "=a")
943         (unspec:HI
944           [(compare:CCFP
945              (match_operand 1 "register_operand" "f")
946              (match_operator 3 "float_operator"
947                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
948           UNSPEC_FNSTSW))]
949   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
950    && FLOAT_MODE_P (GET_MODE (operands[1]))
951    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
952   "* return output_fp_compare (insn, operands, 0, 0);"
953   [(set_attr "type" "multi")
954    (set_attr "unit" "i387")
955    (set_attr "fp_int_src" "true")
956    (set_attr "mode" "<MODE>")])
957
958 ;; FP compares, step 2
959 ;; Move the fpsw to ax.
960
961 (define_insn "x86_fnstsw_1"
962   [(set (match_operand:HI 0 "register_operand" "=a")
963         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
964   "TARGET_80387"
965   "fnstsw\t%0"
966   [(set_attr "length" "2")
967    (set_attr "mode" "SI")
968    (set_attr "unit" "i387")])
969
970 ;; FP compares, step 3
971 ;; Get ax into flags, general case.
972
973 (define_insn "x86_sahf_1"
974   [(set (reg:CC FLAGS_REG)
975         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
976   "!TARGET_64BIT"
977   "sahf"
978   [(set_attr "length" "1")
979    (set_attr "athlon_decode" "vector")
980    (set_attr "mode" "SI")])
981
982 ;; Pentium Pro can do steps 1 through 3 in one go.
983
984 (define_insn "*cmpfp_i_mixed"
985   [(set (reg:CCFP FLAGS_REG)
986         (compare:CCFP (match_operand 0 "register_operand" "f,x")
987                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
988   "TARGET_MIX_SSE_I387
989    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991   "* return output_fp_compare (insn, operands, 1, 0);"
992   [(set_attr "type" "fcmp,ssecomi")
993    (set (attr "mode")
994      (if_then_else (match_operand:SF 1 "" "")
995         (const_string "SF")
996         (const_string "DF")))
997    (set_attr "athlon_decode" "vector")])
998
999 (define_insn "*cmpfp_i_sse"
1000   [(set (reg:CCFP FLAGS_REG)
1001         (compare:CCFP (match_operand 0 "register_operand" "x")
1002                       (match_operand 1 "nonimmediate_operand" "xm")))]
1003   "TARGET_SSE_MATH
1004    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1005    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006   "* return output_fp_compare (insn, operands, 1, 0);"
1007   [(set_attr "type" "ssecomi")
1008    (set (attr "mode")
1009      (if_then_else (match_operand:SF 1 "" "")
1010         (const_string "SF")
1011         (const_string "DF")))
1012    (set_attr "athlon_decode" "vector")])
1013
1014 (define_insn "*cmpfp_i_i387"
1015   [(set (reg:CCFP FLAGS_REG)
1016         (compare:CCFP (match_operand 0 "register_operand" "f")
1017                       (match_operand 1 "register_operand" "f")))]
1018   "TARGET_80387 && TARGET_CMOVE
1019    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1020    && FLOAT_MODE_P (GET_MODE (operands[0]))
1021    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022   "* return output_fp_compare (insn, operands, 1, 0);"
1023   [(set_attr "type" "fcmp")
1024    (set (attr "mode")
1025      (cond [(match_operand:SF 1 "" "")
1026               (const_string "SF")
1027             (match_operand:DF 1 "" "")
1028               (const_string "DF")
1029            ]
1030            (const_string "XF")))
1031    (set_attr "athlon_decode" "vector")])
1032
1033 (define_insn "*cmpfp_iu_mixed"
1034   [(set (reg:CCFPU FLAGS_REG)
1035         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1036                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1037   "TARGET_MIX_SSE_I387
1038    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040   "* return output_fp_compare (insn, operands, 1, 1);"
1041   [(set_attr "type" "fcmp,ssecomi")
1042    (set (attr "mode")
1043      (if_then_else (match_operand:SF 1 "" "")
1044         (const_string "SF")
1045         (const_string "DF")))
1046    (set_attr "athlon_decode" "vector")])
1047
1048 (define_insn "*cmpfp_iu_sse"
1049   [(set (reg:CCFPU FLAGS_REG)
1050         (compare:CCFPU (match_operand 0 "register_operand" "x")
1051                        (match_operand 1 "nonimmediate_operand" "xm")))]
1052   "TARGET_SSE_MATH
1053    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1054    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055   "* return output_fp_compare (insn, operands, 1, 1);"
1056   [(set_attr "type" "ssecomi")
1057    (set (attr "mode")
1058      (if_then_else (match_operand:SF 1 "" "")
1059         (const_string "SF")
1060         (const_string "DF")))
1061    (set_attr "athlon_decode" "vector")])
1062
1063 (define_insn "*cmpfp_iu_387"
1064   [(set (reg:CCFPU FLAGS_REG)
1065         (compare:CCFPU (match_operand 0 "register_operand" "f")
1066                        (match_operand 1 "register_operand" "f")))]
1067   "TARGET_80387 && TARGET_CMOVE
1068    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1069    && FLOAT_MODE_P (GET_MODE (operands[0]))
1070    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1071   "* return output_fp_compare (insn, operands, 1, 1);"
1072   [(set_attr "type" "fcmp")
1073    (set (attr "mode")
1074      (cond [(match_operand:SF 1 "" "")
1075               (const_string "SF")
1076             (match_operand:DF 1 "" "")
1077               (const_string "DF")
1078            ]
1079            (const_string "XF")))
1080    (set_attr "athlon_decode" "vector")])
1081 \f
1082 ;; Move instructions.
1083
1084 ;; General case of fullword move.
1085
1086 (define_expand "movsi"
1087   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1088         (match_operand:SI 1 "general_operand" ""))]
1089   ""
1090   "ix86_expand_move (SImode, operands); DONE;")
1091
1092 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1093 ;; general_operand.
1094 ;;
1095 ;; %%% We don't use a post-inc memory reference because x86 is not a
1096 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1097 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1098 ;; targets without our curiosities, and it is just as easy to represent
1099 ;; this differently.
1100
1101 (define_insn "*pushsi2"
1102   [(set (match_operand:SI 0 "push_operand" "=<")
1103         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1104   "!TARGET_64BIT"
1105   "push{l}\t%1"
1106   [(set_attr "type" "push")
1107    (set_attr "mode" "SI")])
1108
1109 ;; For 64BIT abi we always round up to 8 bytes.
1110 (define_insn "*pushsi2_rex64"
1111   [(set (match_operand:SI 0 "push_operand" "=X")
1112         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1113   "TARGET_64BIT"
1114   "push{q}\t%q1"
1115   [(set_attr "type" "push")
1116    (set_attr "mode" "SI")])
1117
1118 (define_insn "*pushsi2_prologue"
1119   [(set (match_operand:SI 0 "push_operand" "=<")
1120         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1121    (clobber (mem:BLK (scratch)))]
1122   "!TARGET_64BIT"
1123   "push{l}\t%1"
1124   [(set_attr "type" "push")
1125    (set_attr "mode" "SI")])
1126
1127 (define_insn "*popsi1_epilogue"
1128   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1129         (mem:SI (reg:SI SP_REG)))
1130    (set (reg:SI SP_REG)
1131         (plus:SI (reg:SI SP_REG) (const_int 4)))
1132    (clobber (mem:BLK (scratch)))]
1133   "!TARGET_64BIT"
1134   "pop{l}\t%0"
1135   [(set_attr "type" "pop")
1136    (set_attr "mode" "SI")])
1137
1138 (define_insn "popsi1"
1139   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1140         (mem:SI (reg:SI SP_REG)))
1141    (set (reg:SI SP_REG)
1142         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1143   "!TARGET_64BIT"
1144   "pop{l}\t%0"
1145   [(set_attr "type" "pop")
1146    (set_attr "mode" "SI")])
1147
1148 (define_insn "*movsi_xor"
1149   [(set (match_operand:SI 0 "register_operand" "=r")
1150         (match_operand:SI 1 "const0_operand" "i"))
1151    (clobber (reg:CC FLAGS_REG))]
1152   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1153   "xor{l}\t{%0, %0|%0, %0}"
1154   [(set_attr "type" "alu1")
1155    (set_attr "mode" "SI")
1156    (set_attr "length_immediate" "0")])
1157
1158 (define_insn "*movsi_or"
1159   [(set (match_operand:SI 0 "register_operand" "=r")
1160         (match_operand:SI 1 "immediate_operand" "i"))
1161    (clobber (reg:CC FLAGS_REG))]
1162   "reload_completed
1163    && operands[1] == constm1_rtx
1164    && (TARGET_PENTIUM || optimize_size)"
1165 {
1166   operands[1] = constm1_rtx;
1167   return "or{l}\t{%1, %0|%0, %1}";
1168 }
1169   [(set_attr "type" "alu1")
1170    (set_attr "mode" "SI")
1171    (set_attr "length_immediate" "1")])
1172
1173 (define_insn "*movsi_1"
1174   [(set (match_operand:SI 0 "nonimmediate_operand"
1175                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1176         (match_operand:SI 1 "general_operand"
1177                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1178   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1179 {
1180   switch (get_attr_type (insn))
1181     {
1182     case TYPE_SSELOG1:
1183       if (get_attr_mode (insn) == MODE_TI)
1184         return "pxor\t%0, %0";
1185       return "xorps\t%0, %0";
1186
1187     case TYPE_SSEMOV:
1188       switch (get_attr_mode (insn))
1189         {
1190         case MODE_TI:
1191           return "movdqa\t{%1, %0|%0, %1}";
1192         case MODE_V4SF:
1193           return "movaps\t{%1, %0|%0, %1}";
1194         case MODE_SI:
1195           return "movd\t{%1, %0|%0, %1}";
1196         case MODE_SF:
1197           return "movss\t{%1, %0|%0, %1}";
1198         default:
1199           gcc_unreachable ();
1200         }
1201
1202     case TYPE_MMXADD:
1203       return "pxor\t%0, %0";
1204
1205     case TYPE_MMXMOV:
1206       if (get_attr_mode (insn) == MODE_DI)
1207         return "movq\t{%1, %0|%0, %1}";
1208       return "movd\t{%1, %0|%0, %1}";
1209
1210     case TYPE_LEA:
1211       return "lea{l}\t{%1, %0|%0, %1}";
1212
1213     default:
1214       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1215       return "mov{l}\t{%1, %0|%0, %1}";
1216     }
1217 }
1218   [(set (attr "type")
1219      (cond [(eq_attr "alternative" "2")
1220               (const_string "mmxadd")
1221             (eq_attr "alternative" "3,4,5")
1222               (const_string "mmxmov")
1223             (eq_attr "alternative" "6")
1224               (const_string "sselog1")
1225             (eq_attr "alternative" "7,8,9,10,11")
1226               (const_string "ssemov")
1227             (match_operand:DI 1 "pic_32bit_operand" "")
1228               (const_string "lea")
1229            ]
1230            (const_string "imov")))
1231    (set (attr "mode")
1232      (cond [(eq_attr "alternative" "2,3")
1233               (const_string "DI")
1234             (eq_attr "alternative" "6,7")
1235               (if_then_else
1236                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1237                 (const_string "V4SF")
1238                 (const_string "TI"))
1239             (and (eq_attr "alternative" "8,9,10,11")
1240                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1241               (const_string "SF")
1242            ]
1243            (const_string "SI")))])
1244
1245 ;; Stores and loads of ax to arbitrary constant address.
1246 ;; We fake an second form of instruction to force reload to load address
1247 ;; into register when rax is not available
1248 (define_insn "*movabssi_1_rex64"
1249   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1250         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1251   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1252   "@
1253    movabs{l}\t{%1, %P0|%P0, %1}
1254    mov{l}\t{%1, %a0|%a0, %1}"
1255   [(set_attr "type" "imov")
1256    (set_attr "modrm" "0,*")
1257    (set_attr "length_address" "8,0")
1258    (set_attr "length_immediate" "0,*")
1259    (set_attr "memory" "store")
1260    (set_attr "mode" "SI")])
1261
1262 (define_insn "*movabssi_2_rex64"
1263   [(set (match_operand:SI 0 "register_operand" "=a,r")
1264         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1265   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1266   "@
1267    movabs{l}\t{%P1, %0|%0, %P1}
1268    mov{l}\t{%a1, %0|%0, %a1}"
1269   [(set_attr "type" "imov")
1270    (set_attr "modrm" "0,*")
1271    (set_attr "length_address" "8,0")
1272    (set_attr "length_immediate" "0")
1273    (set_attr "memory" "load")
1274    (set_attr "mode" "SI")])
1275
1276 (define_insn "*swapsi"
1277   [(set (match_operand:SI 0 "register_operand" "+r")
1278         (match_operand:SI 1 "register_operand" "+r"))
1279    (set (match_dup 1)
1280         (match_dup 0))]
1281   ""
1282   "xchg{l}\t%1, %0"
1283   [(set_attr "type" "imov")
1284    (set_attr "mode" "SI")
1285    (set_attr "pent_pair" "np")
1286    (set_attr "athlon_decode" "vector")])
1287
1288 (define_expand "movhi"
1289   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1290         (match_operand:HI 1 "general_operand" ""))]
1291   ""
1292   "ix86_expand_move (HImode, operands); DONE;")
1293
1294 (define_insn "*pushhi2"
1295   [(set (match_operand:HI 0 "push_operand" "=X")
1296         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1297   "!TARGET_64BIT"
1298   "push{l}\t%k1"
1299   [(set_attr "type" "push")
1300    (set_attr "mode" "SI")])
1301
1302 ;; For 64BIT abi we always round up to 8 bytes.
1303 (define_insn "*pushhi2_rex64"
1304   [(set (match_operand:HI 0 "push_operand" "=X")
1305         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1306   "TARGET_64BIT"
1307   "push{q}\t%q1"
1308   [(set_attr "type" "push")
1309    (set_attr "mode" "DI")])
1310
1311 (define_insn "*movhi_1"
1312   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1313         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1314   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1315 {
1316   switch (get_attr_type (insn))
1317     {
1318     case TYPE_IMOVX:
1319       /* movzwl is faster than movw on p2 due to partial word stalls,
1320          though not as fast as an aligned movl.  */
1321       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1322     default:
1323       if (get_attr_mode (insn) == MODE_SI)
1324         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1325       else
1326         return "mov{w}\t{%1, %0|%0, %1}";
1327     }
1328 }
1329   [(set (attr "type")
1330      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1331               (const_string "imov")
1332             (and (eq_attr "alternative" "0")
1333                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1334                           (const_int 0))
1335                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1336                           (const_int 0))))
1337               (const_string "imov")
1338             (and (eq_attr "alternative" "1,2")
1339                  (match_operand:HI 1 "aligned_operand" ""))
1340               (const_string "imov")
1341             (and (ne (symbol_ref "TARGET_MOVX")
1342                      (const_int 0))
1343                  (eq_attr "alternative" "0,2"))
1344               (const_string "imovx")
1345            ]
1346            (const_string "imov")))
1347     (set (attr "mode")
1348       (cond [(eq_attr "type" "imovx")
1349                (const_string "SI")
1350              (and (eq_attr "alternative" "1,2")
1351                   (match_operand:HI 1 "aligned_operand" ""))
1352                (const_string "SI")
1353              (and (eq_attr "alternative" "0")
1354                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1355                            (const_int 0))
1356                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1357                            (const_int 0))))
1358                (const_string "SI")
1359             ]
1360             (const_string "HI")))])
1361
1362 ;; Stores and loads of ax to arbitrary constant address.
1363 ;; We fake an second form of instruction to force reload to load address
1364 ;; into register when rax is not available
1365 (define_insn "*movabshi_1_rex64"
1366   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1367         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1368   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1369   "@
1370    movabs{w}\t{%1, %P0|%P0, %1}
1371    mov{w}\t{%1, %a0|%a0, %1}"
1372   [(set_attr "type" "imov")
1373    (set_attr "modrm" "0,*")
1374    (set_attr "length_address" "8,0")
1375    (set_attr "length_immediate" "0,*")
1376    (set_attr "memory" "store")
1377    (set_attr "mode" "HI")])
1378
1379 (define_insn "*movabshi_2_rex64"
1380   [(set (match_operand:HI 0 "register_operand" "=a,r")
1381         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1382   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1383   "@
1384    movabs{w}\t{%P1, %0|%0, %P1}
1385    mov{w}\t{%a1, %0|%0, %a1}"
1386   [(set_attr "type" "imov")
1387    (set_attr "modrm" "0,*")
1388    (set_attr "length_address" "8,0")
1389    (set_attr "length_immediate" "0")
1390    (set_attr "memory" "load")
1391    (set_attr "mode" "HI")])
1392
1393 (define_insn "*swaphi_1"
1394   [(set (match_operand:HI 0 "register_operand" "+r")
1395         (match_operand:HI 1 "register_operand" "+r"))
1396    (set (match_dup 1)
1397         (match_dup 0))]
1398   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1399   "xchg{l}\t%k1, %k0"
1400   [(set_attr "type" "imov")
1401    (set_attr "mode" "SI")
1402    (set_attr "pent_pair" "np")
1403    (set_attr "athlon_decode" "vector")])
1404
1405 (define_insn "*swaphi_2"
1406   [(set (match_operand:HI 0 "register_operand" "+r")
1407         (match_operand:HI 1 "register_operand" "+r"))
1408    (set (match_dup 1)
1409         (match_dup 0))]
1410   "TARGET_PARTIAL_REG_STALL"
1411   "xchg{w}\t%1, %0"
1412   [(set_attr "type" "imov")
1413    (set_attr "mode" "HI")
1414    (set_attr "pent_pair" "np")
1415    (set_attr "athlon_decode" "vector")])
1416
1417 (define_expand "movstricthi"
1418   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1419         (match_operand:HI 1 "general_operand" ""))]
1420   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1421 {
1422   /* Don't generate memory->memory moves, go through a register */
1423   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1424     operands[1] = force_reg (HImode, operands[1]);
1425 })
1426
1427 (define_insn "*movstricthi_1"
1428   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1429         (match_operand:HI 1 "general_operand" "rn,m"))]
1430   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1431    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1432   "mov{w}\t{%1, %0|%0, %1}"
1433   [(set_attr "type" "imov")
1434    (set_attr "mode" "HI")])
1435
1436 (define_insn "*movstricthi_xor"
1437   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1438         (match_operand:HI 1 "const0_operand" "i"))
1439    (clobber (reg:CC FLAGS_REG))]
1440   "reload_completed
1441    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1442   "xor{w}\t{%0, %0|%0, %0}"
1443   [(set_attr "type" "alu1")
1444    (set_attr "mode" "HI")
1445    (set_attr "length_immediate" "0")])
1446
1447 (define_expand "movqi"
1448   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1449         (match_operand:QI 1 "general_operand" ""))]
1450   ""
1451   "ix86_expand_move (QImode, operands); DONE;")
1452
1453 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1454 ;; "push a byte".  But actually we use pushl, which has the effect
1455 ;; of rounding the amount pushed up to a word.
1456
1457 (define_insn "*pushqi2"
1458   [(set (match_operand:QI 0 "push_operand" "=X")
1459         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1460   "!TARGET_64BIT"
1461   "push{l}\t%k1"
1462   [(set_attr "type" "push")
1463    (set_attr "mode" "SI")])
1464
1465 ;; For 64BIT abi we always round up to 8 bytes.
1466 (define_insn "*pushqi2_rex64"
1467   [(set (match_operand:QI 0 "push_operand" "=X")
1468         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1469   "TARGET_64BIT"
1470   "push{q}\t%q1"
1471   [(set_attr "type" "push")
1472    (set_attr "mode" "DI")])
1473
1474 ;; Situation is quite tricky about when to choose full sized (SImode) move
1475 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1476 ;; partial register dependency machines (such as AMD Athlon), where QImode
1477 ;; moves issue extra dependency and for partial register stalls machines
1478 ;; that don't use QImode patterns (and QImode move cause stall on the next
1479 ;; instruction).
1480 ;;
1481 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1482 ;; register stall machines with, where we use QImode instructions, since
1483 ;; partial register stall can be caused there.  Then we use movzx.
1484 (define_insn "*movqi_1"
1485   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1486         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1487   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1488 {
1489   switch (get_attr_type (insn))
1490     {
1491     case TYPE_IMOVX:
1492       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1493       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1494     default:
1495       if (get_attr_mode (insn) == MODE_SI)
1496         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1497       else
1498         return "mov{b}\t{%1, %0|%0, %1}";
1499     }
1500 }
1501   [(set (attr "type")
1502      (cond [(and (eq_attr "alternative" "5")
1503                  (not (match_operand:QI 1 "aligned_operand" "")))
1504               (const_string "imovx")
1505             (ne (symbol_ref "optimize_size") (const_int 0))
1506               (const_string "imov")
1507             (and (eq_attr "alternative" "3")
1508                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1509                           (const_int 0))
1510                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1511                           (const_int 0))))
1512               (const_string "imov")
1513             (eq_attr "alternative" "3,5")
1514               (const_string "imovx")
1515             (and (ne (symbol_ref "TARGET_MOVX")
1516                      (const_int 0))
1517                  (eq_attr "alternative" "2"))
1518               (const_string "imovx")
1519            ]
1520            (const_string "imov")))
1521    (set (attr "mode")
1522       (cond [(eq_attr "alternative" "3,4,5")
1523                (const_string "SI")
1524              (eq_attr "alternative" "6")
1525                (const_string "QI")
1526              (eq_attr "type" "imovx")
1527                (const_string "SI")
1528              (and (eq_attr "type" "imov")
1529                   (and (eq_attr "alternative" "0,1")
1530                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1531                                 (const_int 0))
1532                             (and (eq (symbol_ref "optimize_size")
1533                                      (const_int 0))
1534                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1535                                      (const_int 0))))))
1536                (const_string "SI")
1537              ;; Avoid partial register stalls when not using QImode arithmetic
1538              (and (eq_attr "type" "imov")
1539                   (and (eq_attr "alternative" "0,1")
1540                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1541                                 (const_int 0))
1542                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1543                                 (const_int 0)))))
1544                (const_string "SI")
1545            ]
1546            (const_string "QI")))])
1547
1548 (define_expand "reload_outqi"
1549   [(parallel [(match_operand:QI 0 "" "=m")
1550               (match_operand:QI 1 "register_operand" "r")
1551               (match_operand:QI 2 "register_operand" "=&q")])]
1552   ""
1553 {
1554   rtx op0, op1, op2;
1555   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1556
1557   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1558   if (! q_regs_operand (op1, QImode))
1559     {
1560       emit_insn (gen_movqi (op2, op1));
1561       op1 = op2;
1562     }
1563   emit_insn (gen_movqi (op0, op1));
1564   DONE;
1565 })
1566
1567 (define_insn "*swapqi_1"
1568   [(set (match_operand:QI 0 "register_operand" "+r")
1569         (match_operand:QI 1 "register_operand" "+r"))
1570    (set (match_dup 1)
1571         (match_dup 0))]
1572   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1573   "xchg{l}\t%k1, %k0"
1574   [(set_attr "type" "imov")
1575    (set_attr "mode" "SI")
1576    (set_attr "pent_pair" "np")
1577    (set_attr "athlon_decode" "vector")])
1578
1579 (define_insn "*swapqi_2"
1580   [(set (match_operand:QI 0 "register_operand" "+q")
1581         (match_operand:QI 1 "register_operand" "+q"))
1582    (set (match_dup 1)
1583         (match_dup 0))]
1584   "TARGET_PARTIAL_REG_STALL"
1585   "xchg{b}\t%1, %0"
1586   [(set_attr "type" "imov")
1587    (set_attr "mode" "QI")
1588    (set_attr "pent_pair" "np")
1589    (set_attr "athlon_decode" "vector")])
1590
1591 (define_expand "movstrictqi"
1592   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1593         (match_operand:QI 1 "general_operand" ""))]
1594   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1595 {
1596   /* Don't generate memory->memory moves, go through a register.  */
1597   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1598     operands[1] = force_reg (QImode, operands[1]);
1599 })
1600
1601 (define_insn "*movstrictqi_1"
1602   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1603         (match_operand:QI 1 "general_operand" "*qn,m"))]
1604   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1605    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1606   "mov{b}\t{%1, %0|%0, %1}"
1607   [(set_attr "type" "imov")
1608    (set_attr "mode" "QI")])
1609
1610 (define_insn "*movstrictqi_xor"
1611   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1612         (match_operand:QI 1 "const0_operand" "i"))
1613    (clobber (reg:CC FLAGS_REG))]
1614   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1615   "xor{b}\t{%0, %0|%0, %0}"
1616   [(set_attr "type" "alu1")
1617    (set_attr "mode" "QI")
1618    (set_attr "length_immediate" "0")])
1619
1620 (define_insn "*movsi_extv_1"
1621   [(set (match_operand:SI 0 "register_operand" "=R")
1622         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1623                          (const_int 8)
1624                          (const_int 8)))]
1625   ""
1626   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1627   [(set_attr "type" "imovx")
1628    (set_attr "mode" "SI")])
1629
1630 (define_insn "*movhi_extv_1"
1631   [(set (match_operand:HI 0 "register_operand" "=R")
1632         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1633                          (const_int 8)
1634                          (const_int 8)))]
1635   ""
1636   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1637   [(set_attr "type" "imovx")
1638    (set_attr "mode" "SI")])
1639
1640 (define_insn "*movqi_extv_1"
1641   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1642         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1643                          (const_int 8)
1644                          (const_int 8)))]
1645   "!TARGET_64BIT"
1646 {
1647   switch (get_attr_type (insn))
1648     {
1649     case TYPE_IMOVX:
1650       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1651     default:
1652       return "mov{b}\t{%h1, %0|%0, %h1}";
1653     }
1654 }
1655   [(set (attr "type")
1656      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1657                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1658                              (ne (symbol_ref "TARGET_MOVX")
1659                                  (const_int 0))))
1660         (const_string "imovx")
1661         (const_string "imov")))
1662    (set (attr "mode")
1663      (if_then_else (eq_attr "type" "imovx")
1664         (const_string "SI")
1665         (const_string "QI")))])
1666
1667 (define_insn "*movqi_extv_1_rex64"
1668   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1669         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1670                          (const_int 8)
1671                          (const_int 8)))]
1672   "TARGET_64BIT"
1673 {
1674   switch (get_attr_type (insn))
1675     {
1676     case TYPE_IMOVX:
1677       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1678     default:
1679       return "mov{b}\t{%h1, %0|%0, %h1}";
1680     }
1681 }
1682   [(set (attr "type")
1683      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1684                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1685                              (ne (symbol_ref "TARGET_MOVX")
1686                                  (const_int 0))))
1687         (const_string "imovx")
1688         (const_string "imov")))
1689    (set (attr "mode")
1690      (if_then_else (eq_attr "type" "imovx")
1691         (const_string "SI")
1692         (const_string "QI")))])
1693
1694 ;; Stores and loads of ax to arbitrary constant address.
1695 ;; We fake an second form of instruction to force reload to load address
1696 ;; into register when rax is not available
1697 (define_insn "*movabsqi_1_rex64"
1698   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1699         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1700   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1701   "@
1702    movabs{b}\t{%1, %P0|%P0, %1}
1703    mov{b}\t{%1, %a0|%a0, %1}"
1704   [(set_attr "type" "imov")
1705    (set_attr "modrm" "0,*")
1706    (set_attr "length_address" "8,0")
1707    (set_attr "length_immediate" "0,*")
1708    (set_attr "memory" "store")
1709    (set_attr "mode" "QI")])
1710
1711 (define_insn "*movabsqi_2_rex64"
1712   [(set (match_operand:QI 0 "register_operand" "=a,r")
1713         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1714   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1715   "@
1716    movabs{b}\t{%P1, %0|%0, %P1}
1717    mov{b}\t{%a1, %0|%0, %a1}"
1718   [(set_attr "type" "imov")
1719    (set_attr "modrm" "0,*")
1720    (set_attr "length_address" "8,0")
1721    (set_attr "length_immediate" "0")
1722    (set_attr "memory" "load")
1723    (set_attr "mode" "QI")])
1724
1725 (define_insn "*movdi_extzv_1"
1726   [(set (match_operand:DI 0 "register_operand" "=R")
1727         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1728                          (const_int 8)
1729                          (const_int 8)))]
1730   "TARGET_64BIT"
1731   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1732   [(set_attr "type" "imovx")
1733    (set_attr "mode" "DI")])
1734
1735 (define_insn "*movsi_extzv_1"
1736   [(set (match_operand:SI 0 "register_operand" "=R")
1737         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1738                          (const_int 8)
1739                          (const_int 8)))]
1740   ""
1741   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1742   [(set_attr "type" "imovx")
1743    (set_attr "mode" "SI")])
1744
1745 (define_insn "*movqi_extzv_2"
1746   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1747         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1748                                     (const_int 8)
1749                                     (const_int 8)) 0))]
1750   "!TARGET_64BIT"
1751 {
1752   switch (get_attr_type (insn))
1753     {
1754     case TYPE_IMOVX:
1755       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1756     default:
1757       return "mov{b}\t{%h1, %0|%0, %h1}";
1758     }
1759 }
1760   [(set (attr "type")
1761      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1762                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1763                              (ne (symbol_ref "TARGET_MOVX")
1764                                  (const_int 0))))
1765         (const_string "imovx")
1766         (const_string "imov")))
1767    (set (attr "mode")
1768      (if_then_else (eq_attr "type" "imovx")
1769         (const_string "SI")
1770         (const_string "QI")))])
1771
1772 (define_insn "*movqi_extzv_2_rex64"
1773   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1774         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1775                                     (const_int 8)
1776                                     (const_int 8)) 0))]
1777   "TARGET_64BIT"
1778 {
1779   switch (get_attr_type (insn))
1780     {
1781     case TYPE_IMOVX:
1782       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1783     default:
1784       return "mov{b}\t{%h1, %0|%0, %h1}";
1785     }
1786 }
1787   [(set (attr "type")
1788      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1789                         (ne (symbol_ref "TARGET_MOVX")
1790                             (const_int 0)))
1791         (const_string "imovx")
1792         (const_string "imov")))
1793    (set (attr "mode")
1794      (if_then_else (eq_attr "type" "imovx")
1795         (const_string "SI")
1796         (const_string "QI")))])
1797
1798 (define_insn "movsi_insv_1"
1799   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1800                          (const_int 8)
1801                          (const_int 8))
1802         (match_operand:SI 1 "general_operand" "Qmn"))]
1803   "!TARGET_64BIT"
1804   "mov{b}\t{%b1, %h0|%h0, %b1}"
1805   [(set_attr "type" "imov")
1806    (set_attr "mode" "QI")])
1807
1808 (define_insn "movdi_insv_1_rex64"
1809   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1810                          (const_int 8)
1811                          (const_int 8))
1812         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1813   "TARGET_64BIT"
1814   "mov{b}\t{%b1, %h0|%h0, %b1}"
1815   [(set_attr "type" "imov")
1816    (set_attr "mode" "QI")])
1817
1818 (define_insn "*movqi_insv_2"
1819   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1820                          (const_int 8)
1821                          (const_int 8))
1822         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1823                      (const_int 8)))]
1824   ""
1825   "mov{b}\t{%h1, %h0|%h0, %h1}"
1826   [(set_attr "type" "imov")
1827    (set_attr "mode" "QI")])
1828
1829 (define_expand "movdi"
1830   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1831         (match_operand:DI 1 "general_operand" ""))]
1832   ""
1833   "ix86_expand_move (DImode, operands); DONE;")
1834
1835 (define_insn "*pushdi"
1836   [(set (match_operand:DI 0 "push_operand" "=<")
1837         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1838   "!TARGET_64BIT"
1839   "#")
1840
1841 (define_insn "*pushdi2_rex64"
1842   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1843         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1844   "TARGET_64BIT"
1845   "@
1846    push{q}\t%1
1847    #"
1848   [(set_attr "type" "push,multi")
1849    (set_attr "mode" "DI")])
1850
1851 ;; Convert impossible pushes of immediate to existing instructions.
1852 ;; First try to get scratch register and go through it.  In case this
1853 ;; fails, push sign extended lower part first and then overwrite
1854 ;; upper part by 32bit move.
1855 (define_peephole2
1856   [(match_scratch:DI 2 "r")
1857    (set (match_operand:DI 0 "push_operand" "")
1858         (match_operand:DI 1 "immediate_operand" ""))]
1859   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1860    && !x86_64_immediate_operand (operands[1], DImode)"
1861   [(set (match_dup 2) (match_dup 1))
1862    (set (match_dup 0) (match_dup 2))]
1863   "")
1864
1865 ;; We need to define this as both peepholer and splitter for case
1866 ;; peephole2 pass is not run.
1867 ;; "&& 1" is needed to keep it from matching the previous pattern.
1868 (define_peephole2
1869   [(set (match_operand:DI 0 "push_operand" "")
1870         (match_operand:DI 1 "immediate_operand" ""))]
1871   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1872    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1873   [(set (match_dup 0) (match_dup 1))
1874    (set (match_dup 2) (match_dup 3))]
1875   "split_di (operands + 1, 1, operands + 2, operands + 3);
1876    operands[1] = gen_lowpart (DImode, operands[2]);
1877    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1878                                                     GEN_INT (4)));
1879   ")
1880
1881 (define_split
1882   [(set (match_operand:DI 0 "push_operand" "")
1883         (match_operand:DI 1 "immediate_operand" ""))]
1884   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1885                     ? flow2_completed : reload_completed)
1886    && !symbolic_operand (operands[1], DImode)
1887    && !x86_64_immediate_operand (operands[1], DImode)"
1888   [(set (match_dup 0) (match_dup 1))
1889    (set (match_dup 2) (match_dup 3))]
1890   "split_di (operands + 1, 1, operands + 2, operands + 3);
1891    operands[1] = gen_lowpart (DImode, operands[2]);
1892    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1893                                                     GEN_INT (4)));
1894   ")
1895
1896 (define_insn "*pushdi2_prologue_rex64"
1897   [(set (match_operand:DI 0 "push_operand" "=<")
1898         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1899    (clobber (mem:BLK (scratch)))]
1900   "TARGET_64BIT"
1901   "push{q}\t%1"
1902   [(set_attr "type" "push")
1903    (set_attr "mode" "DI")])
1904
1905 (define_insn "*popdi1_epilogue_rex64"
1906   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1907         (mem:DI (reg:DI SP_REG)))
1908    (set (reg:DI SP_REG)
1909         (plus:DI (reg:DI SP_REG) (const_int 8)))
1910    (clobber (mem:BLK (scratch)))]
1911   "TARGET_64BIT"
1912   "pop{q}\t%0"
1913   [(set_attr "type" "pop")
1914    (set_attr "mode" "DI")])
1915
1916 (define_insn "popdi1"
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   "TARGET_64BIT"
1922   "pop{q}\t%0"
1923   [(set_attr "type" "pop")
1924    (set_attr "mode" "DI")])
1925
1926 (define_insn "*movdi_xor_rex64"
1927   [(set (match_operand:DI 0 "register_operand" "=r")
1928         (match_operand:DI 1 "const0_operand" "i"))
1929    (clobber (reg:CC FLAGS_REG))]
1930   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1931    && reload_completed"
1932   "xor{l}\t{%k0, %k0|%k0, %k0}"
1933   [(set_attr "type" "alu1")
1934    (set_attr "mode" "SI")
1935    (set_attr "length_immediate" "0")])
1936
1937 (define_insn "*movdi_or_rex64"
1938   [(set (match_operand:DI 0 "register_operand" "=r")
1939         (match_operand:DI 1 "const_int_operand" "i"))
1940    (clobber (reg:CC FLAGS_REG))]
1941   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1942    && reload_completed
1943    && operands[1] == constm1_rtx"
1944 {
1945   operands[1] = constm1_rtx;
1946   return "or{q}\t{%1, %0|%0, %1}";
1947 }
1948   [(set_attr "type" "alu1")
1949    (set_attr "mode" "DI")
1950    (set_attr "length_immediate" "1")])
1951
1952 (define_insn "*movdi_2"
1953   [(set (match_operand:DI 0 "nonimmediate_operand"
1954                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1955         (match_operand:DI 1 "general_operand"
1956                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1957   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1958   "@
1959    #
1960    #
1961    pxor\t%0, %0
1962    movq\t{%1, %0|%0, %1}
1963    movq\t{%1, %0|%0, %1}
1964    pxor\t%0, %0
1965    movq\t{%1, %0|%0, %1}
1966    movdqa\t{%1, %0|%0, %1}
1967    movq\t{%1, %0|%0, %1}
1968    xorps\t%0, %0
1969    movlps\t{%1, %0|%0, %1}
1970    movaps\t{%1, %0|%0, %1}
1971    movlps\t{%1, %0|%0, %1}"
1972   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1973    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1974
1975 (define_split
1976   [(set (match_operand:DI 0 "push_operand" "")
1977         (match_operand:DI 1 "general_operand" ""))]
1978   "!TARGET_64BIT && reload_completed
1979    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1980   [(const_int 0)]
1981   "ix86_split_long_move (operands); DONE;")
1982
1983 ;; %%% This multiword shite has got to go.
1984 (define_split
1985   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1986         (match_operand:DI 1 "general_operand" ""))]
1987   "!TARGET_64BIT && reload_completed
1988    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1989    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1990   [(const_int 0)]
1991   "ix86_split_long_move (operands); DONE;")
1992
1993 (define_insn "*movdi_1_rex64"
1994   [(set (match_operand:DI 0 "nonimmediate_operand"
1995                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1996         (match_operand:DI 1 "general_operand"
1997                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1998   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1999 {
2000   switch (get_attr_type (insn))
2001     {
2002     case TYPE_SSECVT:
2003       if (which_alternative == 13)
2004         return "movq2dq\t{%1, %0|%0, %1}";
2005       else
2006         return "movdq2q\t{%1, %0|%0, %1}";
2007     case TYPE_SSEMOV:
2008       if (get_attr_mode (insn) == MODE_TI)
2009           return "movdqa\t{%1, %0|%0, %1}";
2010       /* FALLTHRU */
2011     case TYPE_MMXMOV:
2012       /* Moves from and into integer register is done using movd opcode with
2013          REX prefix.  */
2014       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2015           return "movd\t{%1, %0|%0, %1}";
2016       return "movq\t{%1, %0|%0, %1}";
2017     case TYPE_SSELOG1:
2018     case TYPE_MMXADD:
2019       return "pxor\t%0, %0";
2020     case TYPE_MULTI:
2021       return "#";
2022     case TYPE_LEA:
2023       return "lea{q}\t{%a1, %0|%0, %a1}";
2024     default:
2025       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2026       if (get_attr_mode (insn) == MODE_SI)
2027         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2028       else if (which_alternative == 2)
2029         return "movabs{q}\t{%1, %0|%0, %1}";
2030       else
2031         return "mov{q}\t{%1, %0|%0, %1}";
2032     }
2033 }
2034   [(set (attr "type")
2035      (cond [(eq_attr "alternative" "5")
2036               (const_string "mmxadd")
2037             (eq_attr "alternative" "6,7,8")
2038               (const_string "mmxmov")
2039             (eq_attr "alternative" "9")
2040               (const_string "sselog1")
2041             (eq_attr "alternative" "10,11,12")
2042               (const_string "ssemov")
2043             (eq_attr "alternative" "13,14")
2044               (const_string "ssecvt")
2045             (eq_attr "alternative" "4")
2046               (const_string "multi")
2047             (match_operand:DI 1 "pic_32bit_operand" "")
2048               (const_string "lea")
2049            ]
2050            (const_string "imov")))
2051    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2052    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2053    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2054
2055 ;; Stores and loads of ax to arbitrary constant address.
2056 ;; We fake an second form of instruction to force reload to load address
2057 ;; into register when rax is not available
2058 (define_insn "*movabsdi_1_rex64"
2059   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2060         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2061   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2062   "@
2063    movabs{q}\t{%1, %P0|%P0, %1}
2064    mov{q}\t{%1, %a0|%a0, %1}"
2065   [(set_attr "type" "imov")
2066    (set_attr "modrm" "0,*")
2067    (set_attr "length_address" "8,0")
2068    (set_attr "length_immediate" "0,*")
2069    (set_attr "memory" "store")
2070    (set_attr "mode" "DI")])
2071
2072 (define_insn "*movabsdi_2_rex64"
2073   [(set (match_operand:DI 0 "register_operand" "=a,r")
2074         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2075   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2076   "@
2077    movabs{q}\t{%P1, %0|%0, %P1}
2078    mov{q}\t{%a1, %0|%0, %a1}"
2079   [(set_attr "type" "imov")
2080    (set_attr "modrm" "0,*")
2081    (set_attr "length_address" "8,0")
2082    (set_attr "length_immediate" "0")
2083    (set_attr "memory" "load")
2084    (set_attr "mode" "DI")])
2085
2086 ;; Convert impossible stores of immediate to existing instructions.
2087 ;; First try to get scratch register and go through it.  In case this
2088 ;; fails, move by 32bit parts.
2089 (define_peephole2
2090   [(match_scratch:DI 2 "r")
2091    (set (match_operand:DI 0 "memory_operand" "")
2092         (match_operand:DI 1 "immediate_operand" ""))]
2093   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2094    && !x86_64_immediate_operand (operands[1], DImode)"
2095   [(set (match_dup 2) (match_dup 1))
2096    (set (match_dup 0) (match_dup 2))]
2097   "")
2098
2099 ;; We need to define this as both peepholer and splitter for case
2100 ;; peephole2 pass is not run.
2101 ;; "&& 1" is needed to keep it from matching the previous pattern.
2102 (define_peephole2
2103   [(set (match_operand:DI 0 "memory_operand" "")
2104         (match_operand:DI 1 "immediate_operand" ""))]
2105   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2106    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2107   [(set (match_dup 2) (match_dup 3))
2108    (set (match_dup 4) (match_dup 5))]
2109   "split_di (operands, 2, operands + 2, operands + 4);")
2110
2111 (define_split
2112   [(set (match_operand:DI 0 "memory_operand" "")
2113         (match_operand:DI 1 "immediate_operand" ""))]
2114   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2115                     ? flow2_completed : reload_completed)
2116    && !symbolic_operand (operands[1], DImode)
2117    && !x86_64_immediate_operand (operands[1], DImode)"
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_insn "*swapdi_rex64"
2123   [(set (match_operand:DI 0 "register_operand" "+r")
2124         (match_operand:DI 1 "register_operand" "+r"))
2125    (set (match_dup 1)
2126         (match_dup 0))]
2127   "TARGET_64BIT"
2128   "xchg{q}\t%1, %0"
2129   [(set_attr "type" "imov")
2130    (set_attr "mode" "DI")
2131    (set_attr "pent_pair" "np")
2132    (set_attr "athlon_decode" "vector")])
2133
2134 (define_expand "movti"
2135   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2136         (match_operand:TI 1 "nonimmediate_operand" ""))]
2137   "TARGET_SSE || TARGET_64BIT"
2138 {
2139   if (TARGET_64BIT)
2140     ix86_expand_move (TImode, operands);
2141   else
2142     ix86_expand_vector_move (TImode, operands);
2143   DONE;
2144 })
2145
2146 (define_insn "*movti_internal"
2147   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2148         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2149   "TARGET_SSE && !TARGET_64BIT
2150    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2151 {
2152   switch (which_alternative)
2153     {
2154     case 0:
2155       if (get_attr_mode (insn) == MODE_V4SF)
2156         return "xorps\t%0, %0";
2157       else
2158         return "pxor\t%0, %0";
2159     case 1:
2160     case 2:
2161       if (get_attr_mode (insn) == MODE_V4SF)
2162         return "movaps\t{%1, %0|%0, %1}";
2163       else
2164         return "movdqa\t{%1, %0|%0, %1}";
2165     default:
2166       gcc_unreachable ();
2167     }
2168 }
2169   [(set_attr "type" "sselog1,ssemov,ssemov")
2170    (set (attr "mode")
2171         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2172                     (ne (symbol_ref "optimize_size") (const_int 0)))
2173                  (const_string "V4SF")
2174                (and (eq_attr "alternative" "2")
2175                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2176                         (const_int 0)))
2177                  (const_string "V4SF")]
2178               (const_string "TI")))])
2179
2180 (define_insn "*movti_rex64"
2181   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2182         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2183   "TARGET_64BIT
2184    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2185 {
2186   switch (which_alternative)
2187     {
2188     case 0:
2189     case 1:
2190       return "#";
2191     case 2:
2192       if (get_attr_mode (insn) == MODE_V4SF)
2193         return "xorps\t%0, %0";
2194       else
2195         return "pxor\t%0, %0";
2196     case 3:
2197     case 4:
2198       if (get_attr_mode (insn) == MODE_V4SF)
2199         return "movaps\t{%1, %0|%0, %1}";
2200       else
2201         return "movdqa\t{%1, %0|%0, %1}";
2202     default:
2203       gcc_unreachable ();
2204     }
2205 }
2206   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2207    (set (attr "mode")
2208         (cond [(eq_attr "alternative" "2,3")
2209                  (if_then_else
2210                    (ne (symbol_ref "optimize_size")
2211                        (const_int 0))
2212                    (const_string "V4SF")
2213                    (const_string "TI"))
2214                (eq_attr "alternative" "4")
2215                  (if_then_else
2216                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2217                             (const_int 0))
2218                         (ne (symbol_ref "optimize_size")
2219                             (const_int 0)))
2220                    (const_string "V4SF")
2221                    (const_string "TI"))]
2222                (const_string "DI")))])
2223
2224 (define_split
2225   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2226         (match_operand:TI 1 "general_operand" ""))]
2227   "reload_completed && !SSE_REG_P (operands[0])
2228    && !SSE_REG_P (operands[1])"
2229   [(const_int 0)]
2230   "ix86_split_long_move (operands); DONE;")
2231
2232 (define_expand "movsf"
2233   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2234         (match_operand:SF 1 "general_operand" ""))]
2235   ""
2236   "ix86_expand_move (SFmode, operands); DONE;")
2237
2238 (define_insn "*pushsf"
2239   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2240         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2241   "!TARGET_64BIT"
2242 {
2243   /* Anything else should be already split before reg-stack.  */
2244   gcc_assert (which_alternative == 1);
2245   return "push{l}\t%1";
2246 }
2247   [(set_attr "type" "multi,push,multi")
2248    (set_attr "unit" "i387,*,*")
2249    (set_attr "mode" "SF,SI,SF")])
2250
2251 (define_insn "*pushsf_rex64"
2252   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2253         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2254   "TARGET_64BIT"
2255 {
2256   /* Anything else should be already split before reg-stack.  */
2257   gcc_assert (which_alternative == 1);
2258   return "push{q}\t%q1";
2259 }
2260   [(set_attr "type" "multi,push,multi")
2261    (set_attr "unit" "i387,*,*")
2262    (set_attr "mode" "SF,DI,SF")])
2263
2264 (define_split
2265   [(set (match_operand:SF 0 "push_operand" "")
2266         (match_operand:SF 1 "memory_operand" ""))]
2267   "reload_completed
2268    && GET_CODE (operands[1]) == MEM
2269    && constant_pool_reference_p (operands[1])"
2270   [(set (match_dup 0)
2271         (match_dup 1))]
2272   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2273
2274
2275 ;; %%% Kill this when call knows how to work this out.
2276 (define_split
2277   [(set (match_operand:SF 0 "push_operand" "")
2278         (match_operand:SF 1 "any_fp_register_operand" ""))]
2279   "!TARGET_64BIT"
2280   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2281    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2282
2283 (define_split
2284   [(set (match_operand:SF 0 "push_operand" "")
2285         (match_operand:SF 1 "any_fp_register_operand" ""))]
2286   "TARGET_64BIT"
2287   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2288    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2289
2290 (define_insn "*movsf_1"
2291   [(set (match_operand:SF 0 "nonimmediate_operand"
2292           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2293         (match_operand:SF 1 "general_operand"
2294           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2295   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2296    && (reload_in_progress || reload_completed
2297        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2298        || GET_CODE (operands[1]) != CONST_DOUBLE
2299        || memory_operand (operands[0], SFmode))"
2300 {
2301   switch (which_alternative)
2302     {
2303     case 0:
2304       return output_387_reg_move (insn, operands);
2305
2306     case 1:
2307       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2308         return "fstp%z0\t%y0";
2309       else
2310         return "fst%z0\t%y0";
2311
2312     case 2:
2313       return standard_80387_constant_opcode (operands[1]);
2314
2315     case 3:
2316     case 4:
2317       return "mov{l}\t{%1, %0|%0, %1}";
2318     case 5:
2319       if (get_attr_mode (insn) == MODE_TI)
2320         return "pxor\t%0, %0";
2321       else
2322         return "xorps\t%0, %0";
2323     case 6:
2324       if (get_attr_mode (insn) == MODE_V4SF)
2325         return "movaps\t{%1, %0|%0, %1}";
2326       else
2327         return "movss\t{%1, %0|%0, %1}";
2328     case 7:
2329     case 8:
2330       return "movss\t{%1, %0|%0, %1}";
2331
2332     case 9:
2333     case 10:
2334       return "movd\t{%1, %0|%0, %1}";
2335
2336     case 11:
2337       return "movq\t{%1, %0|%0, %1}";
2338
2339     default:
2340       gcc_unreachable ();
2341     }
2342 }
2343   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2344    (set (attr "mode")
2345         (cond [(eq_attr "alternative" "3,4,9,10")
2346                  (const_string "SI")
2347                (eq_attr "alternative" "5")
2348                  (if_then_else
2349                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2350                                  (const_int 0))
2351                              (ne (symbol_ref "TARGET_SSE2")
2352                                  (const_int 0)))
2353                         (eq (symbol_ref "optimize_size")
2354                             (const_int 0)))
2355                    (const_string "TI")
2356                    (const_string "V4SF"))
2357                /* For architectures resolving dependencies on
2358                   whole SSE registers use APS move to break dependency
2359                   chains, otherwise use short move to avoid extra work.
2360
2361                   Do the same for architectures resolving dependencies on
2362                   the parts.  While in DF mode it is better to always handle
2363                   just register parts, the SF mode is different due to lack
2364                   of instructions to load just part of the register.  It is
2365                   better to maintain the whole registers in single format
2366                   to avoid problems on using packed logical operations.  */
2367                (eq_attr "alternative" "6")
2368                  (if_then_else
2369                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2370                             (const_int 0))
2371                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2372                             (const_int 0)))
2373                    (const_string "V4SF")
2374                    (const_string "SF"))
2375                (eq_attr "alternative" "11")
2376                  (const_string "DI")]
2377                (const_string "SF")))])
2378
2379 (define_insn "*swapsf"
2380   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2381         (match_operand:SF 1 "fp_register_operand" "+f"))
2382    (set (match_dup 1)
2383         (match_dup 0))]
2384   "reload_completed || TARGET_80387"
2385 {
2386   if (STACK_TOP_P (operands[0]))
2387     return "fxch\t%1";
2388   else
2389     return "fxch\t%0";
2390 }
2391   [(set_attr "type" "fxch")
2392    (set_attr "mode" "SF")])
2393
2394 (define_expand "movdf"
2395   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2396         (match_operand:DF 1 "general_operand" ""))]
2397   ""
2398   "ix86_expand_move (DFmode, operands); DONE;")
2399
2400 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2401 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2402 ;; On the average, pushdf using integers can be still shorter.  Allow this
2403 ;; pattern for optimize_size too.
2404
2405 (define_insn "*pushdf_nointeger"
2406   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2407         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2408   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2409 {
2410   /* This insn should be already split before reg-stack.  */
2411   gcc_unreachable ();
2412 }
2413   [(set_attr "type" "multi")
2414    (set_attr "unit" "i387,*,*,*")
2415    (set_attr "mode" "DF,SI,SI,DF")])
2416
2417 (define_insn "*pushdf_integer"
2418   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2419         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,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,DF")])
2428
2429 ;; %%% Kill this when call knows how to work this out.
2430 (define_split
2431   [(set (match_operand:DF 0 "push_operand" "")
2432         (match_operand:DF 1 "any_fp_register_operand" ""))]
2433   "!TARGET_64BIT && reload_completed"
2434   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2435    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2436   "")
2437
2438 (define_split
2439   [(set (match_operand:DF 0 "push_operand" "")
2440         (match_operand:DF 1 "any_fp_register_operand" ""))]
2441   "TARGET_64BIT && reload_completed"
2442   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2443    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2444   "")
2445
2446 (define_split
2447   [(set (match_operand:DF 0 "push_operand" "")
2448         (match_operand:DF 1 "general_operand" ""))]
2449   "reload_completed"
2450   [(const_int 0)]
2451   "ix86_split_long_move (operands); DONE;")
2452
2453 ;; Moving is usually shorter when only FP registers are used. This separate
2454 ;; movdf pattern avoids the use of integer registers for FP operations
2455 ;; when optimizing for size.
2456
2457 (define_insn "*movdf_nointeger"
2458   [(set (match_operand:DF 0 "nonimmediate_operand"
2459                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2460         (match_operand:DF 1 "general_operand"
2461                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2462   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2463    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2464    && (reload_in_progress || reload_completed
2465        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2466        || GET_CODE (operands[1]) != CONST_DOUBLE
2467        || memory_operand (operands[0], DFmode))"
2468 {
2469   switch (which_alternative)
2470     {
2471     case 0:
2472       return output_387_reg_move (insn, operands);
2473
2474     case 1:
2475       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2476         return "fstp%z0\t%y0";
2477       else
2478         return "fst%z0\t%y0";
2479
2480     case 2:
2481       return standard_80387_constant_opcode (operands[1]);
2482
2483     case 3:
2484     case 4:
2485       return "#";
2486     case 5:
2487       switch (get_attr_mode (insn))
2488         {
2489         case MODE_V4SF:
2490           return "xorps\t%0, %0";
2491         case MODE_V2DF:
2492           return "xorpd\t%0, %0";
2493         case MODE_TI:
2494           return "pxor\t%0, %0";
2495         default:
2496           gcc_unreachable ();
2497         }
2498     case 6:
2499     case 7:
2500     case 8:
2501       switch (get_attr_mode (insn))
2502         {
2503         case MODE_V4SF:
2504           return "movaps\t{%1, %0|%0, %1}";
2505         case MODE_V2DF:
2506           return "movapd\t{%1, %0|%0, %1}";
2507         case MODE_TI:
2508           return "movdqa\t{%1, %0|%0, %1}";
2509         case MODE_DI:
2510           return "movq\t{%1, %0|%0, %1}";
2511         case MODE_DF:
2512           return "movsd\t{%1, %0|%0, %1}";
2513         case MODE_V1DF:
2514           return "movlpd\t{%1, %0|%0, %1}";
2515         case MODE_V2SF:
2516           return "movlps\t{%1, %0|%0, %1}";
2517         default:
2518           gcc_unreachable ();
2519         }
2520
2521     default:
2522       gcc_unreachable ();
2523     }
2524 }
2525   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2526    (set (attr "mode")
2527         (cond [(eq_attr "alternative" "0,1,2")
2528                  (const_string "DF")
2529                (eq_attr "alternative" "3,4")
2530                  (const_string "SI")
2531
2532                /* For SSE1, we have many fewer alternatives.  */
2533                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2534                  (cond [(eq_attr "alternative" "5,6")
2535                           (const_string "V4SF")
2536                        ]
2537                    (const_string "V2SF"))
2538
2539                /* xorps is one byte shorter.  */
2540                (eq_attr "alternative" "5")
2541                  (cond [(ne (symbol_ref "optimize_size")
2542                             (const_int 0))
2543                           (const_string "V4SF")
2544                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2545                             (const_int 0))
2546                           (const_string "TI")
2547                        ]
2548                        (const_string "V2DF"))
2549
2550                /* For architectures resolving dependencies on
2551                   whole SSE registers use APD move to break dependency
2552                   chains, otherwise use short move to avoid extra work.
2553
2554                   movaps encodes one byte shorter.  */
2555                (eq_attr "alternative" "6")
2556                  (cond
2557                    [(ne (symbol_ref "optimize_size")
2558                         (const_int 0))
2559                       (const_string "V4SF")
2560                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2561                         (const_int 0))
2562                       (const_string "V2DF")
2563                    ]
2564                    (const_string "DF"))
2565                /* For architectures resolving dependencies on register
2566                   parts we may avoid extra work to zero out upper part
2567                   of register.  */
2568                (eq_attr "alternative" "7")
2569                  (if_then_else
2570                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2571                        (const_int 0))
2572                    (const_string "V1DF")
2573                    (const_string "DF"))
2574               ]
2575               (const_string "DF")))])
2576
2577 (define_insn "*movdf_integer"
2578   [(set (match_operand:DF 0 "nonimmediate_operand"
2579                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2580         (match_operand:DF 1 "general_operand"
2581                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2582   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2583    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2584    && (reload_in_progress || reload_completed
2585        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2586        || GET_CODE (operands[1]) != CONST_DOUBLE
2587        || memory_operand (operands[0], DFmode))"
2588 {
2589   switch (which_alternative)
2590     {
2591     case 0:
2592       return output_387_reg_move (insn, operands);
2593
2594     case 1:
2595       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2596         return "fstp%z0\t%y0";
2597       else
2598         return "fst%z0\t%y0";
2599
2600     case 2:
2601       return standard_80387_constant_opcode (operands[1]);
2602
2603     case 3:
2604     case 4:
2605       return "#";
2606
2607     case 5:
2608       switch (get_attr_mode (insn))
2609         {
2610         case MODE_V4SF:
2611           return "xorps\t%0, %0";
2612         case MODE_V2DF:
2613           return "xorpd\t%0, %0";
2614         case MODE_TI:
2615           return "pxor\t%0, %0";
2616         default:
2617           gcc_unreachable ();
2618         }
2619     case 6:
2620     case 7:
2621     case 8:
2622       switch (get_attr_mode (insn))
2623         {
2624         case MODE_V4SF:
2625           return "movaps\t{%1, %0|%0, %1}";
2626         case MODE_V2DF:
2627           return "movapd\t{%1, %0|%0, %1}";
2628         case MODE_TI:
2629           return "movdqa\t{%1, %0|%0, %1}";
2630         case MODE_DI:
2631           return "movq\t{%1, %0|%0, %1}";
2632         case MODE_DF:
2633           return "movsd\t{%1, %0|%0, %1}";
2634         case MODE_V1DF:
2635           return "movlpd\t{%1, %0|%0, %1}";
2636         case MODE_V2SF:
2637           return "movlps\t{%1, %0|%0, %1}";
2638         default:
2639           gcc_unreachable ();
2640         }
2641
2642     default:
2643       gcc_unreachable();
2644     }
2645 }
2646   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2647    (set (attr "mode")
2648         (cond [(eq_attr "alternative" "0,1,2")
2649                  (const_string "DF")
2650                (eq_attr "alternative" "3,4")
2651                  (const_string "SI")
2652
2653                /* For SSE1, we have many fewer alternatives.  */
2654                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2655                  (cond [(eq_attr "alternative" "5,6")
2656                           (const_string "V4SF")
2657                        ]
2658                    (const_string "V2SF"))
2659
2660                /* xorps is one byte shorter.  */
2661                (eq_attr "alternative" "5")
2662                  (cond [(ne (symbol_ref "optimize_size")
2663                             (const_int 0))
2664                           (const_string "V4SF")
2665                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2666                             (const_int 0))
2667                           (const_string "TI")
2668                        ]
2669                        (const_string "V2DF"))
2670
2671                /* For architectures resolving dependencies on
2672                   whole SSE registers use APD move to break dependency
2673                   chains, otherwise use short move to avoid extra work.
2674
2675                   movaps encodes one byte shorter.  */
2676                (eq_attr "alternative" "6")
2677                  (cond
2678                    [(ne (symbol_ref "optimize_size")
2679                         (const_int 0))
2680                       (const_string "V4SF")
2681                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2682                         (const_int 0))
2683                       (const_string "V2DF")
2684                    ]
2685                    (const_string "DF"))
2686                /* For architectures resolving dependencies on register
2687                   parts we may avoid extra work to zero out upper part
2688                   of register.  */
2689                (eq_attr "alternative" "7")
2690                  (if_then_else
2691                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2692                        (const_int 0))
2693                    (const_string "V1DF")
2694                    (const_string "DF"))
2695               ]
2696               (const_string "DF")))])
2697
2698 (define_split
2699   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2700         (match_operand:DF 1 "general_operand" ""))]
2701   "reload_completed
2702    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2703    && ! (ANY_FP_REG_P (operands[0]) ||
2704          (GET_CODE (operands[0]) == SUBREG
2705           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2706    && ! (ANY_FP_REG_P (operands[1]) ||
2707          (GET_CODE (operands[1]) == SUBREG
2708           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2709   [(const_int 0)]
2710   "ix86_split_long_move (operands); DONE;")
2711
2712 (define_insn "*swapdf"
2713   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2714         (match_operand:DF 1 "fp_register_operand" "+f"))
2715    (set (match_dup 1)
2716         (match_dup 0))]
2717   "reload_completed || TARGET_80387"
2718 {
2719   if (STACK_TOP_P (operands[0]))
2720     return "fxch\t%1";
2721   else
2722     return "fxch\t%0";
2723 }
2724   [(set_attr "type" "fxch")
2725    (set_attr "mode" "DF")])
2726
2727 (define_expand "movxf"
2728   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2729         (match_operand:XF 1 "general_operand" ""))]
2730   ""
2731   "ix86_expand_move (XFmode, operands); DONE;")
2732
2733 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2734 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2735 ;; Pushing using integer instructions is longer except for constants
2736 ;; and direct memory references.
2737 ;; (assuming that any given constant is pushed only once, but this ought to be
2738 ;;  handled elsewhere).
2739
2740 (define_insn "*pushxf_nointeger"
2741   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2742         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2743   "optimize_size"
2744 {
2745   /* This insn should be already split before reg-stack.  */
2746   gcc_unreachable ();
2747 }
2748   [(set_attr "type" "multi")
2749    (set_attr "unit" "i387,*,*")
2750    (set_attr "mode" "XF,SI,SI")])
2751
2752 (define_insn "*pushxf_integer"
2753   [(set (match_operand:XF 0 "push_operand" "=<,<")
2754         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
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")])
2763
2764 (define_split
2765   [(set (match_operand 0 "push_operand" "")
2766         (match_operand 1 "general_operand" ""))]
2767   "reload_completed
2768    && (GET_MODE (operands[0]) == XFmode
2769        || GET_MODE (operands[0]) == DFmode)
2770    && !ANY_FP_REG_P (operands[1])"
2771   [(const_int 0)]
2772   "ix86_split_long_move (operands); DONE;")
2773
2774 (define_split
2775   [(set (match_operand:XF 0 "push_operand" "")
2776         (match_operand:XF 1 "any_fp_register_operand" ""))]
2777   "!TARGET_64BIT"
2778   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2779    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2780   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2781
2782 (define_split
2783   [(set (match_operand:XF 0 "push_operand" "")
2784         (match_operand:XF 1 "any_fp_register_operand" ""))]
2785   "TARGET_64BIT"
2786   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2787    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2788   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2789
2790 ;; Do not use integer registers when optimizing for size
2791 (define_insn "*movxf_nointeger"
2792   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2793         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2794   "optimize_size
2795    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2796    && (reload_in_progress || reload_completed
2797        || standard_80387_constant_p (operands[1])
2798        || GET_CODE (operands[1]) != CONST_DOUBLE
2799        || memory_operand (operands[0], XFmode))"
2800 {
2801   switch (which_alternative)
2802     {
2803     case 0:
2804       return output_387_reg_move (insn, operands);
2805
2806     case 1:
2807       /* There is no non-popping store to memory for XFmode.  So if
2808          we need one, follow the store with a load.  */
2809       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2810         return "fstp%z0\t%y0\;fld%z0\t%y0";
2811       else
2812         return "fstp%z0\t%y0";
2813
2814     case 2:
2815       return standard_80387_constant_opcode (operands[1]);
2816
2817     case 3: case 4:
2818       return "#";
2819     default:
2820       gcc_unreachable ();
2821     }
2822 }
2823   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2824    (set_attr "mode" "XF,XF,XF,SI,SI")])
2825
2826 (define_insn "*movxf_integer"
2827   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2828         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2829   "!optimize_size
2830    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2831    && (reload_in_progress || reload_completed
2832        || standard_80387_constant_p (operands[1])
2833        || GET_CODE (operands[1]) != CONST_DOUBLE
2834        || memory_operand (operands[0], XFmode))"
2835 {
2836   switch (which_alternative)
2837     {
2838     case 0:
2839       return output_387_reg_move (insn, operands);
2840
2841     case 1:
2842       /* There is no non-popping store to memory for XFmode.  So if
2843          we need one, follow the store with a load.  */
2844       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2845         return "fstp%z0\t%y0\;fld%z0\t%y0";
2846       else
2847         return "fstp%z0\t%y0";
2848
2849     case 2:
2850       return standard_80387_constant_opcode (operands[1]);
2851
2852     case 3: case 4:
2853       return "#";
2854
2855     default:
2856       gcc_unreachable ();
2857     }
2858 }
2859   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2860    (set_attr "mode" "XF,XF,XF,SI,SI")])
2861
2862 (define_split
2863   [(set (match_operand 0 "nonimmediate_operand" "")
2864         (match_operand 1 "general_operand" ""))]
2865   "reload_completed
2866    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2867    && GET_MODE (operands[0]) == XFmode
2868    && ! (ANY_FP_REG_P (operands[0]) ||
2869          (GET_CODE (operands[0]) == SUBREG
2870           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2871    && ! (ANY_FP_REG_P (operands[1]) ||
2872          (GET_CODE (operands[1]) == SUBREG
2873           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2874   [(const_int 0)]
2875   "ix86_split_long_move (operands); DONE;")
2876
2877 (define_split
2878   [(set (match_operand 0 "register_operand" "")
2879         (match_operand 1 "memory_operand" ""))]
2880   "reload_completed
2881    && GET_CODE (operands[1]) == MEM
2882    && (GET_MODE (operands[0]) == XFmode
2883        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2884    && constant_pool_reference_p (operands[1])"
2885   [(set (match_dup 0) (match_dup 1))]
2886 {
2887   rtx c = avoid_constant_pool_reference (operands[1]);
2888   rtx r = operands[0];
2889
2890   if (GET_CODE (r) == SUBREG)
2891     r = SUBREG_REG (r);
2892
2893   if (SSE_REG_P (r))
2894     {
2895       if (!standard_sse_constant_p (c))
2896         FAIL;
2897     }
2898   else if (FP_REG_P (r))
2899     {
2900       if (!standard_80387_constant_p (c))
2901         FAIL;
2902     }
2903   else if (MMX_REG_P (r))
2904     FAIL;
2905
2906   operands[1] = c;
2907 })
2908
2909 (define_insn "swapxf"
2910   [(set (match_operand:XF 0 "register_operand" "+f")
2911         (match_operand:XF 1 "register_operand" "+f"))
2912    (set (match_dup 1)
2913         (match_dup 0))]
2914   "TARGET_80387"
2915 {
2916   if (STACK_TOP_P (operands[0]))
2917     return "fxch\t%1";
2918   else
2919     return "fxch\t%0";
2920 }
2921   [(set_attr "type" "fxch")
2922    (set_attr "mode" "XF")])
2923
2924 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2925 (define_split
2926   [(set (match_operand:X87MODEF 0 "register_operand" "")
2927         (match_operand:X87MODEF 1 "immediate_operand" ""))]
2928   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2929    && (standard_80387_constant_p (operands[1]) == 8
2930        || standard_80387_constant_p (operands[1]) == 9)"
2931   [(set (match_dup 0)(match_dup 1))
2932    (set (match_dup 0)
2933         (neg:X87MODEF (match_dup 0)))]
2934 {
2935   REAL_VALUE_TYPE r;
2936
2937   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2938   if (real_isnegzero (&r))
2939     operands[1] = CONST0_RTX (<MODE>mode);
2940   else
2941     operands[1] = CONST1_RTX (<MODE>mode);
2942 })
2943
2944 (define_expand "movtf"
2945   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2946         (match_operand:TF 1 "nonimmediate_operand" ""))]
2947   "TARGET_64BIT"
2948 {
2949   ix86_expand_move (TFmode, operands);
2950   DONE;
2951 })
2952
2953 (define_insn "*movtf_internal"
2954   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2955         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2956   "TARGET_64BIT
2957    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2958 {
2959   switch (which_alternative)
2960     {
2961     case 0:
2962     case 1:
2963       return "#";
2964     case 2:
2965       if (get_attr_mode (insn) == MODE_V4SF)
2966         return "xorps\t%0, %0";
2967       else
2968         return "pxor\t%0, %0";
2969     case 3:
2970     case 4:
2971       if (get_attr_mode (insn) == MODE_V4SF)
2972         return "movaps\t{%1, %0|%0, %1}";
2973       else
2974         return "movdqa\t{%1, %0|%0, %1}";
2975     default:
2976       gcc_unreachable ();
2977     }
2978 }
2979   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2980    (set (attr "mode")
2981         (cond [(eq_attr "alternative" "2,3")
2982                  (if_then_else
2983                    (ne (symbol_ref "optimize_size")
2984                        (const_int 0))
2985                    (const_string "V4SF")
2986                    (const_string "TI"))
2987                (eq_attr "alternative" "4")
2988                  (if_then_else
2989                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2990                             (const_int 0))
2991                         (ne (symbol_ref "optimize_size")
2992                             (const_int 0)))
2993                    (const_string "V4SF")
2994                    (const_string "TI"))]
2995                (const_string "DI")))])
2996
2997 (define_split
2998   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2999         (match_operand:TF 1 "general_operand" ""))]
3000   "reload_completed && !SSE_REG_P (operands[0])
3001    && !SSE_REG_P (operands[1])"
3002   [(const_int 0)]
3003   "ix86_split_long_move (operands); DONE;")
3004 \f
3005 ;; Zero extension instructions
3006
3007 (define_expand "zero_extendhisi2"
3008   [(set (match_operand:SI 0 "register_operand" "")
3009      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3010   ""
3011 {
3012   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3013     {
3014       operands[1] = force_reg (HImode, operands[1]);
3015       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3016       DONE;
3017     }
3018 })
3019
3020 (define_insn "zero_extendhisi2_and"
3021   [(set (match_operand:SI 0 "register_operand" "=r")
3022      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3023    (clobber (reg:CC FLAGS_REG))]
3024   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3025   "#"
3026   [(set_attr "type" "alu1")
3027    (set_attr "mode" "SI")])
3028
3029 (define_split
3030   [(set (match_operand:SI 0 "register_operand" "")
3031         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3032    (clobber (reg:CC FLAGS_REG))]
3033   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3034   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3035               (clobber (reg:CC FLAGS_REG))])]
3036   "")
3037
3038 (define_insn "*zero_extendhisi2_movzwl"
3039   [(set (match_operand:SI 0 "register_operand" "=r")
3040      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3041   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3042   "movz{wl|x}\t{%1, %0|%0, %1}"
3043   [(set_attr "type" "imovx")
3044    (set_attr "mode" "SI")])
3045
3046 (define_expand "zero_extendqihi2"
3047   [(parallel
3048     [(set (match_operand:HI 0 "register_operand" "")
3049        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3050      (clobber (reg:CC FLAGS_REG))])]
3051   ""
3052   "")
3053
3054 (define_insn "*zero_extendqihi2_and"
3055   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3056      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3057    (clobber (reg:CC FLAGS_REG))]
3058   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3059   "#"
3060   [(set_attr "type" "alu1")
3061    (set_attr "mode" "HI")])
3062
3063 (define_insn "*zero_extendqihi2_movzbw_and"
3064   [(set (match_operand:HI 0 "register_operand" "=r,r")
3065      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3066    (clobber (reg:CC FLAGS_REG))]
3067   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3068   "#"
3069   [(set_attr "type" "imovx,alu1")
3070    (set_attr "mode" "HI")])
3071
3072 ; zero extend to SImode here to avoid partial register stalls
3073 (define_insn "*zero_extendqihi2_movzbl"
3074   [(set (match_operand:HI 0 "register_operand" "=r")
3075      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3076   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3077   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3078   [(set_attr "type" "imovx")
3079    (set_attr "mode" "SI")])
3080
3081 ;; For the movzbw case strip only the clobber
3082 (define_split
3083   [(set (match_operand:HI 0 "register_operand" "")
3084         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3085    (clobber (reg:CC FLAGS_REG))]
3086   "reload_completed
3087    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3088    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3089   [(set (match_operand:HI 0 "register_operand" "")
3090         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3091
3092 ;; When source and destination does not overlap, clear destination
3093 ;; first and then do the movb
3094 (define_split
3095   [(set (match_operand:HI 0 "register_operand" "")
3096         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3097    (clobber (reg:CC FLAGS_REG))]
3098   "reload_completed
3099    && ANY_QI_REG_P (operands[0])
3100    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3101    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3102   [(set (match_dup 0) (const_int 0))
3103    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3104   "operands[2] = gen_lowpart (QImode, operands[0]);")
3105
3106 ;; Rest is handled by single and.
3107 (define_split
3108   [(set (match_operand:HI 0 "register_operand" "")
3109         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3110    (clobber (reg:CC FLAGS_REG))]
3111   "reload_completed
3112    && true_regnum (operands[0]) == true_regnum (operands[1])"
3113   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3114               (clobber (reg:CC FLAGS_REG))])]
3115   "")
3116
3117 (define_expand "zero_extendqisi2"
3118   [(parallel
3119     [(set (match_operand:SI 0 "register_operand" "")
3120        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3121      (clobber (reg:CC FLAGS_REG))])]
3122   ""
3123   "")
3124
3125 (define_insn "*zero_extendqisi2_and"
3126   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3127      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3128    (clobber (reg:CC FLAGS_REG))]
3129   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3130   "#"
3131   [(set_attr "type" "alu1")
3132    (set_attr "mode" "SI")])
3133
3134 (define_insn "*zero_extendqisi2_movzbw_and"
3135   [(set (match_operand:SI 0 "register_operand" "=r,r")
3136      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3137    (clobber (reg:CC FLAGS_REG))]
3138   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3139   "#"
3140   [(set_attr "type" "imovx,alu1")
3141    (set_attr "mode" "SI")])
3142
3143 (define_insn "*zero_extendqisi2_movzbw"
3144   [(set (match_operand:SI 0 "register_operand" "=r")
3145      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3146   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3147   "movz{bl|x}\t{%1, %0|%0, %1}"
3148   [(set_attr "type" "imovx")
3149    (set_attr "mode" "SI")])
3150
3151 ;; For the movzbl case strip only the clobber
3152 (define_split
3153   [(set (match_operand:SI 0 "register_operand" "")
3154         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3155    (clobber (reg:CC FLAGS_REG))]
3156   "reload_completed
3157    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3158    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3159   [(set (match_dup 0)
3160         (zero_extend:SI (match_dup 1)))])
3161
3162 ;; When source and destination does not overlap, clear destination
3163 ;; first and then do the movb
3164 (define_split
3165   [(set (match_operand:SI 0 "register_operand" "")
3166         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3167    (clobber (reg:CC FLAGS_REG))]
3168   "reload_completed
3169    && ANY_QI_REG_P (operands[0])
3170    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3171    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3172    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3173   [(set (match_dup 0) (const_int 0))
3174    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3175   "operands[2] = gen_lowpart (QImode, operands[0]);")
3176
3177 ;; Rest is handled by single and.
3178 (define_split
3179   [(set (match_operand:SI 0 "register_operand" "")
3180         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3181    (clobber (reg:CC FLAGS_REG))]
3182   "reload_completed
3183    && true_regnum (operands[0]) == true_regnum (operands[1])"
3184   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3185               (clobber (reg:CC FLAGS_REG))])]
3186   "")
3187
3188 ;; %%% Kill me once multi-word ops are sane.
3189 (define_expand "zero_extendsidi2"
3190   [(set (match_operand:DI 0 "register_operand" "=r")
3191      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3192   ""
3193   "if (!TARGET_64BIT)
3194      {
3195        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3196        DONE;
3197      }
3198   ")
3199
3200 (define_insn "zero_extendsidi2_32"
3201   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3202         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3203    (clobber (reg:CC FLAGS_REG))]
3204   "!TARGET_64BIT"
3205   "@
3206    #
3207    #
3208    #
3209    movd\t{%1, %0|%0, %1}
3210    movd\t{%1, %0|%0, %1}"
3211   [(set_attr "mode" "SI,SI,SI,DI,TI")
3212    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3213
3214 (define_insn "zero_extendsidi2_rex64"
3215   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3216      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3217   "TARGET_64BIT"
3218   "@
3219    mov\t{%k1, %k0|%k0, %k1}
3220    #
3221    movd\t{%1, %0|%0, %1}
3222    movd\t{%1, %0|%0, %1}"
3223   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3224    (set_attr "mode" "SI,DI,SI,SI")])
3225
3226 (define_split
3227   [(set (match_operand:DI 0 "memory_operand" "")
3228      (zero_extend:DI (match_dup 0)))]
3229   "TARGET_64BIT"
3230   [(set (match_dup 4) (const_int 0))]
3231   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3232
3233 (define_split
3234   [(set (match_operand:DI 0 "register_operand" "")
3235         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3236    (clobber (reg:CC FLAGS_REG))]
3237   "!TARGET_64BIT && reload_completed
3238    && true_regnum (operands[0]) == true_regnum (operands[1])"
3239   [(set (match_dup 4) (const_int 0))]
3240   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3241
3242 (define_split
3243   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3244         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3245    (clobber (reg:CC FLAGS_REG))]
3246   "!TARGET_64BIT && reload_completed
3247    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3248   [(set (match_dup 3) (match_dup 1))
3249    (set (match_dup 4) (const_int 0))]
3250   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3251
3252 (define_insn "zero_extendhidi2"
3253   [(set (match_operand:DI 0 "register_operand" "=r")
3254      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3255   "TARGET_64BIT"
3256   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3257   [(set_attr "type" "imovx")
3258    (set_attr "mode" "DI")])
3259
3260 (define_insn "zero_extendqidi2"
3261   [(set (match_operand:DI 0 "register_operand" "=r")
3262      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3263   "TARGET_64BIT"
3264   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3265   [(set_attr "type" "imovx")
3266    (set_attr "mode" "DI")])
3267 \f
3268 ;; Sign extension instructions
3269
3270 (define_expand "extendsidi2"
3271   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3272                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3273               (clobber (reg:CC FLAGS_REG))
3274               (clobber (match_scratch:SI 2 ""))])]
3275   ""
3276 {
3277   if (TARGET_64BIT)
3278     {
3279       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3280       DONE;
3281     }
3282 })
3283
3284 (define_insn "*extendsidi2_1"
3285   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3286         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3287    (clobber (reg:CC FLAGS_REG))
3288    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3289   "!TARGET_64BIT"
3290   "#")
3291
3292 (define_insn "extendsidi2_rex64"
3293   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3294         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3295   "TARGET_64BIT"
3296   "@
3297    {cltq|cdqe}
3298    movs{lq|x}\t{%1,%0|%0, %1}"
3299   [(set_attr "type" "imovx")
3300    (set_attr "mode" "DI")
3301    (set_attr "prefix_0f" "0")
3302    (set_attr "modrm" "0,1")])
3303
3304 (define_insn "extendhidi2"
3305   [(set (match_operand:DI 0 "register_operand" "=r")
3306         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3307   "TARGET_64BIT"
3308   "movs{wq|x}\t{%1,%0|%0, %1}"
3309   [(set_attr "type" "imovx")
3310    (set_attr "mode" "DI")])
3311
3312 (define_insn "extendqidi2"
3313   [(set (match_operand:DI 0 "register_operand" "=r")
3314         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3315   "TARGET_64BIT"
3316   "movs{bq|x}\t{%1,%0|%0, %1}"
3317    [(set_attr "type" "imovx")
3318     (set_attr "mode" "DI")])
3319
3320 ;; Extend to memory case when source register does die.
3321 (define_split
3322   [(set (match_operand:DI 0 "memory_operand" "")
3323         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3324    (clobber (reg:CC FLAGS_REG))
3325    (clobber (match_operand:SI 2 "register_operand" ""))]
3326   "(reload_completed
3327     && dead_or_set_p (insn, operands[1])
3328     && !reg_mentioned_p (operands[1], operands[0]))"
3329   [(set (match_dup 3) (match_dup 1))
3330    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3331               (clobber (reg:CC FLAGS_REG))])
3332    (set (match_dup 4) (match_dup 1))]
3333   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3334
3335 ;; Extend to memory case when source register does not die.
3336 (define_split
3337   [(set (match_operand:DI 0 "memory_operand" "")
3338         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3339    (clobber (reg:CC FLAGS_REG))
3340    (clobber (match_operand:SI 2 "register_operand" ""))]
3341   "reload_completed"
3342   [(const_int 0)]
3343 {
3344   split_di (&operands[0], 1, &operands[3], &operands[4]);
3345
3346   emit_move_insn (operands[3], operands[1]);
3347
3348   /* Generate a cltd if possible and doing so it profitable.  */
3349   if (true_regnum (operands[1]) == 0
3350       && true_regnum (operands[2]) == 1
3351       && (optimize_size || TARGET_USE_CLTD))
3352     {
3353       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3354     }
3355   else
3356     {
3357       emit_move_insn (operands[2], operands[1]);
3358       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3359     }
3360   emit_move_insn (operands[4], operands[2]);
3361   DONE;
3362 })
3363
3364 ;; Extend to register case.  Optimize case where source and destination
3365 ;; registers match and cases where we can use cltd.
3366 (define_split
3367   [(set (match_operand:DI 0 "register_operand" "")
3368         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3369    (clobber (reg:CC FLAGS_REG))
3370    (clobber (match_scratch:SI 2 ""))]
3371   "reload_completed"
3372   [(const_int 0)]
3373 {
3374   split_di (&operands[0], 1, &operands[3], &operands[4]);
3375
3376   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3377     emit_move_insn (operands[3], operands[1]);
3378
3379   /* Generate a cltd if possible and doing so it profitable.  */
3380   if (true_regnum (operands[3]) == 0
3381       && (optimize_size || TARGET_USE_CLTD))
3382     {
3383       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3384       DONE;
3385     }
3386
3387   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3388     emit_move_insn (operands[4], operands[1]);
3389
3390   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3391   DONE;
3392 })
3393
3394 (define_insn "extendhisi2"
3395   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3396         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3397   ""
3398 {
3399   switch (get_attr_prefix_0f (insn))
3400     {
3401     case 0:
3402       return "{cwtl|cwde}";
3403     default:
3404       return "movs{wl|x}\t{%1,%0|%0, %1}";
3405     }
3406 }
3407   [(set_attr "type" "imovx")
3408    (set_attr "mode" "SI")
3409    (set (attr "prefix_0f")
3410      ;; movsx is short decodable while cwtl is vector decoded.
3411      (if_then_else (and (eq_attr "cpu" "!k6")
3412                         (eq_attr "alternative" "0"))
3413         (const_string "0")
3414         (const_string "1")))
3415    (set (attr "modrm")
3416      (if_then_else (eq_attr "prefix_0f" "0")
3417         (const_string "0")
3418         (const_string "1")))])
3419
3420 (define_insn "*extendhisi2_zext"
3421   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3422         (zero_extend:DI
3423           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3424   "TARGET_64BIT"
3425 {
3426   switch (get_attr_prefix_0f (insn))
3427     {
3428     case 0:
3429       return "{cwtl|cwde}";
3430     default:
3431       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3432     }
3433 }
3434   [(set_attr "type" "imovx")
3435    (set_attr "mode" "SI")
3436    (set (attr "prefix_0f")
3437      ;; movsx is short decodable while cwtl is vector decoded.
3438      (if_then_else (and (eq_attr "cpu" "!k6")
3439                         (eq_attr "alternative" "0"))
3440         (const_string "0")
3441         (const_string "1")))
3442    (set (attr "modrm")
3443      (if_then_else (eq_attr "prefix_0f" "0")
3444         (const_string "0")
3445         (const_string "1")))])
3446
3447 (define_insn "extendqihi2"
3448   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3449         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3450   ""
3451 {
3452   switch (get_attr_prefix_0f (insn))
3453     {
3454     case 0:
3455       return "{cbtw|cbw}";
3456     default:
3457       return "movs{bw|x}\t{%1,%0|%0, %1}";
3458     }
3459 }
3460   [(set_attr "type" "imovx")
3461    (set_attr "mode" "HI")
3462    (set (attr "prefix_0f")
3463      ;; movsx is short decodable while cwtl is vector decoded.
3464      (if_then_else (and (eq_attr "cpu" "!k6")
3465                         (eq_attr "alternative" "0"))
3466         (const_string "0")
3467         (const_string "1")))
3468    (set (attr "modrm")
3469      (if_then_else (eq_attr "prefix_0f" "0")
3470         (const_string "0")
3471         (const_string "1")))])
3472
3473 (define_insn "extendqisi2"
3474   [(set (match_operand:SI 0 "register_operand" "=r")
3475         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3476   ""
3477   "movs{bl|x}\t{%1,%0|%0, %1}"
3478    [(set_attr "type" "imovx")
3479     (set_attr "mode" "SI")])
3480
3481 (define_insn "*extendqisi2_zext"
3482   [(set (match_operand:DI 0 "register_operand" "=r")
3483         (zero_extend:DI
3484           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3485   "TARGET_64BIT"
3486   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3487    [(set_attr "type" "imovx")
3488     (set_attr "mode" "SI")])
3489 \f
3490 ;; Conversions between float and double.
3491
3492 ;; These are all no-ops in the model used for the 80387.  So just
3493 ;; emit moves.
3494
3495 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3496 (define_insn "*dummy_extendsfdf2"
3497   [(set (match_operand:DF 0 "push_operand" "=<")
3498         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3499   "0"
3500   "#")
3501
3502 (define_split
3503   [(set (match_operand:DF 0 "push_operand" "")
3504         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3505   "!TARGET_64BIT"
3506   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3507    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3508
3509 (define_split
3510   [(set (match_operand:DF 0 "push_operand" "")
3511         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3512   "TARGET_64BIT"
3513   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3514    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3515
3516 (define_insn "*dummy_extendsfxf2"
3517   [(set (match_operand:XF 0 "push_operand" "=<")
3518         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3519   "0"
3520   "#")
3521
3522 (define_split
3523   [(set (match_operand:XF 0 "push_operand" "")
3524         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3525   ""
3526   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3527    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3528   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3529
3530 (define_split
3531   [(set (match_operand:XF 0 "push_operand" "")
3532         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3533   "TARGET_64BIT"
3534   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3535    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3536   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3537
3538 (define_split
3539   [(set (match_operand:XF 0 "push_operand" "")
3540         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3541   ""
3542   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3543    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3544   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3545
3546 (define_split
3547   [(set (match_operand:XF 0 "push_operand" "")
3548         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3549   "TARGET_64BIT"
3550   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3551    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3552   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3553
3554 (define_expand "extendsfdf2"
3555   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3556         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3557   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3558 {
3559   /* ??? Needed for compress_float_constant since all fp constants
3560      are LEGITIMATE_CONSTANT_P.  */
3561   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3562     {
3563       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3564           && standard_80387_constant_p (operands[1]) > 0)
3565         {
3566           operands[1] = simplify_const_unary_operation
3567             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3568           emit_move_insn_1 (operands[0], operands[1]);
3569           DONE;
3570         }
3571       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3572     }
3573 })
3574
3575 (define_insn "*extendsfdf2_mixed"
3576   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3577         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3578   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3579 {
3580   switch (which_alternative)
3581     {
3582     case 0:
3583       return output_387_reg_move (insn, operands);
3584
3585     case 1:
3586       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3587         return "fstp%z0\t%y0";
3588       else
3589         return "fst%z0\t%y0";
3590
3591     case 2:
3592       return "cvtss2sd\t{%1, %0|%0, %1}";
3593
3594     default:
3595       gcc_unreachable ();
3596     }
3597 }
3598   [(set_attr "type" "fmov,fmov,ssecvt")
3599    (set_attr "mode" "SF,XF,DF")])
3600
3601 (define_insn "*extendsfdf2_sse"
3602   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3603         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3604   "TARGET_SSE2 && TARGET_SSE_MATH"
3605   "cvtss2sd\t{%1, %0|%0, %1}"
3606   [(set_attr "type" "ssecvt")
3607    (set_attr "mode" "DF")])
3608
3609 (define_insn "*extendsfdf2_i387"
3610   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3611         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3612   "TARGET_80387"
3613 {
3614   switch (which_alternative)
3615     {
3616     case 0:
3617       return output_387_reg_move (insn, operands);
3618
3619     case 1:
3620       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3621         return "fstp%z0\t%y0";
3622       else
3623         return "fst%z0\t%y0";
3624
3625     default:
3626       gcc_unreachable ();
3627     }
3628 }
3629   [(set_attr "type" "fmov")
3630    (set_attr "mode" "SF,XF")])
3631
3632 (define_expand "extendsfxf2"
3633   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3634         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3635   "TARGET_80387"
3636 {
3637   /* ??? Needed for compress_float_constant since all fp constants
3638      are LEGITIMATE_CONSTANT_P.  */
3639   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3640     {
3641       if (standard_80387_constant_p (operands[1]) > 0)
3642         {
3643           operands[1] = simplify_const_unary_operation
3644             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3645           emit_move_insn_1 (operands[0], operands[1]);
3646           DONE;
3647         }
3648       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3649     }
3650 })
3651
3652 (define_insn "*extendsfxf2_i387"
3653   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3654         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3655   "TARGET_80387"
3656 {
3657   switch (which_alternative)
3658     {
3659     case 0:
3660       return output_387_reg_move (insn, operands);
3661
3662     case 1:
3663       /* There is no non-popping store to memory for XFmode.  So if
3664          we need one, follow the store with a load.  */
3665       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3666         return "fstp%z0\t%y0";
3667       else
3668         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3669
3670     default:
3671       gcc_unreachable ();
3672     }
3673 }
3674   [(set_attr "type" "fmov")
3675    (set_attr "mode" "SF,XF")])
3676
3677 (define_expand "extenddfxf2"
3678   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3679         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3680   "TARGET_80387"
3681 {
3682   /* ??? Needed for compress_float_constant since all fp constants
3683      are LEGITIMATE_CONSTANT_P.  */
3684   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3685     {
3686       if (standard_80387_constant_p (operands[1]) > 0)
3687         {
3688           operands[1] = simplify_const_unary_operation
3689             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3690           emit_move_insn_1 (operands[0], operands[1]);
3691           DONE;
3692         }
3693       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3694     }
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 {
3702   switch (which_alternative)
3703     {
3704     case 0:
3705       return output_387_reg_move (insn, operands);
3706
3707     case 1:
3708       /* There is no non-popping store to memory for XFmode.  So if
3709          we need one, follow the store with a load.  */
3710       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3711         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3712       else
3713         return "fstp%z0\t%y0";
3714
3715     default:
3716       gcc_unreachable ();
3717     }
3718 }
3719   [(set_attr "type" "fmov")
3720    (set_attr "mode" "DF,XF")])
3721
3722 ;; %%% This seems bad bad news.
3723 ;; This cannot output into an f-reg because there is no way to be sure
3724 ;; of truncating in that case.  Otherwise this is just like a simple move
3725 ;; insn.  So we pretend we can output to a reg in order to get better
3726 ;; register preferencing, but we really use a stack slot.
3727
3728 ;; Conversion from DFmode to SFmode.
3729
3730 (define_expand "truncdfsf2"
3731   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3732         (float_truncate:SF
3733           (match_operand:DF 1 "nonimmediate_operand" "")))]
3734   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3735 {
3736   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3737     ;
3738   else if (flag_unsafe_math_optimizations)
3739     ;
3740   else
3741     {
3742       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3743       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3744       DONE;
3745     }
3746 })
3747
3748 (define_expand "truncdfsf2_with_temp"
3749   [(parallel [(set (match_operand:SF 0 "" "")
3750                    (float_truncate:SF (match_operand:DF 1 "" "")))
3751               (clobber (match_operand:SF 2 "" ""))])]
3752   "")
3753
3754 (define_insn "*truncdfsf_fast_mixed"
3755   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3756         (float_truncate:SF
3757           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3758   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3759 {
3760   switch (which_alternative)
3761     {
3762     case 0:
3763       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3764         return "fstp%z0\t%y0";
3765       else
3766         return "fst%z0\t%y0";
3767     case 1:
3768       return output_387_reg_move (insn, operands);
3769     case 2:
3770       return "cvtsd2ss\t{%1, %0|%0, %1}";
3771     default:
3772       gcc_unreachable ();
3773     }
3774 }
3775   [(set_attr "type" "fmov,fmov,ssecvt")
3776    (set_attr "mode" "SF")])
3777
3778 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3779 ;; because nothing we do here is unsafe.
3780 (define_insn "*truncdfsf_fast_sse"
3781   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3782         (float_truncate:SF
3783           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3784   "TARGET_SSE2 && TARGET_SSE_MATH"
3785   "cvtsd2ss\t{%1, %0|%0, %1}"
3786   [(set_attr "type" "ssecvt")
3787    (set_attr "mode" "SF")])
3788
3789 (define_insn "*truncdfsf_fast_i387"
3790   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3791         (float_truncate:SF
3792           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3793   "TARGET_80387 && flag_unsafe_math_optimizations"
3794   "* return output_387_reg_move (insn, operands);"
3795   [(set_attr "type" "fmov")
3796    (set_attr "mode" "SF")])
3797
3798 (define_insn "*truncdfsf_mixed"
3799   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3800         (float_truncate:SF
3801           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3802    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3803   "TARGET_MIX_SSE_I387"
3804 {
3805   switch (which_alternative)
3806     {
3807     case 0:
3808       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3809         return "fstp%z0\t%y0";
3810       else
3811         return "fst%z0\t%y0";
3812     case 1:
3813       return "#";
3814     case 2:
3815       return "cvtsd2ss\t{%1, %0|%0, %1}";
3816     default:
3817       gcc_unreachable ();
3818     }
3819 }
3820   [(set_attr "type" "fmov,multi,ssecvt")
3821    (set_attr "unit" "*,i387,*")
3822    (set_attr "mode" "SF")])
3823
3824 (define_insn "*truncdfsf_i387"
3825   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3826         (float_truncate:SF
3827           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3828    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3829   "TARGET_80387"
3830 {
3831   switch (which_alternative)
3832     {
3833     case 0:
3834       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3835         return "fstp%z0\t%y0";
3836       else
3837         return "fst%z0\t%y0";
3838     case 1:
3839       return "#";
3840     default:
3841       gcc_unreachable ();
3842     }
3843 }
3844   [(set_attr "type" "fmov,multi")
3845    (set_attr "unit" "*,i387")
3846    (set_attr "mode" "SF")])
3847
3848 (define_insn "*truncdfsf2_i387_1"
3849   [(set (match_operand:SF 0 "memory_operand" "=m")
3850         (float_truncate:SF
3851           (match_operand:DF 1 "register_operand" "f")))]
3852   "TARGET_80387
3853    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3854    && !TARGET_MIX_SSE_I387"
3855 {
3856   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3857     return "fstp%z0\t%y0";
3858   else
3859     return "fst%z0\t%y0";
3860 }
3861   [(set_attr "type" "fmov")
3862    (set_attr "mode" "SF")])
3863
3864 (define_split
3865   [(set (match_operand:SF 0 "register_operand" "")
3866         (float_truncate:SF
3867          (match_operand:DF 1 "fp_register_operand" "")))
3868    (clobber (match_operand 2 "" ""))]
3869   "reload_completed"
3870   [(set (match_dup 2) (match_dup 1))
3871    (set (match_dup 0) (match_dup 2))]
3872 {
3873   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3874 })
3875
3876 ;; Conversion from XFmode to SFmode.
3877
3878 (define_expand "truncxfsf2"
3879   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3880                    (float_truncate:SF
3881                     (match_operand:XF 1 "register_operand" "")))
3882               (clobber (match_dup 2))])]
3883   "TARGET_80387"
3884 {
3885   if (flag_unsafe_math_optimizations)
3886     {
3887       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3888       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3889       if (reg != operands[0])
3890         emit_move_insn (operands[0], reg);
3891       DONE;
3892     }
3893   else
3894     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3895 })
3896
3897 (define_insn "*truncxfsf2_mixed"
3898   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3899         (float_truncate:SF
3900          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3901    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3902   "TARGET_MIX_SSE_I387"
3903 {
3904   gcc_assert (!which_alternative);
3905   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3906     return "fstp%z0\t%y0";
3907   else
3908     return "fst%z0\t%y0";
3909 }
3910   [(set_attr "type" "fmov,multi,multi,multi")
3911    (set_attr "unit" "*,i387,i387,i387")
3912    (set_attr "mode" "SF")])
3913
3914 (define_insn "truncxfsf2_i387_noop"
3915   [(set (match_operand:SF 0 "register_operand" "=f")
3916         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3917   "TARGET_80387 && flag_unsafe_math_optimizations"
3918   "* return output_387_reg_move (insn, operands);"
3919   [(set_attr "type" "fmov")
3920    (set_attr "mode" "SF")])
3921
3922 (define_insn "*truncxfsf2_i387"
3923   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3924         (float_truncate:SF
3925          (match_operand:XF 1 "register_operand" "f,f,f")))
3926    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3927   "TARGET_80387"
3928 {
3929   gcc_assert (!which_alternative);
3930   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3931     return "fstp%z0\t%y0";
3932    else
3933      return "fst%z0\t%y0";
3934 }
3935   [(set_attr "type" "fmov,multi,multi")
3936    (set_attr "unit" "*,i387,i387")
3937    (set_attr "mode" "SF")])
3938
3939 (define_insn "*truncxfsf2_i387_1"
3940   [(set (match_operand:SF 0 "memory_operand" "=m")
3941         (float_truncate:SF
3942          (match_operand:XF 1 "register_operand" "f")))]
3943   "TARGET_80387"
3944 {
3945   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3946     return "fstp%z0\t%y0";
3947   else
3948     return "fst%z0\t%y0";
3949 }
3950   [(set_attr "type" "fmov")
3951    (set_attr "mode" "SF")])
3952
3953 (define_split
3954   [(set (match_operand:SF 0 "register_operand" "")
3955         (float_truncate:SF
3956          (match_operand:XF 1 "register_operand" "")))
3957    (clobber (match_operand:SF 2 "memory_operand" ""))]
3958   "TARGET_80387 && reload_completed"
3959   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3960    (set (match_dup 0) (match_dup 2))]
3961   "")
3962
3963 (define_split
3964   [(set (match_operand:SF 0 "memory_operand" "")
3965         (float_truncate:SF
3966          (match_operand:XF 1 "register_operand" "")))
3967    (clobber (match_operand:SF 2 "memory_operand" ""))]
3968   "TARGET_80387"
3969   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3970   "")
3971
3972 ;; Conversion from XFmode to DFmode.
3973
3974 (define_expand "truncxfdf2"
3975   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3976                    (float_truncate:DF
3977                     (match_operand:XF 1 "register_operand" "")))
3978               (clobber (match_dup 2))])]
3979   "TARGET_80387"
3980 {
3981   if (flag_unsafe_math_optimizations)
3982     {
3983       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3984       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3985       if (reg != operands[0])
3986         emit_move_insn (operands[0], reg);
3987       DONE;
3988     }
3989   else
3990     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3991 })
3992
3993 (define_insn "*truncxfdf2_mixed"
3994   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3995         (float_truncate:DF
3996          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3997    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3998   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3999 {
4000   gcc_assert (!which_alternative);
4001   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4002     return "fstp%z0\t%y0";
4003   else
4004     return "fst%z0\t%y0";
4005 }
4006   [(set_attr "type" "fmov,multi,multi,multi")
4007    (set_attr "unit" "*,i387,i387,i387")
4008    (set_attr "mode" "DF")])
4009
4010 (define_insn "truncxfdf2_i387_noop"
4011   [(set (match_operand:DF 0 "register_operand" "=f")
4012         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4013   "TARGET_80387 && flag_unsafe_math_optimizations"
4014   "* return output_387_reg_move (insn, operands);"
4015   [(set_attr "type" "fmov")
4016    (set_attr "mode" "DF")])
4017
4018 (define_insn "*truncxfdf2_i387"
4019   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4020         (float_truncate:DF
4021          (match_operand:XF 1 "register_operand" "f,f,f")))
4022    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4023   "TARGET_80387"
4024 {
4025   gcc_assert (!which_alternative);
4026   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4027     return "fstp%z0\t%y0";
4028   else
4029     return "fst%z0\t%y0";
4030 }
4031   [(set_attr "type" "fmov,multi,multi")
4032    (set_attr "unit" "*,i387,i387")
4033    (set_attr "mode" "DF")])
4034
4035 (define_insn "*truncxfdf2_i387_1"
4036   [(set (match_operand:DF 0 "memory_operand" "=m")
4037         (float_truncate:DF
4038           (match_operand:XF 1 "register_operand" "f")))]
4039   "TARGET_80387"
4040 {
4041   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4042     return "fstp%z0\t%y0";
4043   else
4044     return "fst%z0\t%y0";
4045 }
4046   [(set_attr "type" "fmov")
4047    (set_attr "mode" "DF")])
4048
4049 (define_split
4050   [(set (match_operand:DF 0 "register_operand" "")
4051         (float_truncate:DF
4052          (match_operand:XF 1 "register_operand" "")))
4053    (clobber (match_operand:DF 2 "memory_operand" ""))]
4054   "TARGET_80387 && reload_completed"
4055   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4056    (set (match_dup 0) (match_dup 2))]
4057   "")
4058
4059 (define_split
4060   [(set (match_operand:DF 0 "memory_operand" "")
4061         (float_truncate:DF
4062          (match_operand:XF 1 "register_operand" "")))
4063    (clobber (match_operand:DF 2 "memory_operand" ""))]
4064   "TARGET_80387"
4065   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4066   "")
4067 \f
4068 ;; Signed conversion to DImode.
4069
4070 (define_expand "fix_truncxfdi2"
4071   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4072                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4073               (clobber (reg:CC FLAGS_REG))])]
4074   "TARGET_80387"
4075 {
4076   if (TARGET_FISTTP)
4077    {
4078      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4079      DONE;
4080    }
4081 })
4082
4083 (define_expand "fix_trunc<mode>di2"
4084   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4085                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4086               (clobber (reg:CC FLAGS_REG))])]
4087   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4088 {
4089   if (TARGET_FISTTP
4090       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4091    {
4092      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4093      DONE;
4094    }
4095   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4096    {
4097      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4098      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4099      if (out != operands[0])
4100         emit_move_insn (operands[0], out);
4101      DONE;
4102    }
4103 })
4104
4105 ;; Signed conversion to SImode.
4106
4107 (define_expand "fix_truncxfsi2"
4108   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4109                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4110               (clobber (reg:CC FLAGS_REG))])]
4111   "TARGET_80387"
4112 {
4113   if (TARGET_FISTTP)
4114    {
4115      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4116      DONE;
4117    }
4118 })
4119
4120 (define_expand "fix_trunc<mode>si2"
4121   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4122                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4123               (clobber (reg:CC FLAGS_REG))])]
4124   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4125 {
4126   if (TARGET_FISTTP
4127       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4128    {
4129      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4130      DONE;
4131    }
4132   if (SSE_FLOAT_MODE_P (<MODE>mode))
4133    {
4134      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4135      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4136      if (out != operands[0])
4137         emit_move_insn (operands[0], out);
4138      DONE;
4139    }
4140 })
4141
4142 ;; Signed conversion to HImode.
4143
4144 (define_expand "fix_trunc<mode>hi2"
4145   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4146                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4147               (clobber (reg:CC FLAGS_REG))])]
4148   "TARGET_80387
4149    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4150 {
4151   if (TARGET_FISTTP)
4152    {
4153      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4154      DONE;
4155    }
4156 })
4157
4158 ;; When SSE is available, it is always faster to use it!
4159 (define_insn "fix_truncsfdi_sse"
4160   [(set (match_operand:DI 0 "register_operand" "=r,r")
4161         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4162   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4163   "cvttss2si{q}\t{%1, %0|%0, %1}"
4164   [(set_attr "type" "sseicvt")
4165    (set_attr "mode" "SF")
4166    (set_attr "athlon_decode" "double,vector")])
4167
4168 (define_insn "fix_truncdfdi_sse"
4169   [(set (match_operand:DI 0 "register_operand" "=r,r")
4170         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4171   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4172   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4173   [(set_attr "type" "sseicvt")
4174    (set_attr "mode" "DF")
4175    (set_attr "athlon_decode" "double,vector")])
4176
4177 (define_insn "fix_truncsfsi_sse"
4178   [(set (match_operand:SI 0 "register_operand" "=r,r")
4179         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4180   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4181   "cvttss2si\t{%1, %0|%0, %1}"
4182   [(set_attr "type" "sseicvt")
4183    (set_attr "mode" "DF")
4184    (set_attr "athlon_decode" "double,vector")])
4185
4186 (define_insn "fix_truncdfsi_sse"
4187   [(set (match_operand:SI 0 "register_operand" "=r,r")
4188         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4189   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4190   "cvttsd2si\t{%1, %0|%0, %1}"
4191   [(set_attr "type" "sseicvt")
4192    (set_attr "mode" "DF")
4193    (set_attr "athlon_decode" "double,vector")])
4194
4195 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4196 (define_peephole2
4197   [(set (match_operand:DF 0 "register_operand" "")
4198         (match_operand:DF 1 "memory_operand" ""))
4199    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4200         (fix:SSEMODEI24 (match_dup 0)))]
4201   "!TARGET_K8
4202    && peep2_reg_dead_p (2, operands[0])"
4203   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4204   "")
4205
4206 (define_peephole2
4207   [(set (match_operand:SF 0 "register_operand" "")
4208         (match_operand:SF 1 "memory_operand" ""))
4209    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4210         (fix:SSEMODEI24 (match_dup 0)))]
4211   "!TARGET_K8
4212    && peep2_reg_dead_p (2, operands[0])"
4213   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4214   "")
4215
4216 ;; Avoid vector decoded forms of the instruction.
4217 (define_peephole2
4218   [(match_scratch:DF 2 "Y")
4219    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4220         (fix:SSEMODEI24 (match_operand:DF 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_peephole2
4227   [(match_scratch:SF 2 "x")
4228    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4229         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4230   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4231   [(set (match_dup 2) (match_dup 1))
4232    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4233   "")
4234
4235 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4236   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4237         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4238   "TARGET_FISTTP
4239    && FLOAT_MODE_P (GET_MODE (operands[1]))
4240    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4241          && (TARGET_64BIT || <MODE>mode != DImode))
4242         && TARGET_SSE_MATH)
4243    && !(reload_completed || reload_in_progress)"
4244   "#"
4245   "&& 1"
4246   [(const_int 0)]
4247 {
4248   if (memory_operand (operands[0], VOIDmode))
4249     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4250   else
4251     {
4252       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4253       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4254                                                             operands[1],
4255                                                             operands[2]));
4256     }
4257   DONE;
4258 }
4259   [(set_attr "type" "fisttp")
4260    (set_attr "mode" "<MODE>")])
4261
4262 (define_insn "fix_trunc<mode>_i387_fisttp"
4263   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4264         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4265    (clobber (match_scratch:XF 2 "=&1f"))]
4266   "TARGET_FISTTP
4267    && FLOAT_MODE_P (GET_MODE (operands[1]))
4268    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4269          && (TARGET_64BIT || <MODE>mode != DImode))
4270         && TARGET_SSE_MATH)"
4271   "* return output_fix_trunc (insn, operands, 1);"
4272   [(set_attr "type" "fisttp")
4273    (set_attr "mode" "<MODE>")])
4274
4275 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4276   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4277         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4278    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4279    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4280   "TARGET_FISTTP
4281    && FLOAT_MODE_P (GET_MODE (operands[1]))
4282    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4283         && (TARGET_64BIT || <MODE>mode != DImode))
4284         && TARGET_SSE_MATH)"
4285   "#"
4286   [(set_attr "type" "fisttp")
4287    (set_attr "mode" "<MODE>")])
4288
4289 (define_split
4290   [(set (match_operand:X87MODEI 0 "register_operand" "")
4291         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4292    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4293    (clobber (match_scratch 3 ""))]
4294   "reload_completed"
4295   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4296               (clobber (match_dup 3))])
4297    (set (match_dup 0) (match_dup 2))]
4298   "")
4299
4300 (define_split
4301   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4302         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4303    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4304    (clobber (match_scratch 3 ""))]
4305   "reload_completed"
4306   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4307               (clobber (match_dup 3))])]
4308   "")
4309
4310 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4311 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4312 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4313 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4314 ;; function in i386.c.
4315 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4316   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4317         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4318    (clobber (reg:CC FLAGS_REG))]
4319   "TARGET_80387 && !TARGET_FISTTP
4320    && FLOAT_MODE_P (GET_MODE (operands[1]))
4321    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4322          && (TARGET_64BIT || <MODE>mode != DImode))
4323    && !(reload_completed || reload_in_progress)"
4324   "#"
4325   "&& 1"
4326   [(const_int 0)]
4327 {
4328   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4329
4330   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4331   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4332   if (memory_operand (operands[0], VOIDmode))
4333     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4334                                          operands[2], operands[3]));
4335   else
4336     {
4337       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4338       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4339                                                      operands[2], operands[3],
4340                                                      operands[4]));
4341     }
4342   DONE;
4343 }
4344   [(set_attr "type" "fistp")
4345    (set_attr "i387_cw" "trunc")
4346    (set_attr "mode" "<MODE>")])
4347
4348 (define_insn "fix_truncdi_i387"
4349   [(set (match_operand:DI 0 "memory_operand" "=m")
4350         (fix:DI (match_operand 1 "register_operand" "f")))
4351    (use (match_operand:HI 2 "memory_operand" "m"))
4352    (use (match_operand:HI 3 "memory_operand" "m"))
4353    (clobber (match_scratch:XF 4 "=&1f"))]
4354   "TARGET_80387 && !TARGET_FISTTP
4355    && FLOAT_MODE_P (GET_MODE (operands[1]))
4356    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4357   "* return output_fix_trunc (insn, operands, 0);"
4358   [(set_attr "type" "fistp")
4359    (set_attr "i387_cw" "trunc")
4360    (set_attr "mode" "DI")])
4361
4362 (define_insn "fix_truncdi_i387_with_temp"
4363   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4364         (fix:DI (match_operand 1 "register_operand" "f,f")))
4365    (use (match_operand:HI 2 "memory_operand" "m,m"))
4366    (use (match_operand:HI 3 "memory_operand" "m,m"))
4367    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4368    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4369   "TARGET_80387 && !TARGET_FISTTP
4370    && FLOAT_MODE_P (GET_MODE (operands[1]))
4371    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4372   "#"
4373   [(set_attr "type" "fistp")
4374    (set_attr "i387_cw" "trunc")
4375    (set_attr "mode" "DI")])
4376
4377 (define_split
4378   [(set (match_operand:DI 0 "register_operand" "")
4379         (fix:DI (match_operand 1 "register_operand" "")))
4380    (use (match_operand:HI 2 "memory_operand" ""))
4381    (use (match_operand:HI 3 "memory_operand" ""))
4382    (clobber (match_operand:DI 4 "memory_operand" ""))
4383    (clobber (match_scratch 5 ""))]
4384   "reload_completed"
4385   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4386               (use (match_dup 2))
4387               (use (match_dup 3))
4388               (clobber (match_dup 5))])
4389    (set (match_dup 0) (match_dup 4))]
4390   "")
4391
4392 (define_split
4393   [(set (match_operand:DI 0 "memory_operand" "")
4394         (fix:DI (match_operand 1 "register_operand" "")))
4395    (use (match_operand:HI 2 "memory_operand" ""))
4396    (use (match_operand:HI 3 "memory_operand" ""))
4397    (clobber (match_operand:DI 4 "memory_operand" ""))
4398    (clobber (match_scratch 5 ""))]
4399   "reload_completed"
4400   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4401               (use (match_dup 2))
4402               (use (match_dup 3))
4403               (clobber (match_dup 5))])]
4404   "")
4405
4406 (define_insn "fix_trunc<mode>_i387"
4407   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4408         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4409    (use (match_operand:HI 2 "memory_operand" "m"))
4410    (use (match_operand:HI 3 "memory_operand" "m"))]
4411   "TARGET_80387 && !TARGET_FISTTP
4412    && FLOAT_MODE_P (GET_MODE (operands[1]))
4413    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4414   "* return output_fix_trunc (insn, operands, 0);"
4415   [(set_attr "type" "fistp")
4416    (set_attr "i387_cw" "trunc")
4417    (set_attr "mode" "<MODE>")])
4418
4419 (define_insn "fix_trunc<mode>_i387_with_temp"
4420   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4421         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4422    (use (match_operand:HI 2 "memory_operand" "m,m"))
4423    (use (match_operand:HI 3 "memory_operand" "m,m"))
4424    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4425   "TARGET_80387 && !TARGET_FISTTP
4426    && FLOAT_MODE_P (GET_MODE (operands[1]))
4427    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4428   "#"
4429   [(set_attr "type" "fistp")
4430    (set_attr "i387_cw" "trunc")
4431    (set_attr "mode" "<MODE>")])
4432
4433 (define_split
4434   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4435         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4436    (use (match_operand:HI 2 "memory_operand" ""))
4437    (use (match_operand:HI 3 "memory_operand" ""))
4438    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4439   "reload_completed"
4440   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4441               (use (match_dup 2))
4442               (use (match_dup 3))])
4443    (set (match_dup 0) (match_dup 4))]
4444   "")
4445
4446 (define_split
4447   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4448         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4449    (use (match_operand:HI 2 "memory_operand" ""))
4450    (use (match_operand:HI 3 "memory_operand" ""))
4451    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4452   "reload_completed"
4453   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4454               (use (match_dup 2))
4455               (use (match_dup 3))])]
4456   "")
4457
4458 (define_insn "x86_fnstcw_1"
4459   [(set (match_operand:HI 0 "memory_operand" "=m")
4460         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4461   "TARGET_80387"
4462   "fnstcw\t%0"
4463   [(set_attr "length" "2")
4464    (set_attr "mode" "HI")
4465    (set_attr "unit" "i387")])
4466
4467 (define_insn "x86_fldcw_1"
4468   [(set (reg:HI FPCR_REG)
4469         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4470   "TARGET_80387"
4471   "fldcw\t%0"
4472   [(set_attr "length" "2")
4473    (set_attr "mode" "HI")
4474    (set_attr "unit" "i387")
4475    (set_attr "athlon_decode" "vector")])
4476 \f
4477 ;; Conversion between fixed point and floating point.
4478
4479 ;; Even though we only accept memory inputs, the backend _really_
4480 ;; wants to be able to do this between registers.
4481
4482 (define_expand "floathisf2"
4483   [(set (match_operand:SF 0 "register_operand" "")
4484         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4485   "TARGET_80387 || TARGET_SSE_MATH"
4486 {
4487   if (TARGET_SSE_MATH)
4488     {
4489       emit_insn (gen_floatsisf2 (operands[0],
4490                                  convert_to_mode (SImode, operands[1], 0)));
4491       DONE;
4492     }
4493 })
4494
4495 (define_insn "*floathisf2_i387"
4496   [(set (match_operand:SF 0 "register_operand" "=f,f")
4497         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4498   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4499   "@
4500    fild%z1\t%1
4501    #"
4502   [(set_attr "type" "fmov,multi")
4503    (set_attr "mode" "SF")
4504    (set_attr "unit" "*,i387")
4505    (set_attr "fp_int_src" "true")])
4506
4507 (define_expand "floatsisf2"
4508   [(set (match_operand:SF 0 "register_operand" "")
4509         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4510   "TARGET_80387 || TARGET_SSE_MATH"
4511   "")
4512
4513 (define_insn "*floatsisf2_mixed"
4514   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4515         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4516   "TARGET_MIX_SSE_I387"
4517   "@
4518    fild%z1\t%1
4519    #
4520    cvtsi2ss\t{%1, %0|%0, %1}
4521    cvtsi2ss\t{%1, %0|%0, %1}"
4522   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4523    (set_attr "mode" "SF")
4524    (set_attr "unit" "*,i387,*,*")
4525    (set_attr "athlon_decode" "*,*,vector,double")
4526    (set_attr "fp_int_src" "true")])
4527
4528 (define_insn "*floatsisf2_sse"
4529   [(set (match_operand:SF 0 "register_operand" "=x,x")
4530         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4531   "TARGET_SSE_MATH"
4532   "cvtsi2ss\t{%1, %0|%0, %1}"
4533   [(set_attr "type" "sseicvt")
4534    (set_attr "mode" "SF")
4535    (set_attr "athlon_decode" "vector,double")
4536    (set_attr "fp_int_src" "true")])
4537
4538 (define_insn "*floatsisf2_i387"
4539   [(set (match_operand:SF 0 "register_operand" "=f,f")
4540         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4541   "TARGET_80387"
4542   "@
4543    fild%z1\t%1
4544    #"
4545   [(set_attr "type" "fmov,multi")
4546    (set_attr "mode" "SF")
4547    (set_attr "unit" "*,i387")
4548    (set_attr "fp_int_src" "true")])
4549
4550 (define_expand "floatdisf2"
4551   [(set (match_operand:SF 0 "register_operand" "")
4552         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4553   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4554   "")
4555
4556 (define_insn "*floatdisf2_mixed"
4557   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4558         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4559   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4560   "@
4561    fild%z1\t%1
4562    #
4563    cvtsi2ss{q}\t{%1, %0|%0, %1}
4564    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4565   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4566    (set_attr "mode" "SF")
4567    (set_attr "unit" "*,i387,*,*")
4568    (set_attr "athlon_decode" "*,*,vector,double")
4569    (set_attr "fp_int_src" "true")])
4570
4571 (define_insn "*floatdisf2_sse"
4572   [(set (match_operand:SF 0 "register_operand" "=x,x")
4573         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4574   "TARGET_64BIT && TARGET_SSE_MATH"
4575   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4576   [(set_attr "type" "sseicvt")
4577    (set_attr "mode" "SF")
4578    (set_attr "athlon_decode" "vector,double")
4579    (set_attr "fp_int_src" "true")])
4580
4581 (define_insn "*floatdisf2_i387"
4582   [(set (match_operand:SF 0 "register_operand" "=f,f")
4583         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4584   "TARGET_80387"
4585   "@
4586    fild%z1\t%1
4587    #"
4588   [(set_attr "type" "fmov,multi")
4589    (set_attr "mode" "SF")
4590    (set_attr "unit" "*,i387")
4591    (set_attr "fp_int_src" "true")])
4592
4593 (define_expand "floathidf2"
4594   [(set (match_operand:DF 0 "register_operand" "")
4595         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4596   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4597 {
4598   if (TARGET_SSE2 && TARGET_SSE_MATH)
4599     {
4600       emit_insn (gen_floatsidf2 (operands[0],
4601                                  convert_to_mode (SImode, operands[1], 0)));
4602       DONE;
4603     }
4604 })
4605
4606 (define_insn "*floathidf2_i387"
4607   [(set (match_operand:DF 0 "register_operand" "=f,f")
4608         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4609   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4610   "@
4611    fild%z1\t%1
4612    #"
4613   [(set_attr "type" "fmov,multi")
4614    (set_attr "mode" "DF")
4615    (set_attr "unit" "*,i387")
4616    (set_attr "fp_int_src" "true")])
4617
4618 (define_expand "floatsidf2"
4619   [(set (match_operand:DF 0 "register_operand" "")
4620         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4621   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4622   "")
4623
4624 (define_insn "*floatsidf2_mixed"
4625   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4626         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4627   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4628   "@
4629    fild%z1\t%1
4630    #
4631    cvtsi2sd\t{%1, %0|%0, %1}
4632    cvtsi2sd\t{%1, %0|%0, %1}"
4633   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4634    (set_attr "mode" "DF")
4635    (set_attr "unit" "*,i387,*,*")
4636    (set_attr "athlon_decode" "*,*,double,direct")
4637    (set_attr "fp_int_src" "true")])
4638
4639 (define_insn "*floatsidf2_sse"
4640   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4641         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4642   "TARGET_SSE2 && TARGET_SSE_MATH"
4643   "cvtsi2sd\t{%1, %0|%0, %1}"
4644   [(set_attr "type" "sseicvt")
4645    (set_attr "mode" "DF")
4646    (set_attr "athlon_decode" "double,direct")
4647    (set_attr "fp_int_src" "true")])
4648
4649 (define_insn "*floatsidf2_i387"
4650   [(set (match_operand:DF 0 "register_operand" "=f,f")
4651         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4652   "TARGET_80387"
4653   "@
4654    fild%z1\t%1
4655    #"
4656   [(set_attr "type" "fmov,multi")
4657    (set_attr "mode" "DF")
4658    (set_attr "unit" "*,i387")
4659    (set_attr "fp_int_src" "true")])
4660
4661 (define_expand "floatdidf2"
4662   [(set (match_operand:DF 0 "register_operand" "")
4663         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4664   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4665   "")
4666
4667 (define_insn "*floatdidf2_mixed"
4668   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4669         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4670   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4671   "@
4672    fild%z1\t%1
4673    #
4674    cvtsi2sd{q}\t{%1, %0|%0, %1}
4675    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4676   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4677    (set_attr "mode" "DF")
4678    (set_attr "unit" "*,i387,*,*")
4679    (set_attr "athlon_decode" "*,*,double,direct")
4680    (set_attr "fp_int_src" "true")])
4681
4682 (define_insn "*floatdidf2_sse"
4683   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4684         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4685   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4686   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4687   [(set_attr "type" "sseicvt")
4688    (set_attr "mode" "DF")
4689    (set_attr "athlon_decode" "double,direct")
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 "general_operand" "roiF,riF")))
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 "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 "general_operand" "roiF,riF")))
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 "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 (define_insn "*muldi3_1_rex64"
6898   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6899         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6900                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6901    (clobber (reg:CC FLAGS_REG))]
6902   "TARGET_64BIT
6903    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6904   "@
6905    imul{q}\t{%2, %1, %0|%0, %1, %2}
6906    imul{q}\t{%2, %1, %0|%0, %1, %2}
6907    imul{q}\t{%2, %0|%0, %2}"
6908   [(set_attr "type" "imul")
6909    (set_attr "prefix_0f" "0,0,1")
6910    (set (attr "athlon_decode")
6911         (cond [(eq_attr "cpu" "athlon")
6912                   (const_string "vector")
6913                (eq_attr "alternative" "1")
6914                   (const_string "vector")
6915                (and (eq_attr "alternative" "2")
6916                     (match_operand 1 "memory_operand" ""))
6917                   (const_string "vector")]
6918               (const_string "direct")))
6919    (set_attr "mode" "DI")])
6920
6921 (define_expand "mulsi3"
6922   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6923                    (mult:SI (match_operand:SI 1 "register_operand" "")
6924                             (match_operand:SI 2 "general_operand" "")))
6925               (clobber (reg:CC FLAGS_REG))])]
6926   ""
6927   "")
6928
6929 (define_insn "*mulsi3_1"
6930   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6931         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6932                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6933    (clobber (reg:CC FLAGS_REG))]
6934   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6935   "@
6936    imul{l}\t{%2, %1, %0|%0, %1, %2}
6937    imul{l}\t{%2, %1, %0|%0, %1, %2}
6938    imul{l}\t{%2, %0|%0, %2}"
6939   [(set_attr "type" "imul")
6940    (set_attr "prefix_0f" "0,0,1")
6941    (set (attr "athlon_decode")
6942         (cond [(eq_attr "cpu" "athlon")
6943                   (const_string "vector")
6944                (eq_attr "alternative" "1")
6945                   (const_string "vector")
6946                (and (eq_attr "alternative" "2")
6947                     (match_operand 1 "memory_operand" ""))
6948                   (const_string "vector")]
6949               (const_string "direct")))
6950    (set_attr "mode" "SI")])
6951
6952 (define_insn "*mulsi3_1_zext"
6953   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6954         (zero_extend:DI
6955           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6956                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6957    (clobber (reg:CC FLAGS_REG))]
6958   "TARGET_64BIT
6959    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6960   "@
6961    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6962    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6963    imul{l}\t{%2, %k0|%k0, %2}"
6964   [(set_attr "type" "imul")
6965    (set_attr "prefix_0f" "0,0,1")
6966    (set (attr "athlon_decode")
6967         (cond [(eq_attr "cpu" "athlon")
6968                   (const_string "vector")
6969                (eq_attr "alternative" "1")
6970                   (const_string "vector")
6971                (and (eq_attr "alternative" "2")
6972                     (match_operand 1 "memory_operand" ""))
6973                   (const_string "vector")]
6974               (const_string "direct")))
6975    (set_attr "mode" "SI")])
6976
6977 (define_expand "mulhi3"
6978   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6979                    (mult:HI (match_operand:HI 1 "register_operand" "")
6980                             (match_operand:HI 2 "general_operand" "")))
6981               (clobber (reg:CC FLAGS_REG))])]
6982   "TARGET_HIMODE_MATH"
6983   "")
6984
6985 (define_insn "*mulhi3_1"
6986   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6987         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6988                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6989    (clobber (reg:CC FLAGS_REG))]
6990   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6991   "@
6992    imul{w}\t{%2, %1, %0|%0, %1, %2}
6993    imul{w}\t{%2, %1, %0|%0, %1, %2}
6994    imul{w}\t{%2, %0|%0, %2}"
6995   [(set_attr "type" "imul")
6996    (set_attr "prefix_0f" "0,0,1")
6997    (set (attr "athlon_decode")
6998         (cond [(eq_attr "cpu" "athlon")
6999                   (const_string "vector")
7000                (eq_attr "alternative" "1,2")
7001                   (const_string "vector")]
7002               (const_string "direct")))
7003    (set_attr "mode" "HI")])
7004
7005 (define_expand "mulqi3"
7006   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7007                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7008                             (match_operand:QI 2 "register_operand" "")))
7009               (clobber (reg:CC FLAGS_REG))])]
7010   "TARGET_QIMODE_MATH"
7011   "")
7012
7013 (define_insn "*mulqi3_1"
7014   [(set (match_operand:QI 0 "register_operand" "=a")
7015         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7016                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7017    (clobber (reg:CC FLAGS_REG))]
7018   "TARGET_QIMODE_MATH
7019    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7020   "mul{b}\t%2"
7021   [(set_attr "type" "imul")
7022    (set_attr "length_immediate" "0")
7023    (set (attr "athlon_decode")
7024      (if_then_else (eq_attr "cpu" "athlon")
7025         (const_string "vector")
7026         (const_string "direct")))
7027    (set_attr "mode" "QI")])
7028
7029 (define_expand "umulqihi3"
7030   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7031                    (mult:HI (zero_extend:HI
7032                               (match_operand:QI 1 "nonimmediate_operand" ""))
7033                             (zero_extend:HI
7034                               (match_operand:QI 2 "register_operand" ""))))
7035               (clobber (reg:CC FLAGS_REG))])]
7036   "TARGET_QIMODE_MATH"
7037   "")
7038
7039 (define_insn "*umulqihi3_1"
7040   [(set (match_operand:HI 0 "register_operand" "=a")
7041         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7042                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7043    (clobber (reg:CC FLAGS_REG))]
7044   "TARGET_QIMODE_MATH
7045    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7046   "mul{b}\t%2"
7047   [(set_attr "type" "imul")
7048    (set_attr "length_immediate" "0")
7049    (set (attr "athlon_decode")
7050      (if_then_else (eq_attr "cpu" "athlon")
7051         (const_string "vector")
7052         (const_string "direct")))
7053    (set_attr "mode" "QI")])
7054
7055 (define_expand "mulqihi3"
7056   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7057                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7058                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7059               (clobber (reg:CC FLAGS_REG))])]
7060   "TARGET_QIMODE_MATH"
7061   "")
7062
7063 (define_insn "*mulqihi3_insn"
7064   [(set (match_operand:HI 0 "register_operand" "=a")
7065         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7066                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7067    (clobber (reg:CC FLAGS_REG))]
7068   "TARGET_QIMODE_MATH
7069    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7070   "imul{b}\t%2"
7071   [(set_attr "type" "imul")
7072    (set_attr "length_immediate" "0")
7073    (set (attr "athlon_decode")
7074      (if_then_else (eq_attr "cpu" "athlon")
7075         (const_string "vector")
7076         (const_string "direct")))
7077    (set_attr "mode" "QI")])
7078
7079 (define_expand "umulditi3"
7080   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7081                    (mult:TI (zero_extend:TI
7082                               (match_operand:DI 1 "nonimmediate_operand" ""))
7083                             (zero_extend:TI
7084                               (match_operand:DI 2 "register_operand" ""))))
7085               (clobber (reg:CC FLAGS_REG))])]
7086   "TARGET_64BIT"
7087   "")
7088
7089 (define_insn "*umulditi3_insn"
7090   [(set (match_operand:TI 0 "register_operand" "=A")
7091         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7092                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7093    (clobber (reg:CC FLAGS_REG))]
7094   "TARGET_64BIT
7095    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7096   "mul{q}\t%2"
7097   [(set_attr "type" "imul")
7098    (set_attr "length_immediate" "0")
7099    (set (attr "athlon_decode")
7100      (if_then_else (eq_attr "cpu" "athlon")
7101         (const_string "vector")
7102         (const_string "double")))
7103    (set_attr "mode" "DI")])
7104
7105 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7106 (define_expand "umulsidi3"
7107   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7108                    (mult:DI (zero_extend:DI
7109                               (match_operand:SI 1 "nonimmediate_operand" ""))
7110                             (zero_extend:DI
7111                               (match_operand:SI 2 "register_operand" ""))))
7112               (clobber (reg:CC FLAGS_REG))])]
7113   "!TARGET_64BIT"
7114   "")
7115
7116 (define_insn "*umulsidi3_insn"
7117   [(set (match_operand:DI 0 "register_operand" "=A")
7118         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7119                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7120    (clobber (reg:CC FLAGS_REG))]
7121   "!TARGET_64BIT
7122    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7123   "mul{l}\t%2"
7124   [(set_attr "type" "imul")
7125    (set_attr "length_immediate" "0")
7126    (set (attr "athlon_decode")
7127      (if_then_else (eq_attr "cpu" "athlon")
7128         (const_string "vector")
7129         (const_string "double")))
7130    (set_attr "mode" "SI")])
7131
7132 (define_expand "mulditi3"
7133   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7134                    (mult:TI (sign_extend:TI
7135                               (match_operand:DI 1 "nonimmediate_operand" ""))
7136                             (sign_extend:TI
7137                               (match_operand:DI 2 "register_operand" ""))))
7138               (clobber (reg:CC FLAGS_REG))])]
7139   "TARGET_64BIT"
7140   "")
7141
7142 (define_insn "*mulditi3_insn"
7143   [(set (match_operand:TI 0 "register_operand" "=A")
7144         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7145                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7146    (clobber (reg:CC FLAGS_REG))]
7147   "TARGET_64BIT
7148    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7149   "imul{q}\t%2"
7150   [(set_attr "type" "imul")
7151    (set_attr "length_immediate" "0")
7152    (set (attr "athlon_decode")
7153      (if_then_else (eq_attr "cpu" "athlon")
7154         (const_string "vector")
7155         (const_string "double")))
7156    (set_attr "mode" "DI")])
7157
7158 (define_expand "mulsidi3"
7159   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7160                    (mult:DI (sign_extend:DI
7161                               (match_operand:SI 1 "nonimmediate_operand" ""))
7162                             (sign_extend:DI
7163                               (match_operand:SI 2 "register_operand" ""))))
7164               (clobber (reg:CC FLAGS_REG))])]
7165   "!TARGET_64BIT"
7166   "")
7167
7168 (define_insn "*mulsidi3_insn"
7169   [(set (match_operand:DI 0 "register_operand" "=A")
7170         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7171                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7172    (clobber (reg:CC FLAGS_REG))]
7173   "!TARGET_64BIT
7174    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7175   "imul{l}\t%2"
7176   [(set_attr "type" "imul")
7177    (set_attr "length_immediate" "0")
7178    (set (attr "athlon_decode")
7179      (if_then_else (eq_attr "cpu" "athlon")
7180         (const_string "vector")
7181         (const_string "double")))
7182    (set_attr "mode" "SI")])
7183
7184 (define_expand "umuldi3_highpart"
7185   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7186                    (truncate:DI
7187                      (lshiftrt:TI
7188                        (mult:TI (zero_extend:TI
7189                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7190                                 (zero_extend:TI
7191                                   (match_operand:DI 2 "register_operand" "")))
7192                        (const_int 64))))
7193               (clobber (match_scratch:DI 3 ""))
7194               (clobber (reg:CC FLAGS_REG))])]
7195   "TARGET_64BIT"
7196   "")
7197
7198 (define_insn "*umuldi3_highpart_rex64"
7199   [(set (match_operand:DI 0 "register_operand" "=d")
7200         (truncate:DI
7201           (lshiftrt:TI
7202             (mult:TI (zero_extend:TI
7203                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7204                      (zero_extend:TI
7205                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7206             (const_int 64))))
7207    (clobber (match_scratch:DI 3 "=1"))
7208    (clobber (reg:CC FLAGS_REG))]
7209   "TARGET_64BIT
7210    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7211   "mul{q}\t%2"
7212   [(set_attr "type" "imul")
7213    (set_attr "length_immediate" "0")
7214    (set (attr "athlon_decode")
7215      (if_then_else (eq_attr "cpu" "athlon")
7216         (const_string "vector")
7217         (const_string "double")))
7218    (set_attr "mode" "DI")])
7219
7220 (define_expand "umulsi3_highpart"
7221   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7222                    (truncate:SI
7223                      (lshiftrt:DI
7224                        (mult:DI (zero_extend:DI
7225                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7226                                 (zero_extend:DI
7227                                   (match_operand:SI 2 "register_operand" "")))
7228                        (const_int 32))))
7229               (clobber (match_scratch:SI 3 ""))
7230               (clobber (reg:CC FLAGS_REG))])]
7231   ""
7232   "")
7233
7234 (define_insn "*umulsi3_highpart_insn"
7235   [(set (match_operand:SI 0 "register_operand" "=d")
7236         (truncate:SI
7237           (lshiftrt:DI
7238             (mult:DI (zero_extend:DI
7239                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7240                      (zero_extend:DI
7241                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7242             (const_int 32))))
7243    (clobber (match_scratch:SI 3 "=1"))
7244    (clobber (reg:CC FLAGS_REG))]
7245   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7246   "mul{l}\t%2"
7247   [(set_attr "type" "imul")
7248    (set_attr "length_immediate" "0")
7249    (set (attr "athlon_decode")
7250      (if_then_else (eq_attr "cpu" "athlon")
7251         (const_string "vector")
7252         (const_string "double")))
7253    (set_attr "mode" "SI")])
7254
7255 (define_insn "*umulsi3_highpart_zext"
7256   [(set (match_operand:DI 0 "register_operand" "=d")
7257         (zero_extend:DI (truncate:SI
7258           (lshiftrt:DI
7259             (mult:DI (zero_extend:DI
7260                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7261                      (zero_extend:DI
7262                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7263             (const_int 32)))))
7264    (clobber (match_scratch:SI 3 "=1"))
7265    (clobber (reg:CC FLAGS_REG))]
7266   "TARGET_64BIT
7267    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7268   "mul{l}\t%2"
7269   [(set_attr "type" "imul")
7270    (set_attr "length_immediate" "0")
7271    (set (attr "athlon_decode")
7272      (if_then_else (eq_attr "cpu" "athlon")
7273         (const_string "vector")
7274         (const_string "double")))
7275    (set_attr "mode" "SI")])
7276
7277 (define_expand "smuldi3_highpart"
7278   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7279                    (truncate:DI
7280                      (lshiftrt:TI
7281                        (mult:TI (sign_extend:TI
7282                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7283                                 (sign_extend:TI
7284                                   (match_operand:DI 2 "register_operand" "")))
7285                        (const_int 64))))
7286               (clobber (match_scratch:DI 3 ""))
7287               (clobber (reg:CC FLAGS_REG))])]
7288   "TARGET_64BIT"
7289   "")
7290
7291 (define_insn "*smuldi3_highpart_rex64"
7292   [(set (match_operand:DI 0 "register_operand" "=d")
7293         (truncate:DI
7294           (lshiftrt:TI
7295             (mult:TI (sign_extend:TI
7296                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7297                      (sign_extend:TI
7298                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7299             (const_int 64))))
7300    (clobber (match_scratch:DI 3 "=1"))
7301    (clobber (reg:CC FLAGS_REG))]
7302   "TARGET_64BIT
7303    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7304   "imul{q}\t%2"
7305   [(set_attr "type" "imul")
7306    (set (attr "athlon_decode")
7307      (if_then_else (eq_attr "cpu" "athlon")
7308         (const_string "vector")
7309         (const_string "double")))
7310    (set_attr "mode" "DI")])
7311
7312 (define_expand "smulsi3_highpart"
7313   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7314                    (truncate:SI
7315                      (lshiftrt:DI
7316                        (mult:DI (sign_extend:DI
7317                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7318                                 (sign_extend:DI
7319                                   (match_operand:SI 2 "register_operand" "")))
7320                        (const_int 32))))
7321               (clobber (match_scratch:SI 3 ""))
7322               (clobber (reg:CC FLAGS_REG))])]
7323   ""
7324   "")
7325
7326 (define_insn "*smulsi3_highpart_insn"
7327   [(set (match_operand:SI 0 "register_operand" "=d")
7328         (truncate:SI
7329           (lshiftrt:DI
7330             (mult:DI (sign_extend:DI
7331                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7332                      (sign_extend:DI
7333                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7334             (const_int 32))))
7335    (clobber (match_scratch:SI 3 "=1"))
7336    (clobber (reg:CC FLAGS_REG))]
7337   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7338   "imul{l}\t%2"
7339   [(set_attr "type" "imul")
7340    (set (attr "athlon_decode")
7341      (if_then_else (eq_attr "cpu" "athlon")
7342         (const_string "vector")
7343         (const_string "double")))
7344    (set_attr "mode" "SI")])
7345
7346 (define_insn "*smulsi3_highpart_zext"
7347   [(set (match_operand:DI 0 "register_operand" "=d")
7348         (zero_extend:DI (truncate:SI
7349           (lshiftrt:DI
7350             (mult:DI (sign_extend:DI
7351                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7352                      (sign_extend:DI
7353                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7354             (const_int 32)))))
7355    (clobber (match_scratch:SI 3 "=1"))
7356    (clobber (reg:CC FLAGS_REG))]
7357   "TARGET_64BIT
7358    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7359   "imul{l}\t%2"
7360   [(set_attr "type" "imul")
7361    (set (attr "athlon_decode")
7362      (if_then_else (eq_attr "cpu" "athlon")
7363         (const_string "vector")
7364         (const_string "double")))
7365    (set_attr "mode" "SI")])
7366
7367 ;; The patterns that match these are at the end of this file.
7368
7369 (define_expand "mulxf3"
7370   [(set (match_operand:XF 0 "register_operand" "")
7371         (mult:XF (match_operand:XF 1 "register_operand" "")
7372                  (match_operand:XF 2 "register_operand" "")))]
7373   "TARGET_80387"
7374   "")
7375
7376 (define_expand "muldf3"
7377   [(set (match_operand:DF 0 "register_operand" "")
7378         (mult:DF (match_operand:DF 1 "register_operand" "")
7379                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7380   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7381   "")
7382
7383 (define_expand "mulsf3"
7384   [(set (match_operand:SF 0 "register_operand" "")
7385         (mult:SF (match_operand:SF 1 "register_operand" "")
7386                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7387   "TARGET_80387 || TARGET_SSE_MATH"
7388   "")
7389 \f
7390 ;; Divide instructions
7391
7392 (define_insn "divqi3"
7393   [(set (match_operand:QI 0 "register_operand" "=a")
7394         (div:QI (match_operand:HI 1 "register_operand" "0")
7395                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7396    (clobber (reg:CC FLAGS_REG))]
7397   "TARGET_QIMODE_MATH"
7398   "idiv{b}\t%2"
7399   [(set_attr "type" "idiv")
7400    (set_attr "mode" "QI")])
7401
7402 (define_insn "udivqi3"
7403   [(set (match_operand:QI 0 "register_operand" "=a")
7404         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7405                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7406    (clobber (reg:CC FLAGS_REG))]
7407   "TARGET_QIMODE_MATH"
7408   "div{b}\t%2"
7409   [(set_attr "type" "idiv")
7410    (set_attr "mode" "QI")])
7411
7412 ;; The patterns that match these are at the end of this file.
7413
7414 (define_expand "divxf3"
7415   [(set (match_operand:XF 0 "register_operand" "")
7416         (div:XF (match_operand:XF 1 "register_operand" "")
7417                 (match_operand:XF 2 "register_operand" "")))]
7418   "TARGET_80387"
7419   "")
7420
7421 (define_expand "divdf3"
7422   [(set (match_operand:DF 0 "register_operand" "")
7423         (div:DF (match_operand:DF 1 "register_operand" "")
7424                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7425    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7426    "")
7427
7428 (define_expand "divsf3"
7429   [(set (match_operand:SF 0 "register_operand" "")
7430         (div:SF (match_operand:SF 1 "register_operand" "")
7431                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7432   "TARGET_80387 || TARGET_SSE_MATH"
7433   "")
7434 \f
7435 ;; Remainder instructions.
7436
7437 (define_expand "divmoddi4"
7438   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7439                    (div:DI (match_operand:DI 1 "register_operand" "")
7440                            (match_operand:DI 2 "nonimmediate_operand" "")))
7441               (set (match_operand:DI 3 "register_operand" "")
7442                    (mod:DI (match_dup 1) (match_dup 2)))
7443               (clobber (reg:CC FLAGS_REG))])]
7444   "TARGET_64BIT"
7445   "")
7446
7447 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7448 ;; Penalize eax case slightly because it results in worse scheduling
7449 ;; of code.
7450 (define_insn "*divmoddi4_nocltd_rex64"
7451   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7452         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7453                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7454    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7455         (mod:DI (match_dup 2) (match_dup 3)))
7456    (clobber (reg:CC FLAGS_REG))]
7457   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7458   "#"
7459   [(set_attr "type" "multi")])
7460
7461 (define_insn "*divmoddi4_cltd_rex64"
7462   [(set (match_operand:DI 0 "register_operand" "=a")
7463         (div:DI (match_operand:DI 2 "register_operand" "a")
7464                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7465    (set (match_operand:DI 1 "register_operand" "=&d")
7466         (mod:DI (match_dup 2) (match_dup 3)))
7467    (clobber (reg:CC FLAGS_REG))]
7468   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7469   "#"
7470   [(set_attr "type" "multi")])
7471
7472 (define_insn "*divmoddi_noext_rex64"
7473   [(set (match_operand:DI 0 "register_operand" "=a")
7474         (div:DI (match_operand:DI 1 "register_operand" "0")
7475                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7476    (set (match_operand:DI 3 "register_operand" "=d")
7477         (mod:DI (match_dup 1) (match_dup 2)))
7478    (use (match_operand:DI 4 "register_operand" "3"))
7479    (clobber (reg:CC FLAGS_REG))]
7480   "TARGET_64BIT"
7481   "idiv{q}\t%2"
7482   [(set_attr "type" "idiv")
7483    (set_attr "mode" "DI")])
7484
7485 (define_split
7486   [(set (match_operand:DI 0 "register_operand" "")
7487         (div:DI (match_operand:DI 1 "register_operand" "")
7488                 (match_operand:DI 2 "nonimmediate_operand" "")))
7489    (set (match_operand:DI 3 "register_operand" "")
7490         (mod:DI (match_dup 1) (match_dup 2)))
7491    (clobber (reg:CC FLAGS_REG))]
7492   "TARGET_64BIT && reload_completed"
7493   [(parallel [(set (match_dup 3)
7494                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7495               (clobber (reg:CC FLAGS_REG))])
7496    (parallel [(set (match_dup 0)
7497                    (div:DI (reg:DI 0) (match_dup 2)))
7498               (set (match_dup 3)
7499                    (mod:DI (reg:DI 0) (match_dup 2)))
7500               (use (match_dup 3))
7501               (clobber (reg:CC FLAGS_REG))])]
7502 {
7503   /* Avoid use of cltd in favor of a mov+shift.  */
7504   if (!TARGET_USE_CLTD && !optimize_size)
7505     {
7506       if (true_regnum (operands[1]))
7507         emit_move_insn (operands[0], operands[1]);
7508       else
7509         emit_move_insn (operands[3], operands[1]);
7510       operands[4] = operands[3];
7511     }
7512   else
7513     {
7514       gcc_assert (!true_regnum (operands[1]));
7515       operands[4] = operands[1];
7516     }
7517 })
7518
7519
7520 (define_expand "divmodsi4"
7521   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7522                    (div:SI (match_operand:SI 1 "register_operand" "")
7523                            (match_operand:SI 2 "nonimmediate_operand" "")))
7524               (set (match_operand:SI 3 "register_operand" "")
7525                    (mod:SI (match_dup 1) (match_dup 2)))
7526               (clobber (reg:CC FLAGS_REG))])]
7527   ""
7528   "")
7529
7530 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7531 ;; Penalize eax case slightly because it results in worse scheduling
7532 ;; of code.
7533 (define_insn "*divmodsi4_nocltd"
7534   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7535         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7536                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7537    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7538         (mod:SI (match_dup 2) (match_dup 3)))
7539    (clobber (reg:CC FLAGS_REG))]
7540   "!optimize_size && !TARGET_USE_CLTD"
7541   "#"
7542   [(set_attr "type" "multi")])
7543
7544 (define_insn "*divmodsi4_cltd"
7545   [(set (match_operand:SI 0 "register_operand" "=a")
7546         (div:SI (match_operand:SI 2 "register_operand" "a")
7547                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7548    (set (match_operand:SI 1 "register_operand" "=&d")
7549         (mod:SI (match_dup 2) (match_dup 3)))
7550    (clobber (reg:CC FLAGS_REG))]
7551   "optimize_size || TARGET_USE_CLTD"
7552   "#"
7553   [(set_attr "type" "multi")])
7554
7555 (define_insn "*divmodsi_noext"
7556   [(set (match_operand:SI 0 "register_operand" "=a")
7557         (div:SI (match_operand:SI 1 "register_operand" "0")
7558                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7559    (set (match_operand:SI 3 "register_operand" "=d")
7560         (mod:SI (match_dup 1) (match_dup 2)))
7561    (use (match_operand:SI 4 "register_operand" "3"))
7562    (clobber (reg:CC FLAGS_REG))]
7563   ""
7564   "idiv{l}\t%2"
7565   [(set_attr "type" "idiv")
7566    (set_attr "mode" "SI")])
7567
7568 (define_split
7569   [(set (match_operand:SI 0 "register_operand" "")
7570         (div:SI (match_operand:SI 1 "register_operand" "")
7571                 (match_operand:SI 2 "nonimmediate_operand" "")))
7572    (set (match_operand:SI 3 "register_operand" "")
7573         (mod:SI (match_dup 1) (match_dup 2)))
7574    (clobber (reg:CC FLAGS_REG))]
7575   "reload_completed"
7576   [(parallel [(set (match_dup 3)
7577                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7578               (clobber (reg:CC FLAGS_REG))])
7579    (parallel [(set (match_dup 0)
7580                    (div:SI (reg:SI 0) (match_dup 2)))
7581               (set (match_dup 3)
7582                    (mod:SI (reg:SI 0) (match_dup 2)))
7583               (use (match_dup 3))
7584               (clobber (reg:CC FLAGS_REG))])]
7585 {
7586   /* Avoid use of cltd in favor of a mov+shift.  */
7587   if (!TARGET_USE_CLTD && !optimize_size)
7588     {
7589       if (true_regnum (operands[1]))
7590         emit_move_insn (operands[0], operands[1]);
7591       else
7592         emit_move_insn (operands[3], operands[1]);
7593       operands[4] = operands[3];
7594     }
7595   else
7596     {
7597       gcc_assert (!true_regnum (operands[1]));
7598       operands[4] = operands[1];
7599     }
7600 })
7601 ;; %%% Split me.
7602 (define_insn "divmodhi4"
7603   [(set (match_operand:HI 0 "register_operand" "=a")
7604         (div:HI (match_operand:HI 1 "register_operand" "0")
7605                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7606    (set (match_operand:HI 3 "register_operand" "=&d")
7607         (mod:HI (match_dup 1) (match_dup 2)))
7608    (clobber (reg:CC FLAGS_REG))]
7609   "TARGET_HIMODE_MATH"
7610   "cwtd\;idiv{w}\t%2"
7611   [(set_attr "type" "multi")
7612    (set_attr "length_immediate" "0")
7613    (set_attr "mode" "SI")])
7614
7615 (define_insn "udivmoddi4"
7616   [(set (match_operand:DI 0 "register_operand" "=a")
7617         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7618                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7619    (set (match_operand:DI 3 "register_operand" "=&d")
7620         (umod:DI (match_dup 1) (match_dup 2)))
7621    (clobber (reg:CC FLAGS_REG))]
7622   "TARGET_64BIT"
7623   "xor{q}\t%3, %3\;div{q}\t%2"
7624   [(set_attr "type" "multi")
7625    (set_attr "length_immediate" "0")
7626    (set_attr "mode" "DI")])
7627
7628 (define_insn "*udivmoddi4_noext"
7629   [(set (match_operand:DI 0 "register_operand" "=a")
7630         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7631                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7632    (set (match_operand:DI 3 "register_operand" "=d")
7633         (umod:DI (match_dup 1) (match_dup 2)))
7634    (use (match_dup 3))
7635    (clobber (reg:CC FLAGS_REG))]
7636   "TARGET_64BIT"
7637   "div{q}\t%2"
7638   [(set_attr "type" "idiv")
7639    (set_attr "mode" "DI")])
7640
7641 (define_split
7642   [(set (match_operand:DI 0 "register_operand" "")
7643         (udiv:DI (match_operand:DI 1 "register_operand" "")
7644                  (match_operand:DI 2 "nonimmediate_operand" "")))
7645    (set (match_operand:DI 3 "register_operand" "")
7646         (umod:DI (match_dup 1) (match_dup 2)))
7647    (clobber (reg:CC FLAGS_REG))]
7648   "TARGET_64BIT && reload_completed"
7649   [(set (match_dup 3) (const_int 0))
7650    (parallel [(set (match_dup 0)
7651                    (udiv:DI (match_dup 1) (match_dup 2)))
7652               (set (match_dup 3)
7653                    (umod:DI (match_dup 1) (match_dup 2)))
7654               (use (match_dup 3))
7655               (clobber (reg:CC FLAGS_REG))])]
7656   "")
7657
7658 (define_insn "udivmodsi4"
7659   [(set (match_operand:SI 0 "register_operand" "=a")
7660         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7661                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7662    (set (match_operand:SI 3 "register_operand" "=&d")
7663         (umod:SI (match_dup 1) (match_dup 2)))
7664    (clobber (reg:CC FLAGS_REG))]
7665   ""
7666   "xor{l}\t%3, %3\;div{l}\t%2"
7667   [(set_attr "type" "multi")
7668    (set_attr "length_immediate" "0")
7669    (set_attr "mode" "SI")])
7670
7671 (define_insn "*udivmodsi4_noext"
7672   [(set (match_operand:SI 0 "register_operand" "=a")
7673         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7674                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7675    (set (match_operand:SI 3 "register_operand" "=d")
7676         (umod:SI (match_dup 1) (match_dup 2)))
7677    (use (match_dup 3))
7678    (clobber (reg:CC FLAGS_REG))]
7679   ""
7680   "div{l}\t%2"
7681   [(set_attr "type" "idiv")
7682    (set_attr "mode" "SI")])
7683
7684 (define_split
7685   [(set (match_operand:SI 0 "register_operand" "")
7686         (udiv:SI (match_operand:SI 1 "register_operand" "")
7687                  (match_operand:SI 2 "nonimmediate_operand" "")))
7688    (set (match_operand:SI 3 "register_operand" "")
7689         (umod:SI (match_dup 1) (match_dup 2)))
7690    (clobber (reg:CC FLAGS_REG))]
7691   "reload_completed"
7692   [(set (match_dup 3) (const_int 0))
7693    (parallel [(set (match_dup 0)
7694                    (udiv:SI (match_dup 1) (match_dup 2)))
7695               (set (match_dup 3)
7696                    (umod:SI (match_dup 1) (match_dup 2)))
7697               (use (match_dup 3))
7698               (clobber (reg:CC FLAGS_REG))])]
7699   "")
7700
7701 (define_expand "udivmodhi4"
7702   [(set (match_dup 4) (const_int 0))
7703    (parallel [(set (match_operand:HI 0 "register_operand" "")
7704                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7705                             (match_operand:HI 2 "nonimmediate_operand" "")))
7706               (set (match_operand:HI 3 "register_operand" "")
7707                    (umod:HI (match_dup 1) (match_dup 2)))
7708               (use (match_dup 4))
7709               (clobber (reg:CC FLAGS_REG))])]
7710   "TARGET_HIMODE_MATH"
7711   "operands[4] = gen_reg_rtx (HImode);")
7712
7713 (define_insn "*udivmodhi_noext"
7714   [(set (match_operand:HI 0 "register_operand" "=a")
7715         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7716                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7717    (set (match_operand:HI 3 "register_operand" "=d")
7718         (umod:HI (match_dup 1) (match_dup 2)))
7719    (use (match_operand:HI 4 "register_operand" "3"))
7720    (clobber (reg:CC FLAGS_REG))]
7721   ""
7722   "div{w}\t%2"
7723   [(set_attr "type" "idiv")
7724    (set_attr "mode" "HI")])
7725
7726 ;; We cannot use div/idiv for double division, because it causes
7727 ;; "division by zero" on the overflow and that's not what we expect
7728 ;; from truncate.  Because true (non truncating) double division is
7729 ;; never generated, we can't create this insn anyway.
7730 ;
7731 ;(define_insn ""
7732 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7733 ;       (truncate:SI
7734 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7735 ;                  (zero_extend:DI
7736 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7737 ;   (set (match_operand:SI 3 "register_operand" "=d")
7738 ;       (truncate:SI
7739 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7740 ;   (clobber (reg:CC FLAGS_REG))]
7741 ;  ""
7742 ;  "div{l}\t{%2, %0|%0, %2}"
7743 ;  [(set_attr "type" "idiv")])
7744 \f
7745 ;;- Logical AND instructions
7746
7747 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7748 ;; Note that this excludes ah.
7749
7750 (define_insn "*testdi_1_rex64"
7751   [(set (reg FLAGS_REG)
7752         (compare
7753           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7754                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7755           (const_int 0)))]
7756   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7757    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7758   "@
7759    test{l}\t{%k1, %k0|%k0, %k1}
7760    test{l}\t{%k1, %k0|%k0, %k1}
7761    test{q}\t{%1, %0|%0, %1}
7762    test{q}\t{%1, %0|%0, %1}
7763    test{q}\t{%1, %0|%0, %1}"
7764   [(set_attr "type" "test")
7765    (set_attr "modrm" "0,1,0,1,1")
7766    (set_attr "mode" "SI,SI,DI,DI,DI")
7767    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7768
7769 (define_insn "testsi_1"
7770   [(set (reg FLAGS_REG)
7771         (compare
7772           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7773                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7774           (const_int 0)))]
7775   "ix86_match_ccmode (insn, CCNOmode)
7776    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7777   "test{l}\t{%1, %0|%0, %1}"
7778   [(set_attr "type" "test")
7779    (set_attr "modrm" "0,1,1")
7780    (set_attr "mode" "SI")
7781    (set_attr "pent_pair" "uv,np,uv")])
7782
7783 (define_expand "testsi_ccno_1"
7784   [(set (reg:CCNO FLAGS_REG)
7785         (compare:CCNO
7786           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7787                   (match_operand:SI 1 "nonmemory_operand" ""))
7788           (const_int 0)))]
7789   ""
7790   "")
7791
7792 (define_insn "*testhi_1"
7793   [(set (reg FLAGS_REG)
7794         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7795                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7796                  (const_int 0)))]
7797   "ix86_match_ccmode (insn, CCNOmode)
7798    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7799   "test{w}\t{%1, %0|%0, %1}"
7800   [(set_attr "type" "test")
7801    (set_attr "modrm" "0,1,1")
7802    (set_attr "mode" "HI")
7803    (set_attr "pent_pair" "uv,np,uv")])
7804
7805 (define_expand "testqi_ccz_1"
7806   [(set (reg:CCZ FLAGS_REG)
7807         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7808                              (match_operand:QI 1 "nonmemory_operand" ""))
7809                  (const_int 0)))]
7810   ""
7811   "")
7812
7813 (define_insn "*testqi_1_maybe_si"
7814   [(set (reg FLAGS_REG)
7815         (compare
7816           (and:QI
7817             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7818             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7819           (const_int 0)))]
7820    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7821     && ix86_match_ccmode (insn,
7822                          GET_CODE (operands[1]) == CONST_INT
7823                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7824 {
7825   if (which_alternative == 3)
7826     {
7827       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7828         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7829       return "test{l}\t{%1, %k0|%k0, %1}";
7830     }
7831   return "test{b}\t{%1, %0|%0, %1}";
7832 }
7833   [(set_attr "type" "test")
7834    (set_attr "modrm" "0,1,1,1")
7835    (set_attr "mode" "QI,QI,QI,SI")
7836    (set_attr "pent_pair" "uv,np,uv,np")])
7837
7838 (define_insn "*testqi_1"
7839   [(set (reg FLAGS_REG)
7840         (compare
7841           (and:QI
7842             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7843             (match_operand:QI 1 "general_operand" "n,n,qn"))
7844           (const_int 0)))]
7845   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7846    && ix86_match_ccmode (insn, CCNOmode)"
7847   "test{b}\t{%1, %0|%0, %1}"
7848   [(set_attr "type" "test")
7849    (set_attr "modrm" "0,1,1")
7850    (set_attr "mode" "QI")
7851    (set_attr "pent_pair" "uv,np,uv")])
7852
7853 (define_expand "testqi_ext_ccno_0"
7854   [(set (reg:CCNO FLAGS_REG)
7855         (compare:CCNO
7856           (and:SI
7857             (zero_extract:SI
7858               (match_operand 0 "ext_register_operand" "")
7859               (const_int 8)
7860               (const_int 8))
7861             (match_operand 1 "const_int_operand" ""))
7862           (const_int 0)))]
7863   ""
7864   "")
7865
7866 (define_insn "*testqi_ext_0"
7867   [(set (reg FLAGS_REG)
7868         (compare
7869           (and:SI
7870             (zero_extract:SI
7871               (match_operand 0 "ext_register_operand" "Q")
7872               (const_int 8)
7873               (const_int 8))
7874             (match_operand 1 "const_int_operand" "n"))
7875           (const_int 0)))]
7876   "ix86_match_ccmode (insn, CCNOmode)"
7877   "test{b}\t{%1, %h0|%h0, %1}"
7878   [(set_attr "type" "test")
7879    (set_attr "mode" "QI")
7880    (set_attr "length_immediate" "1")
7881    (set_attr "pent_pair" "np")])
7882
7883 (define_insn "*testqi_ext_1"
7884   [(set (reg FLAGS_REG)
7885         (compare
7886           (and:SI
7887             (zero_extract:SI
7888               (match_operand 0 "ext_register_operand" "Q")
7889               (const_int 8)
7890               (const_int 8))
7891             (zero_extend:SI
7892               (match_operand:QI 1 "general_operand" "Qm")))
7893           (const_int 0)))]
7894   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7895    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7896   "test{b}\t{%1, %h0|%h0, %1}"
7897   [(set_attr "type" "test")
7898    (set_attr "mode" "QI")])
7899
7900 (define_insn "*testqi_ext_1_rex64"
7901   [(set (reg FLAGS_REG)
7902         (compare
7903           (and:SI
7904             (zero_extract:SI
7905               (match_operand 0 "ext_register_operand" "Q")
7906               (const_int 8)
7907               (const_int 8))
7908             (zero_extend:SI
7909               (match_operand:QI 1 "register_operand" "Q")))
7910           (const_int 0)))]
7911   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7912   "test{b}\t{%1, %h0|%h0, %1}"
7913   [(set_attr "type" "test")
7914    (set_attr "mode" "QI")])
7915
7916 (define_insn "*testqi_ext_2"
7917   [(set (reg FLAGS_REG)
7918         (compare
7919           (and:SI
7920             (zero_extract:SI
7921               (match_operand 0 "ext_register_operand" "Q")
7922               (const_int 8)
7923               (const_int 8))
7924             (zero_extract:SI
7925               (match_operand 1 "ext_register_operand" "Q")
7926               (const_int 8)
7927               (const_int 8)))
7928           (const_int 0)))]
7929   "ix86_match_ccmode (insn, CCNOmode)"
7930   "test{b}\t{%h1, %h0|%h0, %h1}"
7931   [(set_attr "type" "test")
7932    (set_attr "mode" "QI")])
7933
7934 ;; Combine likes to form bit extractions for some tests.  Humor it.
7935 (define_insn "*testqi_ext_3"
7936   [(set (reg FLAGS_REG)
7937         (compare (zero_extract:SI
7938                    (match_operand 0 "nonimmediate_operand" "rm")
7939                    (match_operand:SI 1 "const_int_operand" "")
7940                    (match_operand:SI 2 "const_int_operand" ""))
7941                  (const_int 0)))]
7942   "ix86_match_ccmode (insn, CCNOmode)
7943    && INTVAL (operands[1]) > 0
7944    && INTVAL (operands[2]) >= 0
7945    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7946    && (GET_MODE (operands[0]) == SImode
7947        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7948        || GET_MODE (operands[0]) == HImode
7949        || GET_MODE (operands[0]) == QImode)"
7950   "#")
7951
7952 (define_insn "*testqi_ext_3_rex64"
7953   [(set (reg FLAGS_REG)
7954         (compare (zero_extract:DI
7955                    (match_operand 0 "nonimmediate_operand" "rm")
7956                    (match_operand:DI 1 "const_int_operand" "")
7957                    (match_operand:DI 2 "const_int_operand" ""))
7958                  (const_int 0)))]
7959   "TARGET_64BIT
7960    && ix86_match_ccmode (insn, CCNOmode)
7961    && INTVAL (operands[1]) > 0
7962    && INTVAL (operands[2]) >= 0
7963    /* Ensure that resulting mask is zero or sign extended operand.  */
7964    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7965        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7966            && INTVAL (operands[1]) > 32))
7967    && (GET_MODE (operands[0]) == SImode
7968        || GET_MODE (operands[0]) == DImode
7969        || GET_MODE (operands[0]) == HImode
7970        || GET_MODE (operands[0]) == QImode)"
7971   "#")
7972
7973 (define_split
7974   [(set (match_operand 0 "flags_reg_operand" "")
7975         (match_operator 1 "compare_operator"
7976           [(zero_extract
7977              (match_operand 2 "nonimmediate_operand" "")
7978              (match_operand 3 "const_int_operand" "")
7979              (match_operand 4 "const_int_operand" ""))
7980            (const_int 0)]))]
7981   "ix86_match_ccmode (insn, CCNOmode)"
7982   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7983 {
7984   rtx val = operands[2];
7985   HOST_WIDE_INT len = INTVAL (operands[3]);
7986   HOST_WIDE_INT pos = INTVAL (operands[4]);
7987   HOST_WIDE_INT mask;
7988   enum machine_mode mode, submode;
7989
7990   mode = GET_MODE (val);
7991   if (GET_CODE (val) == MEM)
7992     {
7993       /* ??? Combine likes to put non-volatile mem extractions in QImode
7994          no matter the size of the test.  So find a mode that works.  */
7995       if (! MEM_VOLATILE_P (val))
7996         {
7997           mode = smallest_mode_for_size (pos + len, MODE_INT);
7998           val = adjust_address (val, mode, 0);
7999         }
8000     }
8001   else if (GET_CODE (val) == SUBREG
8002            && (submode = GET_MODE (SUBREG_REG (val)),
8003                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8004            && pos + len <= GET_MODE_BITSIZE (submode))
8005     {
8006       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8007       mode = submode;
8008       val = SUBREG_REG (val);
8009     }
8010   else if (mode == HImode && pos + len <= 8)
8011     {
8012       /* Small HImode tests can be converted to QImode.  */
8013       mode = QImode;
8014       val = gen_lowpart (QImode, val);
8015     }
8016
8017   if (len == HOST_BITS_PER_WIDE_INT)
8018     mask = -1;
8019   else
8020     mask = ((HOST_WIDE_INT)1 << len) - 1;
8021   mask <<= pos;
8022
8023   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8024 })
8025
8026 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8027 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8028 ;; this is relatively important trick.
8029 ;; Do the conversion only post-reload to avoid limiting of the register class
8030 ;; to QI regs.
8031 (define_split
8032   [(set (match_operand 0 "flags_reg_operand" "")
8033         (match_operator 1 "compare_operator"
8034           [(and (match_operand 2 "register_operand" "")
8035                 (match_operand 3 "const_int_operand" ""))
8036            (const_int 0)]))]
8037    "reload_completed
8038     && QI_REG_P (operands[2])
8039     && GET_MODE (operands[2]) != QImode
8040     && ((ix86_match_ccmode (insn, CCZmode)
8041          && !(INTVAL (operands[3]) & ~(255 << 8)))
8042         || (ix86_match_ccmode (insn, CCNOmode)
8043             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8044   [(set (match_dup 0)
8045         (match_op_dup 1
8046           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8047                    (match_dup 3))
8048            (const_int 0)]))]
8049   "operands[2] = gen_lowpart (SImode, operands[2]);
8050    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8051
8052 (define_split
8053   [(set (match_operand 0 "flags_reg_operand" "")
8054         (match_operator 1 "compare_operator"
8055           [(and (match_operand 2 "nonimmediate_operand" "")
8056                 (match_operand 3 "const_int_operand" ""))
8057            (const_int 0)]))]
8058    "reload_completed
8059     && GET_MODE (operands[2]) != QImode
8060     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8061     && ((ix86_match_ccmode (insn, CCZmode)
8062          && !(INTVAL (operands[3]) & ~255))
8063         || (ix86_match_ccmode (insn, CCNOmode)
8064             && !(INTVAL (operands[3]) & ~127)))"
8065   [(set (match_dup 0)
8066         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8067                          (const_int 0)]))]
8068   "operands[2] = gen_lowpart (QImode, operands[2]);
8069    operands[3] = gen_lowpart (QImode, operands[3]);")
8070
8071
8072 ;; %%% This used to optimize known byte-wide and operations to memory,
8073 ;; and sometimes to QImode registers.  If this is considered useful,
8074 ;; it should be done with splitters.
8075
8076 (define_expand "anddi3"
8077   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8078         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8079                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8080    (clobber (reg:CC FLAGS_REG))]
8081   "TARGET_64BIT"
8082   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8083
8084 (define_insn "*anddi_1_rex64"
8085   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8086         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8087                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8088    (clobber (reg:CC FLAGS_REG))]
8089   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8090 {
8091   switch (get_attr_type (insn))
8092     {
8093     case TYPE_IMOVX:
8094       {
8095         enum machine_mode mode;
8096
8097         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8098         if (INTVAL (operands[2]) == 0xff)
8099           mode = QImode;
8100         else
8101           {
8102             gcc_assert (INTVAL (operands[2]) == 0xffff);
8103             mode = HImode;
8104           }
8105
8106         operands[1] = gen_lowpart (mode, operands[1]);
8107         if (mode == QImode)
8108           return "movz{bq|x}\t{%1,%0|%0, %1}";
8109         else
8110           return "movz{wq|x}\t{%1,%0|%0, %1}";
8111       }
8112
8113     default:
8114       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8115       if (get_attr_mode (insn) == MODE_SI)
8116         return "and{l}\t{%k2, %k0|%k0, %k2}";
8117       else
8118         return "and{q}\t{%2, %0|%0, %2}";
8119     }
8120 }
8121   [(set_attr "type" "alu,alu,alu,imovx")
8122    (set_attr "length_immediate" "*,*,*,0")
8123    (set_attr "mode" "SI,DI,DI,DI")])
8124
8125 (define_insn "*anddi_2"
8126   [(set (reg FLAGS_REG)
8127         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8128                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8129                  (const_int 0)))
8130    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8131         (and:DI (match_dup 1) (match_dup 2)))]
8132   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8133    && ix86_binary_operator_ok (AND, DImode, operands)"
8134   "@
8135    and{l}\t{%k2, %k0|%k0, %k2}
8136    and{q}\t{%2, %0|%0, %2}
8137    and{q}\t{%2, %0|%0, %2}"
8138   [(set_attr "type" "alu")
8139    (set_attr "mode" "SI,DI,DI")])
8140
8141 (define_expand "andsi3"
8142   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8143         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8144                 (match_operand:SI 2 "general_operand" "")))
8145    (clobber (reg:CC FLAGS_REG))]
8146   ""
8147   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8148
8149 (define_insn "*andsi_1"
8150   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8151         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8152                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8153    (clobber (reg:CC FLAGS_REG))]
8154   "ix86_binary_operator_ok (AND, SImode, operands)"
8155 {
8156   switch (get_attr_type (insn))
8157     {
8158     case TYPE_IMOVX:
8159       {
8160         enum machine_mode mode;
8161
8162         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8163         if (INTVAL (operands[2]) == 0xff)
8164           mode = QImode;
8165         else
8166           {
8167             gcc_assert (INTVAL (operands[2]) == 0xffff);
8168             mode = HImode;
8169           }
8170
8171         operands[1] = gen_lowpart (mode, operands[1]);
8172         if (mode == QImode)
8173           return "movz{bl|x}\t{%1,%0|%0, %1}";
8174         else
8175           return "movz{wl|x}\t{%1,%0|%0, %1}";
8176       }
8177
8178     default:
8179       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8180       return "and{l}\t{%2, %0|%0, %2}";
8181     }
8182 }
8183   [(set_attr "type" "alu,alu,imovx")
8184    (set_attr "length_immediate" "*,*,0")
8185    (set_attr "mode" "SI")])
8186
8187 (define_split
8188   [(set (match_operand 0 "register_operand" "")
8189         (and (match_dup 0)
8190              (const_int -65536)))
8191    (clobber (reg:CC FLAGS_REG))]
8192   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8193   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8194   "operands[1] = gen_lowpart (HImode, operands[0]);")
8195
8196 (define_split
8197   [(set (match_operand 0 "ext_register_operand" "")
8198         (and (match_dup 0)
8199              (const_int -256)))
8200    (clobber (reg:CC FLAGS_REG))]
8201   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8202   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8203   "operands[1] = gen_lowpart (QImode, operands[0]);")
8204
8205 (define_split
8206   [(set (match_operand 0 "ext_register_operand" "")
8207         (and (match_dup 0)
8208              (const_int -65281)))
8209    (clobber (reg:CC FLAGS_REG))]
8210   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8211   [(parallel [(set (zero_extract:SI (match_dup 0)
8212                                     (const_int 8)
8213                                     (const_int 8))
8214                    (xor:SI
8215                      (zero_extract:SI (match_dup 0)
8216                                       (const_int 8)
8217                                       (const_int 8))
8218                      (zero_extract:SI (match_dup 0)
8219                                       (const_int 8)
8220                                       (const_int 8))))
8221               (clobber (reg:CC FLAGS_REG))])]
8222   "operands[0] = gen_lowpart (SImode, operands[0]);")
8223
8224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8225 (define_insn "*andsi_1_zext"
8226   [(set (match_operand:DI 0 "register_operand" "=r")
8227         (zero_extend:DI
8228           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8229                   (match_operand:SI 2 "general_operand" "rim"))))
8230    (clobber (reg:CC FLAGS_REG))]
8231   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8232   "and{l}\t{%2, %k0|%k0, %2}"
8233   [(set_attr "type" "alu")
8234    (set_attr "mode" "SI")])
8235
8236 (define_insn "*andsi_2"
8237   [(set (reg FLAGS_REG)
8238         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8239                          (match_operand:SI 2 "general_operand" "rim,ri"))
8240                  (const_int 0)))
8241    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8242         (and:SI (match_dup 1) (match_dup 2)))]
8243   "ix86_match_ccmode (insn, CCNOmode)
8244    && ix86_binary_operator_ok (AND, SImode, operands)"
8245   "and{l}\t{%2, %0|%0, %2}"
8246   [(set_attr "type" "alu")
8247    (set_attr "mode" "SI")])
8248
8249 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8250 (define_insn "*andsi_2_zext"
8251   [(set (reg FLAGS_REG)
8252         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8253                          (match_operand:SI 2 "general_operand" "rim"))
8254                  (const_int 0)))
8255    (set (match_operand:DI 0 "register_operand" "=r")
8256         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8257   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8258    && ix86_binary_operator_ok (AND, SImode, operands)"
8259   "and{l}\t{%2, %k0|%k0, %2}"
8260   [(set_attr "type" "alu")
8261    (set_attr "mode" "SI")])
8262
8263 (define_expand "andhi3"
8264   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8265         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8266                 (match_operand:HI 2 "general_operand" "")))
8267    (clobber (reg:CC FLAGS_REG))]
8268   "TARGET_HIMODE_MATH"
8269   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8270
8271 (define_insn "*andhi_1"
8272   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8273         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8274                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8275    (clobber (reg:CC FLAGS_REG))]
8276   "ix86_binary_operator_ok (AND, HImode, operands)"
8277 {
8278   switch (get_attr_type (insn))
8279     {
8280     case TYPE_IMOVX:
8281       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8282       gcc_assert (INTVAL (operands[2]) == 0xff);
8283       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8284
8285     default:
8286       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8287
8288       return "and{w}\t{%2, %0|%0, %2}";
8289     }
8290 }
8291   [(set_attr "type" "alu,alu,imovx")
8292    (set_attr "length_immediate" "*,*,0")
8293    (set_attr "mode" "HI,HI,SI")])
8294
8295 (define_insn "*andhi_2"
8296   [(set (reg FLAGS_REG)
8297         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8298                          (match_operand:HI 2 "general_operand" "rim,ri"))
8299                  (const_int 0)))
8300    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8301         (and:HI (match_dup 1) (match_dup 2)))]
8302   "ix86_match_ccmode (insn, CCNOmode)
8303    && ix86_binary_operator_ok (AND, HImode, operands)"
8304   "and{w}\t{%2, %0|%0, %2}"
8305   [(set_attr "type" "alu")
8306    (set_attr "mode" "HI")])
8307
8308 (define_expand "andqi3"
8309   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8310         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8311                 (match_operand:QI 2 "general_operand" "")))
8312    (clobber (reg:CC FLAGS_REG))]
8313   "TARGET_QIMODE_MATH"
8314   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8315
8316 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8317 (define_insn "*andqi_1"
8318   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8319         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8320                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8321    (clobber (reg:CC FLAGS_REG))]
8322   "ix86_binary_operator_ok (AND, QImode, operands)"
8323   "@
8324    and{b}\t{%2, %0|%0, %2}
8325    and{b}\t{%2, %0|%0, %2}
8326    and{l}\t{%k2, %k0|%k0, %k2}"
8327   [(set_attr "type" "alu")
8328    (set_attr "mode" "QI,QI,SI")])
8329
8330 (define_insn "*andqi_1_slp"
8331   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8332         (and:QI (match_dup 0)
8333                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8334    (clobber (reg:CC FLAGS_REG))]
8335   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8336    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8337   "and{b}\t{%1, %0|%0, %1}"
8338   [(set_attr "type" "alu1")
8339    (set_attr "mode" "QI")])
8340
8341 (define_insn "*andqi_2_maybe_si"
8342   [(set (reg FLAGS_REG)
8343         (compare (and:QI
8344                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8345                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8346                  (const_int 0)))
8347    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8348         (and:QI (match_dup 1) (match_dup 2)))]
8349   "ix86_binary_operator_ok (AND, QImode, operands)
8350    && ix86_match_ccmode (insn,
8351                          GET_CODE (operands[2]) == CONST_INT
8352                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8353 {
8354   if (which_alternative == 2)
8355     {
8356       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8357         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8358       return "and{l}\t{%2, %k0|%k0, %2}";
8359     }
8360   return "and{b}\t{%2, %0|%0, %2}";
8361 }
8362   [(set_attr "type" "alu")
8363    (set_attr "mode" "QI,QI,SI")])
8364
8365 (define_insn "*andqi_2"
8366   [(set (reg FLAGS_REG)
8367         (compare (and:QI
8368                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8369                    (match_operand:QI 2 "general_operand" "qim,qi"))
8370                  (const_int 0)))
8371    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8372         (and:QI (match_dup 1) (match_dup 2)))]
8373   "ix86_match_ccmode (insn, CCNOmode)
8374    && ix86_binary_operator_ok (AND, QImode, operands)"
8375   "and{b}\t{%2, %0|%0, %2}"
8376   [(set_attr "type" "alu")
8377    (set_attr "mode" "QI")])
8378
8379 (define_insn "*andqi_2_slp"
8380   [(set (reg FLAGS_REG)
8381         (compare (and:QI
8382                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8383                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8384                  (const_int 0)))
8385    (set (strict_low_part (match_dup 0))
8386         (and:QI (match_dup 0) (match_dup 1)))]
8387   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8388    && ix86_match_ccmode (insn, CCNOmode)
8389    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8390   "and{b}\t{%1, %0|%0, %1}"
8391   [(set_attr "type" "alu1")
8392    (set_attr "mode" "QI")])
8393
8394 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8395 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8396 ;; for a QImode operand, which of course failed.
8397
8398 (define_insn "andqi_ext_0"
8399   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8400                          (const_int 8)
8401                          (const_int 8))
8402         (and:SI
8403           (zero_extract:SI
8404             (match_operand 1 "ext_register_operand" "0")
8405             (const_int 8)
8406             (const_int 8))
8407           (match_operand 2 "const_int_operand" "n")))
8408    (clobber (reg:CC FLAGS_REG))]
8409   ""
8410   "and{b}\t{%2, %h0|%h0, %2}"
8411   [(set_attr "type" "alu")
8412    (set_attr "length_immediate" "1")
8413    (set_attr "mode" "QI")])
8414
8415 ;; Generated by peephole translating test to and.  This shows up
8416 ;; often in fp comparisons.
8417
8418 (define_insn "*andqi_ext_0_cc"
8419   [(set (reg FLAGS_REG)
8420         (compare
8421           (and:SI
8422             (zero_extract:SI
8423               (match_operand 1 "ext_register_operand" "0")
8424               (const_int 8)
8425               (const_int 8))
8426             (match_operand 2 "const_int_operand" "n"))
8427           (const_int 0)))
8428    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8429                          (const_int 8)
8430                          (const_int 8))
8431         (and:SI
8432           (zero_extract:SI
8433             (match_dup 1)
8434             (const_int 8)
8435             (const_int 8))
8436           (match_dup 2)))]
8437   "ix86_match_ccmode (insn, CCNOmode)"
8438   "and{b}\t{%2, %h0|%h0, %2}"
8439   [(set_attr "type" "alu")
8440    (set_attr "length_immediate" "1")
8441    (set_attr "mode" "QI")])
8442
8443 (define_insn "*andqi_ext_1"
8444   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8445                          (const_int 8)
8446                          (const_int 8))
8447         (and:SI
8448           (zero_extract:SI
8449             (match_operand 1 "ext_register_operand" "0")
8450             (const_int 8)
8451             (const_int 8))
8452           (zero_extend:SI
8453             (match_operand:QI 2 "general_operand" "Qm"))))
8454    (clobber (reg:CC FLAGS_REG))]
8455   "!TARGET_64BIT"
8456   "and{b}\t{%2, %h0|%h0, %2}"
8457   [(set_attr "type" "alu")
8458    (set_attr "length_immediate" "0")
8459    (set_attr "mode" "QI")])
8460
8461 (define_insn "*andqi_ext_1_rex64"
8462   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8463                          (const_int 8)
8464                          (const_int 8))
8465         (and:SI
8466           (zero_extract:SI
8467             (match_operand 1 "ext_register_operand" "0")
8468             (const_int 8)
8469             (const_int 8))
8470           (zero_extend:SI
8471             (match_operand 2 "ext_register_operand" "Q"))))
8472    (clobber (reg:CC FLAGS_REG))]
8473   "TARGET_64BIT"
8474   "and{b}\t{%2, %h0|%h0, %2}"
8475   [(set_attr "type" "alu")
8476    (set_attr "length_immediate" "0")
8477    (set_attr "mode" "QI")])
8478
8479 (define_insn "*andqi_ext_2"
8480   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8481                          (const_int 8)
8482                          (const_int 8))
8483         (and:SI
8484           (zero_extract:SI
8485             (match_operand 1 "ext_register_operand" "%0")
8486             (const_int 8)
8487             (const_int 8))
8488           (zero_extract:SI
8489             (match_operand 2 "ext_register_operand" "Q")
8490             (const_int 8)
8491             (const_int 8))))
8492    (clobber (reg:CC FLAGS_REG))]
8493   ""
8494   "and{b}\t{%h2, %h0|%h0, %h2}"
8495   [(set_attr "type" "alu")
8496    (set_attr "length_immediate" "0")
8497    (set_attr "mode" "QI")])
8498
8499 ;; Convert wide AND instructions with immediate operand to shorter QImode
8500 ;; equivalents when possible.
8501 ;; Don't do the splitting with memory operands, since it introduces risk
8502 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8503 ;; for size, but that can (should?) be handled by generic code instead.
8504 (define_split
8505   [(set (match_operand 0 "register_operand" "")
8506         (and (match_operand 1 "register_operand" "")
8507              (match_operand 2 "const_int_operand" "")))
8508    (clobber (reg:CC FLAGS_REG))]
8509    "reload_completed
8510     && QI_REG_P (operands[0])
8511     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8512     && !(~INTVAL (operands[2]) & ~(255 << 8))
8513     && GET_MODE (operands[0]) != QImode"
8514   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8515                    (and:SI (zero_extract:SI (match_dup 1)
8516                                             (const_int 8) (const_int 8))
8517                            (match_dup 2)))
8518               (clobber (reg:CC FLAGS_REG))])]
8519   "operands[0] = gen_lowpart (SImode, operands[0]);
8520    operands[1] = gen_lowpart (SImode, operands[1]);
8521    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8522
8523 ;; Since AND can be encoded with sign extended immediate, this is only
8524 ;; profitable when 7th bit is not set.
8525 (define_split
8526   [(set (match_operand 0 "register_operand" "")
8527         (and (match_operand 1 "general_operand" "")
8528              (match_operand 2 "const_int_operand" "")))
8529    (clobber (reg:CC FLAGS_REG))]
8530    "reload_completed
8531     && ANY_QI_REG_P (operands[0])
8532     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8533     && !(~INTVAL (operands[2]) & ~255)
8534     && !(INTVAL (operands[2]) & 128)
8535     && GET_MODE (operands[0]) != QImode"
8536   [(parallel [(set (strict_low_part (match_dup 0))
8537                    (and:QI (match_dup 1)
8538                            (match_dup 2)))
8539               (clobber (reg:CC FLAGS_REG))])]
8540   "operands[0] = gen_lowpart (QImode, operands[0]);
8541    operands[1] = gen_lowpart (QImode, operands[1]);
8542    operands[2] = gen_lowpart (QImode, operands[2]);")
8543 \f
8544 ;; Logical inclusive OR instructions
8545
8546 ;; %%% This used to optimize known byte-wide and operations to memory.
8547 ;; If this is considered useful, it should be done with splitters.
8548
8549 (define_expand "iordi3"
8550   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8551         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8552                 (match_operand:DI 2 "x86_64_general_operand" "")))
8553    (clobber (reg:CC FLAGS_REG))]
8554   "TARGET_64BIT"
8555   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8556
8557 (define_insn "*iordi_1_rex64"
8558   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8559         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8560                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8561    (clobber (reg:CC FLAGS_REG))]
8562   "TARGET_64BIT
8563    && ix86_binary_operator_ok (IOR, DImode, operands)"
8564   "or{q}\t{%2, %0|%0, %2}"
8565   [(set_attr "type" "alu")
8566    (set_attr "mode" "DI")])
8567
8568 (define_insn "*iordi_2_rex64"
8569   [(set (reg FLAGS_REG)
8570         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8571                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8572                  (const_int 0)))
8573    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8574         (ior:DI (match_dup 1) (match_dup 2)))]
8575   "TARGET_64BIT
8576    && ix86_match_ccmode (insn, CCNOmode)
8577    && ix86_binary_operator_ok (IOR, DImode, operands)"
8578   "or{q}\t{%2, %0|%0, %2}"
8579   [(set_attr "type" "alu")
8580    (set_attr "mode" "DI")])
8581
8582 (define_insn "*iordi_3_rex64"
8583   [(set (reg FLAGS_REG)
8584         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8585                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8586                  (const_int 0)))
8587    (clobber (match_scratch:DI 0 "=r"))]
8588   "TARGET_64BIT
8589    && ix86_match_ccmode (insn, CCNOmode)
8590    && ix86_binary_operator_ok (IOR, DImode, operands)"
8591   "or{q}\t{%2, %0|%0, %2}"
8592   [(set_attr "type" "alu")
8593    (set_attr "mode" "DI")])
8594
8595
8596 (define_expand "iorsi3"
8597   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8598         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8599                 (match_operand:SI 2 "general_operand" "")))
8600    (clobber (reg:CC FLAGS_REG))]
8601   ""
8602   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8603
8604 (define_insn "*iorsi_1"
8605   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8606         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8607                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8608    (clobber (reg:CC FLAGS_REG))]
8609   "ix86_binary_operator_ok (IOR, SImode, operands)"
8610   "or{l}\t{%2, %0|%0, %2}"
8611   [(set_attr "type" "alu")
8612    (set_attr "mode" "SI")])
8613
8614 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8615 (define_insn "*iorsi_1_zext"
8616   [(set (match_operand:DI 0 "register_operand" "=rm")
8617         (zero_extend:DI
8618           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8619                   (match_operand:SI 2 "general_operand" "rim"))))
8620    (clobber (reg:CC FLAGS_REG))]
8621   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8622   "or{l}\t{%2, %k0|%k0, %2}"
8623   [(set_attr "type" "alu")
8624    (set_attr "mode" "SI")])
8625
8626 (define_insn "*iorsi_1_zext_imm"
8627   [(set (match_operand:DI 0 "register_operand" "=rm")
8628         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8629                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8630    (clobber (reg:CC FLAGS_REG))]
8631   "TARGET_64BIT"
8632   "or{l}\t{%2, %k0|%k0, %2}"
8633   [(set_attr "type" "alu")
8634    (set_attr "mode" "SI")])
8635
8636 (define_insn "*iorsi_2"
8637   [(set (reg FLAGS_REG)
8638         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8639                          (match_operand:SI 2 "general_operand" "rim,ri"))
8640                  (const_int 0)))
8641    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8642         (ior:SI (match_dup 1) (match_dup 2)))]
8643   "ix86_match_ccmode (insn, CCNOmode)
8644    && ix86_binary_operator_ok (IOR, SImode, operands)"
8645   "or{l}\t{%2, %0|%0, %2}"
8646   [(set_attr "type" "alu")
8647    (set_attr "mode" "SI")])
8648
8649 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8650 ;; ??? Special case for immediate operand is missing - it is tricky.
8651 (define_insn "*iorsi_2_zext"
8652   [(set (reg FLAGS_REG)
8653         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8654                          (match_operand:SI 2 "general_operand" "rim"))
8655                  (const_int 0)))
8656    (set (match_operand:DI 0 "register_operand" "=r")
8657         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8658   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8659    && ix86_binary_operator_ok (IOR, SImode, operands)"
8660   "or{l}\t{%2, %k0|%k0, %2}"
8661   [(set_attr "type" "alu")
8662    (set_attr "mode" "SI")])
8663
8664 (define_insn "*iorsi_2_zext_imm"
8665   [(set (reg FLAGS_REG)
8666         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8667                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8668                  (const_int 0)))
8669    (set (match_operand:DI 0 "register_operand" "=r")
8670         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8671   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8672    && ix86_binary_operator_ok (IOR, SImode, operands)"
8673   "or{l}\t{%2, %k0|%k0, %2}"
8674   [(set_attr "type" "alu")
8675    (set_attr "mode" "SI")])
8676
8677 (define_insn "*iorsi_3"
8678   [(set (reg FLAGS_REG)
8679         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8680                          (match_operand:SI 2 "general_operand" "rim"))
8681                  (const_int 0)))
8682    (clobber (match_scratch:SI 0 "=r"))]
8683   "ix86_match_ccmode (insn, CCNOmode)
8684    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8685   "or{l}\t{%2, %0|%0, %2}"
8686   [(set_attr "type" "alu")
8687    (set_attr "mode" "SI")])
8688
8689 (define_expand "iorhi3"
8690   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8691         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8692                 (match_operand:HI 2 "general_operand" "")))
8693    (clobber (reg:CC FLAGS_REG))]
8694   "TARGET_HIMODE_MATH"
8695   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8696
8697 (define_insn "*iorhi_1"
8698   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8699         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8700                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8701    (clobber (reg:CC FLAGS_REG))]
8702   "ix86_binary_operator_ok (IOR, HImode, operands)"
8703   "or{w}\t{%2, %0|%0, %2}"
8704   [(set_attr "type" "alu")
8705    (set_attr "mode" "HI")])
8706
8707 (define_insn "*iorhi_2"
8708   [(set (reg FLAGS_REG)
8709         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8710                          (match_operand:HI 2 "general_operand" "rim,ri"))
8711                  (const_int 0)))
8712    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8713         (ior:HI (match_dup 1) (match_dup 2)))]
8714   "ix86_match_ccmode (insn, CCNOmode)
8715    && ix86_binary_operator_ok (IOR, HImode, operands)"
8716   "or{w}\t{%2, %0|%0, %2}"
8717   [(set_attr "type" "alu")
8718    (set_attr "mode" "HI")])
8719
8720 (define_insn "*iorhi_3"
8721   [(set (reg FLAGS_REG)
8722         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8723                          (match_operand:HI 2 "general_operand" "rim"))
8724                  (const_int 0)))
8725    (clobber (match_scratch:HI 0 "=r"))]
8726   "ix86_match_ccmode (insn, CCNOmode)
8727    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8728   "or{w}\t{%2, %0|%0, %2}"
8729   [(set_attr "type" "alu")
8730    (set_attr "mode" "HI")])
8731
8732 (define_expand "iorqi3"
8733   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8734         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8735                 (match_operand:QI 2 "general_operand" "")))
8736    (clobber (reg:CC FLAGS_REG))]
8737   "TARGET_QIMODE_MATH"
8738   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8739
8740 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8741 (define_insn "*iorqi_1"
8742   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8743         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8744                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8745    (clobber (reg:CC FLAGS_REG))]
8746   "ix86_binary_operator_ok (IOR, QImode, operands)"
8747   "@
8748    or{b}\t{%2, %0|%0, %2}
8749    or{b}\t{%2, %0|%0, %2}
8750    or{l}\t{%k2, %k0|%k0, %k2}"
8751   [(set_attr "type" "alu")
8752    (set_attr "mode" "QI,QI,SI")])
8753
8754 (define_insn "*iorqi_1_slp"
8755   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8756         (ior:QI (match_dup 0)
8757                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8758    (clobber (reg:CC FLAGS_REG))]
8759   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8760    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8761   "or{b}\t{%1, %0|%0, %1}"
8762   [(set_attr "type" "alu1")
8763    (set_attr "mode" "QI")])
8764
8765 (define_insn "*iorqi_2"
8766   [(set (reg FLAGS_REG)
8767         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8768                          (match_operand:QI 2 "general_operand" "qim,qi"))
8769                  (const_int 0)))
8770    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8771         (ior:QI (match_dup 1) (match_dup 2)))]
8772   "ix86_match_ccmode (insn, CCNOmode)
8773    && ix86_binary_operator_ok (IOR, QImode, operands)"
8774   "or{b}\t{%2, %0|%0, %2}"
8775   [(set_attr "type" "alu")
8776    (set_attr "mode" "QI")])
8777
8778 (define_insn "*iorqi_2_slp"
8779   [(set (reg FLAGS_REG)
8780         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8781                          (match_operand:QI 1 "general_operand" "qim,qi"))
8782                  (const_int 0)))
8783    (set (strict_low_part (match_dup 0))
8784         (ior:QI (match_dup 0) (match_dup 1)))]
8785   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8786    && ix86_match_ccmode (insn, CCNOmode)
8787    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8788   "or{b}\t{%1, %0|%0, %1}"
8789   [(set_attr "type" "alu1")
8790    (set_attr "mode" "QI")])
8791
8792 (define_insn "*iorqi_3"
8793   [(set (reg FLAGS_REG)
8794         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8795                          (match_operand:QI 2 "general_operand" "qim"))
8796                  (const_int 0)))
8797    (clobber (match_scratch:QI 0 "=q"))]
8798   "ix86_match_ccmode (insn, CCNOmode)
8799    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8800   "or{b}\t{%2, %0|%0, %2}"
8801   [(set_attr "type" "alu")
8802    (set_attr "mode" "QI")])
8803
8804 (define_insn "iorqi_ext_0"
8805   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8806                          (const_int 8)
8807                          (const_int 8))
8808         (ior:SI
8809           (zero_extract:SI
8810             (match_operand 1 "ext_register_operand" "0")
8811             (const_int 8)
8812             (const_int 8))
8813           (match_operand 2 "const_int_operand" "n")))
8814    (clobber (reg:CC FLAGS_REG))]
8815   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8816   "or{b}\t{%2, %h0|%h0, %2}"
8817   [(set_attr "type" "alu")
8818    (set_attr "length_immediate" "1")
8819    (set_attr "mode" "QI")])
8820
8821 (define_insn "*iorqi_ext_1"
8822   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8823                          (const_int 8)
8824                          (const_int 8))
8825         (ior:SI
8826           (zero_extract:SI
8827             (match_operand 1 "ext_register_operand" "0")
8828             (const_int 8)
8829             (const_int 8))
8830           (zero_extend:SI
8831             (match_operand:QI 2 "general_operand" "Qm"))))
8832    (clobber (reg:CC FLAGS_REG))]
8833   "!TARGET_64BIT
8834    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8835   "or{b}\t{%2, %h0|%h0, %2}"
8836   [(set_attr "type" "alu")
8837    (set_attr "length_immediate" "0")
8838    (set_attr "mode" "QI")])
8839
8840 (define_insn "*iorqi_ext_1_rex64"
8841   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8842                          (const_int 8)
8843                          (const_int 8))
8844         (ior:SI
8845           (zero_extract:SI
8846             (match_operand 1 "ext_register_operand" "0")
8847             (const_int 8)
8848             (const_int 8))
8849           (zero_extend:SI
8850             (match_operand 2 "ext_register_operand" "Q"))))
8851    (clobber (reg:CC FLAGS_REG))]
8852   "TARGET_64BIT
8853    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8854   "or{b}\t{%2, %h0|%h0, %2}"
8855   [(set_attr "type" "alu")
8856    (set_attr "length_immediate" "0")
8857    (set_attr "mode" "QI")])
8858
8859 (define_insn "*iorqi_ext_2"
8860   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8861                          (const_int 8)
8862                          (const_int 8))
8863         (ior:SI
8864           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8865                            (const_int 8)
8866                            (const_int 8))
8867           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8868                            (const_int 8)
8869                            (const_int 8))))
8870    (clobber (reg:CC FLAGS_REG))]
8871   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8872   "ior{b}\t{%h2, %h0|%h0, %h2}"
8873   [(set_attr "type" "alu")
8874    (set_attr "length_immediate" "0")
8875    (set_attr "mode" "QI")])
8876
8877 (define_split
8878   [(set (match_operand 0 "register_operand" "")
8879         (ior (match_operand 1 "register_operand" "")
8880              (match_operand 2 "const_int_operand" "")))
8881    (clobber (reg:CC FLAGS_REG))]
8882    "reload_completed
8883     && QI_REG_P (operands[0])
8884     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8885     && !(INTVAL (operands[2]) & ~(255 << 8))
8886     && GET_MODE (operands[0]) != QImode"
8887   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8888                    (ior:SI (zero_extract:SI (match_dup 1)
8889                                             (const_int 8) (const_int 8))
8890                            (match_dup 2)))
8891               (clobber (reg:CC FLAGS_REG))])]
8892   "operands[0] = gen_lowpart (SImode, operands[0]);
8893    operands[1] = gen_lowpart (SImode, operands[1]);
8894    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8895
8896 ;; Since OR can be encoded with sign extended immediate, this is only
8897 ;; profitable when 7th bit is set.
8898 (define_split
8899   [(set (match_operand 0 "register_operand" "")
8900         (ior (match_operand 1 "general_operand" "")
8901              (match_operand 2 "const_int_operand" "")))
8902    (clobber (reg:CC FLAGS_REG))]
8903    "reload_completed
8904     && ANY_QI_REG_P (operands[0])
8905     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8906     && !(INTVAL (operands[2]) & ~255)
8907     && (INTVAL (operands[2]) & 128)
8908     && GET_MODE (operands[0]) != QImode"
8909   [(parallel [(set (strict_low_part (match_dup 0))
8910                    (ior:QI (match_dup 1)
8911                            (match_dup 2)))
8912               (clobber (reg:CC FLAGS_REG))])]
8913   "operands[0] = gen_lowpart (QImode, operands[0]);
8914    operands[1] = gen_lowpart (QImode, operands[1]);
8915    operands[2] = gen_lowpart (QImode, operands[2]);")
8916 \f
8917 ;; Logical XOR instructions
8918
8919 ;; %%% This used to optimize known byte-wide and operations to memory.
8920 ;; If this is considered useful, it should be done with splitters.
8921
8922 (define_expand "xordi3"
8923   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8924         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8925                 (match_operand:DI 2 "x86_64_general_operand" "")))
8926    (clobber (reg:CC FLAGS_REG))]
8927   "TARGET_64BIT"
8928   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8929
8930 (define_insn "*xordi_1_rex64"
8931   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8932         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8933                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8934    (clobber (reg:CC FLAGS_REG))]
8935   "TARGET_64BIT
8936    && ix86_binary_operator_ok (XOR, DImode, operands)"
8937   "@
8938    xor{q}\t{%2, %0|%0, %2}
8939    xor{q}\t{%2, %0|%0, %2}"
8940   [(set_attr "type" "alu")
8941    (set_attr "mode" "DI,DI")])
8942
8943 (define_insn "*xordi_2_rex64"
8944   [(set (reg FLAGS_REG)
8945         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8946                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8947                  (const_int 0)))
8948    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8949         (xor:DI (match_dup 1) (match_dup 2)))]
8950   "TARGET_64BIT
8951    && ix86_match_ccmode (insn, CCNOmode)
8952    && ix86_binary_operator_ok (XOR, DImode, operands)"
8953   "@
8954    xor{q}\t{%2, %0|%0, %2}
8955    xor{q}\t{%2, %0|%0, %2}"
8956   [(set_attr "type" "alu")
8957    (set_attr "mode" "DI,DI")])
8958
8959 (define_insn "*xordi_3_rex64"
8960   [(set (reg FLAGS_REG)
8961         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8962                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8963                  (const_int 0)))
8964    (clobber (match_scratch:DI 0 "=r"))]
8965   "TARGET_64BIT
8966    && ix86_match_ccmode (insn, CCNOmode)
8967    && ix86_binary_operator_ok (XOR, DImode, operands)"
8968   "xor{q}\t{%2, %0|%0, %2}"
8969   [(set_attr "type" "alu")
8970    (set_attr "mode" "DI")])
8971
8972 (define_expand "xorsi3"
8973   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8974         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8975                 (match_operand:SI 2 "general_operand" "")))
8976    (clobber (reg:CC FLAGS_REG))]
8977   ""
8978   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8979
8980 (define_insn "*xorsi_1"
8981   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8982         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8983                 (match_operand:SI 2 "general_operand" "ri,rm")))
8984    (clobber (reg:CC FLAGS_REG))]
8985   "ix86_binary_operator_ok (XOR, SImode, operands)"
8986   "xor{l}\t{%2, %0|%0, %2}"
8987   [(set_attr "type" "alu")
8988    (set_attr "mode" "SI")])
8989
8990 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8991 ;; Add speccase for immediates
8992 (define_insn "*xorsi_1_zext"
8993   [(set (match_operand:DI 0 "register_operand" "=r")
8994         (zero_extend:DI
8995           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8996                   (match_operand:SI 2 "general_operand" "rim"))))
8997    (clobber (reg:CC FLAGS_REG))]
8998   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8999   "xor{l}\t{%2, %k0|%k0, %2}"
9000   [(set_attr "type" "alu")
9001    (set_attr "mode" "SI")])
9002
9003 (define_insn "*xorsi_1_zext_imm"
9004   [(set (match_operand:DI 0 "register_operand" "=r")
9005         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9006                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9007    (clobber (reg:CC FLAGS_REG))]
9008   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9009   "xor{l}\t{%2, %k0|%k0, %2}"
9010   [(set_attr "type" "alu")
9011    (set_attr "mode" "SI")])
9012
9013 (define_insn "*xorsi_2"
9014   [(set (reg FLAGS_REG)
9015         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9016                          (match_operand:SI 2 "general_operand" "rim,ri"))
9017                  (const_int 0)))
9018    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9019         (xor:SI (match_dup 1) (match_dup 2)))]
9020   "ix86_match_ccmode (insn, CCNOmode)
9021    && ix86_binary_operator_ok (XOR, SImode, operands)"
9022   "xor{l}\t{%2, %0|%0, %2}"
9023   [(set_attr "type" "alu")
9024    (set_attr "mode" "SI")])
9025
9026 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9027 ;; ??? Special case for immediate operand is missing - it is tricky.
9028 (define_insn "*xorsi_2_zext"
9029   [(set (reg FLAGS_REG)
9030         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9031                          (match_operand:SI 2 "general_operand" "rim"))
9032                  (const_int 0)))
9033    (set (match_operand:DI 0 "register_operand" "=r")
9034         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9035   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9036    && ix86_binary_operator_ok (XOR, SImode, operands)"
9037   "xor{l}\t{%2, %k0|%k0, %2}"
9038   [(set_attr "type" "alu")
9039    (set_attr "mode" "SI")])
9040
9041 (define_insn "*xorsi_2_zext_imm"
9042   [(set (reg FLAGS_REG)
9043         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9044                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9045                  (const_int 0)))
9046    (set (match_operand:DI 0 "register_operand" "=r")
9047         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9048   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9049    && ix86_binary_operator_ok (XOR, SImode, operands)"
9050   "xor{l}\t{%2, %k0|%k0, %2}"
9051   [(set_attr "type" "alu")
9052    (set_attr "mode" "SI")])
9053
9054 (define_insn "*xorsi_3"
9055   [(set (reg FLAGS_REG)
9056         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9057                          (match_operand:SI 2 "general_operand" "rim"))
9058                  (const_int 0)))
9059    (clobber (match_scratch:SI 0 "=r"))]
9060   "ix86_match_ccmode (insn, CCNOmode)
9061    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9062   "xor{l}\t{%2, %0|%0, %2}"
9063   [(set_attr "type" "alu")
9064    (set_attr "mode" "SI")])
9065
9066 (define_expand "xorhi3"
9067   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9068         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9069                 (match_operand:HI 2 "general_operand" "")))
9070    (clobber (reg:CC FLAGS_REG))]
9071   "TARGET_HIMODE_MATH"
9072   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9073
9074 (define_insn "*xorhi_1"
9075   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9076         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9077                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9078    (clobber (reg:CC FLAGS_REG))]
9079   "ix86_binary_operator_ok (XOR, HImode, operands)"
9080   "xor{w}\t{%2, %0|%0, %2}"
9081   [(set_attr "type" "alu")
9082    (set_attr "mode" "HI")])
9083
9084 (define_insn "*xorhi_2"
9085   [(set (reg FLAGS_REG)
9086         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9087                          (match_operand:HI 2 "general_operand" "rim,ri"))
9088                  (const_int 0)))
9089    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9090         (xor:HI (match_dup 1) (match_dup 2)))]
9091   "ix86_match_ccmode (insn, CCNOmode)
9092    && ix86_binary_operator_ok (XOR, HImode, operands)"
9093   "xor{w}\t{%2, %0|%0, %2}"
9094   [(set_attr "type" "alu")
9095    (set_attr "mode" "HI")])
9096
9097 (define_insn "*xorhi_3"
9098   [(set (reg FLAGS_REG)
9099         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9100                          (match_operand:HI 2 "general_operand" "rim"))
9101                  (const_int 0)))
9102    (clobber (match_scratch:HI 0 "=r"))]
9103   "ix86_match_ccmode (insn, CCNOmode)
9104    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9105   "xor{w}\t{%2, %0|%0, %2}"
9106   [(set_attr "type" "alu")
9107    (set_attr "mode" "HI")])
9108
9109 (define_expand "xorqi3"
9110   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9111         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9112                 (match_operand:QI 2 "general_operand" "")))
9113    (clobber (reg:CC FLAGS_REG))]
9114   "TARGET_QIMODE_MATH"
9115   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9116
9117 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9118 (define_insn "*xorqi_1"
9119   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9120         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9121                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9122    (clobber (reg:CC FLAGS_REG))]
9123   "ix86_binary_operator_ok (XOR, QImode, operands)"
9124   "@
9125    xor{b}\t{%2, %0|%0, %2}
9126    xor{b}\t{%2, %0|%0, %2}
9127    xor{l}\t{%k2, %k0|%k0, %k2}"
9128   [(set_attr "type" "alu")
9129    (set_attr "mode" "QI,QI,SI")])
9130
9131 (define_insn "*xorqi_1_slp"
9132   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9133         (xor:QI (match_dup 0)
9134                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9135    (clobber (reg:CC FLAGS_REG))]
9136   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9137    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9138   "xor{b}\t{%1, %0|%0, %1}"
9139   [(set_attr "type" "alu1")
9140    (set_attr "mode" "QI")])
9141
9142 (define_insn "xorqi_ext_0"
9143   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9144                          (const_int 8)
9145                          (const_int 8))
9146         (xor:SI
9147           (zero_extract:SI
9148             (match_operand 1 "ext_register_operand" "0")
9149             (const_int 8)
9150             (const_int 8))
9151           (match_operand 2 "const_int_operand" "n")))
9152    (clobber (reg:CC FLAGS_REG))]
9153   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9154   "xor{b}\t{%2, %h0|%h0, %2}"
9155   [(set_attr "type" "alu")
9156    (set_attr "length_immediate" "1")
9157    (set_attr "mode" "QI")])
9158
9159 (define_insn "*xorqi_ext_1"
9160   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9161                          (const_int 8)
9162                          (const_int 8))
9163         (xor:SI
9164           (zero_extract:SI
9165             (match_operand 1 "ext_register_operand" "0")
9166             (const_int 8)
9167             (const_int 8))
9168           (zero_extend:SI
9169             (match_operand:QI 2 "general_operand" "Qm"))))
9170    (clobber (reg:CC FLAGS_REG))]
9171   "!TARGET_64BIT
9172    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9173   "xor{b}\t{%2, %h0|%h0, %2}"
9174   [(set_attr "type" "alu")
9175    (set_attr "length_immediate" "0")
9176    (set_attr "mode" "QI")])
9177
9178 (define_insn "*xorqi_ext_1_rex64"
9179   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9180                          (const_int 8)
9181                          (const_int 8))
9182         (xor:SI
9183           (zero_extract:SI
9184             (match_operand 1 "ext_register_operand" "0")
9185             (const_int 8)
9186             (const_int 8))
9187           (zero_extend:SI
9188             (match_operand 2 "ext_register_operand" "Q"))))
9189    (clobber (reg:CC FLAGS_REG))]
9190   "TARGET_64BIT
9191    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9192   "xor{b}\t{%2, %h0|%h0, %2}"
9193   [(set_attr "type" "alu")
9194    (set_attr "length_immediate" "0")
9195    (set_attr "mode" "QI")])
9196
9197 (define_insn "*xorqi_ext_2"
9198   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9199                          (const_int 8)
9200                          (const_int 8))
9201         (xor:SI
9202           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9203                            (const_int 8)
9204                            (const_int 8))
9205           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9206                            (const_int 8)
9207                            (const_int 8))))
9208    (clobber (reg:CC FLAGS_REG))]
9209   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9210   "xor{b}\t{%h2, %h0|%h0, %h2}"
9211   [(set_attr "type" "alu")
9212    (set_attr "length_immediate" "0")
9213    (set_attr "mode" "QI")])
9214
9215 (define_insn "*xorqi_cc_1"
9216   [(set (reg FLAGS_REG)
9217         (compare
9218           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9219                   (match_operand:QI 2 "general_operand" "qim,qi"))
9220           (const_int 0)))
9221    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9222         (xor:QI (match_dup 1) (match_dup 2)))]
9223   "ix86_match_ccmode (insn, CCNOmode)
9224    && ix86_binary_operator_ok (XOR, QImode, operands)"
9225   "xor{b}\t{%2, %0|%0, %2}"
9226   [(set_attr "type" "alu")
9227    (set_attr "mode" "QI")])
9228
9229 (define_insn "*xorqi_2_slp"
9230   [(set (reg FLAGS_REG)
9231         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9232                          (match_operand:QI 1 "general_operand" "qim,qi"))
9233                  (const_int 0)))
9234    (set (strict_low_part (match_dup 0))
9235         (xor:QI (match_dup 0) (match_dup 1)))]
9236   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9237    && ix86_match_ccmode (insn, CCNOmode)
9238    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9239   "xor{b}\t{%1, %0|%0, %1}"
9240   [(set_attr "type" "alu1")
9241    (set_attr "mode" "QI")])
9242
9243 (define_insn "*xorqi_cc_2"
9244   [(set (reg FLAGS_REG)
9245         (compare
9246           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9247                   (match_operand:QI 2 "general_operand" "qim"))
9248           (const_int 0)))
9249    (clobber (match_scratch:QI 0 "=q"))]
9250   "ix86_match_ccmode (insn, CCNOmode)
9251    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9252   "xor{b}\t{%2, %0|%0, %2}"
9253   [(set_attr "type" "alu")
9254    (set_attr "mode" "QI")])
9255
9256 (define_insn "*xorqi_cc_ext_1"
9257   [(set (reg FLAGS_REG)
9258         (compare
9259           (xor:SI
9260             (zero_extract:SI
9261               (match_operand 1 "ext_register_operand" "0")
9262               (const_int 8)
9263               (const_int 8))
9264             (match_operand:QI 2 "general_operand" "qmn"))
9265           (const_int 0)))
9266    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9267                          (const_int 8)
9268                          (const_int 8))
9269         (xor:SI
9270           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9271           (match_dup 2)))]
9272   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9273   "xor{b}\t{%2, %h0|%h0, %2}"
9274   [(set_attr "type" "alu")
9275    (set_attr "mode" "QI")])
9276
9277 (define_insn "*xorqi_cc_ext_1_rex64"
9278   [(set (reg FLAGS_REG)
9279         (compare
9280           (xor:SI
9281             (zero_extract:SI
9282               (match_operand 1 "ext_register_operand" "0")
9283               (const_int 8)
9284               (const_int 8))
9285             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9286           (const_int 0)))
9287    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9288                          (const_int 8)
9289                          (const_int 8))
9290         (xor:SI
9291           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9292           (match_dup 2)))]
9293   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9294   "xor{b}\t{%2, %h0|%h0, %2}"
9295   [(set_attr "type" "alu")
9296    (set_attr "mode" "QI")])
9297
9298 (define_expand "xorqi_cc_ext_1"
9299   [(parallel [
9300      (set (reg:CCNO FLAGS_REG)
9301           (compare:CCNO
9302             (xor:SI
9303               (zero_extract:SI
9304                 (match_operand 1 "ext_register_operand" "")
9305                 (const_int 8)
9306                 (const_int 8))
9307               (match_operand:QI 2 "general_operand" ""))
9308             (const_int 0)))
9309      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9310                            (const_int 8)
9311                            (const_int 8))
9312           (xor:SI
9313             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9314             (match_dup 2)))])]
9315   ""
9316   "")
9317
9318 (define_split
9319   [(set (match_operand 0 "register_operand" "")
9320         (xor (match_operand 1 "register_operand" "")
9321              (match_operand 2 "const_int_operand" "")))
9322    (clobber (reg:CC FLAGS_REG))]
9323    "reload_completed
9324     && QI_REG_P (operands[0])
9325     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9326     && !(INTVAL (operands[2]) & ~(255 << 8))
9327     && GET_MODE (operands[0]) != QImode"
9328   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9329                    (xor:SI (zero_extract:SI (match_dup 1)
9330                                             (const_int 8) (const_int 8))
9331                            (match_dup 2)))
9332               (clobber (reg:CC FLAGS_REG))])]
9333   "operands[0] = gen_lowpart (SImode, operands[0]);
9334    operands[1] = gen_lowpart (SImode, operands[1]);
9335    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9336
9337 ;; Since XOR can be encoded with sign extended immediate, this is only
9338 ;; profitable when 7th bit is set.
9339 (define_split
9340   [(set (match_operand 0 "register_operand" "")
9341         (xor (match_operand 1 "general_operand" "")
9342              (match_operand 2 "const_int_operand" "")))
9343    (clobber (reg:CC FLAGS_REG))]
9344    "reload_completed
9345     && ANY_QI_REG_P (operands[0])
9346     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9347     && !(INTVAL (operands[2]) & ~255)
9348     && (INTVAL (operands[2]) & 128)
9349     && GET_MODE (operands[0]) != QImode"
9350   [(parallel [(set (strict_low_part (match_dup 0))
9351                    (xor:QI (match_dup 1)
9352                            (match_dup 2)))
9353               (clobber (reg:CC FLAGS_REG))])]
9354   "operands[0] = gen_lowpart (QImode, operands[0]);
9355    operands[1] = gen_lowpart (QImode, operands[1]);
9356    operands[2] = gen_lowpart (QImode, operands[2]);")
9357 \f
9358 ;; Negation instructions
9359
9360 (define_expand "negti2"
9361   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9362                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9363               (clobber (reg:CC FLAGS_REG))])]
9364   "TARGET_64BIT"
9365   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9366
9367 (define_insn "*negti2_1"
9368   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9369         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9370    (clobber (reg:CC FLAGS_REG))]
9371   "TARGET_64BIT
9372    && ix86_unary_operator_ok (NEG, TImode, operands)"
9373   "#")
9374
9375 (define_split
9376   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9377         (neg:TI (match_operand:TI 1 "general_operand" "")))
9378    (clobber (reg:CC FLAGS_REG))]
9379   "TARGET_64BIT && reload_completed"
9380   [(parallel
9381     [(set (reg:CCZ FLAGS_REG)
9382           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9383      (set (match_dup 0) (neg:DI (match_dup 2)))])
9384    (parallel
9385     [(set (match_dup 1)
9386           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9387                             (match_dup 3))
9388                    (const_int 0)))
9389      (clobber (reg:CC FLAGS_REG))])
9390    (parallel
9391     [(set (match_dup 1)
9392           (neg:DI (match_dup 1)))
9393      (clobber (reg:CC FLAGS_REG))])]
9394   "split_ti (operands+1, 1, operands+2, operands+3);
9395    split_ti (operands+0, 1, operands+0, operands+1);")
9396
9397 (define_expand "negdi2"
9398   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9399                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9400               (clobber (reg:CC FLAGS_REG))])]
9401   ""
9402   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9403
9404 (define_insn "*negdi2_1"
9405   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9406         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9407    (clobber (reg:CC FLAGS_REG))]
9408   "!TARGET_64BIT
9409    && ix86_unary_operator_ok (NEG, DImode, operands)"
9410   "#")
9411
9412 (define_split
9413   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9414         (neg:DI (match_operand:DI 1 "general_operand" "")))
9415    (clobber (reg:CC FLAGS_REG))]
9416   "!TARGET_64BIT && reload_completed"
9417   [(parallel
9418     [(set (reg:CCZ FLAGS_REG)
9419           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9420      (set (match_dup 0) (neg:SI (match_dup 2)))])
9421    (parallel
9422     [(set (match_dup 1)
9423           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9424                             (match_dup 3))
9425                    (const_int 0)))
9426      (clobber (reg:CC FLAGS_REG))])
9427    (parallel
9428     [(set (match_dup 1)
9429           (neg:SI (match_dup 1)))
9430      (clobber (reg:CC FLAGS_REG))])]
9431   "split_di (operands+1, 1, operands+2, operands+3);
9432    split_di (operands+0, 1, operands+0, operands+1);")
9433
9434 (define_insn "*negdi2_1_rex64"
9435   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9436         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9437    (clobber (reg:CC FLAGS_REG))]
9438   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9439   "neg{q}\t%0"
9440   [(set_attr "type" "negnot")
9441    (set_attr "mode" "DI")])
9442
9443 ;; The problem with neg is that it does not perform (compare x 0),
9444 ;; it really performs (compare 0 x), which leaves us with the zero
9445 ;; flag being the only useful item.
9446
9447 (define_insn "*negdi2_cmpz_rex64"
9448   [(set (reg:CCZ FLAGS_REG)
9449         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9450                      (const_int 0)))
9451    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9452         (neg:DI (match_dup 1)))]
9453   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9454   "neg{q}\t%0"
9455   [(set_attr "type" "negnot")
9456    (set_attr "mode" "DI")])
9457
9458
9459 (define_expand "negsi2"
9460   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9461                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9462               (clobber (reg:CC FLAGS_REG))])]
9463   ""
9464   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9465
9466 (define_insn "*negsi2_1"
9467   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9468         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9469    (clobber (reg:CC FLAGS_REG))]
9470   "ix86_unary_operator_ok (NEG, SImode, operands)"
9471   "neg{l}\t%0"
9472   [(set_attr "type" "negnot")
9473    (set_attr "mode" "SI")])
9474
9475 ;; Combine is quite creative about this pattern.
9476 (define_insn "*negsi2_1_zext"
9477   [(set (match_operand:DI 0 "register_operand" "=r")
9478         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9479                                         (const_int 32)))
9480                      (const_int 32)))
9481    (clobber (reg:CC FLAGS_REG))]
9482   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9483   "neg{l}\t%k0"
9484   [(set_attr "type" "negnot")
9485    (set_attr "mode" "SI")])
9486
9487 ;; The problem with neg is that it does not perform (compare x 0),
9488 ;; it really performs (compare 0 x), which leaves us with the zero
9489 ;; flag being the only useful item.
9490
9491 (define_insn "*negsi2_cmpz"
9492   [(set (reg:CCZ FLAGS_REG)
9493         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9494                      (const_int 0)))
9495    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9496         (neg:SI (match_dup 1)))]
9497   "ix86_unary_operator_ok (NEG, SImode, operands)"
9498   "neg{l}\t%0"
9499   [(set_attr "type" "negnot")
9500    (set_attr "mode" "SI")])
9501
9502 (define_insn "*negsi2_cmpz_zext"
9503   [(set (reg:CCZ FLAGS_REG)
9504         (compare:CCZ (lshiftrt:DI
9505                        (neg:DI (ashift:DI
9506                                  (match_operand:DI 1 "register_operand" "0")
9507                                  (const_int 32)))
9508                        (const_int 32))
9509                      (const_int 0)))
9510    (set (match_operand:DI 0 "register_operand" "=r")
9511         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9512                                         (const_int 32)))
9513                      (const_int 32)))]
9514   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9515   "neg{l}\t%k0"
9516   [(set_attr "type" "negnot")
9517    (set_attr "mode" "SI")])
9518
9519 (define_expand "neghi2"
9520   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9521                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9522               (clobber (reg:CC FLAGS_REG))])]
9523   "TARGET_HIMODE_MATH"
9524   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9525
9526 (define_insn "*neghi2_1"
9527   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9528         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9529    (clobber (reg:CC FLAGS_REG))]
9530   "ix86_unary_operator_ok (NEG, HImode, operands)"
9531   "neg{w}\t%0"
9532   [(set_attr "type" "negnot")
9533    (set_attr "mode" "HI")])
9534
9535 (define_insn "*neghi2_cmpz"
9536   [(set (reg:CCZ FLAGS_REG)
9537         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9538                      (const_int 0)))
9539    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9540         (neg:HI (match_dup 1)))]
9541   "ix86_unary_operator_ok (NEG, HImode, operands)"
9542   "neg{w}\t%0"
9543   [(set_attr "type" "negnot")
9544    (set_attr "mode" "HI")])
9545
9546 (define_expand "negqi2"
9547   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9548                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9549               (clobber (reg:CC FLAGS_REG))])]
9550   "TARGET_QIMODE_MATH"
9551   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9552
9553 (define_insn "*negqi2_1"
9554   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9555         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9556    (clobber (reg:CC FLAGS_REG))]
9557   "ix86_unary_operator_ok (NEG, QImode, operands)"
9558   "neg{b}\t%0"
9559   [(set_attr "type" "negnot")
9560    (set_attr "mode" "QI")])
9561
9562 (define_insn "*negqi2_cmpz"
9563   [(set (reg:CCZ FLAGS_REG)
9564         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9565                      (const_int 0)))
9566    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9567         (neg:QI (match_dup 1)))]
9568   "ix86_unary_operator_ok (NEG, QImode, operands)"
9569   "neg{b}\t%0"
9570   [(set_attr "type" "negnot")
9571    (set_attr "mode" "QI")])
9572
9573 ;; Changing of sign for FP values is doable using integer unit too.
9574
9575 (define_expand "negsf2"
9576   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9577         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9578   "TARGET_80387 || TARGET_SSE_MATH"
9579   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9580
9581 (define_expand "abssf2"
9582   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9583         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9584   "TARGET_80387 || TARGET_SSE_MATH"
9585   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9586
9587 (define_insn "*absnegsf2_mixed"
9588   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9589         (match_operator:SF 3 "absneg_operator"
9590           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9591    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9592    (clobber (reg:CC FLAGS_REG))]
9593   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9594    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9595   "#")
9596
9597 (define_insn "*absnegsf2_sse"
9598   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9599         (match_operator:SF 3 "absneg_operator"
9600           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9601    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9602    (clobber (reg:CC FLAGS_REG))]
9603   "TARGET_SSE_MATH
9604    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9605   "#")
9606
9607 (define_insn "*absnegsf2_i387"
9608   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9609         (match_operator:SF 3 "absneg_operator"
9610           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9611    (use (match_operand 2 "" ""))
9612    (clobber (reg:CC FLAGS_REG))]
9613   "TARGET_80387 && !TARGET_SSE_MATH
9614    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9615   "#")
9616
9617 (define_expand "copysignsf3"
9618   [(match_operand:SF 0 "register_operand" "")
9619    (match_operand:SF 1 "nonmemory_operand" "")
9620    (match_operand:SF 2 "register_operand" "")]
9621   "TARGET_SSE_MATH"
9622 {
9623   ix86_expand_copysign (operands);
9624   DONE;
9625 })
9626
9627 (define_insn_and_split "copysignsf3_const"
9628   [(set (match_operand:SF 0 "register_operand"          "=x")
9629         (unspec:SF
9630           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9631            (match_operand:SF 2 "register_operand"       "0")
9632            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9633           UNSPEC_COPYSIGN))]
9634   "TARGET_SSE_MATH"
9635   "#"
9636   "&& reload_completed"
9637   [(const_int 0)]
9638 {
9639   ix86_split_copysign_const (operands);
9640   DONE;
9641 })
9642
9643 (define_insn "copysignsf3_var"
9644   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9645         (unspec:SF
9646           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9647            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9648            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9649            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9650           UNSPEC_COPYSIGN))
9651    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9652   "TARGET_SSE_MATH"
9653   "#")
9654
9655 (define_split
9656   [(set (match_operand:SF 0 "register_operand" "")
9657         (unspec:SF
9658           [(match_operand:SF 2 "register_operand" "")
9659            (match_operand:SF 3 "register_operand" "")
9660            (match_operand:V4SF 4 "" "")
9661            (match_operand:V4SF 5 "" "")]
9662           UNSPEC_COPYSIGN))
9663    (clobber (match_scratch:V4SF 1 ""))]
9664   "TARGET_SSE_MATH && reload_completed"
9665   [(const_int 0)]
9666 {
9667   ix86_split_copysign_var (operands);
9668   DONE;
9669 })
9670
9671 (define_expand "negdf2"
9672   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9673         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9674   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9675   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9676
9677 (define_expand "absdf2"
9678   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9679         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9680   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9681   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9682
9683 (define_insn "*absnegdf2_mixed"
9684   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9685         (match_operator:DF 3 "absneg_operator"
9686           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9687    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9688    (clobber (reg:CC FLAGS_REG))]
9689   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9690    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9691   "#")
9692
9693 (define_insn "*absnegdf2_sse"
9694   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9695         (match_operator:DF 3 "absneg_operator"
9696           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9697    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9698    (clobber (reg:CC FLAGS_REG))]
9699   "TARGET_SSE2 && TARGET_SSE_MATH
9700    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9701   "#")
9702
9703 (define_insn "*absnegdf2_i387"
9704   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9705         (match_operator:DF 3 "absneg_operator"
9706           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9707    (use (match_operand 2 "" ""))
9708    (clobber (reg:CC FLAGS_REG))]
9709   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9710    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9711   "#")
9712
9713 (define_expand "copysigndf3"
9714   [(match_operand:DF 0 "register_operand" "")
9715    (match_operand:DF 1 "nonmemory_operand" "")
9716    (match_operand:DF 2 "register_operand" "")]
9717   "TARGET_SSE2 && TARGET_SSE_MATH"
9718 {
9719   ix86_expand_copysign (operands);
9720   DONE;
9721 })
9722
9723 (define_insn_and_split "copysigndf3_const"
9724   [(set (match_operand:DF 0 "register_operand"          "=x")
9725         (unspec:DF
9726           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9727            (match_operand:DF 2 "register_operand"       "0")
9728            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9729           UNSPEC_COPYSIGN))]
9730   "TARGET_SSE2 && TARGET_SSE_MATH"
9731   "#"
9732   "&& reload_completed"
9733   [(const_int 0)]
9734 {
9735   ix86_split_copysign_const (operands);
9736   DONE;
9737 })
9738
9739 (define_insn "copysigndf3_var"
9740   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9741         (unspec:DF
9742           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9743            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9744            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9745            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9746           UNSPEC_COPYSIGN))
9747    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9748   "TARGET_SSE2 && TARGET_SSE_MATH"
9749   "#")
9750
9751 (define_split
9752   [(set (match_operand:DF 0 "register_operand" "")
9753         (unspec:DF
9754           [(match_operand:DF 2 "register_operand" "")
9755            (match_operand:DF 3 "register_operand" "")
9756            (match_operand:V2DF 4 "" "")
9757            (match_operand:V2DF 5 "" "")]
9758           UNSPEC_COPYSIGN))
9759    (clobber (match_scratch:V2DF 1 ""))]
9760   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9761   [(const_int 0)]
9762 {
9763   ix86_split_copysign_var (operands);
9764   DONE;
9765 })
9766
9767 (define_expand "negxf2"
9768   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9769         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9770   "TARGET_80387"
9771   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9772
9773 (define_expand "absxf2"
9774   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9775         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9776   "TARGET_80387"
9777   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9778
9779 (define_insn "*absnegxf2_i387"
9780   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9781         (match_operator:XF 3 "absneg_operator"
9782           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9783    (use (match_operand 2 "" ""))
9784    (clobber (reg:CC FLAGS_REG))]
9785   "TARGET_80387
9786    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9787   "#")
9788
9789 ;; Splitters for fp abs and neg.
9790
9791 (define_split
9792   [(set (match_operand 0 "fp_register_operand" "")
9793         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9794    (use (match_operand 2 "" ""))
9795    (clobber (reg:CC FLAGS_REG))]
9796   "reload_completed"
9797   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9798
9799 (define_split
9800   [(set (match_operand 0 "register_operand" "")
9801         (match_operator 3 "absneg_operator"
9802           [(match_operand 1 "register_operand" "")]))
9803    (use (match_operand 2 "nonimmediate_operand" ""))
9804    (clobber (reg:CC FLAGS_REG))]
9805   "reload_completed && SSE_REG_P (operands[0])"
9806   [(set (match_dup 0) (match_dup 3))]
9807 {
9808   enum machine_mode mode = GET_MODE (operands[0]);
9809   enum machine_mode vmode = GET_MODE (operands[2]);
9810   rtx tmp;
9811
9812   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9813   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9814   if (operands_match_p (operands[0], operands[2]))
9815     {
9816       tmp = operands[1];
9817       operands[1] = operands[2];
9818       operands[2] = tmp;
9819     }
9820   if (GET_CODE (operands[3]) == ABS)
9821     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9822   else
9823     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9824   operands[3] = tmp;
9825 })
9826
9827 (define_split
9828   [(set (match_operand:SF 0 "register_operand" "")
9829         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9830    (use (match_operand:V4SF 2 "" ""))
9831    (clobber (reg:CC FLAGS_REG))]
9832   "reload_completed"
9833   [(parallel [(set (match_dup 0) (match_dup 1))
9834               (clobber (reg:CC FLAGS_REG))])]
9835 {
9836   rtx tmp;
9837   operands[0] = gen_lowpart (SImode, operands[0]);
9838   if (GET_CODE (operands[1]) == ABS)
9839     {
9840       tmp = gen_int_mode (0x7fffffff, SImode);
9841       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9842     }
9843   else
9844     {
9845       tmp = gen_int_mode (0x80000000, SImode);
9846       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9847     }
9848   operands[1] = tmp;
9849 })
9850
9851 (define_split
9852   [(set (match_operand:DF 0 "register_operand" "")
9853         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9854    (use (match_operand 2 "" ""))
9855    (clobber (reg:CC FLAGS_REG))]
9856   "reload_completed"
9857   [(parallel [(set (match_dup 0) (match_dup 1))
9858               (clobber (reg:CC FLAGS_REG))])]
9859 {
9860   rtx tmp;
9861   if (TARGET_64BIT)
9862     {
9863       tmp = gen_lowpart (DImode, operands[0]);
9864       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9865       operands[0] = tmp;
9866
9867       if (GET_CODE (operands[1]) == ABS)
9868         tmp = const0_rtx;
9869       else
9870         tmp = gen_rtx_NOT (DImode, tmp);
9871     }
9872   else
9873     {
9874       operands[0] = gen_highpart (SImode, operands[0]);
9875       if (GET_CODE (operands[1]) == ABS)
9876         {
9877           tmp = gen_int_mode (0x7fffffff, SImode);
9878           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9879         }
9880       else
9881         {
9882           tmp = gen_int_mode (0x80000000, SImode);
9883           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9884         }
9885     }
9886   operands[1] = tmp;
9887 })
9888
9889 (define_split
9890   [(set (match_operand:XF 0 "register_operand" "")
9891         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9892    (use (match_operand 2 "" ""))
9893    (clobber (reg:CC FLAGS_REG))]
9894   "reload_completed"
9895   [(parallel [(set (match_dup 0) (match_dup 1))
9896               (clobber (reg:CC FLAGS_REG))])]
9897 {
9898   rtx tmp;
9899   operands[0] = gen_rtx_REG (SImode,
9900                              true_regnum (operands[0])
9901                              + (TARGET_64BIT ? 1 : 2));
9902   if (GET_CODE (operands[1]) == ABS)
9903     {
9904       tmp = GEN_INT (0x7fff);
9905       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9906     }
9907   else
9908     {
9909       tmp = GEN_INT (0x8000);
9910       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9911     }
9912   operands[1] = tmp;
9913 })
9914
9915 (define_split
9916   [(set (match_operand 0 "memory_operand" "")
9917         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9918    (use (match_operand 2 "" ""))
9919    (clobber (reg:CC FLAGS_REG))]
9920   "reload_completed"
9921   [(parallel [(set (match_dup 0) (match_dup 1))
9922               (clobber (reg:CC FLAGS_REG))])]
9923 {
9924   enum machine_mode mode = GET_MODE (operands[0]);
9925   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9926   rtx tmp;
9927
9928   operands[0] = adjust_address (operands[0], QImode, size - 1);
9929   if (GET_CODE (operands[1]) == ABS)
9930     {
9931       tmp = gen_int_mode (0x7f, QImode);
9932       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9933     }
9934   else
9935     {
9936       tmp = gen_int_mode (0x80, QImode);
9937       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9938     }
9939   operands[1] = tmp;
9940 })
9941
9942 ;; Conditionalize these after reload. If they match before reload, we
9943 ;; lose the clobber and ability to use integer instructions.
9944
9945 (define_insn "*negsf2_1"
9946   [(set (match_operand:SF 0 "register_operand" "=f")
9947         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9948   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9949   "fchs"
9950   [(set_attr "type" "fsgn")
9951    (set_attr "mode" "SF")])
9952
9953 (define_insn "*negdf2_1"
9954   [(set (match_operand:DF 0 "register_operand" "=f")
9955         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9956   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9957   "fchs"
9958   [(set_attr "type" "fsgn")
9959    (set_attr "mode" "DF")])
9960
9961 (define_insn "*negxf2_1"
9962   [(set (match_operand:XF 0 "register_operand" "=f")
9963         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9964   "TARGET_80387"
9965   "fchs"
9966   [(set_attr "type" "fsgn")
9967    (set_attr "mode" "XF")])
9968
9969 (define_insn "*abssf2_1"
9970   [(set (match_operand:SF 0 "register_operand" "=f")
9971         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9972   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9973   "fabs"
9974   [(set_attr "type" "fsgn")
9975    (set_attr "mode" "SF")])
9976
9977 (define_insn "*absdf2_1"
9978   [(set (match_operand:DF 0 "register_operand" "=f")
9979         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9980   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9981   "fabs"
9982   [(set_attr "type" "fsgn")
9983    (set_attr "mode" "DF")])
9984
9985 (define_insn "*absxf2_1"
9986   [(set (match_operand:XF 0 "register_operand" "=f")
9987         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9988   "TARGET_80387"
9989   "fabs"
9990   [(set_attr "type" "fsgn")
9991    (set_attr "mode" "DF")])
9992
9993 (define_insn "*negextendsfdf2"
9994   [(set (match_operand:DF 0 "register_operand" "=f")
9995         (neg:DF (float_extend:DF
9996                   (match_operand:SF 1 "register_operand" "0"))))]
9997   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9998   "fchs"
9999   [(set_attr "type" "fsgn")
10000    (set_attr "mode" "DF")])
10001
10002 (define_insn "*negextenddfxf2"
10003   [(set (match_operand:XF 0 "register_operand" "=f")
10004         (neg:XF (float_extend:XF
10005                   (match_operand:DF 1 "register_operand" "0"))))]
10006   "TARGET_80387"
10007   "fchs"
10008   [(set_attr "type" "fsgn")
10009    (set_attr "mode" "XF")])
10010
10011 (define_insn "*negextendsfxf2"
10012   [(set (match_operand:XF 0 "register_operand" "=f")
10013         (neg:XF (float_extend:XF
10014                   (match_operand:SF 1 "register_operand" "0"))))]
10015   "TARGET_80387"
10016   "fchs"
10017   [(set_attr "type" "fsgn")
10018    (set_attr "mode" "XF")])
10019
10020 (define_insn "*absextendsfdf2"
10021   [(set (match_operand:DF 0 "register_operand" "=f")
10022         (abs:DF (float_extend:DF
10023                   (match_operand:SF 1 "register_operand" "0"))))]
10024   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10025   "fabs"
10026   [(set_attr "type" "fsgn")
10027    (set_attr "mode" "DF")])
10028
10029 (define_insn "*absextenddfxf2"
10030   [(set (match_operand:XF 0 "register_operand" "=f")
10031         (abs:XF (float_extend:XF
10032           (match_operand:DF 1 "register_operand" "0"))))]
10033   "TARGET_80387"
10034   "fabs"
10035   [(set_attr "type" "fsgn")
10036    (set_attr "mode" "XF")])
10037
10038 (define_insn "*absextendsfxf2"
10039   [(set (match_operand:XF 0 "register_operand" "=f")
10040         (abs:XF (float_extend:XF
10041           (match_operand:SF 1 "register_operand" "0"))))]
10042   "TARGET_80387"
10043   "fabs"
10044   [(set_attr "type" "fsgn")
10045    (set_attr "mode" "XF")])
10046 \f
10047 ;; One complement instructions
10048
10049 (define_expand "one_cmpldi2"
10050   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10051         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10052   "TARGET_64BIT"
10053   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10054
10055 (define_insn "*one_cmpldi2_1_rex64"
10056   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10057         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10058   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10059   "not{q}\t%0"
10060   [(set_attr "type" "negnot")
10061    (set_attr "mode" "DI")])
10062
10063 (define_insn "*one_cmpldi2_2_rex64"
10064   [(set (reg FLAGS_REG)
10065         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10066                  (const_int 0)))
10067    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10068         (not:DI (match_dup 1)))]
10069   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10070    && ix86_unary_operator_ok (NOT, DImode, operands)"
10071   "#"
10072   [(set_attr "type" "alu1")
10073    (set_attr "mode" "DI")])
10074
10075 (define_split
10076   [(set (match_operand 0 "flags_reg_operand" "")
10077         (match_operator 2 "compare_operator"
10078           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10079            (const_int 0)]))
10080    (set (match_operand:DI 1 "nonimmediate_operand" "")
10081         (not:DI (match_dup 3)))]
10082   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10083   [(parallel [(set (match_dup 0)
10084                    (match_op_dup 2
10085                      [(xor:DI (match_dup 3) (const_int -1))
10086                       (const_int 0)]))
10087               (set (match_dup 1)
10088                    (xor:DI (match_dup 3) (const_int -1)))])]
10089   "")
10090
10091 (define_expand "one_cmplsi2"
10092   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10093         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10094   ""
10095   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10096
10097 (define_insn "*one_cmplsi2_1"
10098   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10099         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10100   "ix86_unary_operator_ok (NOT, SImode, operands)"
10101   "not{l}\t%0"
10102   [(set_attr "type" "negnot")
10103    (set_attr "mode" "SI")])
10104
10105 ;; ??? Currently never generated - xor is used instead.
10106 (define_insn "*one_cmplsi2_1_zext"
10107   [(set (match_operand:DI 0 "register_operand" "=r")
10108         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10109   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10110   "not{l}\t%k0"
10111   [(set_attr "type" "negnot")
10112    (set_attr "mode" "SI")])
10113
10114 (define_insn "*one_cmplsi2_2"
10115   [(set (reg FLAGS_REG)
10116         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10117                  (const_int 0)))
10118    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10119         (not:SI (match_dup 1)))]
10120   "ix86_match_ccmode (insn, CCNOmode)
10121    && ix86_unary_operator_ok (NOT, SImode, operands)"
10122   "#"
10123   [(set_attr "type" "alu1")
10124    (set_attr "mode" "SI")])
10125
10126 (define_split
10127   [(set (match_operand 0 "flags_reg_operand" "")
10128         (match_operator 2 "compare_operator"
10129           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10130            (const_int 0)]))
10131    (set (match_operand:SI 1 "nonimmediate_operand" "")
10132         (not:SI (match_dup 3)))]
10133   "ix86_match_ccmode (insn, CCNOmode)"
10134   [(parallel [(set (match_dup 0)
10135                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10136                                     (const_int 0)]))
10137               (set (match_dup 1)
10138                    (xor:SI (match_dup 3) (const_int -1)))])]
10139   "")
10140
10141 ;; ??? Currently never generated - xor is used instead.
10142 (define_insn "*one_cmplsi2_2_zext"
10143   [(set (reg FLAGS_REG)
10144         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10145                  (const_int 0)))
10146    (set (match_operand:DI 0 "register_operand" "=r")
10147         (zero_extend:DI (not:SI (match_dup 1))))]
10148   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10149    && ix86_unary_operator_ok (NOT, SImode, operands)"
10150   "#"
10151   [(set_attr "type" "alu1")
10152    (set_attr "mode" "SI")])
10153
10154 (define_split
10155   [(set (match_operand 0 "flags_reg_operand" "")
10156         (match_operator 2 "compare_operator"
10157           [(not:SI (match_operand:SI 3 "register_operand" ""))
10158            (const_int 0)]))
10159    (set (match_operand:DI 1 "register_operand" "")
10160         (zero_extend:DI (not:SI (match_dup 3))))]
10161   "ix86_match_ccmode (insn, CCNOmode)"
10162   [(parallel [(set (match_dup 0)
10163                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10164                                     (const_int 0)]))
10165               (set (match_dup 1)
10166                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10167   "")
10168
10169 (define_expand "one_cmplhi2"
10170   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10171         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10172   "TARGET_HIMODE_MATH"
10173   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10174
10175 (define_insn "*one_cmplhi2_1"
10176   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10177         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10178   "ix86_unary_operator_ok (NOT, HImode, operands)"
10179   "not{w}\t%0"
10180   [(set_attr "type" "negnot")
10181    (set_attr "mode" "HI")])
10182
10183 (define_insn "*one_cmplhi2_2"
10184   [(set (reg FLAGS_REG)
10185         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10186                  (const_int 0)))
10187    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10188         (not:HI (match_dup 1)))]
10189   "ix86_match_ccmode (insn, CCNOmode)
10190    && ix86_unary_operator_ok (NEG, HImode, operands)"
10191   "#"
10192   [(set_attr "type" "alu1")
10193    (set_attr "mode" "HI")])
10194
10195 (define_split
10196   [(set (match_operand 0 "flags_reg_operand" "")
10197         (match_operator 2 "compare_operator"
10198           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10199            (const_int 0)]))
10200    (set (match_operand:HI 1 "nonimmediate_operand" "")
10201         (not:HI (match_dup 3)))]
10202   "ix86_match_ccmode (insn, CCNOmode)"
10203   [(parallel [(set (match_dup 0)
10204                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10205                                     (const_int 0)]))
10206               (set (match_dup 1)
10207                    (xor:HI (match_dup 3) (const_int -1)))])]
10208   "")
10209
10210 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10211 (define_expand "one_cmplqi2"
10212   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10213         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10214   "TARGET_QIMODE_MATH"
10215   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10216
10217 (define_insn "*one_cmplqi2_1"
10218   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10219         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10220   "ix86_unary_operator_ok (NOT, QImode, operands)"
10221   "@
10222    not{b}\t%0
10223    not{l}\t%k0"
10224   [(set_attr "type" "negnot")
10225    (set_attr "mode" "QI,SI")])
10226
10227 (define_insn "*one_cmplqi2_2"
10228   [(set (reg FLAGS_REG)
10229         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10230                  (const_int 0)))
10231    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10232         (not:QI (match_dup 1)))]
10233   "ix86_match_ccmode (insn, CCNOmode)
10234    && ix86_unary_operator_ok (NOT, QImode, operands)"
10235   "#"
10236   [(set_attr "type" "alu1")
10237    (set_attr "mode" "QI")])
10238
10239 (define_split
10240   [(set (match_operand 0 "flags_reg_operand" "")
10241         (match_operator 2 "compare_operator"
10242           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10243            (const_int 0)]))
10244    (set (match_operand:QI 1 "nonimmediate_operand" "")
10245         (not:QI (match_dup 3)))]
10246   "ix86_match_ccmode (insn, CCNOmode)"
10247   [(parallel [(set (match_dup 0)
10248                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10249                                     (const_int 0)]))
10250               (set (match_dup 1)
10251                    (xor:QI (match_dup 3) (const_int -1)))])]
10252   "")
10253 \f
10254 ;; Arithmetic shift instructions
10255
10256 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10257 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10258 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10259 ;; from the assembler input.
10260 ;;
10261 ;; This instruction shifts the target reg/mem as usual, but instead of
10262 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10263 ;; is a left shift double, bits are taken from the high order bits of
10264 ;; reg, else if the insn is a shift right double, bits are taken from the
10265 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10266 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10267 ;;
10268 ;; Since sh[lr]d does not change the `reg' operand, that is done
10269 ;; separately, making all shifts emit pairs of shift double and normal
10270 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10271 ;; support a 63 bit shift, each shift where the count is in a reg expands
10272 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10273 ;;
10274 ;; If the shift count is a constant, we need never emit more than one
10275 ;; shift pair, instead using moves and sign extension for counts greater
10276 ;; than 31.
10277
10278 (define_expand "ashlti3"
10279   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10280                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10281                               (match_operand:QI 2 "nonmemory_operand" "")))
10282               (clobber (reg:CC FLAGS_REG))])]
10283   "TARGET_64BIT"
10284 {
10285   if (! immediate_operand (operands[2], QImode))
10286     {
10287       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10288       DONE;
10289     }
10290   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10291   DONE;
10292 })
10293
10294 (define_insn "ashlti3_1"
10295   [(set (match_operand:TI 0 "register_operand" "=r")
10296         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10297                    (match_operand:QI 2 "register_operand" "c")))
10298    (clobber (match_scratch:DI 3 "=&r"))
10299    (clobber (reg:CC FLAGS_REG))]
10300   "TARGET_64BIT"
10301   "#"
10302   [(set_attr "type" "multi")])
10303
10304 (define_insn "*ashlti3_2"
10305   [(set (match_operand:TI 0 "register_operand" "=r")
10306         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10307                    (match_operand:QI 2 "immediate_operand" "O")))
10308    (clobber (reg:CC FLAGS_REG))]
10309   "TARGET_64BIT"
10310   "#"
10311   [(set_attr "type" "multi")])
10312
10313 (define_split
10314   [(set (match_operand:TI 0 "register_operand" "")
10315         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10316                    (match_operand:QI 2 "register_operand" "")))
10317    (clobber (match_scratch:DI 3 ""))
10318    (clobber (reg:CC FLAGS_REG))]
10319   "TARGET_64BIT && reload_completed"
10320   [(const_int 0)]
10321   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10322
10323 (define_split
10324   [(set (match_operand:TI 0 "register_operand" "")
10325         (ashift:TI (match_operand:TI 1 "register_operand" "")
10326                    (match_operand:QI 2 "immediate_operand" "")))
10327    (clobber (reg:CC FLAGS_REG))]
10328   "TARGET_64BIT && reload_completed"
10329   [(const_int 0)]
10330   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10331
10332 (define_insn "x86_64_shld"
10333   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10334         (ior:DI (ashift:DI (match_dup 0)
10335                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10336                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10337                   (minus:QI (const_int 64) (match_dup 2)))))
10338    (clobber (reg:CC FLAGS_REG))]
10339   "TARGET_64BIT"
10340   "@
10341    shld{q}\t{%2, %1, %0|%0, %1, %2}
10342    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10343   [(set_attr "type" "ishift")
10344    (set_attr "prefix_0f" "1")
10345    (set_attr "mode" "DI")
10346    (set_attr "athlon_decode" "vector")])
10347
10348 (define_expand "x86_64_shift_adj"
10349   [(set (reg:CCZ FLAGS_REG)
10350         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10351                              (const_int 64))
10352                      (const_int 0)))
10353    (set (match_operand:DI 0 "register_operand" "")
10354         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10355                          (match_operand:DI 1 "register_operand" "")
10356                          (match_dup 0)))
10357    (set (match_dup 1)
10358         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10359                          (match_operand:DI 3 "register_operand" "r")
10360                          (match_dup 1)))]
10361   "TARGET_64BIT"
10362   "")
10363
10364 (define_expand "ashldi3"
10365   [(set (match_operand:DI 0 "shiftdi_operand" "")
10366         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10367                    (match_operand:QI 2 "nonmemory_operand" "")))]
10368   ""
10369   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10370
10371 (define_insn "*ashldi3_1_rex64"
10372   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10373         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10374                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10375    (clobber (reg:CC FLAGS_REG))]
10376   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10377 {
10378   switch (get_attr_type (insn))
10379     {
10380     case TYPE_ALU:
10381       gcc_assert (operands[2] == const1_rtx);
10382       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10383       return "add{q}\t{%0, %0|%0, %0}";
10384
10385     case TYPE_LEA:
10386       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10387       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10388       operands[1] = gen_rtx_MULT (DImode, operands[1],
10389                                   GEN_INT (1 << INTVAL (operands[2])));
10390       return "lea{q}\t{%a1, %0|%0, %a1}";
10391
10392     default:
10393       if (REG_P (operands[2]))
10394         return "sal{q}\t{%b2, %0|%0, %b2}";
10395       else if (operands[2] == const1_rtx
10396                && (TARGET_SHIFT1 || optimize_size))
10397         return "sal{q}\t%0";
10398       else
10399         return "sal{q}\t{%2, %0|%0, %2}";
10400     }
10401 }
10402   [(set (attr "type")
10403      (cond [(eq_attr "alternative" "1")
10404               (const_string "lea")
10405             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10406                           (const_int 0))
10407                       (match_operand 0 "register_operand" ""))
10408                  (match_operand 2 "const1_operand" ""))
10409               (const_string "alu")
10410            ]
10411            (const_string "ishift")))
10412    (set_attr "mode" "DI")])
10413
10414 ;; Convert lea to the lea pattern to avoid flags dependency.
10415 (define_split
10416   [(set (match_operand:DI 0 "register_operand" "")
10417         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10418                    (match_operand:QI 2 "immediate_operand" "")))
10419    (clobber (reg:CC FLAGS_REG))]
10420   "TARGET_64BIT && reload_completed
10421    && true_regnum (operands[0]) != true_regnum (operands[1])"
10422   [(set (match_dup 0)
10423         (mult:DI (match_dup 1)
10424                  (match_dup 2)))]
10425   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10426
10427 ;; This pattern can't accept a variable shift count, since shifts by
10428 ;; zero don't affect the flags.  We assume that shifts by constant
10429 ;; zero are optimized away.
10430 (define_insn "*ashldi3_cmp_rex64"
10431   [(set (reg FLAGS_REG)
10432         (compare
10433           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10434                      (match_operand:QI 2 "immediate_operand" "e"))
10435           (const_int 0)))
10436    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10437         (ashift:DI (match_dup 1) (match_dup 2)))]
10438   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10439    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10440    && (optimize_size
10441        || !TARGET_PARTIAL_FLAG_REG_STALL
10442        || (operands[2] == const1_rtx
10443            && (TARGET_SHIFT1
10444                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10445 {
10446   switch (get_attr_type (insn))
10447     {
10448     case TYPE_ALU:
10449       gcc_assert (operands[2] == const1_rtx);
10450       return "add{q}\t{%0, %0|%0, %0}";
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 [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10464                           (const_int 0))
10465                       (match_operand 0 "register_operand" ""))
10466                  (match_operand 2 "const1_operand" ""))
10467               (const_string "alu")
10468            ]
10469            (const_string "ishift")))
10470    (set_attr "mode" "DI")])
10471
10472 (define_insn "*ashldi3_cconly_rex64"
10473   [(set (reg FLAGS_REG)
10474         (compare
10475           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10476                      (match_operand:QI 2 "immediate_operand" "e"))
10477           (const_int 0)))
10478    (clobber (match_scratch:DI 0 "=r"))]
10479   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10480    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10481    && (optimize_size
10482        || !TARGET_PARTIAL_FLAG_REG_STALL
10483        || (operands[2] == const1_rtx
10484            && (TARGET_SHIFT1
10485                || TARGET_DOUBLE_WITH_ADD)))"
10486 {
10487   switch (get_attr_type (insn))
10488     {
10489     case TYPE_ALU:
10490       gcc_assert (operands[2] == const1_rtx);
10491       return "add{q}\t{%0, %0|%0, %0}";
10492
10493     default:
10494       if (REG_P (operands[2]))
10495         return "sal{q}\t{%b2, %0|%0, %b2}";
10496       else if (operands[2] == const1_rtx
10497                && (TARGET_SHIFT1 || optimize_size))
10498         return "sal{q}\t%0";
10499       else
10500         return "sal{q}\t{%2, %0|%0, %2}";
10501     }
10502 }
10503   [(set (attr "type")
10504      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10505                           (const_int 0))
10506                       (match_operand 0 "register_operand" ""))
10507                  (match_operand 2 "const1_operand" ""))
10508               (const_string "alu")
10509            ]
10510            (const_string "ishift")))
10511    (set_attr "mode" "DI")])
10512
10513 (define_insn "*ashldi3_1"
10514   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10515         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10516                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10517    (clobber (reg:CC FLAGS_REG))]
10518   "!TARGET_64BIT"
10519   "#"
10520   [(set_attr "type" "multi")])
10521
10522 ;; By default we don't ask for a scratch register, because when DImode
10523 ;; values are manipulated, registers are already at a premium.  But if
10524 ;; we have one handy, we won't turn it away.
10525 (define_peephole2
10526   [(match_scratch:SI 3 "r")
10527    (parallel [(set (match_operand:DI 0 "register_operand" "")
10528                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10529                               (match_operand:QI 2 "nonmemory_operand" "")))
10530               (clobber (reg:CC FLAGS_REG))])
10531    (match_dup 3)]
10532   "!TARGET_64BIT && TARGET_CMOVE"
10533   [(const_int 0)]
10534   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10535
10536 (define_split
10537   [(set (match_operand:DI 0 "register_operand" "")
10538         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10539                    (match_operand:QI 2 "nonmemory_operand" "")))
10540    (clobber (reg:CC FLAGS_REG))]
10541   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10542                      ? flow2_completed : reload_completed)"
10543   [(const_int 0)]
10544   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10545
10546 (define_insn "x86_shld_1"
10547   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10548         (ior:SI (ashift:SI (match_dup 0)
10549                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10550                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10551                   (minus:QI (const_int 32) (match_dup 2)))))
10552    (clobber (reg:CC FLAGS_REG))]
10553   ""
10554   "@
10555    shld{l}\t{%2, %1, %0|%0, %1, %2}
10556    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10557   [(set_attr "type" "ishift")
10558    (set_attr "prefix_0f" "1")
10559    (set_attr "mode" "SI")
10560    (set_attr "pent_pair" "np")
10561    (set_attr "athlon_decode" "vector")])
10562
10563 (define_expand "x86_shift_adj_1"
10564   [(set (reg:CCZ FLAGS_REG)
10565         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10566                              (const_int 32))
10567                      (const_int 0)))
10568    (set (match_operand:SI 0 "register_operand" "")
10569         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10570                          (match_operand:SI 1 "register_operand" "")
10571                          (match_dup 0)))
10572    (set (match_dup 1)
10573         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10574                          (match_operand:SI 3 "register_operand" "r")
10575                          (match_dup 1)))]
10576   "TARGET_CMOVE"
10577   "")
10578
10579 (define_expand "x86_shift_adj_2"
10580   [(use (match_operand:SI 0 "register_operand" ""))
10581    (use (match_operand:SI 1 "register_operand" ""))
10582    (use (match_operand:QI 2 "register_operand" ""))]
10583   ""
10584 {
10585   rtx label = gen_label_rtx ();
10586   rtx tmp;
10587
10588   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10589
10590   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10591   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10592   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10593                               gen_rtx_LABEL_REF (VOIDmode, label),
10594                               pc_rtx);
10595   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10596   JUMP_LABEL (tmp) = label;
10597
10598   emit_move_insn (operands[0], operands[1]);
10599   ix86_expand_clear (operands[1]);
10600
10601   emit_label (label);
10602   LABEL_NUSES (label) = 1;
10603
10604   DONE;
10605 })
10606
10607 (define_expand "ashlsi3"
10608   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10609         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10610                    (match_operand:QI 2 "nonmemory_operand" "")))
10611    (clobber (reg:CC FLAGS_REG))]
10612   ""
10613   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10614
10615 (define_insn "*ashlsi3_1"
10616   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10617         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10618                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10619    (clobber (reg:CC FLAGS_REG))]
10620   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10621 {
10622   switch (get_attr_type (insn))
10623     {
10624     case TYPE_ALU:
10625       gcc_assert (operands[2] == const1_rtx);
10626       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10627       return "add{l}\t{%0, %0|%0, %0}";
10628
10629     case TYPE_LEA:
10630       return "#";
10631
10632     default:
10633       if (REG_P (operands[2]))
10634         return "sal{l}\t{%b2, %0|%0, %b2}";
10635       else if (operands[2] == const1_rtx
10636                && (TARGET_SHIFT1 || optimize_size))
10637         return "sal{l}\t%0";
10638       else
10639         return "sal{l}\t{%2, %0|%0, %2}";
10640     }
10641 }
10642   [(set (attr "type")
10643      (cond [(eq_attr "alternative" "1")
10644               (const_string "lea")
10645             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10646                           (const_int 0))
10647                       (match_operand 0 "register_operand" ""))
10648                  (match_operand 2 "const1_operand" ""))
10649               (const_string "alu")
10650            ]
10651            (const_string "ishift")))
10652    (set_attr "mode" "SI")])
10653
10654 ;; Convert lea to the lea pattern to avoid flags dependency.
10655 (define_split
10656   [(set (match_operand 0 "register_operand" "")
10657         (ashift (match_operand 1 "index_register_operand" "")
10658                 (match_operand:QI 2 "const_int_operand" "")))
10659    (clobber (reg:CC FLAGS_REG))]
10660   "reload_completed
10661    && true_regnum (operands[0]) != true_regnum (operands[1])
10662    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10663   [(const_int 0)]
10664 {
10665   rtx pat;
10666   enum machine_mode mode = GET_MODE (operands[0]);
10667
10668   if (GET_MODE_SIZE (mode) < 4)
10669     operands[0] = gen_lowpart (SImode, operands[0]);
10670   if (mode != Pmode)
10671     operands[1] = gen_lowpart (Pmode, operands[1]);
10672   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10673
10674   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10675   if (Pmode != SImode)
10676     pat = gen_rtx_SUBREG (SImode, pat, 0);
10677   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10678   DONE;
10679 })
10680
10681 ;; Rare case of shifting RSP is handled by generating move and shift
10682 (define_split
10683   [(set (match_operand 0 "register_operand" "")
10684         (ashift (match_operand 1 "register_operand" "")
10685                 (match_operand:QI 2 "const_int_operand" "")))
10686    (clobber (reg:CC FLAGS_REG))]
10687   "reload_completed
10688    && true_regnum (operands[0]) != true_regnum (operands[1])"
10689   [(const_int 0)]
10690 {
10691   rtx pat, clob;
10692   emit_move_insn (operands[0], operands[1]);
10693   pat = gen_rtx_SET (VOIDmode, operands[0],
10694                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10695                                      operands[0], operands[2]));
10696   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10697   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10698   DONE;
10699 })
10700
10701 (define_insn "*ashlsi3_1_zext"
10702   [(set (match_operand:DI 0 "register_operand" "=r,r")
10703         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10704                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10705    (clobber (reg:CC FLAGS_REG))]
10706   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10707 {
10708   switch (get_attr_type (insn))
10709     {
10710     case TYPE_ALU:
10711       gcc_assert (operands[2] == const1_rtx);
10712       return "add{l}\t{%k0, %k0|%k0, %k0}";
10713
10714     case TYPE_LEA:
10715       return "#";
10716
10717     default:
10718       if (REG_P (operands[2]))
10719         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10720       else if (operands[2] == const1_rtx
10721                && (TARGET_SHIFT1 || optimize_size))
10722         return "sal{l}\t%k0";
10723       else
10724         return "sal{l}\t{%2, %k0|%k0, %2}";
10725     }
10726 }
10727   [(set (attr "type")
10728      (cond [(eq_attr "alternative" "1")
10729               (const_string "lea")
10730             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10731                      (const_int 0))
10732                  (match_operand 2 "const1_operand" ""))
10733               (const_string "alu")
10734            ]
10735            (const_string "ishift")))
10736    (set_attr "mode" "SI")])
10737
10738 ;; Convert lea to the lea pattern to avoid flags dependency.
10739 (define_split
10740   [(set (match_operand:DI 0 "register_operand" "")
10741         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10742                                 (match_operand:QI 2 "const_int_operand" ""))))
10743    (clobber (reg:CC FLAGS_REG))]
10744   "TARGET_64BIT && reload_completed
10745    && true_regnum (operands[0]) != true_regnum (operands[1])"
10746   [(set (match_dup 0) (zero_extend:DI
10747                         (subreg:SI (mult:SI (match_dup 1)
10748                                             (match_dup 2)) 0)))]
10749 {
10750   operands[1] = gen_lowpart (Pmode, operands[1]);
10751   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10752 })
10753
10754 ;; This pattern can't accept a variable shift count, since shifts by
10755 ;; zero don't affect the flags.  We assume that shifts by constant
10756 ;; zero are optimized away.
10757 (define_insn "*ashlsi3_cmp"
10758   [(set (reg FLAGS_REG)
10759         (compare
10760           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10761                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10762           (const_int 0)))
10763    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10764         (ashift:SI (match_dup 1) (match_dup 2)))]
10765   "ix86_match_ccmode (insn, CCGOCmode)
10766    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10767    && (optimize_size
10768        || !TARGET_PARTIAL_FLAG_REG_STALL
10769        || (operands[2] == const1_rtx
10770            && (TARGET_SHIFT1
10771                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10772 {
10773   switch (get_attr_type (insn))
10774     {
10775     case TYPE_ALU:
10776       gcc_assert (operands[2] == const1_rtx);
10777       return "add{l}\t{%0, %0|%0, %0}";
10778
10779     default:
10780       if (REG_P (operands[2]))
10781         return "sal{l}\t{%b2, %0|%0, %b2}";
10782       else if (operands[2] == const1_rtx
10783                && (TARGET_SHIFT1 || optimize_size))
10784         return "sal{l}\t%0";
10785       else
10786         return "sal{l}\t{%2, %0|%0, %2}";
10787     }
10788 }
10789   [(set (attr "type")
10790      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10791                           (const_int 0))
10792                       (match_operand 0 "register_operand" ""))
10793                  (match_operand 2 "const1_operand" ""))
10794               (const_string "alu")
10795            ]
10796            (const_string "ishift")))
10797    (set_attr "mode" "SI")])
10798
10799 (define_insn "*ashlsi3_cconly"
10800   [(set (reg FLAGS_REG)
10801         (compare
10802           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10803                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10804           (const_int 0)))
10805    (clobber (match_scratch:SI 0 "=r"))]
10806   "ix86_match_ccmode (insn, CCGOCmode)
10807    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10808    && (optimize_size
10809        || !TARGET_PARTIAL_FLAG_REG_STALL
10810        || (operands[2] == const1_rtx
10811            && (TARGET_SHIFT1
10812                || TARGET_DOUBLE_WITH_ADD)))"
10813 {
10814   switch (get_attr_type (insn))
10815     {
10816     case TYPE_ALU:
10817       gcc_assert (operands[2] == const1_rtx);
10818       return "add{l}\t{%0, %0|%0, %0}";
10819
10820     default:
10821       if (REG_P (operands[2]))
10822         return "sal{l}\t{%b2, %0|%0, %b2}";
10823       else if (operands[2] == const1_rtx
10824                && (TARGET_SHIFT1 || optimize_size))
10825         return "sal{l}\t%0";
10826       else
10827         return "sal{l}\t{%2, %0|%0, %2}";
10828     }
10829 }
10830   [(set (attr "type")
10831      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10832                           (const_int 0))
10833                       (match_operand 0 "register_operand" ""))
10834                  (match_operand 2 "const1_operand" ""))
10835               (const_string "alu")
10836            ]
10837            (const_string "ishift")))
10838    (set_attr "mode" "SI")])
10839
10840 (define_insn "*ashlsi3_cmp_zext"
10841   [(set (reg FLAGS_REG)
10842         (compare
10843           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10844                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10845           (const_int 0)))
10846    (set (match_operand:DI 0 "register_operand" "=r")
10847         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10848   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10849    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10850    && (optimize_size
10851        || !TARGET_PARTIAL_FLAG_REG_STALL
10852        || (operands[2] == const1_rtx
10853            && (TARGET_SHIFT1
10854                || TARGET_DOUBLE_WITH_ADD)))"
10855 {
10856   switch (get_attr_type (insn))
10857     {
10858     case TYPE_ALU:
10859       gcc_assert (operands[2] == const1_rtx);
10860       return "add{l}\t{%k0, %k0|%k0, %k0}";
10861
10862     default:
10863       if (REG_P (operands[2]))
10864         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10865       else if (operands[2] == const1_rtx
10866                && (TARGET_SHIFT1 || optimize_size))
10867         return "sal{l}\t%k0";
10868       else
10869         return "sal{l}\t{%2, %k0|%k0, %2}";
10870     }
10871 }
10872   [(set (attr "type")
10873      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10874                      (const_int 0))
10875                  (match_operand 2 "const1_operand" ""))
10876               (const_string "alu")
10877            ]
10878            (const_string "ishift")))
10879    (set_attr "mode" "SI")])
10880
10881 (define_expand "ashlhi3"
10882   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10883         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10884                    (match_operand:QI 2 "nonmemory_operand" "")))
10885    (clobber (reg:CC FLAGS_REG))]
10886   "TARGET_HIMODE_MATH"
10887   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10888
10889 (define_insn "*ashlhi3_1_lea"
10890   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10891         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10892                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10893    (clobber (reg:CC FLAGS_REG))]
10894   "!TARGET_PARTIAL_REG_STALL
10895    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10896 {
10897   switch (get_attr_type (insn))
10898     {
10899     case TYPE_LEA:
10900       return "#";
10901     case TYPE_ALU:
10902       gcc_assert (operands[2] == const1_rtx);
10903       return "add{w}\t{%0, %0|%0, %0}";
10904
10905     default:
10906       if (REG_P (operands[2]))
10907         return "sal{w}\t{%b2, %0|%0, %b2}";
10908       else if (operands[2] == const1_rtx
10909                && (TARGET_SHIFT1 || optimize_size))
10910         return "sal{w}\t%0";
10911       else
10912         return "sal{w}\t{%2, %0|%0, %2}";
10913     }
10914 }
10915   [(set (attr "type")
10916      (cond [(eq_attr "alternative" "1")
10917               (const_string "lea")
10918             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10919                           (const_int 0))
10920                       (match_operand 0 "register_operand" ""))
10921                  (match_operand 2 "const1_operand" ""))
10922               (const_string "alu")
10923            ]
10924            (const_string "ishift")))
10925    (set_attr "mode" "HI,SI")])
10926
10927 (define_insn "*ashlhi3_1"
10928   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10929         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10930                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10931    (clobber (reg:CC FLAGS_REG))]
10932   "TARGET_PARTIAL_REG_STALL
10933    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10934 {
10935   switch (get_attr_type (insn))
10936     {
10937     case TYPE_ALU:
10938       gcc_assert (operands[2] == const1_rtx);
10939       return "add{w}\t{%0, %0|%0, %0}";
10940
10941     default:
10942       if (REG_P (operands[2]))
10943         return "sal{w}\t{%b2, %0|%0, %b2}";
10944       else if (operands[2] == const1_rtx
10945                && (TARGET_SHIFT1 || optimize_size))
10946         return "sal{w}\t%0";
10947       else
10948         return "sal{w}\t{%2, %0|%0, %2}";
10949     }
10950 }
10951   [(set (attr "type")
10952      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10953                           (const_int 0))
10954                       (match_operand 0 "register_operand" ""))
10955                  (match_operand 2 "const1_operand" ""))
10956               (const_string "alu")
10957            ]
10958            (const_string "ishift")))
10959    (set_attr "mode" "HI")])
10960
10961 ;; This pattern can't accept a variable shift count, since shifts by
10962 ;; zero don't affect the flags.  We assume that shifts by constant
10963 ;; zero are optimized away.
10964 (define_insn "*ashlhi3_cmp"
10965   [(set (reg FLAGS_REG)
10966         (compare
10967           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10968                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10969           (const_int 0)))
10970    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10971         (ashift:HI (match_dup 1) (match_dup 2)))]
10972   "ix86_match_ccmode (insn, CCGOCmode)
10973    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10974    && (optimize_size
10975        || !TARGET_PARTIAL_FLAG_REG_STALL
10976        || (operands[2] == const1_rtx
10977            && (TARGET_SHIFT1
10978                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10979 {
10980   switch (get_attr_type (insn))
10981     {
10982     case TYPE_ALU:
10983       gcc_assert (operands[2] == const1_rtx);
10984       return "add{w}\t{%0, %0|%0, %0}";
10985
10986     default:
10987       if (REG_P (operands[2]))
10988         return "sal{w}\t{%b2, %0|%0, %b2}";
10989       else if (operands[2] == const1_rtx
10990                && (TARGET_SHIFT1 || optimize_size))
10991         return "sal{w}\t%0";
10992       else
10993         return "sal{w}\t{%2, %0|%0, %2}";
10994     }
10995 }
10996   [(set (attr "type")
10997      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10998                           (const_int 0))
10999                       (match_operand 0 "register_operand" ""))
11000                  (match_operand 2 "const1_operand" ""))
11001               (const_string "alu")
11002            ]
11003            (const_string "ishift")))
11004    (set_attr "mode" "HI")])
11005
11006 (define_insn "*ashlhi3_cconly"
11007   [(set (reg FLAGS_REG)
11008         (compare
11009           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11010                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11011           (const_int 0)))
11012    (clobber (match_scratch:HI 0 "=r"))]
11013   "ix86_match_ccmode (insn, CCGOCmode)
11014    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11015    && (optimize_size
11016        || !TARGET_PARTIAL_FLAG_REG_STALL
11017        || (operands[2] == const1_rtx
11018            && (TARGET_SHIFT1
11019                || TARGET_DOUBLE_WITH_ADD)))"
11020 {
11021   switch (get_attr_type (insn))
11022     {
11023     case TYPE_ALU:
11024       gcc_assert (operands[2] == const1_rtx);
11025       return "add{w}\t{%0, %0|%0, %0}";
11026
11027     default:
11028       if (REG_P (operands[2]))
11029         return "sal{w}\t{%b2, %0|%0, %b2}";
11030       else if (operands[2] == const1_rtx
11031                && (TARGET_SHIFT1 || optimize_size))
11032         return "sal{w}\t%0";
11033       else
11034         return "sal{w}\t{%2, %0|%0, %2}";
11035     }
11036 }
11037   [(set (attr "type")
11038      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11039                           (const_int 0))
11040                       (match_operand 0 "register_operand" ""))
11041                  (match_operand 2 "const1_operand" ""))
11042               (const_string "alu")
11043            ]
11044            (const_string "ishift")))
11045    (set_attr "mode" "HI")])
11046
11047 (define_expand "ashlqi3"
11048   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11049         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11050                    (match_operand:QI 2 "nonmemory_operand" "")))
11051    (clobber (reg:CC FLAGS_REG))]
11052   "TARGET_QIMODE_MATH"
11053   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11054
11055 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11056
11057 (define_insn "*ashlqi3_1_lea"
11058   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11059         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11060                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11061    (clobber (reg:CC FLAGS_REG))]
11062   "!TARGET_PARTIAL_REG_STALL
11063    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11064 {
11065   switch (get_attr_type (insn))
11066     {
11067     case TYPE_LEA:
11068       return "#";
11069     case TYPE_ALU:
11070       gcc_assert (operands[2] == const1_rtx);
11071       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11072         return "add{l}\t{%k0, %k0|%k0, %k0}";
11073       else
11074         return "add{b}\t{%0, %0|%0, %0}";
11075
11076     default:
11077       if (REG_P (operands[2]))
11078         {
11079           if (get_attr_mode (insn) == MODE_SI)
11080             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11081           else
11082             return "sal{b}\t{%b2, %0|%0, %b2}";
11083         }
11084       else if (operands[2] == const1_rtx
11085                && (TARGET_SHIFT1 || optimize_size))
11086         {
11087           if (get_attr_mode (insn) == MODE_SI)
11088             return "sal{l}\t%0";
11089           else
11090             return "sal{b}\t%0";
11091         }
11092       else
11093         {
11094           if (get_attr_mode (insn) == MODE_SI)
11095             return "sal{l}\t{%2, %k0|%k0, %2}";
11096           else
11097             return "sal{b}\t{%2, %0|%0, %2}";
11098         }
11099     }
11100 }
11101   [(set (attr "type")
11102      (cond [(eq_attr "alternative" "2")
11103               (const_string "lea")
11104             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11105                           (const_int 0))
11106                       (match_operand 0 "register_operand" ""))
11107                  (match_operand 2 "const1_operand" ""))
11108               (const_string "alu")
11109            ]
11110            (const_string "ishift")))
11111    (set_attr "mode" "QI,SI,SI")])
11112
11113 (define_insn "*ashlqi3_1"
11114   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11115         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11116                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11117    (clobber (reg:CC FLAGS_REG))]
11118   "TARGET_PARTIAL_REG_STALL
11119    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11120 {
11121   switch (get_attr_type (insn))
11122     {
11123     case TYPE_ALU:
11124       gcc_assert (operands[2] == const1_rtx);
11125       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11126         return "add{l}\t{%k0, %k0|%k0, %k0}";
11127       else
11128         return "add{b}\t{%0, %0|%0, %0}";
11129
11130     default:
11131       if (REG_P (operands[2]))
11132         {
11133           if (get_attr_mode (insn) == MODE_SI)
11134             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11135           else
11136             return "sal{b}\t{%b2, %0|%0, %b2}";
11137         }
11138       else if (operands[2] == const1_rtx
11139                && (TARGET_SHIFT1 || optimize_size))
11140         {
11141           if (get_attr_mode (insn) == MODE_SI)
11142             return "sal{l}\t%0";
11143           else
11144             return "sal{b}\t%0";
11145         }
11146       else
11147         {
11148           if (get_attr_mode (insn) == MODE_SI)
11149             return "sal{l}\t{%2, %k0|%k0, %2}";
11150           else
11151             return "sal{b}\t{%2, %0|%0, %2}";
11152         }
11153     }
11154 }
11155   [(set (attr "type")
11156      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11157                           (const_int 0))
11158                       (match_operand 0 "register_operand" ""))
11159                  (match_operand 2 "const1_operand" ""))
11160               (const_string "alu")
11161            ]
11162            (const_string "ishift")))
11163    (set_attr "mode" "QI,SI")])
11164
11165 ;; This pattern can't accept a variable shift count, since shifts by
11166 ;; zero don't affect the flags.  We assume that shifts by constant
11167 ;; zero are optimized away.
11168 (define_insn "*ashlqi3_cmp"
11169   [(set (reg FLAGS_REG)
11170         (compare
11171           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11172                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11173           (const_int 0)))
11174    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11175         (ashift:QI (match_dup 1) (match_dup 2)))]
11176   "ix86_match_ccmode (insn, CCGOCmode)
11177    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11178    && (optimize_size
11179        || !TARGET_PARTIAL_FLAG_REG_STALL
11180        || (operands[2] == const1_rtx
11181            && (TARGET_SHIFT1
11182                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11183 {
11184   switch (get_attr_type (insn))
11185     {
11186     case TYPE_ALU:
11187       gcc_assert (operands[2] == const1_rtx);
11188       return "add{b}\t{%0, %0|%0, %0}";
11189
11190     default:
11191       if (REG_P (operands[2]))
11192         return "sal{b}\t{%b2, %0|%0, %b2}";
11193       else if (operands[2] == const1_rtx
11194                && (TARGET_SHIFT1 || optimize_size))
11195         return "sal{b}\t%0";
11196       else
11197         return "sal{b}\t{%2, %0|%0, %2}";
11198     }
11199 }
11200   [(set (attr "type")
11201      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11202                           (const_int 0))
11203                       (match_operand 0 "register_operand" ""))
11204                  (match_operand 2 "const1_operand" ""))
11205               (const_string "alu")
11206            ]
11207            (const_string "ishift")))
11208    (set_attr "mode" "QI")])
11209
11210 (define_insn "*ashlqi3_cconly"
11211   [(set (reg FLAGS_REG)
11212         (compare
11213           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11214                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11215           (const_int 0)))
11216    (clobber (match_scratch:QI 0 "=q"))]
11217   "ix86_match_ccmode (insn, CCGOCmode)
11218    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11219    && (optimize_size
11220        || !TARGET_PARTIAL_FLAG_REG_STALL
11221        || (operands[2] == const1_rtx
11222            && (TARGET_SHIFT1
11223                || TARGET_DOUBLE_WITH_ADD)))"
11224 {
11225   switch (get_attr_type (insn))
11226     {
11227     case TYPE_ALU:
11228       gcc_assert (operands[2] == const1_rtx);
11229       return "add{b}\t{%0, %0|%0, %0}";
11230
11231     default:
11232       if (REG_P (operands[2]))
11233         return "sal{b}\t{%b2, %0|%0, %b2}";
11234       else if (operands[2] == const1_rtx
11235                && (TARGET_SHIFT1 || optimize_size))
11236         return "sal{b}\t%0";
11237       else
11238         return "sal{b}\t{%2, %0|%0, %2}";
11239     }
11240 }
11241   [(set (attr "type")
11242      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11243                           (const_int 0))
11244                       (match_operand 0 "register_operand" ""))
11245                  (match_operand 2 "const1_operand" ""))
11246               (const_string "alu")
11247            ]
11248            (const_string "ishift")))
11249    (set_attr "mode" "QI")])
11250
11251 ;; See comment above `ashldi3' about how this works.
11252
11253 (define_expand "ashrti3"
11254   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11255                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11256                                 (match_operand:QI 2 "nonmemory_operand" "")))
11257               (clobber (reg:CC FLAGS_REG))])]
11258   "TARGET_64BIT"
11259 {
11260   if (! immediate_operand (operands[2], QImode))
11261     {
11262       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11263       DONE;
11264     }
11265   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11266   DONE;
11267 })
11268
11269 (define_insn "ashrti3_1"
11270   [(set (match_operand:TI 0 "register_operand" "=r")
11271         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11272                      (match_operand:QI 2 "register_operand" "c")))
11273    (clobber (match_scratch:DI 3 "=&r"))
11274    (clobber (reg:CC FLAGS_REG))]
11275   "TARGET_64BIT"
11276   "#"
11277   [(set_attr "type" "multi")])
11278
11279 (define_insn "*ashrti3_2"
11280   [(set (match_operand:TI 0 "register_operand" "=r")
11281         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11282                      (match_operand:QI 2 "immediate_operand" "O")))
11283    (clobber (reg:CC FLAGS_REG))]
11284   "TARGET_64BIT"
11285   "#"
11286   [(set_attr "type" "multi")])
11287
11288 (define_split
11289   [(set (match_operand:TI 0 "register_operand" "")
11290         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11291                      (match_operand:QI 2 "register_operand" "")))
11292    (clobber (match_scratch:DI 3 ""))
11293    (clobber (reg:CC FLAGS_REG))]
11294   "TARGET_64BIT && reload_completed"
11295   [(const_int 0)]
11296   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11297
11298 (define_split
11299   [(set (match_operand:TI 0 "register_operand" "")
11300         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11301                      (match_operand:QI 2 "immediate_operand" "")))
11302    (clobber (reg:CC FLAGS_REG))]
11303   "TARGET_64BIT && reload_completed"
11304   [(const_int 0)]
11305   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11306
11307 (define_insn "x86_64_shrd"
11308   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11309         (ior:DI (ashiftrt:DI (match_dup 0)
11310                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11311                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11312                   (minus:QI (const_int 64) (match_dup 2)))))
11313    (clobber (reg:CC FLAGS_REG))]
11314   "TARGET_64BIT"
11315   "@
11316    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11317    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11318   [(set_attr "type" "ishift")
11319    (set_attr "prefix_0f" "1")
11320    (set_attr "mode" "DI")
11321    (set_attr "athlon_decode" "vector")])
11322
11323 (define_expand "ashrdi3"
11324   [(set (match_operand:DI 0 "shiftdi_operand" "")
11325         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11326                      (match_operand:QI 2 "nonmemory_operand" "")))]
11327   ""
11328   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11329
11330 (define_insn "*ashrdi3_63_rex64"
11331   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11332         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11333                      (match_operand:DI 2 "const_int_operand" "i,i")))
11334    (clobber (reg:CC FLAGS_REG))]
11335   "TARGET_64BIT && INTVAL (operands[2]) == 63
11336    && (TARGET_USE_CLTD || optimize_size)
11337    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11338   "@
11339    {cqto|cqo}
11340    sar{q}\t{%2, %0|%0, %2}"
11341   [(set_attr "type" "imovx,ishift")
11342    (set_attr "prefix_0f" "0,*")
11343    (set_attr "length_immediate" "0,*")
11344    (set_attr "modrm" "0,1")
11345    (set_attr "mode" "DI")])
11346
11347 (define_insn "*ashrdi3_1_one_bit_rex64"
11348   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11349         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11350                      (match_operand:QI 2 "const1_operand" "")))
11351    (clobber (reg:CC FLAGS_REG))]
11352   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11353    && (TARGET_SHIFT1 || optimize_size)"
11354   "sar{q}\t%0"
11355   [(set_attr "type" "ishift")
11356    (set (attr "length")
11357      (if_then_else (match_operand:DI 0 "register_operand" "")
11358         (const_string "2")
11359         (const_string "*")))])
11360
11361 (define_insn "*ashrdi3_1_rex64"
11362   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11363         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11364                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11365    (clobber (reg:CC FLAGS_REG))]
11366   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11367   "@
11368    sar{q}\t{%2, %0|%0, %2}
11369    sar{q}\t{%b2, %0|%0, %b2}"
11370   [(set_attr "type" "ishift")
11371    (set_attr "mode" "DI")])
11372
11373 ;; This pattern can't accept a variable shift count, since shifts by
11374 ;; zero don't affect the flags.  We assume that shifts by constant
11375 ;; zero are optimized away.
11376 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11377   [(set (reg FLAGS_REG)
11378         (compare
11379           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11380                        (match_operand:QI 2 "const1_operand" ""))
11381           (const_int 0)))
11382    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11383         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11384   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11385    && (TARGET_SHIFT1 || optimize_size)
11386    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11387   "sar{q}\t%0"
11388   [(set_attr "type" "ishift")
11389    (set (attr "length")
11390      (if_then_else (match_operand:DI 0 "register_operand" "")
11391         (const_string "2")
11392         (const_string "*")))])
11393
11394 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11395   [(set (reg FLAGS_REG)
11396         (compare
11397           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11398                        (match_operand:QI 2 "const1_operand" ""))
11399           (const_int 0)))
11400    (clobber (match_scratch:DI 0 "=r"))]
11401   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11402    && (TARGET_SHIFT1 || optimize_size)
11403    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11404   "sar{q}\t%0"
11405   [(set_attr "type" "ishift")
11406    (set_attr "length" "2")])
11407
11408 ;; This pattern can't accept a variable shift count, since shifts by
11409 ;; zero don't affect the flags.  We assume that shifts by constant
11410 ;; zero are optimized away.
11411 (define_insn "*ashrdi3_cmp_rex64"
11412   [(set (reg FLAGS_REG)
11413         (compare
11414           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11415                        (match_operand:QI 2 "const_int_operand" "n"))
11416           (const_int 0)))
11417    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11418         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11419   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11420    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11421    && (optimize_size
11422        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11423   "sar{q}\t{%2, %0|%0, %2}"
11424   [(set_attr "type" "ishift")
11425    (set_attr "mode" "DI")])
11426
11427 (define_insn "*ashrdi3_cconly_rex64"
11428   [(set (reg FLAGS_REG)
11429         (compare
11430           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11431                        (match_operand:QI 2 "const_int_operand" "n"))
11432           (const_int 0)))
11433    (clobber (match_scratch:DI 0 "=r"))]
11434   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11435    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11436    && (optimize_size
11437        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11438   "sar{q}\t{%2, %0|%0, %2}"
11439   [(set_attr "type" "ishift")
11440    (set_attr "mode" "DI")])
11441
11442 (define_insn "*ashrdi3_1"
11443   [(set (match_operand:DI 0 "register_operand" "=r")
11444         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11445                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11446    (clobber (reg:CC FLAGS_REG))]
11447   "!TARGET_64BIT"
11448   "#"
11449   [(set_attr "type" "multi")])
11450
11451 ;; By default we don't ask for a scratch register, because when DImode
11452 ;; values are manipulated, registers are already at a premium.  But if
11453 ;; we have one handy, we won't turn it away.
11454 (define_peephole2
11455   [(match_scratch:SI 3 "r")
11456    (parallel [(set (match_operand:DI 0 "register_operand" "")
11457                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11458                                 (match_operand:QI 2 "nonmemory_operand" "")))
11459               (clobber (reg:CC FLAGS_REG))])
11460    (match_dup 3)]
11461   "!TARGET_64BIT && TARGET_CMOVE"
11462   [(const_int 0)]
11463   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11464
11465 (define_split
11466   [(set (match_operand:DI 0 "register_operand" "")
11467         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11468                      (match_operand:QI 2 "nonmemory_operand" "")))
11469    (clobber (reg:CC FLAGS_REG))]
11470   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11471                      ? flow2_completed : reload_completed)"
11472   [(const_int 0)]
11473   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11474
11475 (define_insn "x86_shrd_1"
11476   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11477         (ior:SI (ashiftrt:SI (match_dup 0)
11478                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11479                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11480                   (minus:QI (const_int 32) (match_dup 2)))))
11481    (clobber (reg:CC FLAGS_REG))]
11482   ""
11483   "@
11484    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11485    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11486   [(set_attr "type" "ishift")
11487    (set_attr "prefix_0f" "1")
11488    (set_attr "pent_pair" "np")
11489    (set_attr "mode" "SI")])
11490
11491 (define_expand "x86_shift_adj_3"
11492   [(use (match_operand:SI 0 "register_operand" ""))
11493    (use (match_operand:SI 1 "register_operand" ""))
11494    (use (match_operand:QI 2 "register_operand" ""))]
11495   ""
11496 {
11497   rtx label = gen_label_rtx ();
11498   rtx tmp;
11499
11500   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11501
11502   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11503   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11504   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11505                               gen_rtx_LABEL_REF (VOIDmode, label),
11506                               pc_rtx);
11507   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11508   JUMP_LABEL (tmp) = label;
11509
11510   emit_move_insn (operands[0], operands[1]);
11511   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11512
11513   emit_label (label);
11514   LABEL_NUSES (label) = 1;
11515
11516   DONE;
11517 })
11518
11519 (define_insn "ashrsi3_31"
11520   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11521         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11522                      (match_operand:SI 2 "const_int_operand" "i,i")))
11523    (clobber (reg:CC FLAGS_REG))]
11524   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11525    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11526   "@
11527    {cltd|cdq}
11528    sar{l}\t{%2, %0|%0, %2}"
11529   [(set_attr "type" "imovx,ishift")
11530    (set_attr "prefix_0f" "0,*")
11531    (set_attr "length_immediate" "0,*")
11532    (set_attr "modrm" "0,1")
11533    (set_attr "mode" "SI")])
11534
11535 (define_insn "*ashrsi3_31_zext"
11536   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11537         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11538                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11539    (clobber (reg:CC FLAGS_REG))]
11540   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11541    && INTVAL (operands[2]) == 31
11542    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11543   "@
11544    {cltd|cdq}
11545    sar{l}\t{%2, %k0|%k0, %2}"
11546   [(set_attr "type" "imovx,ishift")
11547    (set_attr "prefix_0f" "0,*")
11548    (set_attr "length_immediate" "0,*")
11549    (set_attr "modrm" "0,1")
11550    (set_attr "mode" "SI")])
11551
11552 (define_expand "ashrsi3"
11553   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11554         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11555                      (match_operand:QI 2 "nonmemory_operand" "")))
11556    (clobber (reg:CC FLAGS_REG))]
11557   ""
11558   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11559
11560 (define_insn "*ashrsi3_1_one_bit"
11561   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11562         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11563                      (match_operand:QI 2 "const1_operand" "")))
11564    (clobber (reg:CC FLAGS_REG))]
11565   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11566    && (TARGET_SHIFT1 || optimize_size)"
11567   "sar{l}\t%0"
11568   [(set_attr "type" "ishift")
11569    (set (attr "length")
11570      (if_then_else (match_operand:SI 0 "register_operand" "")
11571         (const_string "2")
11572         (const_string "*")))])
11573
11574 (define_insn "*ashrsi3_1_one_bit_zext"
11575   [(set (match_operand:DI 0 "register_operand" "=r")
11576         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11577                                      (match_operand:QI 2 "const1_operand" ""))))
11578    (clobber (reg:CC FLAGS_REG))]
11579   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11580    && (TARGET_SHIFT1 || optimize_size)"
11581   "sar{l}\t%k0"
11582   [(set_attr "type" "ishift")
11583    (set_attr "length" "2")])
11584
11585 (define_insn "*ashrsi3_1"
11586   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11587         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11588                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11589    (clobber (reg:CC FLAGS_REG))]
11590   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11591   "@
11592    sar{l}\t{%2, %0|%0, %2}
11593    sar{l}\t{%b2, %0|%0, %b2}"
11594   [(set_attr "type" "ishift")
11595    (set_attr "mode" "SI")])
11596
11597 (define_insn "*ashrsi3_1_zext"
11598   [(set (match_operand:DI 0 "register_operand" "=r,r")
11599         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11600                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11601    (clobber (reg:CC FLAGS_REG))]
11602   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11603   "@
11604    sar{l}\t{%2, %k0|%k0, %2}
11605    sar{l}\t{%b2, %k0|%k0, %b2}"
11606   [(set_attr "type" "ishift")
11607    (set_attr "mode" "SI")])
11608
11609 ;; This pattern can't accept a variable shift count, since shifts by
11610 ;; zero don't affect the flags.  We assume that shifts by constant
11611 ;; zero are optimized away.
11612 (define_insn "*ashrsi3_one_bit_cmp"
11613   [(set (reg FLAGS_REG)
11614         (compare
11615           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11616                        (match_operand:QI 2 "const1_operand" ""))
11617           (const_int 0)))
11618    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11619         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11620   "ix86_match_ccmode (insn, CCGOCmode)
11621    && (TARGET_SHIFT1 || optimize_size)
11622    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11623   "sar{l}\t%0"
11624   [(set_attr "type" "ishift")
11625    (set (attr "length")
11626      (if_then_else (match_operand:SI 0 "register_operand" "")
11627         (const_string "2")
11628         (const_string "*")))])
11629
11630 (define_insn "*ashrsi3_one_bit_cconly"
11631   [(set (reg FLAGS_REG)
11632         (compare
11633           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11634                        (match_operand:QI 2 "const1_operand" ""))
11635           (const_int 0)))
11636    (clobber (match_scratch:SI 0 "=r"))]
11637   "ix86_match_ccmode (insn, CCGOCmode)
11638    && (TARGET_SHIFT1 || optimize_size)
11639    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11640   "sar{l}\t%0"
11641   [(set_attr "type" "ishift")
11642    (set_attr "length" "2")])
11643
11644 (define_insn "*ashrsi3_one_bit_cmp_zext"
11645   [(set (reg FLAGS_REG)
11646         (compare
11647           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11648                        (match_operand:QI 2 "const1_operand" ""))
11649           (const_int 0)))
11650    (set (match_operand:DI 0 "register_operand" "=r")
11651         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11652   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11653    && (TARGET_SHIFT1 || optimize_size)
11654    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11655   "sar{l}\t%k0"
11656   [(set_attr "type" "ishift")
11657    (set_attr "length" "2")])
11658
11659 ;; This pattern can't accept a variable shift count, since shifts by
11660 ;; zero don't affect the flags.  We assume that shifts by constant
11661 ;; zero are optimized away.
11662 (define_insn "*ashrsi3_cmp"
11663   [(set (reg FLAGS_REG)
11664         (compare
11665           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11666                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11667           (const_int 0)))
11668    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11669         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11670   "ix86_match_ccmode (insn, CCGOCmode)
11671    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11672    && (optimize_size
11673        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11674   "sar{l}\t{%2, %0|%0, %2}"
11675   [(set_attr "type" "ishift")
11676    (set_attr "mode" "SI")])
11677
11678 (define_insn "*ashrsi3_cconly"
11679   [(set (reg FLAGS_REG)
11680         (compare
11681           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11682                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11683           (const_int 0)))
11684    (clobber (match_scratch:SI 0 "=r"))]
11685   "ix86_match_ccmode (insn, CCGOCmode)
11686    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11687    && (optimize_size
11688        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11689   "sar{l}\t{%2, %0|%0, %2}"
11690   [(set_attr "type" "ishift")
11691    (set_attr "mode" "SI")])
11692
11693 (define_insn "*ashrsi3_cmp_zext"
11694   [(set (reg FLAGS_REG)
11695         (compare
11696           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11697                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11698           (const_int 0)))
11699    (set (match_operand:DI 0 "register_operand" "=r")
11700         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11701   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11702    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11703    && (optimize_size
11704        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11705   "sar{l}\t{%2, %k0|%k0, %2}"
11706   [(set_attr "type" "ishift")
11707    (set_attr "mode" "SI")])
11708
11709 (define_expand "ashrhi3"
11710   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11711         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11712                      (match_operand:QI 2 "nonmemory_operand" "")))
11713    (clobber (reg:CC FLAGS_REG))]
11714   "TARGET_HIMODE_MATH"
11715   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11716
11717 (define_insn "*ashrhi3_1_one_bit"
11718   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11719         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11720                      (match_operand:QI 2 "const1_operand" "")))
11721    (clobber (reg:CC FLAGS_REG))]
11722   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11723    && (TARGET_SHIFT1 || optimize_size)"
11724   "sar{w}\t%0"
11725   [(set_attr "type" "ishift")
11726    (set (attr "length")
11727      (if_then_else (match_operand 0 "register_operand" "")
11728         (const_string "2")
11729         (const_string "*")))])
11730
11731 (define_insn "*ashrhi3_1"
11732   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11733         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11734                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11735    (clobber (reg:CC FLAGS_REG))]
11736   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11737   "@
11738    sar{w}\t{%2, %0|%0, %2}
11739    sar{w}\t{%b2, %0|%0, %b2}"
11740   [(set_attr "type" "ishift")
11741    (set_attr "mode" "HI")])
11742
11743 ;; This pattern can't accept a variable shift count, since shifts by
11744 ;; zero don't affect the flags.  We assume that shifts by constant
11745 ;; zero are optimized away.
11746 (define_insn "*ashrhi3_one_bit_cmp"
11747   [(set (reg FLAGS_REG)
11748         (compare
11749           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11750                        (match_operand:QI 2 "const1_operand" ""))
11751           (const_int 0)))
11752    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11753         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11754   "ix86_match_ccmode (insn, CCGOCmode)
11755    && (TARGET_SHIFT1 || optimize_size)
11756    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11757   "sar{w}\t%0"
11758   [(set_attr "type" "ishift")
11759    (set (attr "length")
11760      (if_then_else (match_operand 0 "register_operand" "")
11761         (const_string "2")
11762         (const_string "*")))])
11763
11764 (define_insn "*ashrhi3_one_bit_cconly"
11765   [(set (reg FLAGS_REG)
11766         (compare
11767           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11768                        (match_operand:QI 2 "const1_operand" ""))
11769           (const_int 0)))
11770    (clobber (match_scratch:HI 0 "=r"))]
11771   "ix86_match_ccmode (insn, CCGOCmode)
11772    && (TARGET_SHIFT1 || optimize_size)
11773    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11774   "sar{w}\t%0"
11775   [(set_attr "type" "ishift")
11776    (set_attr "length" "2")])
11777
11778 ;; This pattern can't accept a variable shift count, since shifts by
11779 ;; zero don't affect the flags.  We assume that shifts by constant
11780 ;; zero are optimized away.
11781 (define_insn "*ashrhi3_cmp"
11782   [(set (reg FLAGS_REG)
11783         (compare
11784           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11785                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11786           (const_int 0)))
11787    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11788         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11789   "ix86_match_ccmode (insn, CCGOCmode)
11790    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11791    && (optimize_size
11792        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11793   "sar{w}\t{%2, %0|%0, %2}"
11794   [(set_attr "type" "ishift")
11795    (set_attr "mode" "HI")])
11796
11797 (define_insn "*ashrhi3_cconly"
11798   [(set (reg FLAGS_REG)
11799         (compare
11800           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11801                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11802           (const_int 0)))
11803    (clobber (match_scratch:HI 0 "=r"))]
11804   "ix86_match_ccmode (insn, CCGOCmode)
11805    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11806    && (optimize_size
11807        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11808   "sar{w}\t{%2, %0|%0, %2}"
11809   [(set_attr "type" "ishift")
11810    (set_attr "mode" "HI")])
11811
11812 (define_expand "ashrqi3"
11813   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11814         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11815                      (match_operand:QI 2 "nonmemory_operand" "")))
11816    (clobber (reg:CC FLAGS_REG))]
11817   "TARGET_QIMODE_MATH"
11818   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11819
11820 (define_insn "*ashrqi3_1_one_bit"
11821   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11822         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11823                      (match_operand:QI 2 "const1_operand" "")))
11824    (clobber (reg:CC FLAGS_REG))]
11825   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11826    && (TARGET_SHIFT1 || optimize_size)"
11827   "sar{b}\t%0"
11828   [(set_attr "type" "ishift")
11829    (set (attr "length")
11830      (if_then_else (match_operand 0 "register_operand" "")
11831         (const_string "2")
11832         (const_string "*")))])
11833
11834 (define_insn "*ashrqi3_1_one_bit_slp"
11835   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11836         (ashiftrt:QI (match_dup 0)
11837                      (match_operand:QI 1 "const1_operand" "")))
11838    (clobber (reg:CC FLAGS_REG))]
11839   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11840    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11841    && (TARGET_SHIFT1 || optimize_size)"
11842   "sar{b}\t%0"
11843   [(set_attr "type" "ishift1")
11844    (set (attr "length")
11845      (if_then_else (match_operand 0 "register_operand" "")
11846         (const_string "2")
11847         (const_string "*")))])
11848
11849 (define_insn "*ashrqi3_1"
11850   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11851         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11852                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11853    (clobber (reg:CC FLAGS_REG))]
11854   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11855   "@
11856    sar{b}\t{%2, %0|%0, %2}
11857    sar{b}\t{%b2, %0|%0, %b2}"
11858   [(set_attr "type" "ishift")
11859    (set_attr "mode" "QI")])
11860
11861 (define_insn "*ashrqi3_1_slp"
11862   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11863         (ashiftrt:QI (match_dup 0)
11864                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11865    (clobber (reg:CC FLAGS_REG))]
11866   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11867    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11868   "@
11869    sar{b}\t{%1, %0|%0, %1}
11870    sar{b}\t{%b1, %0|%0, %b1}"
11871   [(set_attr "type" "ishift1")
11872    (set_attr "mode" "QI")])
11873
11874 ;; This pattern can't accept a variable shift count, since shifts by
11875 ;; zero don't affect the flags.  We assume that shifts by constant
11876 ;; zero are optimized away.
11877 (define_insn "*ashrqi3_one_bit_cmp"
11878   [(set (reg FLAGS_REG)
11879         (compare
11880           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11881                        (match_operand:QI 2 "const1_operand" "I"))
11882           (const_int 0)))
11883    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11884         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11885   "ix86_match_ccmode (insn, CCGOCmode)
11886    && (TARGET_SHIFT1 || optimize_size)
11887    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11888   "sar{b}\t%0"
11889   [(set_attr "type" "ishift")
11890    (set (attr "length")
11891      (if_then_else (match_operand 0 "register_operand" "")
11892         (const_string "2")
11893         (const_string "*")))])
11894
11895 (define_insn "*ashrqi3_one_bit_cconly"
11896   [(set (reg FLAGS_REG)
11897         (compare
11898           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11899                        (match_operand:QI 2 "const1_operand" "I"))
11900           (const_int 0)))
11901    (clobber (match_scratch:QI 0 "=q"))]
11902   "ix86_match_ccmode (insn, CCGOCmode)
11903    && (TARGET_SHIFT1 || optimize_size)
11904    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11905   "sar{b}\t%0"
11906   [(set_attr "type" "ishift")
11907    (set_attr "length" "2")])
11908
11909 ;; This pattern can't accept a variable shift count, since shifts by
11910 ;; zero don't affect the flags.  We assume that shifts by constant
11911 ;; zero are optimized away.
11912 (define_insn "*ashrqi3_cmp"
11913   [(set (reg FLAGS_REG)
11914         (compare
11915           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11916                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11917           (const_int 0)))
11918    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11919         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11920   "ix86_match_ccmode (insn, CCGOCmode)
11921    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11922    && (optimize_size
11923        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11924   "sar{b}\t{%2, %0|%0, %2}"
11925   [(set_attr "type" "ishift")
11926    (set_attr "mode" "QI")])
11927
11928 (define_insn "*ashrqi3_cconly"
11929   [(set (reg FLAGS_REG)
11930         (compare
11931           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11932                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11933           (const_int 0)))
11934    (clobber (match_scratch:QI 0 "=q"))]
11935   "ix86_match_ccmode (insn, CCGOCmode)
11936    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11937    && (optimize_size
11938        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11939   "sar{b}\t{%2, %0|%0, %2}"
11940   [(set_attr "type" "ishift")
11941    (set_attr "mode" "QI")])
11942
11943 \f
11944 ;; Logical shift instructions
11945
11946 ;; See comment above `ashldi3' about how this works.
11947
11948 (define_expand "lshrti3"
11949   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11950                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11951                                 (match_operand:QI 2 "nonmemory_operand" "")))
11952               (clobber (reg:CC FLAGS_REG))])]
11953   "TARGET_64BIT"
11954 {
11955   if (! immediate_operand (operands[2], QImode))
11956     {
11957       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11958       DONE;
11959     }
11960   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11961   DONE;
11962 })
11963
11964 (define_insn "lshrti3_1"
11965   [(set (match_operand:TI 0 "register_operand" "=r")
11966         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11967                      (match_operand:QI 2 "register_operand" "c")))
11968    (clobber (match_scratch:DI 3 "=&r"))
11969    (clobber (reg:CC FLAGS_REG))]
11970   "TARGET_64BIT"
11971   "#"
11972   [(set_attr "type" "multi")])
11973
11974 (define_insn "*lshrti3_2"
11975   [(set (match_operand:TI 0 "register_operand" "=r")
11976         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11977                      (match_operand:QI 2 "immediate_operand" "O")))
11978    (clobber (reg:CC FLAGS_REG))]
11979   "TARGET_64BIT"
11980   "#"
11981   [(set_attr "type" "multi")])
11982
11983 (define_split
11984   [(set (match_operand:TI 0 "register_operand" "")
11985         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11986                      (match_operand:QI 2 "register_operand" "")))
11987    (clobber (match_scratch:DI 3 ""))
11988    (clobber (reg:CC FLAGS_REG))]
11989   "TARGET_64BIT && reload_completed"
11990   [(const_int 0)]
11991   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11992
11993 (define_split
11994   [(set (match_operand:TI 0 "register_operand" "")
11995         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11996                      (match_operand:QI 2 "immediate_operand" "")))
11997    (clobber (reg:CC FLAGS_REG))]
11998   "TARGET_64BIT && reload_completed"
11999   [(const_int 0)]
12000   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12001
12002 (define_expand "lshrdi3"
12003   [(set (match_operand:DI 0 "shiftdi_operand" "")
12004         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12005                      (match_operand:QI 2 "nonmemory_operand" "")))]
12006   ""
12007   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12008
12009 (define_insn "*lshrdi3_1_one_bit_rex64"
12010   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12011         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12012                      (match_operand:QI 2 "const1_operand" "")))
12013    (clobber (reg:CC FLAGS_REG))]
12014   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12015    && (TARGET_SHIFT1 || optimize_size)"
12016   "shr{q}\t%0"
12017   [(set_attr "type" "ishift")
12018    (set (attr "length")
12019      (if_then_else (match_operand:DI 0 "register_operand" "")
12020         (const_string "2")
12021         (const_string "*")))])
12022
12023 (define_insn "*lshrdi3_1_rex64"
12024   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12025         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12026                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12027    (clobber (reg:CC FLAGS_REG))]
12028   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12029   "@
12030    shr{q}\t{%2, %0|%0, %2}
12031    shr{q}\t{%b2, %0|%0, %b2}"
12032   [(set_attr "type" "ishift")
12033    (set_attr "mode" "DI")])
12034
12035 ;; This pattern can't accept a variable shift count, since shifts by
12036 ;; zero don't affect the flags.  We assume that shifts by constant
12037 ;; zero are optimized away.
12038 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12039   [(set (reg FLAGS_REG)
12040         (compare
12041           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12042                        (match_operand:QI 2 "const1_operand" ""))
12043           (const_int 0)))
12044    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12045         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12046   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12047    && (TARGET_SHIFT1 || optimize_size)
12048    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12049   "shr{q}\t%0"
12050   [(set_attr "type" "ishift")
12051    (set (attr "length")
12052      (if_then_else (match_operand:DI 0 "register_operand" "")
12053         (const_string "2")
12054         (const_string "*")))])
12055
12056 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12057   [(set (reg FLAGS_REG)
12058         (compare
12059           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12060                        (match_operand:QI 2 "const1_operand" ""))
12061           (const_int 0)))
12062    (clobber (match_scratch:DI 0 "=r"))]
12063   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12064    && (TARGET_SHIFT1 || optimize_size)
12065    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12066   "shr{q}\t%0"
12067   [(set_attr "type" "ishift")
12068    (set_attr "length" "2")])
12069
12070 ;; This pattern can't accept a variable shift count, since shifts by
12071 ;; zero don't affect the flags.  We assume that shifts by constant
12072 ;; zero are optimized away.
12073 (define_insn "*lshrdi3_cmp_rex64"
12074   [(set (reg FLAGS_REG)
12075         (compare
12076           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12077                        (match_operand:QI 2 "const_int_operand" "e"))
12078           (const_int 0)))
12079    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12080         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12081   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12082    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12083    && (optimize_size
12084        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12085   "shr{q}\t{%2, %0|%0, %2}"
12086   [(set_attr "type" "ishift")
12087    (set_attr "mode" "DI")])
12088
12089 (define_insn "*lshrdi3_cconly_rex64"
12090   [(set (reg FLAGS_REG)
12091         (compare
12092           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12093                        (match_operand:QI 2 "const_int_operand" "e"))
12094           (const_int 0)))
12095    (clobber (match_scratch:DI 0 "=r"))]
12096   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12097    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12098    && (optimize_size
12099        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12100   "shr{q}\t{%2, %0|%0, %2}"
12101   [(set_attr "type" "ishift")
12102    (set_attr "mode" "DI")])
12103
12104 (define_insn "*lshrdi3_1"
12105   [(set (match_operand:DI 0 "register_operand" "=r")
12106         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12107                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12108    (clobber (reg:CC FLAGS_REG))]
12109   "!TARGET_64BIT"
12110   "#"
12111   [(set_attr "type" "multi")])
12112
12113 ;; By default we don't ask for a scratch register, because when DImode
12114 ;; values are manipulated, registers are already at a premium.  But if
12115 ;; we have one handy, we won't turn it away.
12116 (define_peephole2
12117   [(match_scratch:SI 3 "r")
12118    (parallel [(set (match_operand:DI 0 "register_operand" "")
12119                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12120                                 (match_operand:QI 2 "nonmemory_operand" "")))
12121               (clobber (reg:CC FLAGS_REG))])
12122    (match_dup 3)]
12123   "!TARGET_64BIT && TARGET_CMOVE"
12124   [(const_int 0)]
12125   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12126
12127 (define_split
12128   [(set (match_operand:DI 0 "register_operand" "")
12129         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12130                      (match_operand:QI 2 "nonmemory_operand" "")))
12131    (clobber (reg:CC FLAGS_REG))]
12132   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12133                      ? flow2_completed : reload_completed)"
12134   [(const_int 0)]
12135   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12136
12137 (define_expand "lshrsi3"
12138   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12139         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12140                      (match_operand:QI 2 "nonmemory_operand" "")))
12141    (clobber (reg:CC FLAGS_REG))]
12142   ""
12143   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12144
12145 (define_insn "*lshrsi3_1_one_bit"
12146   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12147         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12148                      (match_operand:QI 2 "const1_operand" "")))
12149    (clobber (reg:CC FLAGS_REG))]
12150   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12151    && (TARGET_SHIFT1 || optimize_size)"
12152   "shr{l}\t%0"
12153   [(set_attr "type" "ishift")
12154    (set (attr "length")
12155      (if_then_else (match_operand:SI 0 "register_operand" "")
12156         (const_string "2")
12157         (const_string "*")))])
12158
12159 (define_insn "*lshrsi3_1_one_bit_zext"
12160   [(set (match_operand:DI 0 "register_operand" "=r")
12161         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12162                      (match_operand:QI 2 "const1_operand" "")))
12163    (clobber (reg:CC FLAGS_REG))]
12164   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12165    && (TARGET_SHIFT1 || optimize_size)"
12166   "shr{l}\t%k0"
12167   [(set_attr "type" "ishift")
12168    (set_attr "length" "2")])
12169
12170 (define_insn "*lshrsi3_1"
12171   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12172         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12173                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12174    (clobber (reg:CC FLAGS_REG))]
12175   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12176   "@
12177    shr{l}\t{%2, %0|%0, %2}
12178    shr{l}\t{%b2, %0|%0, %b2}"
12179   [(set_attr "type" "ishift")
12180    (set_attr "mode" "SI")])
12181
12182 (define_insn "*lshrsi3_1_zext"
12183   [(set (match_operand:DI 0 "register_operand" "=r,r")
12184         (zero_extend:DI
12185           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12186                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12187    (clobber (reg:CC FLAGS_REG))]
12188   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12189   "@
12190    shr{l}\t{%2, %k0|%k0, %2}
12191    shr{l}\t{%b2, %k0|%k0, %b2}"
12192   [(set_attr "type" "ishift")
12193    (set_attr "mode" "SI")])
12194
12195 ;; This pattern can't accept a variable shift count, since shifts by
12196 ;; zero don't affect the flags.  We assume that shifts by constant
12197 ;; zero are optimized away.
12198 (define_insn "*lshrsi3_one_bit_cmp"
12199   [(set (reg FLAGS_REG)
12200         (compare
12201           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12202                        (match_operand:QI 2 "const1_operand" ""))
12203           (const_int 0)))
12204    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12205         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12206   "ix86_match_ccmode (insn, CCGOCmode)
12207    && (TARGET_SHIFT1 || optimize_size)
12208    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12209   "shr{l}\t%0"
12210   [(set_attr "type" "ishift")
12211    (set (attr "length")
12212      (if_then_else (match_operand:SI 0 "register_operand" "")
12213         (const_string "2")
12214         (const_string "*")))])
12215
12216 (define_insn "*lshrsi3_one_bit_cconly"
12217   [(set (reg FLAGS_REG)
12218         (compare
12219           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12220                        (match_operand:QI 2 "const1_operand" ""))
12221           (const_int 0)))
12222    (clobber (match_scratch:SI 0 "=r"))]
12223   "ix86_match_ccmode (insn, CCGOCmode)
12224    && (TARGET_SHIFT1 || optimize_size)
12225    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12226   "shr{l}\t%0"
12227   [(set_attr "type" "ishift")
12228    (set_attr "length" "2")])
12229
12230 (define_insn "*lshrsi3_cmp_one_bit_zext"
12231   [(set (reg FLAGS_REG)
12232         (compare
12233           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12234                        (match_operand:QI 2 "const1_operand" ""))
12235           (const_int 0)))
12236    (set (match_operand:DI 0 "register_operand" "=r")
12237         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12238   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12239    && (TARGET_SHIFT1 || optimize_size)
12240    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12241   "shr{l}\t%k0"
12242   [(set_attr "type" "ishift")
12243    (set_attr "length" "2")])
12244
12245 ;; This pattern can't accept a variable shift count, since shifts by
12246 ;; zero don't affect the flags.  We assume that shifts by constant
12247 ;; zero are optimized away.
12248 (define_insn "*lshrsi3_cmp"
12249   [(set (reg FLAGS_REG)
12250         (compare
12251           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12252                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12253           (const_int 0)))
12254    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12255         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12256   "ix86_match_ccmode (insn, CCGOCmode)
12257    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12258    && (optimize_size
12259        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12260   "shr{l}\t{%2, %0|%0, %2}"
12261   [(set_attr "type" "ishift")
12262    (set_attr "mode" "SI")])
12263
12264 (define_insn "*lshrsi3_cconly"
12265   [(set (reg FLAGS_REG)
12266       (compare
12267         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12268                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12269         (const_int 0)))
12270    (clobber (match_scratch:SI 0 "=r"))]
12271   "ix86_match_ccmode (insn, CCGOCmode)
12272    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12273    && (optimize_size
12274        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12275   "shr{l}\t{%2, %0|%0, %2}"
12276   [(set_attr "type" "ishift")
12277    (set_attr "mode" "SI")])
12278
12279 (define_insn "*lshrsi3_cmp_zext"
12280   [(set (reg FLAGS_REG)
12281         (compare
12282           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12283                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12284           (const_int 0)))
12285    (set (match_operand:DI 0 "register_operand" "=r")
12286         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12287   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12288    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12289    && (optimize_size
12290        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12291   "shr{l}\t{%2, %k0|%k0, %2}"
12292   [(set_attr "type" "ishift")
12293    (set_attr "mode" "SI")])
12294
12295 (define_expand "lshrhi3"
12296   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12297         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12298                      (match_operand:QI 2 "nonmemory_operand" "")))
12299    (clobber (reg:CC FLAGS_REG))]
12300   "TARGET_HIMODE_MATH"
12301   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12302
12303 (define_insn "*lshrhi3_1_one_bit"
12304   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12305         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12306                      (match_operand:QI 2 "const1_operand" "")))
12307    (clobber (reg:CC FLAGS_REG))]
12308   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12309    && (TARGET_SHIFT1 || optimize_size)"
12310   "shr{w}\t%0"
12311   [(set_attr "type" "ishift")
12312    (set (attr "length")
12313      (if_then_else (match_operand 0 "register_operand" "")
12314         (const_string "2")
12315         (const_string "*")))])
12316
12317 (define_insn "*lshrhi3_1"
12318   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12319         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12320                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12321    (clobber (reg:CC FLAGS_REG))]
12322   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12323   "@
12324    shr{w}\t{%2, %0|%0, %2}
12325    shr{w}\t{%b2, %0|%0, %b2}"
12326   [(set_attr "type" "ishift")
12327    (set_attr "mode" "HI")])
12328
12329 ;; This pattern can't accept a variable shift count, since shifts by
12330 ;; zero don't affect the flags.  We assume that shifts by constant
12331 ;; zero are optimized away.
12332 (define_insn "*lshrhi3_one_bit_cmp"
12333   [(set (reg FLAGS_REG)
12334         (compare
12335           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12336                        (match_operand:QI 2 "const1_operand" ""))
12337           (const_int 0)))
12338    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12339         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12340   "ix86_match_ccmode (insn, CCGOCmode)
12341    && (TARGET_SHIFT1 || optimize_size)
12342    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12343   "shr{w}\t%0"
12344   [(set_attr "type" "ishift")
12345    (set (attr "length")
12346      (if_then_else (match_operand:SI 0 "register_operand" "")
12347         (const_string "2")
12348         (const_string "*")))])
12349
12350 (define_insn "*lshrhi3_one_bit_cconly"
12351   [(set (reg FLAGS_REG)
12352         (compare
12353           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12354                        (match_operand:QI 2 "const1_operand" ""))
12355           (const_int 0)))
12356    (clobber (match_scratch:HI 0 "=r"))]
12357   "ix86_match_ccmode (insn, CCGOCmode)
12358    && (TARGET_SHIFT1 || optimize_size)
12359    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12360   "shr{w}\t%0"
12361   [(set_attr "type" "ishift")
12362    (set_attr "length" "2")])
12363
12364 ;; This pattern can't accept a variable shift count, since shifts by
12365 ;; zero don't affect the flags.  We assume that shifts by constant
12366 ;; zero are optimized away.
12367 (define_insn "*lshrhi3_cmp"
12368   [(set (reg FLAGS_REG)
12369         (compare
12370           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12371                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12372           (const_int 0)))
12373    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12374         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12375   "ix86_match_ccmode (insn, CCGOCmode)
12376    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12377    && (optimize_size
12378        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12379   "shr{w}\t{%2, %0|%0, %2}"
12380   [(set_attr "type" "ishift")
12381    (set_attr "mode" "HI")])
12382
12383 (define_insn "*lshrhi3_cconly"
12384   [(set (reg FLAGS_REG)
12385         (compare
12386           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12387                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12388           (const_int 0)))
12389    (clobber (match_scratch:HI 0 "=r"))]
12390   "ix86_match_ccmode (insn, CCGOCmode)
12391    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12392    && (optimize_size
12393        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12394   "shr{w}\t{%2, %0|%0, %2}"
12395   [(set_attr "type" "ishift")
12396    (set_attr "mode" "HI")])
12397
12398 (define_expand "lshrqi3"
12399   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12400         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12401                      (match_operand:QI 2 "nonmemory_operand" "")))
12402    (clobber (reg:CC FLAGS_REG))]
12403   "TARGET_QIMODE_MATH"
12404   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12405
12406 (define_insn "*lshrqi3_1_one_bit"
12407   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12408         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12409                      (match_operand:QI 2 "const1_operand" "")))
12410    (clobber (reg:CC FLAGS_REG))]
12411   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12412    && (TARGET_SHIFT1 || optimize_size)"
12413   "shr{b}\t%0"
12414   [(set_attr "type" "ishift")
12415    (set (attr "length")
12416      (if_then_else (match_operand 0 "register_operand" "")
12417         (const_string "2")
12418         (const_string "*")))])
12419
12420 (define_insn "*lshrqi3_1_one_bit_slp"
12421   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12422         (lshiftrt:QI (match_dup 0)
12423                      (match_operand:QI 1 "const1_operand" "")))
12424    (clobber (reg:CC FLAGS_REG))]
12425   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12426    && (TARGET_SHIFT1 || optimize_size)"
12427   "shr{b}\t%0"
12428   [(set_attr "type" "ishift1")
12429    (set (attr "length")
12430      (if_then_else (match_operand 0 "register_operand" "")
12431         (const_string "2")
12432         (const_string "*")))])
12433
12434 (define_insn "*lshrqi3_1"
12435   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12436         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12437                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12438    (clobber (reg:CC FLAGS_REG))]
12439   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12440   "@
12441    shr{b}\t{%2, %0|%0, %2}
12442    shr{b}\t{%b2, %0|%0, %b2}"
12443   [(set_attr "type" "ishift")
12444    (set_attr "mode" "QI")])
12445
12446 (define_insn "*lshrqi3_1_slp"
12447   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12448         (lshiftrt:QI (match_dup 0)
12449                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12450    (clobber (reg:CC FLAGS_REG))]
12451   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12452    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12453   "@
12454    shr{b}\t{%1, %0|%0, %1}
12455    shr{b}\t{%b1, %0|%0, %b1}"
12456   [(set_attr "type" "ishift1")
12457    (set_attr "mode" "QI")])
12458
12459 ;; This pattern can't accept a variable shift count, since shifts by
12460 ;; zero don't affect the flags.  We assume that shifts by constant
12461 ;; zero are optimized away.
12462 (define_insn "*lshrqi2_one_bit_cmp"
12463   [(set (reg FLAGS_REG)
12464         (compare
12465           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12466                        (match_operand:QI 2 "const1_operand" ""))
12467           (const_int 0)))
12468    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12469         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12470   "ix86_match_ccmode (insn, CCGOCmode)
12471    && (TARGET_SHIFT1 || optimize_size)
12472    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12473   "shr{b}\t%0"
12474   [(set_attr "type" "ishift")
12475    (set (attr "length")
12476      (if_then_else (match_operand:SI 0 "register_operand" "")
12477         (const_string "2")
12478         (const_string "*")))])
12479
12480 (define_insn "*lshrqi2_one_bit_cconly"
12481   [(set (reg FLAGS_REG)
12482         (compare
12483           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12484                        (match_operand:QI 2 "const1_operand" ""))
12485           (const_int 0)))
12486    (clobber (match_scratch:QI 0 "=q"))]
12487   "ix86_match_ccmode (insn, CCGOCmode)
12488    && (TARGET_SHIFT1 || optimize_size)
12489    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12490   "shr{b}\t%0"
12491   [(set_attr "type" "ishift")
12492    (set_attr "length" "2")])
12493
12494 ;; This pattern can't accept a variable shift count, since shifts by
12495 ;; zero don't affect the flags.  We assume that shifts by constant
12496 ;; zero are optimized away.
12497 (define_insn "*lshrqi2_cmp"
12498   [(set (reg FLAGS_REG)
12499         (compare
12500           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12501                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12502           (const_int 0)))
12503    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12504         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12505   "ix86_match_ccmode (insn, CCGOCmode)
12506    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12507    && (optimize_size
12508        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12509   "shr{b}\t{%2, %0|%0, %2}"
12510   [(set_attr "type" "ishift")
12511    (set_attr "mode" "QI")])
12512
12513 (define_insn "*lshrqi2_cconly"
12514   [(set (reg FLAGS_REG)
12515         (compare
12516           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12517                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12518           (const_int 0)))
12519    (clobber (match_scratch:QI 0 "=q"))]
12520   "ix86_match_ccmode (insn, CCGOCmode)
12521    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12522    && (optimize_size
12523        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12524   "shr{b}\t{%2, %0|%0, %2}"
12525   [(set_attr "type" "ishift")
12526    (set_attr "mode" "QI")])
12527 \f
12528 ;; Rotate instructions
12529
12530 (define_expand "rotldi3"
12531   [(set (match_operand:DI 0 "shiftdi_operand" "")
12532         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12533                    (match_operand:QI 2 "nonmemory_operand" "")))
12534    (clobber (reg:CC FLAGS_REG))]
12535  ""
12536 {
12537   if (TARGET_64BIT)
12538     {
12539       ix86_expand_binary_operator (ROTATE, DImode, operands);
12540       DONE;
12541     }
12542   if (!const_1_to_31_operand (operands[2], VOIDmode))
12543     FAIL;
12544   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12545   DONE;
12546 })
12547
12548 ;; Implement rotation using two double-precision shift instructions
12549 ;; and a scratch register.
12550 (define_insn_and_split "ix86_rotldi3"
12551  [(set (match_operand:DI 0 "register_operand" "=r")
12552        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12553                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12554   (clobber (reg:CC FLAGS_REG))
12555   (clobber (match_scratch:SI 3 "=&r"))]
12556  "!TARGET_64BIT"
12557  ""
12558  "&& reload_completed"
12559  [(set (match_dup 3) (match_dup 4))
12560   (parallel
12561    [(set (match_dup 4)
12562          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12563                  (lshiftrt:SI (match_dup 5)
12564                               (minus:QI (const_int 32) (match_dup 2)))))
12565     (clobber (reg:CC FLAGS_REG))])
12566   (parallel
12567    [(set (match_dup 5)
12568          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12569                  (lshiftrt:SI (match_dup 3)
12570                               (minus:QI (const_int 32) (match_dup 2)))))
12571     (clobber (reg:CC FLAGS_REG))])]
12572  "split_di (operands, 1, operands + 4, operands + 5);")
12573
12574 (define_insn "*rotlsi3_1_one_bit_rex64"
12575   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12576         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12577                    (match_operand:QI 2 "const1_operand" "")))
12578    (clobber (reg:CC FLAGS_REG))]
12579   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12580    && (TARGET_SHIFT1 || optimize_size)"
12581   "rol{q}\t%0"
12582   [(set_attr "type" "rotate")
12583    (set (attr "length")
12584      (if_then_else (match_operand:DI 0 "register_operand" "")
12585         (const_string "2")
12586         (const_string "*")))])
12587
12588 (define_insn "*rotldi3_1_rex64"
12589   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12590         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12591                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12592    (clobber (reg:CC FLAGS_REG))]
12593   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12594   "@
12595    rol{q}\t{%2, %0|%0, %2}
12596    rol{q}\t{%b2, %0|%0, %b2}"
12597   [(set_attr "type" "rotate")
12598    (set_attr "mode" "DI")])
12599
12600 (define_expand "rotlsi3"
12601   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12602         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12603                    (match_operand:QI 2 "nonmemory_operand" "")))
12604    (clobber (reg:CC FLAGS_REG))]
12605   ""
12606   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12607
12608 (define_insn "*rotlsi3_1_one_bit"
12609   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12610         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12611                    (match_operand:QI 2 "const1_operand" "")))
12612    (clobber (reg:CC FLAGS_REG))]
12613   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12614    && (TARGET_SHIFT1 || optimize_size)"
12615   "rol{l}\t%0"
12616   [(set_attr "type" "rotate")
12617    (set (attr "length")
12618      (if_then_else (match_operand:SI 0 "register_operand" "")
12619         (const_string "2")
12620         (const_string "*")))])
12621
12622 (define_insn "*rotlsi3_1_one_bit_zext"
12623   [(set (match_operand:DI 0 "register_operand" "=r")
12624         (zero_extend:DI
12625           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12626                      (match_operand:QI 2 "const1_operand" ""))))
12627    (clobber (reg:CC FLAGS_REG))]
12628   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12629    && (TARGET_SHIFT1 || optimize_size)"
12630   "rol{l}\t%k0"
12631   [(set_attr "type" "rotate")
12632    (set_attr "length" "2")])
12633
12634 (define_insn "*rotlsi3_1"
12635   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12636         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12637                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12638    (clobber (reg:CC FLAGS_REG))]
12639   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12640   "@
12641    rol{l}\t{%2, %0|%0, %2}
12642    rol{l}\t{%b2, %0|%0, %b2}"
12643   [(set_attr "type" "rotate")
12644    (set_attr "mode" "SI")])
12645
12646 (define_insn "*rotlsi3_1_zext"
12647   [(set (match_operand:DI 0 "register_operand" "=r,r")
12648         (zero_extend:DI
12649           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12650                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12651    (clobber (reg:CC FLAGS_REG))]
12652   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12653   "@
12654    rol{l}\t{%2, %k0|%k0, %2}
12655    rol{l}\t{%b2, %k0|%k0, %b2}"
12656   [(set_attr "type" "rotate")
12657    (set_attr "mode" "SI")])
12658
12659 (define_expand "rotlhi3"
12660   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12661         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12662                    (match_operand:QI 2 "nonmemory_operand" "")))
12663    (clobber (reg:CC FLAGS_REG))]
12664   "TARGET_HIMODE_MATH"
12665   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12666
12667 (define_insn "*rotlhi3_1_one_bit"
12668   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12669         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12670                    (match_operand:QI 2 "const1_operand" "")))
12671    (clobber (reg:CC FLAGS_REG))]
12672   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12673    && (TARGET_SHIFT1 || optimize_size)"
12674   "rol{w}\t%0"
12675   [(set_attr "type" "rotate")
12676    (set (attr "length")
12677      (if_then_else (match_operand 0 "register_operand" "")
12678         (const_string "2")
12679         (const_string "*")))])
12680
12681 (define_insn "*rotlhi3_1"
12682   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12683         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12684                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12685    (clobber (reg:CC FLAGS_REG))]
12686   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12687   "@
12688    rol{w}\t{%2, %0|%0, %2}
12689    rol{w}\t{%b2, %0|%0, %b2}"
12690   [(set_attr "type" "rotate")
12691    (set_attr "mode" "HI")])
12692
12693 (define_expand "rotlqi3"
12694   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12695         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12696                    (match_operand:QI 2 "nonmemory_operand" "")))
12697    (clobber (reg:CC FLAGS_REG))]
12698   "TARGET_QIMODE_MATH"
12699   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12700
12701 (define_insn "*rotlqi3_1_one_bit_slp"
12702   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12703         (rotate:QI (match_dup 0)
12704                    (match_operand:QI 1 "const1_operand" "")))
12705    (clobber (reg:CC FLAGS_REG))]
12706   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12707    && (TARGET_SHIFT1 || optimize_size)"
12708   "rol{b}\t%0"
12709   [(set_attr "type" "rotate1")
12710    (set (attr "length")
12711      (if_then_else (match_operand 0 "register_operand" "")
12712         (const_string "2")
12713         (const_string "*")))])
12714
12715 (define_insn "*rotlqi3_1_one_bit"
12716   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12717         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12718                    (match_operand:QI 2 "const1_operand" "")))
12719    (clobber (reg:CC FLAGS_REG))]
12720   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12721    && (TARGET_SHIFT1 || optimize_size)"
12722   "rol{b}\t%0"
12723   [(set_attr "type" "rotate")
12724    (set (attr "length")
12725      (if_then_else (match_operand 0 "register_operand" "")
12726         (const_string "2")
12727         (const_string "*")))])
12728
12729 (define_insn "*rotlqi3_1_slp"
12730   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12731         (rotate:QI (match_dup 0)
12732                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12733    (clobber (reg:CC FLAGS_REG))]
12734   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12735    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12736   "@
12737    rol{b}\t{%1, %0|%0, %1}
12738    rol{b}\t{%b1, %0|%0, %b1}"
12739   [(set_attr "type" "rotate1")
12740    (set_attr "mode" "QI")])
12741
12742 (define_insn "*rotlqi3_1"
12743   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12744         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12745                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12746    (clobber (reg:CC FLAGS_REG))]
12747   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12748   "@
12749    rol{b}\t{%2, %0|%0, %2}
12750    rol{b}\t{%b2, %0|%0, %b2}"
12751   [(set_attr "type" "rotate")
12752    (set_attr "mode" "QI")])
12753
12754 (define_expand "rotrdi3"
12755   [(set (match_operand:DI 0 "shiftdi_operand" "")
12756         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12757                    (match_operand:QI 2 "nonmemory_operand" "")))
12758    (clobber (reg:CC FLAGS_REG))]
12759  ""
12760 {
12761   if (TARGET_64BIT)
12762     {
12763       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12764       DONE;
12765     }
12766   if (!const_1_to_31_operand (operands[2], VOIDmode))
12767     FAIL;
12768   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12769   DONE;
12770 })
12771
12772 ;; Implement rotation using two double-precision shift instructions
12773 ;; and a scratch register.
12774 (define_insn_and_split "ix86_rotrdi3"
12775  [(set (match_operand:DI 0 "register_operand" "=r")
12776        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12777                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12778   (clobber (reg:CC FLAGS_REG))
12779   (clobber (match_scratch:SI 3 "=&r"))]
12780  "!TARGET_64BIT"
12781  ""
12782  "&& reload_completed"
12783  [(set (match_dup 3) (match_dup 4))
12784   (parallel
12785    [(set (match_dup 4)
12786          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12787                  (ashift:SI (match_dup 5)
12788                             (minus:QI (const_int 32) (match_dup 2)))))
12789     (clobber (reg:CC FLAGS_REG))])
12790   (parallel
12791    [(set (match_dup 5)
12792          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12793                  (ashift:SI (match_dup 3)
12794                             (minus:QI (const_int 32) (match_dup 2)))))
12795     (clobber (reg:CC FLAGS_REG))])]
12796  "split_di (operands, 1, operands + 4, operands + 5);")
12797
12798 (define_insn "*rotrdi3_1_one_bit_rex64"
12799   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12800         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12801                      (match_operand:QI 2 "const1_operand" "")))
12802    (clobber (reg:CC FLAGS_REG))]
12803   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12804    && (TARGET_SHIFT1 || optimize_size)"
12805   "ror{q}\t%0"
12806   [(set_attr "type" "rotate")
12807    (set (attr "length")
12808      (if_then_else (match_operand:DI 0 "register_operand" "")
12809         (const_string "2")
12810         (const_string "*")))])
12811
12812 (define_insn "*rotrdi3_1_rex64"
12813   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12814         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12815                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12816    (clobber (reg:CC FLAGS_REG))]
12817   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12818   "@
12819    ror{q}\t{%2, %0|%0, %2}
12820    ror{q}\t{%b2, %0|%0, %b2}"
12821   [(set_attr "type" "rotate")
12822    (set_attr "mode" "DI")])
12823
12824 (define_expand "rotrsi3"
12825   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12826         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12827                      (match_operand:QI 2 "nonmemory_operand" "")))
12828    (clobber (reg:CC FLAGS_REG))]
12829   ""
12830   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12831
12832 (define_insn "*rotrsi3_1_one_bit"
12833   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12834         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12835                      (match_operand:QI 2 "const1_operand" "")))
12836    (clobber (reg:CC FLAGS_REG))]
12837   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12838    && (TARGET_SHIFT1 || optimize_size)"
12839   "ror{l}\t%0"
12840   [(set_attr "type" "rotate")
12841    (set (attr "length")
12842      (if_then_else (match_operand:SI 0 "register_operand" "")
12843         (const_string "2")
12844         (const_string "*")))])
12845
12846 (define_insn "*rotrsi3_1_one_bit_zext"
12847   [(set (match_operand:DI 0 "register_operand" "=r")
12848         (zero_extend:DI
12849           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12850                        (match_operand:QI 2 "const1_operand" ""))))
12851    (clobber (reg:CC FLAGS_REG))]
12852   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12853    && (TARGET_SHIFT1 || optimize_size)"
12854   "ror{l}\t%k0"
12855   [(set_attr "type" "rotate")
12856    (set (attr "length")
12857      (if_then_else (match_operand:SI 0 "register_operand" "")
12858         (const_string "2")
12859         (const_string "*")))])
12860
12861 (define_insn "*rotrsi3_1"
12862   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12863         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12864                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12865    (clobber (reg:CC FLAGS_REG))]
12866   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12867   "@
12868    ror{l}\t{%2, %0|%0, %2}
12869    ror{l}\t{%b2, %0|%0, %b2}"
12870   [(set_attr "type" "rotate")
12871    (set_attr "mode" "SI")])
12872
12873 (define_insn "*rotrsi3_1_zext"
12874   [(set (match_operand:DI 0 "register_operand" "=r,r")
12875         (zero_extend:DI
12876           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12877                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12878    (clobber (reg:CC FLAGS_REG))]
12879   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12880   "@
12881    ror{l}\t{%2, %k0|%k0, %2}
12882    ror{l}\t{%b2, %k0|%k0, %b2}"
12883   [(set_attr "type" "rotate")
12884    (set_attr "mode" "SI")])
12885
12886 (define_expand "rotrhi3"
12887   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12888         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12889                      (match_operand:QI 2 "nonmemory_operand" "")))
12890    (clobber (reg:CC FLAGS_REG))]
12891   "TARGET_HIMODE_MATH"
12892   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12893
12894 (define_insn "*rotrhi3_one_bit"
12895   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12896         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12897                      (match_operand:QI 2 "const1_operand" "")))
12898    (clobber (reg:CC FLAGS_REG))]
12899   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12900    && (TARGET_SHIFT1 || optimize_size)"
12901   "ror{w}\t%0"
12902   [(set_attr "type" "rotate")
12903    (set (attr "length")
12904      (if_then_else (match_operand 0 "register_operand" "")
12905         (const_string "2")
12906         (const_string "*")))])
12907
12908 (define_insn "*rotrhi3"
12909   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12910         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12911                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12912    (clobber (reg:CC FLAGS_REG))]
12913   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12914   "@
12915    ror{w}\t{%2, %0|%0, %2}
12916    ror{w}\t{%b2, %0|%0, %b2}"
12917   [(set_attr "type" "rotate")
12918    (set_attr "mode" "HI")])
12919
12920 (define_expand "rotrqi3"
12921   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12922         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12923                      (match_operand:QI 2 "nonmemory_operand" "")))
12924    (clobber (reg:CC FLAGS_REG))]
12925   "TARGET_QIMODE_MATH"
12926   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12927
12928 (define_insn "*rotrqi3_1_one_bit"
12929   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12930         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12931                      (match_operand:QI 2 "const1_operand" "")))
12932    (clobber (reg:CC FLAGS_REG))]
12933   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12934    && (TARGET_SHIFT1 || optimize_size)"
12935   "ror{b}\t%0"
12936   [(set_attr "type" "rotate")
12937    (set (attr "length")
12938      (if_then_else (match_operand 0 "register_operand" "")
12939         (const_string "2")
12940         (const_string "*")))])
12941
12942 (define_insn "*rotrqi3_1_one_bit_slp"
12943   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12944         (rotatert:QI (match_dup 0)
12945                      (match_operand:QI 1 "const1_operand" "")))
12946    (clobber (reg:CC FLAGS_REG))]
12947   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12948    && (TARGET_SHIFT1 || optimize_size)"
12949   "ror{b}\t%0"
12950   [(set_attr "type" "rotate1")
12951    (set (attr "length")
12952      (if_then_else (match_operand 0 "register_operand" "")
12953         (const_string "2")
12954         (const_string "*")))])
12955
12956 (define_insn "*rotrqi3_1"
12957   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12958         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12959                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12960    (clobber (reg:CC FLAGS_REG))]
12961   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12962   "@
12963    ror{b}\t{%2, %0|%0, %2}
12964    ror{b}\t{%b2, %0|%0, %b2}"
12965   [(set_attr "type" "rotate")
12966    (set_attr "mode" "QI")])
12967
12968 (define_insn "*rotrqi3_1_slp"
12969   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12970         (rotatert:QI (match_dup 0)
12971                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12972    (clobber (reg:CC FLAGS_REG))]
12973   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12974    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12975   "@
12976    ror{b}\t{%1, %0|%0, %1}
12977    ror{b}\t{%b1, %0|%0, %b1}"
12978   [(set_attr "type" "rotate1")
12979    (set_attr "mode" "QI")])
12980 \f
12981 ;; Bit set / bit test instructions
12982
12983 (define_expand "extv"
12984   [(set (match_operand:SI 0 "register_operand" "")
12985         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12986                          (match_operand:SI 2 "const8_operand" "")
12987                          (match_operand:SI 3 "const8_operand" "")))]
12988   ""
12989 {
12990   /* Handle extractions from %ah et al.  */
12991   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12992     FAIL;
12993
12994   /* From mips.md: extract_bit_field doesn't verify that our source
12995      matches the predicate, so check it again here.  */
12996   if (! ext_register_operand (operands[1], VOIDmode))
12997     FAIL;
12998 })
12999
13000 (define_expand "extzv"
13001   [(set (match_operand:SI 0 "register_operand" "")
13002         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13003                          (match_operand:SI 2 "const8_operand" "")
13004                          (match_operand:SI 3 "const8_operand" "")))]
13005   ""
13006 {
13007   /* Handle extractions from %ah et al.  */
13008   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13009     FAIL;
13010
13011   /* From mips.md: extract_bit_field doesn't verify that our source
13012      matches the predicate, so check it again here.  */
13013   if (! ext_register_operand (operands[1], VOIDmode))
13014     FAIL;
13015 })
13016
13017 (define_expand "insv"
13018   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13019                       (match_operand 1 "const8_operand" "")
13020                       (match_operand 2 "const8_operand" ""))
13021         (match_operand 3 "register_operand" ""))]
13022   ""
13023 {
13024   /* Handle insertions to %ah et al.  */
13025   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13026     FAIL;
13027
13028   /* From mips.md: insert_bit_field doesn't verify that our source
13029      matches the predicate, so check it again here.  */
13030   if (! ext_register_operand (operands[0], VOIDmode))
13031     FAIL;
13032
13033   if (TARGET_64BIT)
13034     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13035   else
13036     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13037
13038   DONE;
13039 })
13040
13041 ;; %%% bts, btr, btc, bt.
13042 ;; In general these instructions are *slow* when applied to memory,
13043 ;; since they enforce atomic operation.  When applied to registers,
13044 ;; it depends on the cpu implementation.  They're never faster than
13045 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13046 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13047 ;; within the instruction itself, so operating on bits in the high
13048 ;; 32-bits of a register becomes easier.
13049 ;;
13050 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13051 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13052 ;; negdf respectively, so they can never be disabled entirely.
13053
13054 (define_insn "*btsq"
13055   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13056                          (const_int 1)
13057                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13058         (const_int 1))
13059    (clobber (reg:CC FLAGS_REG))]
13060   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13061   "bts{q} %1,%0"
13062   [(set_attr "type" "alu1")])
13063
13064 (define_insn "*btrq"
13065   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13066                          (const_int 1)
13067                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13068         (const_int 0))
13069    (clobber (reg:CC FLAGS_REG))]
13070   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13071   "btr{q} %1,%0"
13072   [(set_attr "type" "alu1")])
13073
13074 (define_insn "*btcq"
13075   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13076                          (const_int 1)
13077                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13078         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13079    (clobber (reg:CC FLAGS_REG))]
13080   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13081   "btc{q} %1,%0"
13082   [(set_attr "type" "alu1")])
13083
13084 ;; Allow Nocona to avoid these instructions if a register is available.
13085
13086 (define_peephole2
13087   [(match_scratch:DI 2 "r")
13088    (parallel [(set (zero_extract:DI
13089                      (match_operand:DI 0 "register_operand" "")
13090                      (const_int 1)
13091                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13092                    (const_int 1))
13093               (clobber (reg:CC FLAGS_REG))])]
13094   "TARGET_64BIT && !TARGET_USE_BT"
13095   [(const_int 0)]
13096 {
13097   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13098   rtx op1;
13099
13100   if (HOST_BITS_PER_WIDE_INT >= 64)
13101     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13102   else if (i < HOST_BITS_PER_WIDE_INT)
13103     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13104   else
13105     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13106
13107   op1 = immed_double_const (lo, hi, DImode);
13108   if (i >= 31)
13109     {
13110       emit_move_insn (operands[2], op1);
13111       op1 = operands[2];
13112     }
13113
13114   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13115   DONE;
13116 })
13117
13118 (define_peephole2
13119   [(match_scratch:DI 2 "r")
13120    (parallel [(set (zero_extract:DI
13121                      (match_operand:DI 0 "register_operand" "")
13122                      (const_int 1)
13123                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13124                    (const_int 0))
13125               (clobber (reg:CC FLAGS_REG))])]
13126   "TARGET_64BIT && !TARGET_USE_BT"
13127   [(const_int 0)]
13128 {
13129   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13130   rtx op1;
13131
13132   if (HOST_BITS_PER_WIDE_INT >= 64)
13133     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13134   else if (i < HOST_BITS_PER_WIDE_INT)
13135     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13136   else
13137     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13138
13139   op1 = immed_double_const (~lo, ~hi, DImode);
13140   if (i >= 32)
13141     {
13142       emit_move_insn (operands[2], op1);
13143       op1 = operands[2];
13144     }
13145
13146   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13147   DONE;
13148 })
13149
13150 (define_peephole2
13151   [(match_scratch:DI 2 "r")
13152    (parallel [(set (zero_extract:DI
13153                      (match_operand:DI 0 "register_operand" "")
13154                      (const_int 1)
13155                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13156               (not:DI (zero_extract:DI
13157                         (match_dup 0) (const_int 1) (match_dup 1))))
13158               (clobber (reg:CC FLAGS_REG))])]
13159   "TARGET_64BIT && !TARGET_USE_BT"
13160   [(const_int 0)]
13161 {
13162   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13163   rtx op1;
13164
13165   if (HOST_BITS_PER_WIDE_INT >= 64)
13166     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13167   else if (i < HOST_BITS_PER_WIDE_INT)
13168     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13169   else
13170     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13171
13172   op1 = immed_double_const (lo, hi, DImode);
13173   if (i >= 31)
13174     {
13175       emit_move_insn (operands[2], op1);
13176       op1 = operands[2];
13177     }
13178
13179   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13180   DONE;
13181 })
13182 \f
13183 ;; Store-flag instructions.
13184
13185 ;; For all sCOND expanders, also expand the compare or test insn that
13186 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13187
13188 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13189 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13190 ;; way, which can later delete the movzx if only QImode is needed.
13191
13192 (define_expand "seq"
13193   [(set (match_operand:QI 0 "register_operand" "")
13194         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13195   ""
13196   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13197
13198 (define_expand "sne"
13199   [(set (match_operand:QI 0 "register_operand" "")
13200         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13201   ""
13202   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13203
13204 (define_expand "sgt"
13205   [(set (match_operand:QI 0 "register_operand" "")
13206         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13207   ""
13208   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13209
13210 (define_expand "sgtu"
13211   [(set (match_operand:QI 0 "register_operand" "")
13212         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13213   ""
13214   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13215
13216 (define_expand "slt"
13217   [(set (match_operand:QI 0 "register_operand" "")
13218         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13219   ""
13220   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13221
13222 (define_expand "sltu"
13223   [(set (match_operand:QI 0 "register_operand" "")
13224         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13225   ""
13226   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13227
13228 (define_expand "sge"
13229   [(set (match_operand:QI 0 "register_operand" "")
13230         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13231   ""
13232   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13233
13234 (define_expand "sgeu"
13235   [(set (match_operand:QI 0 "register_operand" "")
13236         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13237   ""
13238   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13239
13240 (define_expand "sle"
13241   [(set (match_operand:QI 0 "register_operand" "")
13242         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13243   ""
13244   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13245
13246 (define_expand "sleu"
13247   [(set (match_operand:QI 0 "register_operand" "")
13248         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13249   ""
13250   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13251
13252 (define_expand "sunordered"
13253   [(set (match_operand:QI 0 "register_operand" "")
13254         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13255   "TARGET_80387 || TARGET_SSE"
13256   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13257
13258 (define_expand "sordered"
13259   [(set (match_operand:QI 0 "register_operand" "")
13260         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13261   "TARGET_80387"
13262   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13263
13264 (define_expand "suneq"
13265   [(set (match_operand:QI 0 "register_operand" "")
13266         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13267   "TARGET_80387 || TARGET_SSE"
13268   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13269
13270 (define_expand "sunge"
13271   [(set (match_operand:QI 0 "register_operand" "")
13272         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13273   "TARGET_80387 || TARGET_SSE"
13274   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13275
13276 (define_expand "sungt"
13277   [(set (match_operand:QI 0 "register_operand" "")
13278         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13279   "TARGET_80387 || TARGET_SSE"
13280   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13281
13282 (define_expand "sunle"
13283   [(set (match_operand:QI 0 "register_operand" "")
13284         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13285   "TARGET_80387 || TARGET_SSE"
13286   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13287
13288 (define_expand "sunlt"
13289   [(set (match_operand:QI 0 "register_operand" "")
13290         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13291   "TARGET_80387 || TARGET_SSE"
13292   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13293
13294 (define_expand "sltgt"
13295   [(set (match_operand:QI 0 "register_operand" "")
13296         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13297   "TARGET_80387 || TARGET_SSE"
13298   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13299
13300 (define_insn "*setcc_1"
13301   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13302         (match_operator:QI 1 "ix86_comparison_operator"
13303           [(reg FLAGS_REG) (const_int 0)]))]
13304   ""
13305   "set%C1\t%0"
13306   [(set_attr "type" "setcc")
13307    (set_attr "mode" "QI")])
13308
13309 (define_insn "*setcc_2"
13310   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13311         (match_operator:QI 1 "ix86_comparison_operator"
13312           [(reg FLAGS_REG) (const_int 0)]))]
13313   ""
13314   "set%C1\t%0"
13315   [(set_attr "type" "setcc")
13316    (set_attr "mode" "QI")])
13317
13318 ;; In general it is not safe to assume too much about CCmode registers,
13319 ;; so simplify-rtx stops when it sees a second one.  Under certain
13320 ;; conditions this is safe on x86, so help combine not create
13321 ;;
13322 ;;      seta    %al
13323 ;;      testb   %al, %al
13324 ;;      sete    %al
13325
13326 (define_split
13327   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13328         (ne:QI (match_operator 1 "ix86_comparison_operator"
13329                  [(reg FLAGS_REG) (const_int 0)])
13330             (const_int 0)))]
13331   ""
13332   [(set (match_dup 0) (match_dup 1))]
13333 {
13334   PUT_MODE (operands[1], QImode);
13335 })
13336
13337 (define_split
13338   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13339         (ne:QI (match_operator 1 "ix86_comparison_operator"
13340                  [(reg FLAGS_REG) (const_int 0)])
13341             (const_int 0)))]
13342   ""
13343   [(set (match_dup 0) (match_dup 1))]
13344 {
13345   PUT_MODE (operands[1], QImode);
13346 })
13347
13348 (define_split
13349   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13350         (eq:QI (match_operator 1 "ix86_comparison_operator"
13351                  [(reg FLAGS_REG) (const_int 0)])
13352             (const_int 0)))]
13353   ""
13354   [(set (match_dup 0) (match_dup 1))]
13355 {
13356   rtx new_op1 = copy_rtx (operands[1]);
13357   operands[1] = new_op1;
13358   PUT_MODE (new_op1, QImode);
13359   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13360                                              GET_MODE (XEXP (new_op1, 0))));
13361
13362   /* Make sure that (a) the CCmode we have for the flags is strong
13363      enough for the reversed compare or (b) we have a valid FP compare.  */
13364   if (! ix86_comparison_operator (new_op1, VOIDmode))
13365     FAIL;
13366 })
13367
13368 (define_split
13369   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13370         (eq:QI (match_operator 1 "ix86_comparison_operator"
13371                  [(reg FLAGS_REG) (const_int 0)])
13372             (const_int 0)))]
13373   ""
13374   [(set (match_dup 0) (match_dup 1))]
13375 {
13376   rtx new_op1 = copy_rtx (operands[1]);
13377   operands[1] = new_op1;
13378   PUT_MODE (new_op1, QImode);
13379   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13380                                              GET_MODE (XEXP (new_op1, 0))));
13381
13382   /* Make sure that (a) the CCmode we have for the flags is strong
13383      enough for the reversed compare or (b) we have a valid FP compare.  */
13384   if (! ix86_comparison_operator (new_op1, VOIDmode))
13385     FAIL;
13386 })
13387
13388 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13389 ;; subsequent logical operations are used to imitate conditional moves.
13390 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13391 ;; it directly.
13392
13393 (define_insn "*sse_setccsf"
13394   [(set (match_operand:SF 0 "register_operand" "=x")
13395         (match_operator:SF 1 "sse_comparison_operator"
13396           [(match_operand:SF 2 "register_operand" "0")
13397            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13398   "TARGET_SSE"
13399   "cmp%D1ss\t{%3, %0|%0, %3}"
13400   [(set_attr "type" "ssecmp")
13401    (set_attr "mode" "SF")])
13402
13403 (define_insn "*sse_setccdf"
13404   [(set (match_operand:DF 0 "register_operand" "=Y")
13405         (match_operator:DF 1 "sse_comparison_operator"
13406           [(match_operand:DF 2 "register_operand" "0")
13407            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13408   "TARGET_SSE2"
13409   "cmp%D1sd\t{%3, %0|%0, %3}"
13410   [(set_attr "type" "ssecmp")
13411    (set_attr "mode" "DF")])
13412 \f
13413 ;; Basic conditional jump instructions.
13414 ;; We ignore the overflow flag for signed branch instructions.
13415
13416 ;; For all bCOND expanders, also expand the compare or test insn that
13417 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13418
13419 (define_expand "beq"
13420   [(set (pc)
13421         (if_then_else (match_dup 1)
13422                       (label_ref (match_operand 0 "" ""))
13423                       (pc)))]
13424   ""
13425   "ix86_expand_branch (EQ, operands[0]); DONE;")
13426
13427 (define_expand "bne"
13428   [(set (pc)
13429         (if_then_else (match_dup 1)
13430                       (label_ref (match_operand 0 "" ""))
13431                       (pc)))]
13432   ""
13433   "ix86_expand_branch (NE, operands[0]); DONE;")
13434
13435 (define_expand "bgt"
13436   [(set (pc)
13437         (if_then_else (match_dup 1)
13438                       (label_ref (match_operand 0 "" ""))
13439                       (pc)))]
13440   ""
13441   "ix86_expand_branch (GT, operands[0]); DONE;")
13442
13443 (define_expand "bgtu"
13444   [(set (pc)
13445         (if_then_else (match_dup 1)
13446                       (label_ref (match_operand 0 "" ""))
13447                       (pc)))]
13448   ""
13449   "ix86_expand_branch (GTU, operands[0]); DONE;")
13450
13451 (define_expand "blt"
13452   [(set (pc)
13453         (if_then_else (match_dup 1)
13454                       (label_ref (match_operand 0 "" ""))
13455                       (pc)))]
13456   ""
13457   "ix86_expand_branch (LT, operands[0]); DONE;")
13458
13459 (define_expand "bltu"
13460   [(set (pc)
13461         (if_then_else (match_dup 1)
13462                       (label_ref (match_operand 0 "" ""))
13463                       (pc)))]
13464   ""
13465   "ix86_expand_branch (LTU, operands[0]); DONE;")
13466
13467 (define_expand "bge"
13468   [(set (pc)
13469         (if_then_else (match_dup 1)
13470                       (label_ref (match_operand 0 "" ""))
13471                       (pc)))]
13472   ""
13473   "ix86_expand_branch (GE, operands[0]); DONE;")
13474
13475 (define_expand "bgeu"
13476   [(set (pc)
13477         (if_then_else (match_dup 1)
13478                       (label_ref (match_operand 0 "" ""))
13479                       (pc)))]
13480   ""
13481   "ix86_expand_branch (GEU, operands[0]); DONE;")
13482
13483 (define_expand "ble"
13484   [(set (pc)
13485         (if_then_else (match_dup 1)
13486                       (label_ref (match_operand 0 "" ""))
13487                       (pc)))]
13488   ""
13489   "ix86_expand_branch (LE, operands[0]); DONE;")
13490
13491 (define_expand "bleu"
13492   [(set (pc)
13493         (if_then_else (match_dup 1)
13494                       (label_ref (match_operand 0 "" ""))
13495                       (pc)))]
13496   ""
13497   "ix86_expand_branch (LEU, operands[0]); DONE;")
13498
13499 (define_expand "bunordered"
13500   [(set (pc)
13501         (if_then_else (match_dup 1)
13502                       (label_ref (match_operand 0 "" ""))
13503                       (pc)))]
13504   "TARGET_80387 || TARGET_SSE_MATH"
13505   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13506
13507 (define_expand "bordered"
13508   [(set (pc)
13509         (if_then_else (match_dup 1)
13510                       (label_ref (match_operand 0 "" ""))
13511                       (pc)))]
13512   "TARGET_80387 || TARGET_SSE_MATH"
13513   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13514
13515 (define_expand "buneq"
13516   [(set (pc)
13517         (if_then_else (match_dup 1)
13518                       (label_ref (match_operand 0 "" ""))
13519                       (pc)))]
13520   "TARGET_80387 || TARGET_SSE_MATH"
13521   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13522
13523 (define_expand "bunge"
13524   [(set (pc)
13525         (if_then_else (match_dup 1)
13526                       (label_ref (match_operand 0 "" ""))
13527                       (pc)))]
13528   "TARGET_80387 || TARGET_SSE_MATH"
13529   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13530
13531 (define_expand "bungt"
13532   [(set (pc)
13533         (if_then_else (match_dup 1)
13534                       (label_ref (match_operand 0 "" ""))
13535                       (pc)))]
13536   "TARGET_80387 || TARGET_SSE_MATH"
13537   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13538
13539 (define_expand "bunle"
13540   [(set (pc)
13541         (if_then_else (match_dup 1)
13542                       (label_ref (match_operand 0 "" ""))
13543                       (pc)))]
13544   "TARGET_80387 || TARGET_SSE_MATH"
13545   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13546
13547 (define_expand "bunlt"
13548   [(set (pc)
13549         (if_then_else (match_dup 1)
13550                       (label_ref (match_operand 0 "" ""))
13551                       (pc)))]
13552   "TARGET_80387 || TARGET_SSE_MATH"
13553   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13554
13555 (define_expand "bltgt"
13556   [(set (pc)
13557         (if_then_else (match_dup 1)
13558                       (label_ref (match_operand 0 "" ""))
13559                       (pc)))]
13560   "TARGET_80387 || TARGET_SSE_MATH"
13561   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13562
13563 (define_insn "*jcc_1"
13564   [(set (pc)
13565         (if_then_else (match_operator 1 "ix86_comparison_operator"
13566                                       [(reg FLAGS_REG) (const_int 0)])
13567                       (label_ref (match_operand 0 "" ""))
13568                       (pc)))]
13569   ""
13570   "%+j%C1\t%l0"
13571   [(set_attr "type" "ibr")
13572    (set_attr "modrm" "0")
13573    (set (attr "length")
13574            (if_then_else (and (ge (minus (match_dup 0) (pc))
13575                                   (const_int -126))
13576                               (lt (minus (match_dup 0) (pc))
13577                                   (const_int 128)))
13578              (const_int 2)
13579              (const_int 6)))])
13580
13581 (define_insn "*jcc_2"
13582   [(set (pc)
13583         (if_then_else (match_operator 1 "ix86_comparison_operator"
13584                                       [(reg FLAGS_REG) (const_int 0)])
13585                       (pc)
13586                       (label_ref (match_operand 0 "" ""))))]
13587   ""
13588   "%+j%c1\t%l0"
13589   [(set_attr "type" "ibr")
13590    (set_attr "modrm" "0")
13591    (set (attr "length")
13592            (if_then_else (and (ge (minus (match_dup 0) (pc))
13593                                   (const_int -126))
13594                               (lt (minus (match_dup 0) (pc))
13595                                   (const_int 128)))
13596              (const_int 2)
13597              (const_int 6)))])
13598
13599 ;; In general it is not safe to assume too much about CCmode registers,
13600 ;; so simplify-rtx stops when it sees a second one.  Under certain
13601 ;; conditions this is safe on x86, so help combine not create
13602 ;;
13603 ;;      seta    %al
13604 ;;      testb   %al, %al
13605 ;;      je      Lfoo
13606
13607 (define_split
13608   [(set (pc)
13609         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13610                                       [(reg FLAGS_REG) (const_int 0)])
13611                           (const_int 0))
13612                       (label_ref (match_operand 1 "" ""))
13613                       (pc)))]
13614   ""
13615   [(set (pc)
13616         (if_then_else (match_dup 0)
13617                       (label_ref (match_dup 1))
13618                       (pc)))]
13619 {
13620   PUT_MODE (operands[0], VOIDmode);
13621 })
13622
13623 (define_split
13624   [(set (pc)
13625         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13626                                       [(reg FLAGS_REG) (const_int 0)])
13627                           (const_int 0))
13628                       (label_ref (match_operand 1 "" ""))
13629                       (pc)))]
13630   ""
13631   [(set (pc)
13632         (if_then_else (match_dup 0)
13633                       (label_ref (match_dup 1))
13634                       (pc)))]
13635 {
13636   rtx new_op0 = copy_rtx (operands[0]);
13637   operands[0] = new_op0;
13638   PUT_MODE (new_op0, VOIDmode);
13639   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13640                                              GET_MODE (XEXP (new_op0, 0))));
13641
13642   /* Make sure that (a) the CCmode we have for the flags is strong
13643      enough for the reversed compare or (b) we have a valid FP compare.  */
13644   if (! ix86_comparison_operator (new_op0, VOIDmode))
13645     FAIL;
13646 })
13647
13648 ;; Define combination compare-and-branch fp compare instructions to use
13649 ;; during early optimization.  Splitting the operation apart early makes
13650 ;; for bad code when we want to reverse the operation.
13651
13652 (define_insn "*fp_jcc_1_mixed"
13653   [(set (pc)
13654         (if_then_else (match_operator 0 "comparison_operator"
13655                         [(match_operand 1 "register_operand" "f,x")
13656                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13657           (label_ref (match_operand 3 "" ""))
13658           (pc)))
13659    (clobber (reg:CCFP FPSR_REG))
13660    (clobber (reg:CCFP FLAGS_REG))]
13661   "TARGET_MIX_SSE_I387
13662    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13663    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13664    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13665   "#")
13666
13667 (define_insn "*fp_jcc_1_sse"
13668   [(set (pc)
13669         (if_then_else (match_operator 0 "comparison_operator"
13670                         [(match_operand 1 "register_operand" "x")
13671                          (match_operand 2 "nonimmediate_operand" "xm")])
13672           (label_ref (match_operand 3 "" ""))
13673           (pc)))
13674    (clobber (reg:CCFP FPSR_REG))
13675    (clobber (reg:CCFP FLAGS_REG))]
13676   "TARGET_SSE_MATH
13677    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13678    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13679    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13680   "#")
13681
13682 (define_insn "*fp_jcc_1_387"
13683   [(set (pc)
13684         (if_then_else (match_operator 0 "comparison_operator"
13685                         [(match_operand 1 "register_operand" "f")
13686                          (match_operand 2 "register_operand" "f")])
13687           (label_ref (match_operand 3 "" ""))
13688           (pc)))
13689    (clobber (reg:CCFP FPSR_REG))
13690    (clobber (reg:CCFP FLAGS_REG))]
13691   "TARGET_CMOVE && TARGET_80387
13692    && FLOAT_MODE_P (GET_MODE (operands[1]))
13693    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13694    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13695   "#")
13696
13697 (define_insn "*fp_jcc_2_mixed"
13698   [(set (pc)
13699         (if_then_else (match_operator 0 "comparison_operator"
13700                         [(match_operand 1 "register_operand" "f,x")
13701                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13702           (pc)
13703           (label_ref (match_operand 3 "" ""))))
13704    (clobber (reg:CCFP FPSR_REG))
13705    (clobber (reg:CCFP FLAGS_REG))]
13706   "TARGET_MIX_SSE_I387
13707    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13708    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13709    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13710   "#")
13711
13712 (define_insn "*fp_jcc_2_sse"
13713   [(set (pc)
13714         (if_then_else (match_operator 0 "comparison_operator"
13715                         [(match_operand 1 "register_operand" "x")
13716                          (match_operand 2 "nonimmediate_operand" "xm")])
13717           (pc)
13718           (label_ref (match_operand 3 "" ""))))
13719    (clobber (reg:CCFP FPSR_REG))
13720    (clobber (reg:CCFP FLAGS_REG))]
13721   "TARGET_SSE_MATH
13722    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13723    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13724    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13725   "#")
13726
13727 (define_insn "*fp_jcc_2_387"
13728   [(set (pc)
13729         (if_then_else (match_operator 0 "comparison_operator"
13730                         [(match_operand 1 "register_operand" "f")
13731                          (match_operand 2 "register_operand" "f")])
13732           (pc)
13733           (label_ref (match_operand 3 "" ""))))
13734    (clobber (reg:CCFP FPSR_REG))
13735    (clobber (reg:CCFP FLAGS_REG))]
13736   "TARGET_CMOVE && TARGET_80387
13737    && FLOAT_MODE_P (GET_MODE (operands[1]))
13738    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13739    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13740   "#")
13741
13742 (define_insn "*fp_jcc_3_387"
13743   [(set (pc)
13744         (if_then_else (match_operator 0 "comparison_operator"
13745                         [(match_operand 1 "register_operand" "f")
13746                          (match_operand 2 "nonimmediate_operand" "fm")])
13747           (label_ref (match_operand 3 "" ""))
13748           (pc)))
13749    (clobber (reg:CCFP FPSR_REG))
13750    (clobber (reg:CCFP FLAGS_REG))
13751    (clobber (match_scratch:HI 4 "=a"))]
13752   "TARGET_80387
13753    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13754    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13755    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13756    && SELECT_CC_MODE (GET_CODE (operands[0]),
13757                       operands[1], operands[2]) == CCFPmode
13758    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13759   "#")
13760
13761 (define_insn "*fp_jcc_4_387"
13762   [(set (pc)
13763         (if_then_else (match_operator 0 "comparison_operator"
13764                         [(match_operand 1 "register_operand" "f")
13765                          (match_operand 2 "nonimmediate_operand" "fm")])
13766           (pc)
13767           (label_ref (match_operand 3 "" ""))))
13768    (clobber (reg:CCFP FPSR_REG))
13769    (clobber (reg:CCFP FLAGS_REG))
13770    (clobber (match_scratch:HI 4 "=a"))]
13771   "TARGET_80387
13772    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13773    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13774    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13775    && SELECT_CC_MODE (GET_CODE (operands[0]),
13776                       operands[1], operands[2]) == CCFPmode
13777    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13778   "#")
13779
13780 (define_insn "*fp_jcc_5_387"
13781   [(set (pc)
13782         (if_then_else (match_operator 0 "comparison_operator"
13783                         [(match_operand 1 "register_operand" "f")
13784                          (match_operand 2 "register_operand" "f")])
13785           (label_ref (match_operand 3 "" ""))
13786           (pc)))
13787    (clobber (reg:CCFP FPSR_REG))
13788    (clobber (reg:CCFP FLAGS_REG))
13789    (clobber (match_scratch:HI 4 "=a"))]
13790   "TARGET_80387
13791    && FLOAT_MODE_P (GET_MODE (operands[1]))
13792    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13793    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13794   "#")
13795
13796 (define_insn "*fp_jcc_6_387"
13797   [(set (pc)
13798         (if_then_else (match_operator 0 "comparison_operator"
13799                         [(match_operand 1 "register_operand" "f")
13800                          (match_operand 2 "register_operand" "f")])
13801           (pc)
13802           (label_ref (match_operand 3 "" ""))))
13803    (clobber (reg:CCFP FPSR_REG))
13804    (clobber (reg:CCFP FLAGS_REG))
13805    (clobber (match_scratch:HI 4 "=a"))]
13806   "TARGET_80387
13807    && FLOAT_MODE_P (GET_MODE (operands[1]))
13808    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13809    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13810   "#")
13811
13812 (define_insn "*fp_jcc_7_387"
13813   [(set (pc)
13814         (if_then_else (match_operator 0 "comparison_operator"
13815                         [(match_operand 1 "register_operand" "f")
13816                          (match_operand 2 "const0_operand" "X")])
13817           (label_ref (match_operand 3 "" ""))
13818           (pc)))
13819    (clobber (reg:CCFP FPSR_REG))
13820    (clobber (reg:CCFP FLAGS_REG))
13821    (clobber (match_scratch:HI 4 "=a"))]
13822   "TARGET_80387
13823    && FLOAT_MODE_P (GET_MODE (operands[1]))
13824    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13825    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13826    && SELECT_CC_MODE (GET_CODE (operands[0]),
13827                       operands[1], operands[2]) == CCFPmode
13828    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13829   "#")
13830
13831 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13832 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13833 ;; with a precedence over other operators and is always put in the first
13834 ;; place. Swap condition and operands to match ficom instruction.
13835
13836 (define_insn "*fp_jcc_8<mode>_387"
13837   [(set (pc)
13838         (if_then_else (match_operator 0 "comparison_operator"
13839                         [(match_operator 1 "float_operator"
13840                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13841                            (match_operand 3 "register_operand" "f,f")])
13842           (label_ref (match_operand 4 "" ""))
13843           (pc)))
13844    (clobber (reg:CCFP FPSR_REG))
13845    (clobber (reg:CCFP FLAGS_REG))
13846    (clobber (match_scratch:HI 5 "=a,a"))]
13847   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13848    && FLOAT_MODE_P (GET_MODE (operands[3]))
13849    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13850    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13851    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13852    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13853   "#")
13854
13855 (define_split
13856   [(set (pc)
13857         (if_then_else (match_operator 0 "comparison_operator"
13858                         [(match_operand 1 "register_operand" "")
13859                          (match_operand 2 "nonimmediate_operand" "")])
13860           (match_operand 3 "" "")
13861           (match_operand 4 "" "")))
13862    (clobber (reg:CCFP FPSR_REG))
13863    (clobber (reg:CCFP FLAGS_REG))]
13864   "reload_completed"
13865   [(const_int 0)]
13866 {
13867   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13868                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13869   DONE;
13870 })
13871
13872 (define_split
13873   [(set (pc)
13874         (if_then_else (match_operator 0 "comparison_operator"
13875                         [(match_operand 1 "register_operand" "")
13876                          (match_operand 2 "general_operand" "")])
13877           (match_operand 3 "" "")
13878           (match_operand 4 "" "")))
13879    (clobber (reg:CCFP FPSR_REG))
13880    (clobber (reg:CCFP FLAGS_REG))
13881    (clobber (match_scratch:HI 5 "=a"))]
13882   "reload_completed"
13883   [(const_int 0)]
13884 {
13885   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13886                         operands[3], operands[4], operands[5], NULL_RTX);
13887   DONE;
13888 })
13889
13890 (define_split
13891   [(set (pc)
13892         (if_then_else (match_operator 0 "comparison_operator"
13893                         [(match_operator 1 "float_operator"
13894                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13895                            (match_operand 3 "register_operand" "")])
13896           (match_operand 4 "" "")
13897           (match_operand 5 "" "")))
13898    (clobber (reg:CCFP FPSR_REG))
13899    (clobber (reg:CCFP FLAGS_REG))
13900    (clobber (match_scratch:HI 6 "=a"))]
13901   "reload_completed"
13902   [(const_int 0)]
13903 {
13904   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13905   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13906                         operands[3], operands[7],
13907                         operands[4], operands[5], operands[6], NULL_RTX);
13908   DONE;
13909 })
13910
13911 ;; %%% Kill this when reload knows how to do it.
13912 (define_split
13913   [(set (pc)
13914         (if_then_else (match_operator 0 "comparison_operator"
13915                         [(match_operator 1 "float_operator"
13916                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13917                            (match_operand 3 "register_operand" "")])
13918           (match_operand 4 "" "")
13919           (match_operand 5 "" "")))
13920    (clobber (reg:CCFP FPSR_REG))
13921    (clobber (reg:CCFP FLAGS_REG))
13922    (clobber (match_scratch:HI 6 "=a"))]
13923   "reload_completed"
13924   [(const_int 0)]
13925 {
13926   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13927   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13928   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13929                         operands[3], operands[7],
13930                         operands[4], operands[5], operands[6], operands[2]);
13931   DONE;
13932 })
13933 \f
13934 ;; Unconditional and other jump instructions
13935
13936 (define_insn "jump"
13937   [(set (pc)
13938         (label_ref (match_operand 0 "" "")))]
13939   ""
13940   "jmp\t%l0"
13941   [(set_attr "type" "ibr")
13942    (set (attr "length")
13943            (if_then_else (and (ge (minus (match_dup 0) (pc))
13944                                   (const_int -126))
13945                               (lt (minus (match_dup 0) (pc))
13946                                   (const_int 128)))
13947              (const_int 2)
13948              (const_int 5)))
13949    (set_attr "modrm" "0")])
13950
13951 (define_expand "indirect_jump"
13952   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13953   ""
13954   "")
13955
13956 (define_insn "*indirect_jump"
13957   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13958   "!TARGET_64BIT"
13959   "jmp\t%A0"
13960   [(set_attr "type" "ibr")
13961    (set_attr "length_immediate" "0")])
13962
13963 (define_insn "*indirect_jump_rtx64"
13964   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13965   "TARGET_64BIT"
13966   "jmp\t%A0"
13967   [(set_attr "type" "ibr")
13968    (set_attr "length_immediate" "0")])
13969
13970 (define_expand "tablejump"
13971   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13972               (use (label_ref (match_operand 1 "" "")))])]
13973   ""
13974 {
13975   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13976      relative.  Convert the relative address to an absolute address.  */
13977   if (flag_pic)
13978     {
13979       rtx op0, op1;
13980       enum rtx_code code;
13981
13982       if (TARGET_64BIT)
13983         {
13984           code = PLUS;
13985           op0 = operands[0];
13986           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13987         }
13988       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13989         {
13990           code = PLUS;
13991           op0 = operands[0];
13992           op1 = pic_offset_table_rtx;
13993         }
13994       else
13995         {
13996           code = MINUS;
13997           op0 = pic_offset_table_rtx;
13998           op1 = operands[0];
13999         }
14000
14001       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14002                                          OPTAB_DIRECT);
14003     }
14004 })
14005
14006 (define_insn "*tablejump_1"
14007   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14008    (use (label_ref (match_operand 1 "" "")))]
14009   "!TARGET_64BIT"
14010   "jmp\t%A0"
14011   [(set_attr "type" "ibr")
14012    (set_attr "length_immediate" "0")])
14013
14014 (define_insn "*tablejump_1_rtx64"
14015   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14016    (use (label_ref (match_operand 1 "" "")))]
14017   "TARGET_64BIT"
14018   "jmp\t%A0"
14019   [(set_attr "type" "ibr")
14020    (set_attr "length_immediate" "0")])
14021 \f
14022 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14023
14024 (define_peephole2
14025   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14026    (set (match_operand:QI 1 "register_operand" "")
14027         (match_operator:QI 2 "ix86_comparison_operator"
14028           [(reg FLAGS_REG) (const_int 0)]))
14029    (set (match_operand 3 "q_regs_operand" "")
14030         (zero_extend (match_dup 1)))]
14031   "(peep2_reg_dead_p (3, operands[1])
14032     || operands_match_p (operands[1], operands[3]))
14033    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14034   [(set (match_dup 4) (match_dup 0))
14035    (set (strict_low_part (match_dup 5))
14036         (match_dup 2))]
14037 {
14038   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14039   operands[5] = gen_lowpart (QImode, operands[3]);
14040   ix86_expand_clear (operands[3]);
14041 })
14042
14043 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14044
14045 (define_peephole2
14046   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14047    (set (match_operand:QI 1 "register_operand" "")
14048         (match_operator:QI 2 "ix86_comparison_operator"
14049           [(reg FLAGS_REG) (const_int 0)]))
14050    (parallel [(set (match_operand 3 "q_regs_operand" "")
14051                    (zero_extend (match_dup 1)))
14052               (clobber (reg:CC FLAGS_REG))])]
14053   "(peep2_reg_dead_p (3, operands[1])
14054     || operands_match_p (operands[1], operands[3]))
14055    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14056   [(set (match_dup 4) (match_dup 0))
14057    (set (strict_low_part (match_dup 5))
14058         (match_dup 2))]
14059 {
14060   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14061   operands[5] = gen_lowpart (QImode, operands[3]);
14062   ix86_expand_clear (operands[3]);
14063 })
14064 \f
14065 ;; Call instructions.
14066
14067 ;; The predicates normally associated with named expanders are not properly
14068 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14069 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14070
14071 ;; Call subroutine returning no value.
14072
14073 (define_expand "call_pop"
14074   [(parallel [(call (match_operand:QI 0 "" "")
14075                     (match_operand:SI 1 "" ""))
14076               (set (reg:SI SP_REG)
14077                    (plus:SI (reg:SI SP_REG)
14078                             (match_operand:SI 3 "" "")))])]
14079   "!TARGET_64BIT"
14080 {
14081   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14082   DONE;
14083 })
14084
14085 (define_insn "*call_pop_0"
14086   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14087          (match_operand:SI 1 "" ""))
14088    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14089                             (match_operand:SI 2 "immediate_operand" "")))]
14090   "!TARGET_64BIT"
14091 {
14092   if (SIBLING_CALL_P (insn))
14093     return "jmp\t%P0";
14094   else
14095     return "call\t%P0";
14096 }
14097   [(set_attr "type" "call")])
14098
14099 (define_insn "*call_pop_1"
14100   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14101          (match_operand:SI 1 "" ""))
14102    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14103                             (match_operand:SI 2 "immediate_operand" "i")))]
14104   "!TARGET_64BIT"
14105 {
14106   if (constant_call_address_operand (operands[0], Pmode))
14107     {
14108       if (SIBLING_CALL_P (insn))
14109         return "jmp\t%P0";
14110       else
14111         return "call\t%P0";
14112     }
14113   if (SIBLING_CALL_P (insn))
14114     return "jmp\t%A0";
14115   else
14116     return "call\t%A0";
14117 }
14118   [(set_attr "type" "call")])
14119
14120 (define_expand "call"
14121   [(call (match_operand:QI 0 "" "")
14122          (match_operand 1 "" ""))
14123    (use (match_operand 2 "" ""))]
14124   ""
14125 {
14126   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14127   DONE;
14128 })
14129
14130 (define_expand "sibcall"
14131   [(call (match_operand:QI 0 "" "")
14132          (match_operand 1 "" ""))
14133    (use (match_operand 2 "" ""))]
14134   ""
14135 {
14136   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14137   DONE;
14138 })
14139
14140 (define_insn "*call_0"
14141   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14142          (match_operand 1 "" ""))]
14143   ""
14144 {
14145   if (SIBLING_CALL_P (insn))
14146     return "jmp\t%P0";
14147   else
14148     return "call\t%P0";
14149 }
14150   [(set_attr "type" "call")])
14151
14152 (define_insn "*call_1"
14153   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14154          (match_operand 1 "" ""))]
14155   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14156 {
14157   if (constant_call_address_operand (operands[0], Pmode))
14158     return "call\t%P0";
14159   return "call\t%A0";
14160 }
14161   [(set_attr "type" "call")])
14162
14163 (define_insn "*sibcall_1"
14164   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14165          (match_operand 1 "" ""))]
14166   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14167 {
14168   if (constant_call_address_operand (operands[0], Pmode))
14169     return "jmp\t%P0";
14170   return "jmp\t%A0";
14171 }
14172   [(set_attr "type" "call")])
14173
14174 (define_insn "*call_1_rex64"
14175   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14176          (match_operand 1 "" ""))]
14177   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14178 {
14179   if (constant_call_address_operand (operands[0], Pmode))
14180     return "call\t%P0";
14181   return "call\t%A0";
14182 }
14183   [(set_attr "type" "call")])
14184
14185 (define_insn "*sibcall_1_rex64"
14186   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14187          (match_operand 1 "" ""))]
14188   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14189   "jmp\t%P0"
14190   [(set_attr "type" "call")])
14191
14192 (define_insn "*sibcall_1_rex64_v"
14193   [(call (mem:QI (reg:DI R11_REG))
14194          (match_operand 0 "" ""))]
14195   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14196   "jmp\t*%%r11"
14197   [(set_attr "type" "call")])
14198
14199
14200 ;; Call subroutine, returning value in operand 0
14201
14202 (define_expand "call_value_pop"
14203   [(parallel [(set (match_operand 0 "" "")
14204                    (call (match_operand:QI 1 "" "")
14205                          (match_operand:SI 2 "" "")))
14206               (set (reg:SI SP_REG)
14207                    (plus:SI (reg:SI SP_REG)
14208                             (match_operand:SI 4 "" "")))])]
14209   "!TARGET_64BIT"
14210 {
14211   ix86_expand_call (operands[0], operands[1], operands[2],
14212                     operands[3], operands[4], 0);
14213   DONE;
14214 })
14215
14216 (define_expand "call_value"
14217   [(set (match_operand 0 "" "")
14218         (call (match_operand:QI 1 "" "")
14219               (match_operand:SI 2 "" "")))
14220    (use (match_operand:SI 3 "" ""))]
14221   ;; Operand 2 not used on the i386.
14222   ""
14223 {
14224   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14225   DONE;
14226 })
14227
14228 (define_expand "sibcall_value"
14229   [(set (match_operand 0 "" "")
14230         (call (match_operand:QI 1 "" "")
14231               (match_operand:SI 2 "" "")))
14232    (use (match_operand:SI 3 "" ""))]
14233   ;; Operand 2 not used on the i386.
14234   ""
14235 {
14236   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14237   DONE;
14238 })
14239
14240 ;; Call subroutine returning any type.
14241
14242 (define_expand "untyped_call"
14243   [(parallel [(call (match_operand 0 "" "")
14244                     (const_int 0))
14245               (match_operand 1 "" "")
14246               (match_operand 2 "" "")])]
14247   ""
14248 {
14249   int i;
14250
14251   /* In order to give reg-stack an easier job in validating two
14252      coprocessor registers as containing a possible return value,
14253      simply pretend the untyped call returns a complex long double
14254      value.  */
14255
14256   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14257                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14258                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14259                     NULL, 0);
14260
14261   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14262     {
14263       rtx set = XVECEXP (operands[2], 0, i);
14264       emit_move_insn (SET_DEST (set), SET_SRC (set));
14265     }
14266
14267   /* The optimizer does not know that the call sets the function value
14268      registers we stored in the result block.  We avoid problems by
14269      claiming that all hard registers are used and clobbered at this
14270      point.  */
14271   emit_insn (gen_blockage (const0_rtx));
14272
14273   DONE;
14274 })
14275 \f
14276 ;; Prologue and epilogue instructions
14277
14278 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14279 ;; all of memory.  This blocks insns from being moved across this point.
14280
14281 (define_insn "blockage"
14282   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14283   ""
14284   ""
14285   [(set_attr "length" "0")])
14286
14287 ;; Insn emitted into the body of a function to return from a function.
14288 ;; This is only done if the function's epilogue is known to be simple.
14289 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14290
14291 (define_expand "return"
14292   [(return)]
14293   "ix86_can_use_return_insn_p ()"
14294 {
14295   if (current_function_pops_args)
14296     {
14297       rtx popc = GEN_INT (current_function_pops_args);
14298       emit_jump_insn (gen_return_pop_internal (popc));
14299       DONE;
14300     }
14301 })
14302
14303 (define_insn "return_internal"
14304   [(return)]
14305   "reload_completed"
14306   "ret"
14307   [(set_attr "length" "1")
14308    (set_attr "length_immediate" "0")
14309    (set_attr "modrm" "0")])
14310
14311 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14312 ;; instruction Athlon and K8 have.
14313
14314 (define_insn "return_internal_long"
14315   [(return)
14316    (unspec [(const_int 0)] UNSPEC_REP)]
14317   "reload_completed"
14318   "rep {;} ret"
14319   [(set_attr "length" "1")
14320    (set_attr "length_immediate" "0")
14321    (set_attr "prefix_rep" "1")
14322    (set_attr "modrm" "0")])
14323
14324 (define_insn "return_pop_internal"
14325   [(return)
14326    (use (match_operand:SI 0 "const_int_operand" ""))]
14327   "reload_completed"
14328   "ret\t%0"
14329   [(set_attr "length" "3")
14330    (set_attr "length_immediate" "2")
14331    (set_attr "modrm" "0")])
14332
14333 (define_insn "return_indirect_internal"
14334   [(return)
14335    (use (match_operand:SI 0 "register_operand" "r"))]
14336   "reload_completed"
14337   "jmp\t%A0"
14338   [(set_attr "type" "ibr")
14339    (set_attr "length_immediate" "0")])
14340
14341 (define_insn "nop"
14342   [(const_int 0)]
14343   ""
14344   "nop"
14345   [(set_attr "length" "1")
14346    (set_attr "length_immediate" "0")
14347    (set_attr "modrm" "0")])
14348
14349 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14350 ;; branch prediction penalty for the third jump in a 16-byte
14351 ;; block on K8.
14352
14353 (define_insn "align"
14354   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14355   ""
14356 {
14357 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14358   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14359 #else
14360   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14361      The align insn is used to avoid 3 jump instructions in the row to improve
14362      branch prediction and the benefits hardly outweigh the cost of extra 8
14363      nops on the average inserted by full alignment pseudo operation.  */
14364 #endif
14365   return "";
14366 }
14367   [(set_attr "length" "16")])
14368
14369 (define_expand "prologue"
14370   [(const_int 1)]
14371   ""
14372   "ix86_expand_prologue (); DONE;")
14373
14374 (define_insn "set_got"
14375   [(set (match_operand:SI 0 "register_operand" "=r")
14376         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14377    (clobber (reg:CC FLAGS_REG))]
14378   "!TARGET_64BIT"
14379   { return output_set_got (operands[0], NULL_RTX); }
14380   [(set_attr "type" "multi")
14381    (set_attr "length" "12")])
14382
14383 (define_insn "set_got_labelled"
14384   [(set (match_operand:SI 0 "register_operand" "=r")
14385         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14386          UNSPEC_SET_GOT))
14387    (clobber (reg:CC FLAGS_REG))]
14388   "!TARGET_64BIT"
14389   { return output_set_got (operands[0], operands[1]); }
14390   [(set_attr "type" "multi")
14391    (set_attr "length" "12")])
14392
14393 (define_insn "set_got_rex64"
14394   [(set (match_operand:DI 0 "register_operand" "=r")
14395         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14396   "TARGET_64BIT"
14397   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14398   [(set_attr "type" "lea")
14399    (set_attr "length" "6")])
14400
14401 (define_expand "epilogue"
14402   [(const_int 1)]
14403   ""
14404   "ix86_expand_epilogue (1); DONE;")
14405
14406 (define_expand "sibcall_epilogue"
14407   [(const_int 1)]
14408   ""
14409   "ix86_expand_epilogue (0); DONE;")
14410
14411 (define_expand "eh_return"
14412   [(use (match_operand 0 "register_operand" ""))]
14413   ""
14414 {
14415   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14416
14417   /* Tricky bit: we write the address of the handler to which we will
14418      be returning into someone else's stack frame, one word below the
14419      stack address we wish to restore.  */
14420   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14421   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14422   tmp = gen_rtx_MEM (Pmode, tmp);
14423   emit_move_insn (tmp, ra);
14424
14425   if (Pmode == SImode)
14426     emit_jump_insn (gen_eh_return_si (sa));
14427   else
14428     emit_jump_insn (gen_eh_return_di (sa));
14429   emit_barrier ();
14430   DONE;
14431 })
14432
14433 (define_insn_and_split "eh_return_si"
14434   [(set (pc)
14435         (unspec [(match_operand:SI 0 "register_operand" "c")]
14436                  UNSPEC_EH_RETURN))]
14437   "!TARGET_64BIT"
14438   "#"
14439   "reload_completed"
14440   [(const_int 1)]
14441   "ix86_expand_epilogue (2); DONE;")
14442
14443 (define_insn_and_split "eh_return_di"
14444   [(set (pc)
14445         (unspec [(match_operand:DI 0 "register_operand" "c")]
14446                  UNSPEC_EH_RETURN))]
14447   "TARGET_64BIT"
14448   "#"
14449   "reload_completed"
14450   [(const_int 1)]
14451   "ix86_expand_epilogue (2); DONE;")
14452
14453 (define_insn "leave"
14454   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14455    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14456    (clobber (mem:BLK (scratch)))]
14457   "!TARGET_64BIT"
14458   "leave"
14459   [(set_attr "type" "leave")])
14460
14461 (define_insn "leave_rex64"
14462   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14463    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14464    (clobber (mem:BLK (scratch)))]
14465   "TARGET_64BIT"
14466   "leave"
14467   [(set_attr "type" "leave")])
14468 \f
14469 (define_expand "ffssi2"
14470   [(parallel
14471      [(set (match_operand:SI 0 "register_operand" "")
14472            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14473       (clobber (match_scratch:SI 2 ""))
14474       (clobber (reg:CC FLAGS_REG))])]
14475   ""
14476   "")
14477
14478 (define_insn_and_split "*ffs_cmove"
14479   [(set (match_operand:SI 0 "register_operand" "=r")
14480         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14481    (clobber (match_scratch:SI 2 "=&r"))
14482    (clobber (reg:CC FLAGS_REG))]
14483   "TARGET_CMOVE"
14484   "#"
14485   "&& reload_completed"
14486   [(set (match_dup 2) (const_int -1))
14487    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14488               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14489    (set (match_dup 0) (if_then_else:SI
14490                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14491                         (match_dup 2)
14492                         (match_dup 0)))
14493    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14494               (clobber (reg:CC FLAGS_REG))])]
14495   "")
14496
14497 (define_insn_and_split "*ffs_no_cmove"
14498   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14499         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14500    (clobber (match_scratch:SI 2 "=&q"))
14501    (clobber (reg:CC FLAGS_REG))]
14502   ""
14503   "#"
14504   "reload_completed"
14505   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14506               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14507    (set (strict_low_part (match_dup 3))
14508         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14509    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14510               (clobber (reg:CC FLAGS_REG))])
14511    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14512               (clobber (reg:CC FLAGS_REG))])
14513    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14514               (clobber (reg:CC FLAGS_REG))])]
14515 {
14516   operands[3] = gen_lowpart (QImode, operands[2]);
14517   ix86_expand_clear (operands[2]);
14518 })
14519
14520 (define_insn "*ffssi_1"
14521   [(set (reg:CCZ FLAGS_REG)
14522         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14523                      (const_int 0)))
14524    (set (match_operand:SI 0 "register_operand" "=r")
14525         (ctz:SI (match_dup 1)))]
14526   ""
14527   "bsf{l}\t{%1, %0|%0, %1}"
14528   [(set_attr "prefix_0f" "1")])
14529
14530 (define_expand "ffsdi2"
14531   [(parallel
14532      [(set (match_operand:DI 0 "register_operand" "")
14533            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14534       (clobber (match_scratch:DI 2 ""))
14535       (clobber (reg:CC FLAGS_REG))])]
14536   "TARGET_64BIT && TARGET_CMOVE"
14537   "")
14538
14539 (define_insn_and_split "*ffs_rex64"
14540   [(set (match_operand:DI 0 "register_operand" "=r")
14541         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14542    (clobber (match_scratch:DI 2 "=&r"))
14543    (clobber (reg:CC FLAGS_REG))]
14544   "TARGET_64BIT && TARGET_CMOVE"
14545   "#"
14546   "&& reload_completed"
14547   [(set (match_dup 2) (const_int -1))
14548    (parallel [(set (reg:CCZ FLAGS_REG)
14549                    (compare:CCZ (match_dup 1) (const_int 0)))
14550               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14551    (set (match_dup 0) (if_then_else:DI
14552                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14553                         (match_dup 2)
14554                         (match_dup 0)))
14555    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14556               (clobber (reg:CC FLAGS_REG))])]
14557   "")
14558
14559 (define_insn "*ffsdi_1"
14560   [(set (reg:CCZ FLAGS_REG)
14561         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14562                      (const_int 0)))
14563    (set (match_operand:DI 0 "register_operand" "=r")
14564         (ctz:DI (match_dup 1)))]
14565   "TARGET_64BIT"
14566   "bsf{q}\t{%1, %0|%0, %1}"
14567   [(set_attr "prefix_0f" "1")])
14568
14569 (define_insn "ctzsi2"
14570   [(set (match_operand:SI 0 "register_operand" "=r")
14571         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14572    (clobber (reg:CC FLAGS_REG))]
14573   ""
14574   "bsf{l}\t{%1, %0|%0, %1}"
14575   [(set_attr "prefix_0f" "1")])
14576
14577 (define_insn "ctzdi2"
14578   [(set (match_operand:DI 0 "register_operand" "=r")
14579         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14580    (clobber (reg:CC FLAGS_REG))]
14581   "TARGET_64BIT"
14582   "bsf{q}\t{%1, %0|%0, %1}"
14583   [(set_attr "prefix_0f" "1")])
14584
14585 (define_expand "clzsi2"
14586   [(parallel
14587      [(set (match_operand:SI 0 "register_operand" "")
14588            (minus:SI (const_int 31)
14589                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14590       (clobber (reg:CC FLAGS_REG))])
14591    (parallel
14592      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14593       (clobber (reg:CC FLAGS_REG))])]
14594   ""
14595   "")
14596
14597 (define_insn "*bsr"
14598   [(set (match_operand:SI 0 "register_operand" "=r")
14599         (minus:SI (const_int 31)
14600                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14601    (clobber (reg:CC FLAGS_REG))]
14602   ""
14603   "bsr{l}\t{%1, %0|%0, %1}"
14604   [(set_attr "prefix_0f" "1")])
14605
14606 (define_insn "bswapsi2"
14607   [(set (match_operand:SI 0 "register_operand" "=r")
14608         (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14609    (clobber (reg:CC FLAGS_REG))]
14610   "TARGET_BSWAP"
14611   "bswap\t%k0"
14612   [(set_attr "prefix_0f" "1")
14613    (set_attr "length" "2")])
14614
14615 (define_insn "bswapdi2"
14616   [(set (match_operand:DI 0 "register_operand" "=r")
14617         (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14618    (clobber (reg:CC FLAGS_REG))]
14619   "TARGET_64BIT && TARGET_BSWAP"
14620   "bswap\t%0"
14621   [(set_attr "prefix_0f" "1")
14622    (set_attr "length" "3")])
14623
14624 (define_expand "clzdi2"
14625   [(parallel
14626      [(set (match_operand:DI 0 "register_operand" "")
14627            (minus:DI (const_int 63)
14628                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14629       (clobber (reg:CC FLAGS_REG))])
14630    (parallel
14631      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14632       (clobber (reg:CC FLAGS_REG))])]
14633   "TARGET_64BIT"
14634   "")
14635
14636 (define_insn "*bsr_rex64"
14637   [(set (match_operand:DI 0 "register_operand" "=r")
14638         (minus:DI (const_int 63)
14639                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14640    (clobber (reg:CC FLAGS_REG))]
14641   "TARGET_64BIT"
14642   "bsr{q}\t{%1, %0|%0, %1}"
14643   [(set_attr "prefix_0f" "1")])
14644 \f
14645 ;; Thread-local storage patterns for ELF.
14646 ;;
14647 ;; Note that these code sequences must appear exactly as shown
14648 ;; in order to allow linker relaxation.
14649
14650 (define_insn "*tls_global_dynamic_32_gnu"
14651   [(set (match_operand:SI 0 "register_operand" "=a")
14652         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14653                     (match_operand:SI 2 "tls_symbolic_operand" "")
14654                     (match_operand:SI 3 "call_insn_operand" "")]
14655                     UNSPEC_TLS_GD))
14656    (clobber (match_scratch:SI 4 "=d"))
14657    (clobber (match_scratch:SI 5 "=c"))
14658    (clobber (reg:CC FLAGS_REG))]
14659   "!TARGET_64BIT && TARGET_GNU_TLS"
14660   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14661   [(set_attr "type" "multi")
14662    (set_attr "length" "12")])
14663
14664 (define_insn "*tls_global_dynamic_32_sun"
14665   [(set (match_operand:SI 0 "register_operand" "=a")
14666         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14667                     (match_operand:SI 2 "tls_symbolic_operand" "")
14668                     (match_operand:SI 3 "call_insn_operand" "")]
14669                     UNSPEC_TLS_GD))
14670    (clobber (match_scratch:SI 4 "=d"))
14671    (clobber (match_scratch:SI 5 "=c"))
14672    (clobber (reg:CC FLAGS_REG))]
14673   "!TARGET_64BIT && TARGET_SUN_TLS"
14674   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14675         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14676   [(set_attr "type" "multi")
14677    (set_attr "length" "14")])
14678
14679 (define_expand "tls_global_dynamic_32"
14680   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14681                    (unspec:SI
14682                     [(match_dup 2)
14683                      (match_operand:SI 1 "tls_symbolic_operand" "")
14684                      (match_dup 3)]
14685                     UNSPEC_TLS_GD))
14686               (clobber (match_scratch:SI 4 ""))
14687               (clobber (match_scratch:SI 5 ""))
14688               (clobber (reg:CC FLAGS_REG))])]
14689   ""
14690 {
14691   if (flag_pic)
14692     operands[2] = pic_offset_table_rtx;
14693   else
14694     {
14695       operands[2] = gen_reg_rtx (Pmode);
14696       emit_insn (gen_set_got (operands[2]));
14697     }
14698   if (TARGET_GNU2_TLS)
14699     {
14700        emit_insn (gen_tls_dynamic_gnu2_32
14701                   (operands[0], operands[1], operands[2]));
14702        DONE;
14703     }
14704   operands[3] = ix86_tls_get_addr ();
14705 })
14706
14707 (define_insn "*tls_global_dynamic_64"
14708   [(set (match_operand:DI 0 "register_operand" "=a")
14709         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14710                  (match_operand:DI 3 "" "")))
14711    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14712               UNSPEC_TLS_GD)]
14713   "TARGET_64BIT"
14714   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14715   [(set_attr "type" "multi")
14716    (set_attr "length" "16")])
14717
14718 (define_expand "tls_global_dynamic_64"
14719   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14720                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14721               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14722                          UNSPEC_TLS_GD)])]
14723   ""
14724 {
14725   if (TARGET_GNU2_TLS)
14726     {
14727        emit_insn (gen_tls_dynamic_gnu2_64
14728                   (operands[0], operands[1]));
14729        DONE;
14730     }
14731   operands[2] = ix86_tls_get_addr ();
14732 })
14733
14734 (define_insn "*tls_local_dynamic_base_32_gnu"
14735   [(set (match_operand:SI 0 "register_operand" "=a")
14736         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14737                     (match_operand:SI 2 "call_insn_operand" "")]
14738                    UNSPEC_TLS_LD_BASE))
14739    (clobber (match_scratch:SI 3 "=d"))
14740    (clobber (match_scratch:SI 4 "=c"))
14741    (clobber (reg:CC FLAGS_REG))]
14742   "!TARGET_64BIT && TARGET_GNU_TLS"
14743   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14744   [(set_attr "type" "multi")
14745    (set_attr "length" "11")])
14746
14747 (define_insn "*tls_local_dynamic_base_32_sun"
14748   [(set (match_operand:SI 0 "register_operand" "=a")
14749         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14750                     (match_operand:SI 2 "call_insn_operand" "")]
14751                    UNSPEC_TLS_LD_BASE))
14752    (clobber (match_scratch:SI 3 "=d"))
14753    (clobber (match_scratch:SI 4 "=c"))
14754    (clobber (reg:CC FLAGS_REG))]
14755   "!TARGET_64BIT && TARGET_SUN_TLS"
14756   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14757         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14758   [(set_attr "type" "multi")
14759    (set_attr "length" "13")])
14760
14761 (define_expand "tls_local_dynamic_base_32"
14762   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14763                    (unspec:SI [(match_dup 1) (match_dup 2)]
14764                               UNSPEC_TLS_LD_BASE))
14765               (clobber (match_scratch:SI 3 ""))
14766               (clobber (match_scratch:SI 4 ""))
14767               (clobber (reg:CC FLAGS_REG))])]
14768   ""
14769 {
14770   if (flag_pic)
14771     operands[1] = pic_offset_table_rtx;
14772   else
14773     {
14774       operands[1] = gen_reg_rtx (Pmode);
14775       emit_insn (gen_set_got (operands[1]));
14776     }
14777   if (TARGET_GNU2_TLS)
14778     {
14779        emit_insn (gen_tls_dynamic_gnu2_32
14780                   (operands[0], ix86_tls_module_base (), operands[1]));
14781        DONE;
14782     }
14783   operands[2] = ix86_tls_get_addr ();
14784 })
14785
14786 (define_insn "*tls_local_dynamic_base_64"
14787   [(set (match_operand:DI 0 "register_operand" "=a")
14788         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14789                  (match_operand:DI 2 "" "")))
14790    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14791   "TARGET_64BIT"
14792   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14793   [(set_attr "type" "multi")
14794    (set_attr "length" "12")])
14795
14796 (define_expand "tls_local_dynamic_base_64"
14797   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14798                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14799               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14800   ""
14801 {
14802   if (TARGET_GNU2_TLS)
14803     {
14804        emit_insn (gen_tls_dynamic_gnu2_64
14805                   (operands[0], ix86_tls_module_base ()));
14806        DONE;
14807     }
14808   operands[1] = ix86_tls_get_addr ();
14809 })
14810
14811 ;; Local dynamic of a single variable is a lose.  Show combine how
14812 ;; to convert that back to global dynamic.
14813
14814 (define_insn_and_split "*tls_local_dynamic_32_once"
14815   [(set (match_operand:SI 0 "register_operand" "=a")
14816         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14817                              (match_operand:SI 2 "call_insn_operand" "")]
14818                             UNSPEC_TLS_LD_BASE)
14819                  (const:SI (unspec:SI
14820                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14821                             UNSPEC_DTPOFF))))
14822    (clobber (match_scratch:SI 4 "=d"))
14823    (clobber (match_scratch:SI 5 "=c"))
14824    (clobber (reg:CC FLAGS_REG))]
14825   ""
14826   "#"
14827   ""
14828   [(parallel [(set (match_dup 0)
14829                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14830                               UNSPEC_TLS_GD))
14831               (clobber (match_dup 4))
14832               (clobber (match_dup 5))
14833               (clobber (reg:CC FLAGS_REG))])]
14834   "")
14835
14836 ;; Load and add the thread base pointer from %gs:0.
14837
14838 (define_insn "*load_tp_si"
14839   [(set (match_operand:SI 0 "register_operand" "=r")
14840         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14841   "!TARGET_64BIT"
14842   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14843   [(set_attr "type" "imov")
14844    (set_attr "modrm" "0")
14845    (set_attr "length" "7")
14846    (set_attr "memory" "load")
14847    (set_attr "imm_disp" "false")])
14848
14849 (define_insn "*add_tp_si"
14850   [(set (match_operand:SI 0 "register_operand" "=r")
14851         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14852                  (match_operand:SI 1 "register_operand" "0")))
14853    (clobber (reg:CC FLAGS_REG))]
14854   "!TARGET_64BIT"
14855   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14856   [(set_attr "type" "alu")
14857    (set_attr "modrm" "0")
14858    (set_attr "length" "7")
14859    (set_attr "memory" "load")
14860    (set_attr "imm_disp" "false")])
14861
14862 (define_insn "*load_tp_di"
14863   [(set (match_operand:DI 0 "register_operand" "=r")
14864         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14865   "TARGET_64BIT"
14866   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14867   [(set_attr "type" "imov")
14868    (set_attr "modrm" "0")
14869    (set_attr "length" "7")
14870    (set_attr "memory" "load")
14871    (set_attr "imm_disp" "false")])
14872
14873 (define_insn "*add_tp_di"
14874   [(set (match_operand:DI 0 "register_operand" "=r")
14875         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14876                  (match_operand:DI 1 "register_operand" "0")))
14877    (clobber (reg:CC FLAGS_REG))]
14878   "TARGET_64BIT"
14879   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14880   [(set_attr "type" "alu")
14881    (set_attr "modrm" "0")
14882    (set_attr "length" "7")
14883    (set_attr "memory" "load")
14884    (set_attr "imm_disp" "false")])
14885
14886 ;; GNU2 TLS patterns can be split.
14887
14888 (define_expand "tls_dynamic_gnu2_32"
14889   [(set (match_dup 3)
14890         (plus:SI (match_operand:SI 2 "register_operand" "")
14891                  (const:SI
14892                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14893                              UNSPEC_TLSDESC))))
14894    (parallel
14895     [(set (match_operand:SI 0 "register_operand" "")
14896           (unspec:SI [(match_dup 1) (match_dup 3)
14897                       (match_dup 2) (reg:SI SP_REG)]
14898                       UNSPEC_TLSDESC))
14899      (clobber (reg:CC FLAGS_REG))])]
14900   "!TARGET_64BIT && TARGET_GNU2_TLS"
14901 {
14902   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14903   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14904 })
14905
14906 (define_insn "*tls_dynamic_lea_32"
14907   [(set (match_operand:SI 0 "register_operand" "=r")
14908         (plus:SI (match_operand:SI 1 "register_operand" "b")
14909                  (const:SI
14910                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14911                               UNSPEC_TLSDESC))))]
14912   "!TARGET_64BIT && TARGET_GNU2_TLS"
14913   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14914   [(set_attr "type" "lea")
14915    (set_attr "mode" "SI")
14916    (set_attr "length" "6")
14917    (set_attr "length_address" "4")])
14918
14919 (define_insn "*tls_dynamic_call_32"
14920   [(set (match_operand:SI 0 "register_operand" "=a")
14921         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14922                     (match_operand:SI 2 "register_operand" "0")
14923                     ;; we have to make sure %ebx still points to the GOT
14924                     (match_operand:SI 3 "register_operand" "b")
14925                     (reg:SI SP_REG)]
14926                    UNSPEC_TLSDESC))
14927    (clobber (reg:CC FLAGS_REG))]
14928   "!TARGET_64BIT && TARGET_GNU2_TLS"
14929   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14930   [(set_attr "type" "call")
14931    (set_attr "length" "2")
14932    (set_attr "length_address" "0")])
14933
14934 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14935   [(set (match_operand:SI 0 "register_operand" "=&a")
14936         (plus:SI
14937          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14938                      (match_operand:SI 4 "" "")
14939                      (match_operand:SI 2 "register_operand" "b")
14940                      (reg:SI SP_REG)]
14941                     UNSPEC_TLSDESC)
14942          (const:SI (unspec:SI
14943                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14944                     UNSPEC_DTPOFF))))
14945    (clobber (reg:CC FLAGS_REG))]
14946   "!TARGET_64BIT && TARGET_GNU2_TLS"
14947   "#"
14948   ""
14949   [(set (match_dup 0) (match_dup 5))]
14950 {
14951   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14952   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14953 })
14954
14955 (define_expand "tls_dynamic_gnu2_64"
14956   [(set (match_dup 2)
14957         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14958                    UNSPEC_TLSDESC))
14959    (parallel
14960     [(set (match_operand:DI 0 "register_operand" "")
14961           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14962                      UNSPEC_TLSDESC))
14963      (clobber (reg:CC FLAGS_REG))])]
14964   "TARGET_64BIT && TARGET_GNU2_TLS"
14965 {
14966   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14967   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14968 })
14969
14970 (define_insn "*tls_dynamic_lea_64"
14971   [(set (match_operand:DI 0 "register_operand" "=r")
14972         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14973                    UNSPEC_TLSDESC))]
14974   "TARGET_64BIT && TARGET_GNU2_TLS"
14975   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14976   [(set_attr "type" "lea")
14977    (set_attr "mode" "DI")
14978    (set_attr "length" "7")
14979    (set_attr "length_address" "4")])
14980
14981 (define_insn "*tls_dynamic_call_64"
14982   [(set (match_operand:DI 0 "register_operand" "=a")
14983         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14984                     (match_operand:DI 2 "register_operand" "0")
14985                     (reg:DI SP_REG)]
14986                    UNSPEC_TLSDESC))
14987    (clobber (reg:CC FLAGS_REG))]
14988   "TARGET_64BIT && TARGET_GNU2_TLS"
14989   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14990   [(set_attr "type" "call")
14991    (set_attr "length" "2")
14992    (set_attr "length_address" "0")])
14993
14994 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14995   [(set (match_operand:DI 0 "register_operand" "=&a")
14996         (plus:DI
14997          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14998                      (match_operand:DI 3 "" "")
14999                      (reg:DI SP_REG)]
15000                     UNSPEC_TLSDESC)
15001          (const:DI (unspec:DI
15002                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15003                     UNSPEC_DTPOFF))))
15004    (clobber (reg:CC FLAGS_REG))]
15005   "TARGET_64BIT && TARGET_GNU2_TLS"
15006   "#"
15007   ""
15008   [(set (match_dup 0) (match_dup 4))]
15009 {
15010   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15011   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15012 })
15013
15014 ;;
15015 \f
15016 ;; These patterns match the binary 387 instructions for addM3, subM3,
15017 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15018 ;; SFmode.  The first is the normal insn, the second the same insn but
15019 ;; with one operand a conversion, and the third the same insn but with
15020 ;; the other operand a conversion.  The conversion may be SFmode or
15021 ;; SImode if the target mode DFmode, but only SImode if the target mode
15022 ;; is SFmode.
15023
15024 ;; Gcc is slightly more smart about handling normal two address instructions
15025 ;; so use special patterns for add and mull.
15026
15027 (define_insn "*fop_sf_comm_mixed"
15028   [(set (match_operand:SF 0 "register_operand" "=f,x")
15029         (match_operator:SF 3 "binary_fp_operator"
15030                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15031                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15032   "TARGET_MIX_SSE_I387
15033    && COMMUTATIVE_ARITH_P (operands[3])
15034    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15035   "* return output_387_binary_op (insn, operands);"
15036   [(set (attr "type")
15037         (if_then_else (eq_attr "alternative" "1")
15038            (if_then_else (match_operand:SF 3 "mult_operator" "")
15039               (const_string "ssemul")
15040               (const_string "sseadd"))
15041            (if_then_else (match_operand:SF 3 "mult_operator" "")
15042               (const_string "fmul")
15043               (const_string "fop"))))
15044    (set_attr "mode" "SF")])
15045
15046 (define_insn "*fop_sf_comm_sse"
15047   [(set (match_operand:SF 0 "register_operand" "=x")
15048         (match_operator:SF 3 "binary_fp_operator"
15049                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15050                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15051   "TARGET_SSE_MATH
15052    && COMMUTATIVE_ARITH_P (operands[3])
15053    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15054   "* return output_387_binary_op (insn, operands);"
15055   [(set (attr "type")
15056         (if_then_else (match_operand:SF 3 "mult_operator" "")
15057            (const_string "ssemul")
15058            (const_string "sseadd")))
15059    (set_attr "mode" "SF")])
15060
15061 (define_insn "*fop_sf_comm_i387"
15062   [(set (match_operand:SF 0 "register_operand" "=f")
15063         (match_operator:SF 3 "binary_fp_operator"
15064                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15065                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15066   "TARGET_80387
15067    && COMMUTATIVE_ARITH_P (operands[3])
15068    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15069   "* return output_387_binary_op (insn, operands);"
15070   [(set (attr "type")
15071         (if_then_else (match_operand:SF 3 "mult_operator" "")
15072            (const_string "fmul")
15073            (const_string "fop")))
15074    (set_attr "mode" "SF")])
15075
15076 (define_insn "*fop_sf_1_mixed"
15077   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15078         (match_operator:SF 3 "binary_fp_operator"
15079                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15080                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15081   "TARGET_MIX_SSE_I387
15082    && !COMMUTATIVE_ARITH_P (operands[3])
15083    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15084   "* return output_387_binary_op (insn, operands);"
15085   [(set (attr "type")
15086         (cond [(and (eq_attr "alternative" "2")
15087                     (match_operand:SF 3 "mult_operator" ""))
15088                  (const_string "ssemul")
15089                (and (eq_attr "alternative" "2")
15090                     (match_operand:SF 3 "div_operator" ""))
15091                  (const_string "ssediv")
15092                (eq_attr "alternative" "2")
15093                  (const_string "sseadd")
15094                (match_operand:SF 3 "mult_operator" "")
15095                  (const_string "fmul")
15096                (match_operand:SF 3 "div_operator" "")
15097                  (const_string "fdiv")
15098               ]
15099               (const_string "fop")))
15100    (set_attr "mode" "SF")])
15101
15102 (define_insn "*fop_sf_1_sse"
15103   [(set (match_operand:SF 0 "register_operand" "=x")
15104         (match_operator:SF 3 "binary_fp_operator"
15105                         [(match_operand:SF 1 "register_operand" "0")
15106                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15107   "TARGET_SSE_MATH
15108    && !COMMUTATIVE_ARITH_P (operands[3])"
15109   "* return output_387_binary_op (insn, operands);"
15110   [(set (attr "type")
15111         (cond [(match_operand:SF 3 "mult_operator" "")
15112                  (const_string "ssemul")
15113                (match_operand:SF 3 "div_operator" "")
15114                  (const_string "ssediv")
15115               ]
15116               (const_string "sseadd")))
15117    (set_attr "mode" "SF")])
15118
15119 ;; This pattern is not fully shadowed by the pattern above.
15120 (define_insn "*fop_sf_1_i387"
15121   [(set (match_operand:SF 0 "register_operand" "=f,f")
15122         (match_operator:SF 3 "binary_fp_operator"
15123                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15124                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15125   "TARGET_80387 && !TARGET_SSE_MATH
15126    && !COMMUTATIVE_ARITH_P (operands[3])
15127    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15128   "* return output_387_binary_op (insn, operands);"
15129   [(set (attr "type")
15130         (cond [(match_operand:SF 3 "mult_operator" "")
15131                  (const_string "fmul")
15132                (match_operand:SF 3 "div_operator" "")
15133                  (const_string "fdiv")
15134               ]
15135               (const_string "fop")))
15136    (set_attr "mode" "SF")])
15137
15138 ;; ??? Add SSE splitters for these!
15139 (define_insn "*fop_sf_2<mode>_i387"
15140   [(set (match_operand:SF 0 "register_operand" "=f,f")
15141         (match_operator:SF 3 "binary_fp_operator"
15142           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15143            (match_operand:SF 2 "register_operand" "0,0")]))]
15144   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15145   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15146   [(set (attr "type")
15147         (cond [(match_operand:SF 3 "mult_operator" "")
15148                  (const_string "fmul")
15149                (match_operand:SF 3 "div_operator" "")
15150                  (const_string "fdiv")
15151               ]
15152               (const_string "fop")))
15153    (set_attr "fp_int_src" "true")
15154    (set_attr "mode" "<MODE>")])
15155
15156 (define_insn "*fop_sf_3<mode>_i387"
15157   [(set (match_operand:SF 0 "register_operand" "=f,f")
15158         (match_operator:SF 3 "binary_fp_operator"
15159           [(match_operand:SF 1 "register_operand" "0,0")
15160            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15161   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15162   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15163   [(set (attr "type")
15164         (cond [(match_operand:SF 3 "mult_operator" "")
15165                  (const_string "fmul")
15166                (match_operand:SF 3 "div_operator" "")
15167                  (const_string "fdiv")
15168               ]
15169               (const_string "fop")))
15170    (set_attr "fp_int_src" "true")
15171    (set_attr "mode" "<MODE>")])
15172
15173 (define_insn "*fop_df_comm_mixed"
15174   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15175         (match_operator:DF 3 "binary_fp_operator"
15176                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15177                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15178   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15179    && COMMUTATIVE_ARITH_P (operands[3])
15180    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15181   "* return output_387_binary_op (insn, operands);"
15182   [(set (attr "type")
15183         (if_then_else (eq_attr "alternative" "1")
15184            (if_then_else (match_operand:DF 3 "mult_operator" "")
15185               (const_string "ssemul")
15186               (const_string "sseadd"))
15187            (if_then_else (match_operand:DF 3 "mult_operator" "")
15188               (const_string "fmul")
15189               (const_string "fop"))))
15190    (set_attr "mode" "DF")])
15191
15192 (define_insn "*fop_df_comm_sse"
15193   [(set (match_operand:DF 0 "register_operand" "=Y")
15194         (match_operator:DF 3 "binary_fp_operator"
15195                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15196                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15197   "TARGET_SSE2 && TARGET_SSE_MATH
15198    && COMMUTATIVE_ARITH_P (operands[3])
15199    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15200   "* return output_387_binary_op (insn, operands);"
15201   [(set (attr "type")
15202         (if_then_else (match_operand:DF 3 "mult_operator" "")
15203            (const_string "ssemul")
15204            (const_string "sseadd")))
15205    (set_attr "mode" "DF")])
15206
15207 (define_insn "*fop_df_comm_i387"
15208   [(set (match_operand:DF 0 "register_operand" "=f")
15209         (match_operator:DF 3 "binary_fp_operator"
15210                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15211                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15212   "TARGET_80387
15213    && COMMUTATIVE_ARITH_P (operands[3])
15214    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15215   "* return output_387_binary_op (insn, operands);"
15216   [(set (attr "type")
15217         (if_then_else (match_operand:DF 3 "mult_operator" "")
15218            (const_string "fmul")
15219            (const_string "fop")))
15220    (set_attr "mode" "DF")])
15221
15222 (define_insn "*fop_df_1_mixed"
15223   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15224         (match_operator:DF 3 "binary_fp_operator"
15225                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15226                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15227   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15228    && !COMMUTATIVE_ARITH_P (operands[3])
15229    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15230   "* return output_387_binary_op (insn, operands);"
15231   [(set (attr "type")
15232         (cond [(and (eq_attr "alternative" "2")
15233                     (match_operand:DF 3 "mult_operator" ""))
15234                  (const_string "ssemul")
15235                (and (eq_attr "alternative" "2")
15236                     (match_operand:DF 3 "div_operator" ""))
15237                  (const_string "ssediv")
15238                (eq_attr "alternative" "2")
15239                  (const_string "sseadd")
15240                (match_operand:DF 3 "mult_operator" "")
15241                  (const_string "fmul")
15242                (match_operand:DF 3 "div_operator" "")
15243                  (const_string "fdiv")
15244               ]
15245               (const_string "fop")))
15246    (set_attr "mode" "DF")])
15247
15248 (define_insn "*fop_df_1_sse"
15249   [(set (match_operand:DF 0 "register_operand" "=Y")
15250         (match_operator:DF 3 "binary_fp_operator"
15251                         [(match_operand:DF 1 "register_operand" "0")
15252                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15253   "TARGET_SSE2 && TARGET_SSE_MATH
15254    && !COMMUTATIVE_ARITH_P (operands[3])"
15255   "* return output_387_binary_op (insn, operands);"
15256   [(set_attr "mode" "DF")
15257    (set (attr "type")
15258         (cond [(match_operand:DF 3 "mult_operator" "")
15259                  (const_string "ssemul")
15260                (match_operand:DF 3 "div_operator" "")
15261                  (const_string "ssediv")
15262               ]
15263               (const_string "sseadd")))])
15264
15265 ;; This pattern is not fully shadowed by the pattern above.
15266 (define_insn "*fop_df_1_i387"
15267   [(set (match_operand:DF 0 "register_operand" "=f,f")
15268         (match_operator:DF 3 "binary_fp_operator"
15269                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15270                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15271   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15272    && !COMMUTATIVE_ARITH_P (operands[3])
15273    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15274   "* return output_387_binary_op (insn, operands);"
15275   [(set (attr "type")
15276         (cond [(match_operand:DF 3 "mult_operator" "")
15277                  (const_string "fmul")
15278                (match_operand:DF 3 "div_operator" "")
15279                  (const_string "fdiv")
15280               ]
15281               (const_string "fop")))
15282    (set_attr "mode" "DF")])
15283
15284 ;; ??? Add SSE splitters for these!
15285 (define_insn "*fop_df_2<mode>_i387"
15286   [(set (match_operand:DF 0 "register_operand" "=f,f")
15287         (match_operator:DF 3 "binary_fp_operator"
15288            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15289             (match_operand:DF 2 "register_operand" "0,0")]))]
15290   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15291    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15292   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15293   [(set (attr "type")
15294         (cond [(match_operand:DF 3 "mult_operator" "")
15295                  (const_string "fmul")
15296                (match_operand:DF 3 "div_operator" "")
15297                  (const_string "fdiv")
15298               ]
15299               (const_string "fop")))
15300    (set_attr "fp_int_src" "true")
15301    (set_attr "mode" "<MODE>")])
15302
15303 (define_insn "*fop_df_3<mode>_i387"
15304   [(set (match_operand:DF 0 "register_operand" "=f,f")
15305         (match_operator:DF 3 "binary_fp_operator"
15306            [(match_operand:DF 1 "register_operand" "0,0")
15307             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15308   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15309    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15310   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15311   [(set (attr "type")
15312         (cond [(match_operand:DF 3 "mult_operator" "")
15313                  (const_string "fmul")
15314                (match_operand:DF 3 "div_operator" "")
15315                  (const_string "fdiv")
15316               ]
15317               (const_string "fop")))
15318    (set_attr "fp_int_src" "true")
15319    (set_attr "mode" "<MODE>")])
15320
15321 (define_insn "*fop_df_4_i387"
15322   [(set (match_operand:DF 0 "register_operand" "=f,f")
15323         (match_operator:DF 3 "binary_fp_operator"
15324            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15325             (match_operand:DF 2 "register_operand" "0,f")]))]
15326   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15327    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15328   "* return output_387_binary_op (insn, operands);"
15329   [(set (attr "type")
15330         (cond [(match_operand:DF 3 "mult_operator" "")
15331                  (const_string "fmul")
15332                (match_operand:DF 3 "div_operator" "")
15333                  (const_string "fdiv")
15334               ]
15335               (const_string "fop")))
15336    (set_attr "mode" "SF")])
15337
15338 (define_insn "*fop_df_5_i387"
15339   [(set (match_operand:DF 0 "register_operand" "=f,f")
15340         (match_operator:DF 3 "binary_fp_operator"
15341           [(match_operand:DF 1 "register_operand" "0,f")
15342            (float_extend:DF
15343             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15344   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15345   "* return output_387_binary_op (insn, operands);"
15346   [(set (attr "type")
15347         (cond [(match_operand:DF 3 "mult_operator" "")
15348                  (const_string "fmul")
15349                (match_operand:DF 3 "div_operator" "")
15350                  (const_string "fdiv")
15351               ]
15352               (const_string "fop")))
15353    (set_attr "mode" "SF")])
15354
15355 (define_insn "*fop_df_6_i387"
15356   [(set (match_operand:DF 0 "register_operand" "=f,f")
15357         (match_operator:DF 3 "binary_fp_operator"
15358           [(float_extend:DF
15359             (match_operand:SF 1 "register_operand" "0,f"))
15360            (float_extend:DF
15361             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15362   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15363   "* return output_387_binary_op (insn, operands);"
15364   [(set (attr "type")
15365         (cond [(match_operand:DF 3 "mult_operator" "")
15366                  (const_string "fmul")
15367                (match_operand:DF 3 "div_operator" "")
15368                  (const_string "fdiv")
15369               ]
15370               (const_string "fop")))
15371    (set_attr "mode" "SF")])
15372
15373 (define_insn "*fop_xf_comm_i387"
15374   [(set (match_operand:XF 0 "register_operand" "=f")
15375         (match_operator:XF 3 "binary_fp_operator"
15376                         [(match_operand:XF 1 "register_operand" "%0")
15377                          (match_operand:XF 2 "register_operand" "f")]))]
15378   "TARGET_80387
15379    && COMMUTATIVE_ARITH_P (operands[3])"
15380   "* return output_387_binary_op (insn, operands);"
15381   [(set (attr "type")
15382         (if_then_else (match_operand:XF 3 "mult_operator" "")
15383            (const_string "fmul")
15384            (const_string "fop")))
15385    (set_attr "mode" "XF")])
15386
15387 (define_insn "*fop_xf_1_i387"
15388   [(set (match_operand:XF 0 "register_operand" "=f,f")
15389         (match_operator:XF 3 "binary_fp_operator"
15390                         [(match_operand:XF 1 "register_operand" "0,f")
15391                          (match_operand:XF 2 "register_operand" "f,0")]))]
15392   "TARGET_80387
15393    && !COMMUTATIVE_ARITH_P (operands[3])"
15394   "* return output_387_binary_op (insn, operands);"
15395   [(set (attr "type")
15396         (cond [(match_operand:XF 3 "mult_operator" "")
15397                  (const_string "fmul")
15398                (match_operand:XF 3 "div_operator" "")
15399                  (const_string "fdiv")
15400               ]
15401               (const_string "fop")))
15402    (set_attr "mode" "XF")])
15403
15404 (define_insn "*fop_xf_2<mode>_i387"
15405   [(set (match_operand:XF 0 "register_operand" "=f,f")
15406         (match_operator:XF 3 "binary_fp_operator"
15407            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15408             (match_operand:XF 2 "register_operand" "0,0")]))]
15409   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15410   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15411   [(set (attr "type")
15412         (cond [(match_operand:XF 3 "mult_operator" "")
15413                  (const_string "fmul")
15414                (match_operand:XF 3 "div_operator" "")
15415                  (const_string "fdiv")
15416               ]
15417               (const_string "fop")))
15418    (set_attr "fp_int_src" "true")
15419    (set_attr "mode" "<MODE>")])
15420
15421 (define_insn "*fop_xf_3<mode>_i387"
15422   [(set (match_operand:XF 0 "register_operand" "=f,f")
15423         (match_operator:XF 3 "binary_fp_operator"
15424           [(match_operand:XF 1 "register_operand" "0,0")
15425            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15426   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15427   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15428   [(set (attr "type")
15429         (cond [(match_operand:XF 3 "mult_operator" "")
15430                  (const_string "fmul")
15431                (match_operand:XF 3 "div_operator" "")
15432                  (const_string "fdiv")
15433               ]
15434               (const_string "fop")))
15435    (set_attr "fp_int_src" "true")
15436    (set_attr "mode" "<MODE>")])
15437
15438 (define_insn "*fop_xf_4_i387"
15439   [(set (match_operand:XF 0 "register_operand" "=f,f")
15440         (match_operator:XF 3 "binary_fp_operator"
15441            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15442             (match_operand:XF 2 "register_operand" "0,f")]))]
15443   "TARGET_80387"
15444   "* return output_387_binary_op (insn, operands);"
15445   [(set (attr "type")
15446         (cond [(match_operand:XF 3 "mult_operator" "")
15447                  (const_string "fmul")
15448                (match_operand:XF 3 "div_operator" "")
15449                  (const_string "fdiv")
15450               ]
15451               (const_string "fop")))
15452    (set_attr "mode" "SF")])
15453
15454 (define_insn "*fop_xf_5_i387"
15455   [(set (match_operand:XF 0 "register_operand" "=f,f")
15456         (match_operator:XF 3 "binary_fp_operator"
15457           [(match_operand:XF 1 "register_operand" "0,f")
15458            (float_extend:XF
15459             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15460   "TARGET_80387"
15461   "* return output_387_binary_op (insn, operands);"
15462   [(set (attr "type")
15463         (cond [(match_operand:XF 3 "mult_operator" "")
15464                  (const_string "fmul")
15465                (match_operand:XF 3 "div_operator" "")
15466                  (const_string "fdiv")
15467               ]
15468               (const_string "fop")))
15469    (set_attr "mode" "SF")])
15470
15471 (define_insn "*fop_xf_6_i387"
15472   [(set (match_operand:XF 0 "register_operand" "=f,f")
15473         (match_operator:XF 3 "binary_fp_operator"
15474           [(float_extend:XF
15475             (match_operand 1 "register_operand" "0,f"))
15476            (float_extend:XF
15477             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15478   "TARGET_80387"
15479   "* return output_387_binary_op (insn, operands);"
15480   [(set (attr "type")
15481         (cond [(match_operand:XF 3 "mult_operator" "")
15482                  (const_string "fmul")
15483                (match_operand:XF 3 "div_operator" "")
15484                  (const_string "fdiv")
15485               ]
15486               (const_string "fop")))
15487    (set_attr "mode" "SF")])
15488
15489 (define_split
15490   [(set (match_operand 0 "register_operand" "")
15491         (match_operator 3 "binary_fp_operator"
15492            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15493             (match_operand 2 "register_operand" "")]))]
15494   "TARGET_80387 && reload_completed
15495    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15496   [(const_int 0)]
15497 {
15498   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15499   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15500   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15501                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15502                                           GET_MODE (operands[3]),
15503                                           operands[4],
15504                                           operands[2])));
15505   ix86_free_from_memory (GET_MODE (operands[1]));
15506   DONE;
15507 })
15508
15509 (define_split
15510   [(set (match_operand 0 "register_operand" "")
15511         (match_operator 3 "binary_fp_operator"
15512            [(match_operand 1 "register_operand" "")
15513             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15514   "TARGET_80387 && reload_completed
15515    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15516   [(const_int 0)]
15517 {
15518   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15519   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15520   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15521                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15522                                           GET_MODE (operands[3]),
15523                                           operands[1],
15524                                           operands[4])));
15525   ix86_free_from_memory (GET_MODE (operands[2]));
15526   DONE;
15527 })
15528 \f
15529 ;; FPU special functions.
15530
15531 ;; This pattern implements a no-op XFmode truncation for
15532 ;; all fancy i386 XFmode math functions.
15533
15534 (define_insn "truncxf<mode>2_i387_noop_unspec"
15535   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15536         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15537         UNSPEC_TRUNC_NOOP))]
15538   "TARGET_USE_FANCY_MATH_387"
15539   "* return output_387_reg_move (insn, operands);"
15540   [(set_attr "type" "fmov")
15541    (set_attr "mode" "<MODE>")])
15542
15543 (define_insn "sqrtxf2"
15544   [(set (match_operand:XF 0 "register_operand" "=f")
15545         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15546   "TARGET_USE_FANCY_MATH_387"
15547   "fsqrt"
15548   [(set_attr "type" "fpspc")
15549    (set_attr "mode" "XF")
15550    (set_attr "athlon_decode" "direct")])
15551
15552 (define_insn "sqrt<mode>xf2_i387"
15553   [(set (match_operand:XF 0 "register_operand" "=f")
15554         (sqrt:XF
15555           (float_extend:XF
15556             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15557   "TARGET_USE_FANCY_MATH_387"
15558   "fsqrt"
15559   [(set_attr "type" "fpspc")
15560    (set_attr "mode" "XF")
15561    (set_attr "athlon_decode" "direct")])
15562
15563 (define_insn "*sqrt<mode>2_sse"
15564   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15565         (sqrt:SSEMODEF
15566           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15567   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15568   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15569   [(set_attr "type" "sse")
15570    (set_attr "mode" "<MODE>")
15571    (set_attr "athlon_decode" "*")])
15572
15573 (define_expand "sqrt<mode>2"
15574   [(set (match_operand:X87MODEF12 0 "register_operand" "")
15575         (sqrt:X87MODEF12
15576           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15577   "TARGET_USE_FANCY_MATH_387
15578    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15579 {
15580   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15581     {
15582       rtx op0 = gen_reg_rtx (XFmode);
15583       rtx op1 = force_reg (<MODE>mode, operands[1]);
15584
15585       emit_insn (gen_sqrt<mode>xf2_i387 (op0, op1));
15586       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15587       DONE;
15588    }
15589 })
15590
15591 (define_insn "fpremxf4"
15592   [(set (match_operand:XF 0 "register_operand" "=f")
15593         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15594                     (match_operand:XF 3 "register_operand" "1")]
15595                    UNSPEC_FPREM_F))
15596    (set (match_operand:XF 1 "register_operand" "=u")
15597         (unspec:XF [(match_dup 2) (match_dup 3)]
15598                    UNSPEC_FPREM_U))
15599    (set (reg:CCFP FPSR_REG)
15600         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15601   "TARGET_USE_FANCY_MATH_387"
15602   "fprem"
15603   [(set_attr "type" "fpspc")
15604    (set_attr "mode" "XF")])
15605
15606 (define_expand "fmodsf3"
15607   [(use (match_operand:SF 0 "register_operand" ""))
15608    (use (match_operand:SF 1 "register_operand" ""))
15609    (use (match_operand:SF 2 "register_operand" ""))]
15610   "TARGET_USE_FANCY_MATH_387
15611    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
15612 {
15613   rtx label = gen_label_rtx ();
15614
15615   rtx op1 = gen_reg_rtx (XFmode);
15616   rtx op2 = gen_reg_rtx (XFmode);
15617
15618   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15619   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15620
15621   emit_label (label);
15622
15623   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15624   ix86_emit_fp_unordered_jump (label);
15625
15626   emit_insn (gen_truncxfsf2_i387_noop_unspec (operands[0], op1));
15627   DONE;
15628 })
15629
15630 (define_expand "fmoddf3"
15631   [(use (match_operand:DF 0 "register_operand" ""))
15632    (use (match_operand:DF 1 "register_operand" ""))
15633    (use (match_operand:DF 2 "register_operand" ""))]
15634   "TARGET_USE_FANCY_MATH_387
15635    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15636 {
15637   rtx label = gen_label_rtx ();
15638
15639   rtx op1 = gen_reg_rtx (XFmode);
15640   rtx op2 = gen_reg_rtx (XFmode);
15641
15642   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15643   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15644
15645   emit_label (label);
15646
15647   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15648   ix86_emit_fp_unordered_jump (label);
15649
15650   emit_insn (gen_truncxfdf2_i387_noop_unspec (operands[0], op1));
15651   DONE;
15652 })
15653
15654 (define_expand "fmodxf3"
15655   [(use (match_operand:XF 0 "register_operand" ""))
15656    (use (match_operand:XF 1 "register_operand" ""))
15657    (use (match_operand:XF 2 "register_operand" ""))]
15658   "TARGET_USE_FANCY_MATH_387"
15659 {
15660   rtx label = gen_label_rtx ();
15661
15662   emit_label (label);
15663
15664   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15665                            operands[1], operands[2]));
15666   ix86_emit_fp_unordered_jump (label);
15667
15668   emit_move_insn (operands[0], operands[1]);
15669   DONE;
15670 })
15671
15672 (define_insn "fprem1xf4"
15673   [(set (match_operand:XF 0 "register_operand" "=f")
15674         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15675                     (match_operand:XF 3 "register_operand" "1")]
15676                    UNSPEC_FPREM1_F))
15677    (set (match_operand:XF 1 "register_operand" "=u")
15678         (unspec:XF [(match_dup 2) (match_dup 3)]
15679                    UNSPEC_FPREM1_U))
15680    (set (reg:CCFP FPSR_REG)
15681         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15682   "TARGET_USE_FANCY_MATH_387"
15683   "fprem1"
15684   [(set_attr "type" "fpspc")
15685    (set_attr "mode" "XF")])
15686
15687 (define_expand "remaindersf3"
15688   [(use (match_operand:SF 0 "register_operand" ""))
15689    (use (match_operand:SF 1 "register_operand" ""))
15690    (use (match_operand:SF 2 "register_operand" ""))]
15691   "TARGET_USE_FANCY_MATH_387
15692    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
15693 {
15694   rtx label = gen_label_rtx ();
15695
15696   rtx op1 = gen_reg_rtx (XFmode);
15697   rtx op2 = gen_reg_rtx (XFmode);
15698
15699   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15700   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15701
15702   emit_label (label);
15703
15704   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15705   ix86_emit_fp_unordered_jump (label);
15706
15707   emit_insn (gen_truncxfsf2_i387_noop_unspec (operands[0], op1));
15708   DONE;
15709 })
15710
15711 (define_expand "remainderdf3"
15712   [(use (match_operand:DF 0 "register_operand" ""))
15713    (use (match_operand:DF 1 "register_operand" ""))
15714    (use (match_operand:DF 2 "register_operand" ""))]
15715   "TARGET_USE_FANCY_MATH_387
15716    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15717 {
15718   rtx label = gen_label_rtx ();
15719
15720   rtx op1 = gen_reg_rtx (XFmode);
15721   rtx op2 = gen_reg_rtx (XFmode);
15722
15723   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15724   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15725
15726   emit_label (label);
15727
15728   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15729   ix86_emit_fp_unordered_jump (label);
15730
15731   emit_insn (gen_truncxfdf2_i387_noop_unspec (operands[0], op1));
15732   DONE;
15733 })
15734
15735 (define_expand "remainderxf3"
15736   [(use (match_operand:XF 0 "register_operand" ""))
15737    (use (match_operand:XF 1 "register_operand" ""))
15738    (use (match_operand:XF 2 "register_operand" ""))]
15739   "TARGET_USE_FANCY_MATH_387"
15740 {
15741   rtx label = gen_label_rtx ();
15742
15743   emit_label (label);
15744
15745   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15746                             operands[1], operands[2]));
15747   ix86_emit_fp_unordered_jump (label);
15748
15749   emit_move_insn (operands[0], operands[1]);
15750   DONE;
15751 })
15752
15753 (define_insn "*sindf2"
15754   [(set (match_operand:DF 0 "register_operand" "=f")
15755         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15756   "TARGET_USE_FANCY_MATH_387
15757    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15758    && flag_unsafe_math_optimizations"
15759   "fsin"
15760   [(set_attr "type" "fpspc")
15761    (set_attr "mode" "DF")])
15762
15763 (define_insn "*sinsf2"
15764   [(set (match_operand:SF 0 "register_operand" "=f")
15765         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15766   "TARGET_USE_FANCY_MATH_387
15767    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15768    && flag_unsafe_math_optimizations"
15769   "fsin"
15770   [(set_attr "type" "fpspc")
15771    (set_attr "mode" "SF")])
15772
15773 (define_insn "*sinextendsfdf2"
15774   [(set (match_operand:DF 0 "register_operand" "=f")
15775         (unspec:DF [(float_extend:DF
15776                      (match_operand:SF 1 "register_operand" "0"))]
15777                    UNSPEC_SIN))]
15778   "TARGET_USE_FANCY_MATH_387
15779    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15780    && flag_unsafe_math_optimizations"
15781   "fsin"
15782   [(set_attr "type" "fpspc")
15783    (set_attr "mode" "DF")])
15784
15785 (define_insn "*sinxf2"
15786   [(set (match_operand:XF 0 "register_operand" "=f")
15787         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15788   "TARGET_USE_FANCY_MATH_387
15789    && flag_unsafe_math_optimizations"
15790   "fsin"
15791   [(set_attr "type" "fpspc")
15792    (set_attr "mode" "XF")])
15793
15794 (define_insn "*cosdf2"
15795   [(set (match_operand:DF 0 "register_operand" "=f")
15796         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15797   "TARGET_USE_FANCY_MATH_387
15798    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15799    && flag_unsafe_math_optimizations"
15800   "fcos"
15801   [(set_attr "type" "fpspc")
15802    (set_attr "mode" "DF")])
15803
15804 (define_insn "*cossf2"
15805   [(set (match_operand:SF 0 "register_operand" "=f")
15806         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15807   "TARGET_USE_FANCY_MATH_387
15808    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15809    && flag_unsafe_math_optimizations"
15810   "fcos"
15811   [(set_attr "type" "fpspc")
15812    (set_attr "mode" "SF")])
15813
15814 (define_insn "*cosextendsfdf2"
15815   [(set (match_operand:DF 0 "register_operand" "=f")
15816         (unspec:DF [(float_extend:DF
15817                      (match_operand:SF 1 "register_operand" "0"))]
15818                    UNSPEC_COS))]
15819   "TARGET_USE_FANCY_MATH_387
15820    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15821    && flag_unsafe_math_optimizations"
15822   "fcos"
15823   [(set_attr "type" "fpspc")
15824    (set_attr "mode" "DF")])
15825
15826 (define_insn "*cosxf2"
15827   [(set (match_operand:XF 0 "register_operand" "=f")
15828         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15829   "TARGET_USE_FANCY_MATH_387
15830    && flag_unsafe_math_optimizations"
15831   "fcos"
15832   [(set_attr "type" "fpspc")
15833    (set_attr "mode" "XF")])
15834
15835 ;; With sincos pattern defined, sin and cos builtin function will be
15836 ;; expanded to sincos pattern with one of its outputs left unused.
15837 ;; Cse pass  will detected, if two sincos patterns can be combined,
15838 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15839 ;; depending on the unused output.
15840
15841 (define_insn "sincosdf3"
15842   [(set (match_operand:DF 0 "register_operand" "=f")
15843         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15844                    UNSPEC_SINCOS_COS))
15845    (set (match_operand:DF 1 "register_operand" "=u")
15846         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15847   "TARGET_USE_FANCY_MATH_387
15848    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15849    && flag_unsafe_math_optimizations"
15850   "fsincos"
15851   [(set_attr "type" "fpspc")
15852    (set_attr "mode" "DF")])
15853
15854 (define_split
15855   [(set (match_operand:DF 0 "register_operand" "")
15856         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15857                    UNSPEC_SINCOS_COS))
15858    (set (match_operand:DF 1 "register_operand" "")
15859         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15860   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15861    && !reload_completed && !reload_in_progress"
15862   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15863   "")
15864
15865 (define_split
15866   [(set (match_operand:DF 0 "register_operand" "")
15867         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15868                    UNSPEC_SINCOS_COS))
15869    (set (match_operand:DF 1 "register_operand" "")
15870         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15871   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15872    && !reload_completed && !reload_in_progress"
15873   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15874   "")
15875
15876 (define_insn "sincossf3"
15877   [(set (match_operand:SF 0 "register_operand" "=f")
15878         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15879                    UNSPEC_SINCOS_COS))
15880    (set (match_operand:SF 1 "register_operand" "=u")
15881         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15882   "TARGET_USE_FANCY_MATH_387
15883    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15884    && flag_unsafe_math_optimizations"
15885   "fsincos"
15886   [(set_attr "type" "fpspc")
15887    (set_attr "mode" "SF")])
15888
15889 (define_split
15890   [(set (match_operand:SF 0 "register_operand" "")
15891         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15892                    UNSPEC_SINCOS_COS))
15893    (set (match_operand:SF 1 "register_operand" "")
15894         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15895   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15896    && !reload_completed && !reload_in_progress"
15897   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15898   "")
15899
15900 (define_split
15901   [(set (match_operand:SF 0 "register_operand" "")
15902         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15903                    UNSPEC_SINCOS_COS))
15904    (set (match_operand:SF 1 "register_operand" "")
15905         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15906   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15907    && !reload_completed && !reload_in_progress"
15908   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15909   "")
15910
15911 (define_insn "*sincosextendsfdf3"
15912   [(set (match_operand:DF 0 "register_operand" "=f")
15913         (unspec:DF [(float_extend:DF
15914                      (match_operand:SF 2 "register_operand" "0"))]
15915                    UNSPEC_SINCOS_COS))
15916    (set (match_operand:DF 1 "register_operand" "=u")
15917         (unspec:DF [(float_extend:DF
15918                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15919   "TARGET_USE_FANCY_MATH_387
15920    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15921    && flag_unsafe_math_optimizations"
15922   "fsincos"
15923   [(set_attr "type" "fpspc")
15924    (set_attr "mode" "DF")])
15925
15926 (define_split
15927   [(set (match_operand:DF 0 "register_operand" "")
15928         (unspec:DF [(float_extend:DF
15929                      (match_operand:SF 2 "register_operand" ""))]
15930                    UNSPEC_SINCOS_COS))
15931    (set (match_operand:DF 1 "register_operand" "")
15932         (unspec:DF [(float_extend:DF
15933                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15934   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15935    && !reload_completed && !reload_in_progress"
15936   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15937                                    (match_dup 2))] UNSPEC_SIN))]
15938   "")
15939
15940 (define_split
15941   [(set (match_operand:DF 0 "register_operand" "")
15942         (unspec:DF [(float_extend:DF
15943                      (match_operand:SF 2 "register_operand" ""))]
15944                    UNSPEC_SINCOS_COS))
15945    (set (match_operand:DF 1 "register_operand" "")
15946         (unspec:DF [(float_extend:DF
15947                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15948   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15949    && !reload_completed && !reload_in_progress"
15950   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15951                                    (match_dup 2))] UNSPEC_COS))]
15952   "")
15953
15954 (define_insn "sincosxf3"
15955   [(set (match_operand:XF 0 "register_operand" "=f")
15956         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15957                    UNSPEC_SINCOS_COS))
15958    (set (match_operand:XF 1 "register_operand" "=u")
15959         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15960   "TARGET_USE_FANCY_MATH_387
15961    && flag_unsafe_math_optimizations"
15962   "fsincos"
15963   [(set_attr "type" "fpspc")
15964    (set_attr "mode" "XF")])
15965
15966 (define_split
15967   [(set (match_operand:XF 0 "register_operand" "")
15968         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15969                    UNSPEC_SINCOS_COS))
15970    (set (match_operand:XF 1 "register_operand" "")
15971         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15972   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15973    && !reload_completed && !reload_in_progress"
15974   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15975   "")
15976
15977 (define_split
15978   [(set (match_operand:XF 0 "register_operand" "")
15979         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15980                    UNSPEC_SINCOS_COS))
15981    (set (match_operand:XF 1 "register_operand" "")
15982         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15983   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15984    && !reload_completed && !reload_in_progress"
15985   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15986   "")
15987
15988 (define_insn "*tandf3_1"
15989   [(set (match_operand:DF 0 "register_operand" "=f")
15990         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15991                    UNSPEC_TAN_ONE))
15992    (set (match_operand:DF 1 "register_operand" "=u")
15993         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15994   "TARGET_USE_FANCY_MATH_387
15995    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15996    && flag_unsafe_math_optimizations"
15997   "fptan"
15998   [(set_attr "type" "fpspc")
15999    (set_attr "mode" "DF")])
16000
16001 ;; optimize sequence: fptan
16002 ;;                    fstp    %st(0)
16003 ;;                    fld1
16004 ;; into fptan insn.
16005
16006 (define_peephole2
16007   [(parallel[(set (match_operand:DF 0 "register_operand" "")
16008                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16009                              UNSPEC_TAN_ONE))
16010              (set (match_operand:DF 1 "register_operand" "")
16011                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16012    (set (match_dup 0)
16013         (match_operand:DF 3 "immediate_operand" ""))]
16014   "standard_80387_constant_p (operands[3]) == 2"
16015   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16016              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16017   "")
16018
16019 (define_expand "tandf2"
16020   [(parallel [(set (match_dup 2)
16021                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16022                               UNSPEC_TAN_ONE))
16023               (set (match_operand:DF 0 "register_operand" "")
16024                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16025   "TARGET_USE_FANCY_MATH_387
16026    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16027    && flag_unsafe_math_optimizations"
16028 {
16029   operands[2] = gen_reg_rtx (DFmode);
16030 })
16031
16032 (define_insn "*tansf3_1"
16033   [(set (match_operand:SF 0 "register_operand" "=f")
16034         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16035                    UNSPEC_TAN_ONE))
16036    (set (match_operand:SF 1 "register_operand" "=u")
16037         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16038   "TARGET_USE_FANCY_MATH_387
16039    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16040    && flag_unsafe_math_optimizations"
16041   "fptan"
16042   [(set_attr "type" "fpspc")
16043    (set_attr "mode" "SF")])
16044
16045 ;; optimize sequence: fptan
16046 ;;                    fstp    %st(0)
16047 ;;                    fld1
16048 ;; into fptan insn.
16049
16050 (define_peephole2
16051   [(parallel[(set (match_operand:SF 0 "register_operand" "")
16052                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16053                              UNSPEC_TAN_ONE))
16054              (set (match_operand:SF 1 "register_operand" "")
16055                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16056    (set (match_dup 0)
16057         (match_operand:SF 3 "immediate_operand" ""))]
16058   "standard_80387_constant_p (operands[3]) == 2"
16059   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16060              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16061   "")
16062
16063 (define_expand "tansf2"
16064   [(parallel [(set (match_dup 2)
16065                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16066                               UNSPEC_TAN_ONE))
16067               (set (match_operand:SF 0 "register_operand" "")
16068                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16069   "TARGET_USE_FANCY_MATH_387
16070    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16071    && flag_unsafe_math_optimizations"
16072 {
16073   operands[2] = gen_reg_rtx (SFmode);
16074 })
16075
16076 (define_insn "*tanxf3_1"
16077   [(set (match_operand:XF 0 "register_operand" "=f")
16078         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16079                    UNSPEC_TAN_ONE))
16080    (set (match_operand:XF 1 "register_operand" "=u")
16081         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16082   "TARGET_USE_FANCY_MATH_387
16083    && flag_unsafe_math_optimizations"
16084   "fptan"
16085   [(set_attr "type" "fpspc")
16086    (set_attr "mode" "XF")])
16087
16088 ;; optimize sequence: fptan
16089 ;;                    fstp    %st(0)
16090 ;;                    fld1
16091 ;; into fptan insn.
16092
16093 (define_peephole2
16094   [(parallel[(set (match_operand:XF 0 "register_operand" "")
16095                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16096                              UNSPEC_TAN_ONE))
16097              (set (match_operand:XF 1 "register_operand" "")
16098                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16099    (set (match_dup 0)
16100         (match_operand:XF 3 "immediate_operand" ""))]
16101   "standard_80387_constant_p (operands[3]) == 2"
16102   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16103              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16104   "")
16105
16106 (define_expand "tanxf2"
16107   [(parallel [(set (match_dup 2)
16108                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16109                               UNSPEC_TAN_ONE))
16110               (set (match_operand:XF 0 "register_operand" "")
16111                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16112   "TARGET_USE_FANCY_MATH_387
16113    && flag_unsafe_math_optimizations"
16114 {
16115   operands[2] = gen_reg_rtx (XFmode);
16116 })
16117
16118 (define_insn "atan2df3_1"
16119   [(set (match_operand:DF 0 "register_operand" "=f")
16120         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16121                     (match_operand:DF 1 "register_operand" "u")]
16122                    UNSPEC_FPATAN))
16123    (clobber (match_scratch:DF 3 "=1"))]
16124   "TARGET_USE_FANCY_MATH_387
16125    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16126    && flag_unsafe_math_optimizations"
16127   "fpatan"
16128   [(set_attr "type" "fpspc")
16129    (set_attr "mode" "DF")])
16130
16131 (define_expand "atan2df3"
16132   [(use (match_operand:DF 0 "register_operand" ""))
16133    (use (match_operand:DF 2 "register_operand" ""))
16134    (use (match_operand:DF 1 "register_operand" ""))]
16135   "TARGET_USE_FANCY_MATH_387
16136    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16137    && flag_unsafe_math_optimizations"
16138 {
16139   rtx copy = gen_reg_rtx (DFmode);
16140   emit_move_insn (copy, operands[1]);
16141   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16142   DONE;
16143 })
16144
16145 (define_expand "atandf2"
16146   [(parallel [(set (match_operand:DF 0 "register_operand" "")
16147                    (unspec:DF [(match_dup 2)
16148                                (match_operand:DF 1 "register_operand" "")]
16149                     UNSPEC_FPATAN))
16150               (clobber (match_scratch:DF 3 ""))])]
16151   "TARGET_USE_FANCY_MATH_387
16152    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16153    && flag_unsafe_math_optimizations"
16154 {
16155   operands[2] = gen_reg_rtx (DFmode);
16156   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16157 })
16158
16159 (define_insn "atan2sf3_1"
16160   [(set (match_operand:SF 0 "register_operand" "=f")
16161         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16162                     (match_operand:SF 1 "register_operand" "u")]
16163                    UNSPEC_FPATAN))
16164    (clobber (match_scratch:SF 3 "=1"))]
16165   "TARGET_USE_FANCY_MATH_387
16166    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16167    && flag_unsafe_math_optimizations"
16168   "fpatan"
16169   [(set_attr "type" "fpspc")
16170    (set_attr "mode" "SF")])
16171
16172 (define_expand "atan2sf3"
16173   [(use (match_operand:SF 0 "register_operand" ""))
16174    (use (match_operand:SF 2 "register_operand" ""))
16175    (use (match_operand:SF 1 "register_operand" ""))]
16176   "TARGET_USE_FANCY_MATH_387
16177    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16178    && flag_unsafe_math_optimizations"
16179 {
16180   rtx copy = gen_reg_rtx (SFmode);
16181   emit_move_insn (copy, operands[1]);
16182   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16183   DONE;
16184 })
16185
16186 (define_expand "atansf2"
16187   [(parallel [(set (match_operand:SF 0 "register_operand" "")
16188                    (unspec:SF [(match_dup 2)
16189                                (match_operand:SF 1 "register_operand" "")]
16190                     UNSPEC_FPATAN))
16191               (clobber (match_scratch:SF 3 ""))])]
16192   "TARGET_USE_FANCY_MATH_387
16193    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16194    && flag_unsafe_math_optimizations"
16195 {
16196   operands[2] = gen_reg_rtx (SFmode);
16197   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16198 })
16199
16200 (define_insn "atan2xf3_1"
16201   [(set (match_operand:XF 0 "register_operand" "=f")
16202         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16203                     (match_operand:XF 1 "register_operand" "u")]
16204                    UNSPEC_FPATAN))
16205    (clobber (match_scratch:XF 3 "=1"))]
16206   "TARGET_USE_FANCY_MATH_387
16207    && flag_unsafe_math_optimizations"
16208   "fpatan"
16209   [(set_attr "type" "fpspc")
16210    (set_attr "mode" "XF")])
16211
16212 (define_expand "atan2xf3"
16213   [(use (match_operand:XF 0 "register_operand" ""))
16214    (use (match_operand:XF 2 "register_operand" ""))
16215    (use (match_operand:XF 1 "register_operand" ""))]
16216   "TARGET_USE_FANCY_MATH_387
16217    && flag_unsafe_math_optimizations"
16218 {
16219   rtx copy = gen_reg_rtx (XFmode);
16220   emit_move_insn (copy, operands[1]);
16221   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16222   DONE;
16223 })
16224
16225 (define_expand "atanxf2"
16226   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16227                    (unspec:XF [(match_dup 2)
16228                                (match_operand:XF 1 "register_operand" "")]
16229                     UNSPEC_FPATAN))
16230               (clobber (match_scratch:XF 3 ""))])]
16231   "TARGET_USE_FANCY_MATH_387
16232    && flag_unsafe_math_optimizations"
16233 {
16234   operands[2] = gen_reg_rtx (XFmode);
16235   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16236 })
16237
16238 (define_expand "asindf2"
16239   [(set (match_dup 2)
16240         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16241    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16242    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16243    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16244    (parallel [(set (match_dup 7)
16245                    (unspec:XF [(match_dup 6) (match_dup 2)]
16246                               UNSPEC_FPATAN))
16247               (clobber (match_scratch:XF 8 ""))])
16248    (set (match_operand:DF 0 "register_operand" "")
16249         (float_truncate:DF (match_dup 7)))]
16250   "TARGET_USE_FANCY_MATH_387
16251    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16252    && flag_unsafe_math_optimizations && !optimize_size"
16253 {
16254   int i;
16255
16256   for (i=2; i<8; i++)
16257     operands[i] = gen_reg_rtx (XFmode);
16258
16259   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16260 })
16261
16262 (define_expand "asinsf2"
16263   [(set (match_dup 2)
16264         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16265    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16266    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16267    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16268    (parallel [(set (match_dup 7)
16269                    (unspec:XF [(match_dup 6) (match_dup 2)]
16270                               UNSPEC_FPATAN))
16271               (clobber (match_scratch:XF 8 ""))])
16272    (set (match_operand:SF 0 "register_operand" "")
16273         (float_truncate:SF (match_dup 7)))]
16274   "TARGET_USE_FANCY_MATH_387
16275    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16276    && flag_unsafe_math_optimizations && !optimize_size"
16277 {
16278   int i;
16279
16280   for (i=2; i<8; i++)
16281     operands[i] = gen_reg_rtx (XFmode);
16282
16283   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16284 })
16285
16286 (define_expand "asinxf2"
16287   [(set (match_dup 2)
16288         (mult:XF (match_operand:XF 1 "register_operand" "")
16289                  (match_dup 1)))
16290    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16291    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16292    (parallel [(set (match_operand:XF 0 "register_operand" "")
16293                    (unspec:XF [(match_dup 5) (match_dup 1)]
16294                               UNSPEC_FPATAN))
16295               (clobber (match_scratch:XF 6 ""))])]
16296   "TARGET_USE_FANCY_MATH_387
16297    && flag_unsafe_math_optimizations && !optimize_size"
16298 {
16299   int i;
16300
16301   for (i=2; i<6; i++)
16302     operands[i] = gen_reg_rtx (XFmode);
16303
16304   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16305 })
16306
16307 (define_expand "acosdf2"
16308   [(set (match_dup 2)
16309         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16310    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16311    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16312    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16313    (parallel [(set (match_dup 7)
16314                    (unspec:XF [(match_dup 2) (match_dup 6)]
16315                               UNSPEC_FPATAN))
16316               (clobber (match_scratch:XF 8 ""))])
16317    (set (match_operand:DF 0 "register_operand" "")
16318         (float_truncate:DF (match_dup 7)))]
16319   "TARGET_USE_FANCY_MATH_387
16320    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16321    && flag_unsafe_math_optimizations && !optimize_size"
16322 {
16323   int i;
16324
16325   for (i=2; i<8; i++)
16326     operands[i] = gen_reg_rtx (XFmode);
16327
16328   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16329 })
16330
16331 (define_expand "acossf2"
16332   [(set (match_dup 2)
16333         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16334    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16335    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16336    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16337    (parallel [(set (match_dup 7)
16338                    (unspec:XF [(match_dup 2) (match_dup 6)]
16339                               UNSPEC_FPATAN))
16340               (clobber (match_scratch:XF 8 ""))])
16341    (set (match_operand:SF 0 "register_operand" "")
16342         (float_truncate:SF (match_dup 7)))]
16343   "TARGET_USE_FANCY_MATH_387
16344    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16345    && flag_unsafe_math_optimizations && !optimize_size"
16346 {
16347   int i;
16348
16349   for (i=2; i<8; i++)
16350     operands[i] = gen_reg_rtx (XFmode);
16351
16352   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16353 })
16354
16355 (define_expand "acosxf2"
16356   [(set (match_dup 2)
16357         (mult:XF (match_operand:XF 1 "register_operand" "")
16358                  (match_dup 1)))
16359    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16360    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16361    (parallel [(set (match_operand:XF 0 "register_operand" "")
16362                    (unspec:XF [(match_dup 1) (match_dup 5)]
16363                               UNSPEC_FPATAN))
16364               (clobber (match_scratch:XF 6 ""))])]
16365   "TARGET_USE_FANCY_MATH_387
16366    && flag_unsafe_math_optimizations && !optimize_size"
16367 {
16368   int i;
16369
16370   for (i=2; i<6; i++)
16371     operands[i] = gen_reg_rtx (XFmode);
16372
16373   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16374 })
16375
16376 (define_insn "fyl2x_xf3"
16377   [(set (match_operand:XF 0 "register_operand" "=f")
16378         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16379                     (match_operand:XF 1 "register_operand" "u")]
16380                    UNSPEC_FYL2X))
16381    (clobber (match_scratch:XF 3 "=1"))]
16382   "TARGET_USE_FANCY_MATH_387
16383    && flag_unsafe_math_optimizations"
16384   "fyl2x"
16385   [(set_attr "type" "fpspc")
16386    (set_attr "mode" "XF")])
16387
16388 (define_expand "logsf2"
16389   [(set (match_dup 2)
16390         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16391    (parallel [(set (match_dup 4)
16392                    (unspec:XF [(match_dup 2)
16393                                (match_dup 3)] UNSPEC_FYL2X))
16394               (clobber (match_scratch:XF 5 ""))])
16395    (set (match_operand:SF 0 "register_operand" "")
16396         (float_truncate:SF (match_dup 4)))]
16397   "TARGET_USE_FANCY_MATH_387
16398    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16399    && flag_unsafe_math_optimizations"
16400 {
16401   rtx temp;
16402
16403   operands[2] = gen_reg_rtx (XFmode);
16404   operands[3] = gen_reg_rtx (XFmode);
16405   operands[4] = gen_reg_rtx (XFmode);
16406
16407   temp = standard_80387_constant_rtx (4); /* fldln2 */
16408   emit_move_insn (operands[3], temp);
16409 })
16410
16411 (define_expand "logdf2"
16412   [(set (match_dup 2)
16413         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16414    (parallel [(set (match_dup 4)
16415                    (unspec:XF [(match_dup 2)
16416                                (match_dup 3)] UNSPEC_FYL2X))
16417               (clobber (match_scratch:XF 5 ""))])
16418    (set (match_operand:DF 0 "register_operand" "")
16419         (float_truncate:DF (match_dup 4)))]
16420   "TARGET_USE_FANCY_MATH_387
16421    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16422    && flag_unsafe_math_optimizations"
16423 {
16424   rtx temp;
16425
16426   operands[2] = gen_reg_rtx (XFmode);
16427   operands[3] = gen_reg_rtx (XFmode);
16428   operands[4] = gen_reg_rtx (XFmode);
16429
16430   temp = standard_80387_constant_rtx (4); /* fldln2 */
16431   emit_move_insn (operands[3], temp);
16432 })
16433
16434 (define_expand "logxf2"
16435   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16436                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16437                                (match_dup 2)] UNSPEC_FYL2X))
16438               (clobber (match_scratch:XF 3 ""))])]
16439   "TARGET_USE_FANCY_MATH_387
16440    && flag_unsafe_math_optimizations"
16441 {
16442   rtx temp;
16443
16444   operands[2] = gen_reg_rtx (XFmode);
16445   temp = standard_80387_constant_rtx (4); /* fldln2 */
16446   emit_move_insn (operands[2], temp);
16447 })
16448
16449 (define_expand "log10sf2"
16450   [(set (match_dup 2)
16451         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16452    (parallel [(set (match_dup 4)
16453                    (unspec:XF [(match_dup 2)
16454                                (match_dup 3)] UNSPEC_FYL2X))
16455               (clobber (match_scratch:XF 5 ""))])
16456    (set (match_operand:SF 0 "register_operand" "")
16457         (float_truncate:SF (match_dup 4)))]
16458   "TARGET_USE_FANCY_MATH_387
16459    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16460    && flag_unsafe_math_optimizations"
16461 {
16462   rtx temp;
16463
16464   operands[2] = gen_reg_rtx (XFmode);
16465   operands[3] = gen_reg_rtx (XFmode);
16466   operands[4] = gen_reg_rtx (XFmode);
16467
16468   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16469   emit_move_insn (operands[3], temp);
16470 })
16471
16472 (define_expand "log10df2"
16473   [(set (match_dup 2)
16474         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16475    (parallel [(set (match_dup 4)
16476                    (unspec:XF [(match_dup 2)
16477                                (match_dup 3)] UNSPEC_FYL2X))
16478               (clobber (match_scratch:XF 5 ""))])
16479    (set (match_operand:DF 0 "register_operand" "")
16480         (float_truncate:DF (match_dup 4)))]
16481   "TARGET_USE_FANCY_MATH_387
16482    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16483    && flag_unsafe_math_optimizations"
16484 {
16485   rtx temp;
16486
16487   operands[2] = gen_reg_rtx (XFmode);
16488   operands[3] = gen_reg_rtx (XFmode);
16489   operands[4] = gen_reg_rtx (XFmode);
16490
16491   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16492   emit_move_insn (operands[3], temp);
16493 })
16494
16495 (define_expand "log10xf2"
16496   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16497                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16498                                (match_dup 2)] UNSPEC_FYL2X))
16499               (clobber (match_scratch:XF 3 ""))])]
16500   "TARGET_USE_FANCY_MATH_387
16501    && flag_unsafe_math_optimizations"
16502 {
16503   rtx temp;
16504
16505   operands[2] = gen_reg_rtx (XFmode);
16506   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16507   emit_move_insn (operands[2], temp);
16508 })
16509
16510 (define_expand "log2sf2"
16511   [(set (match_dup 2)
16512         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16513    (parallel [(set (match_dup 4)
16514                    (unspec:XF [(match_dup 2)
16515                                (match_dup 3)] UNSPEC_FYL2X))
16516               (clobber (match_scratch:XF 5 ""))])
16517    (set (match_operand:SF 0 "register_operand" "")
16518         (float_truncate:SF (match_dup 4)))]
16519   "TARGET_USE_FANCY_MATH_387
16520    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16521    && flag_unsafe_math_optimizations"
16522 {
16523   operands[2] = gen_reg_rtx (XFmode);
16524   operands[3] = gen_reg_rtx (XFmode);
16525   operands[4] = gen_reg_rtx (XFmode);
16526
16527   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16528 })
16529
16530 (define_expand "log2df2"
16531   [(set (match_dup 2)
16532         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16533    (parallel [(set (match_dup 4)
16534                    (unspec:XF [(match_dup 2)
16535                                (match_dup 3)] UNSPEC_FYL2X))
16536               (clobber (match_scratch:XF 5 ""))])
16537    (set (match_operand:DF 0 "register_operand" "")
16538         (float_truncate:DF (match_dup 4)))]
16539   "TARGET_USE_FANCY_MATH_387
16540    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16541    && flag_unsafe_math_optimizations"
16542 {
16543   operands[2] = gen_reg_rtx (XFmode);
16544   operands[3] = gen_reg_rtx (XFmode);
16545   operands[4] = gen_reg_rtx (XFmode);
16546
16547   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16548 })
16549
16550 (define_expand "log2xf2"
16551   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16552                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16553                                (match_dup 2)] UNSPEC_FYL2X))
16554               (clobber (match_scratch:XF 3 ""))])]
16555   "TARGET_USE_FANCY_MATH_387
16556    && flag_unsafe_math_optimizations"
16557 {
16558   operands[2] = gen_reg_rtx (XFmode);
16559   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16560 })
16561
16562 (define_insn "fyl2xp1_xf3"
16563   [(set (match_operand:XF 0 "register_operand" "=f")
16564         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16565                     (match_operand:XF 1 "register_operand" "u")]
16566                    UNSPEC_FYL2XP1))
16567    (clobber (match_scratch:XF 3 "=1"))]
16568   "TARGET_USE_FANCY_MATH_387
16569    && flag_unsafe_math_optimizations"
16570   "fyl2xp1"
16571   [(set_attr "type" "fpspc")
16572    (set_attr "mode" "XF")])
16573
16574 (define_expand "log1psf2"
16575   [(use (match_operand:SF 0 "register_operand" ""))
16576    (use (match_operand:SF 1 "register_operand" ""))]
16577   "TARGET_USE_FANCY_MATH_387
16578    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16579    && flag_unsafe_math_optimizations && !optimize_size"
16580 {
16581   rtx op0 = gen_reg_rtx (XFmode);
16582   rtx op1 = gen_reg_rtx (XFmode);
16583
16584   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16585   ix86_emit_i387_log1p (op0, op1);
16586   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16587   DONE;
16588 })
16589
16590 (define_expand "log1pdf2"
16591   [(use (match_operand:DF 0 "register_operand" ""))
16592    (use (match_operand:DF 1 "register_operand" ""))]
16593   "TARGET_USE_FANCY_MATH_387
16594    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16595    && flag_unsafe_math_optimizations && !optimize_size"
16596 {
16597   rtx op0 = gen_reg_rtx (XFmode);
16598   rtx op1 = gen_reg_rtx (XFmode);
16599
16600   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16601   ix86_emit_i387_log1p (op0, op1);
16602   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16603   DONE;
16604 })
16605
16606 (define_expand "log1pxf2"
16607   [(use (match_operand:XF 0 "register_operand" ""))
16608    (use (match_operand:XF 1 "register_operand" ""))]
16609   "TARGET_USE_FANCY_MATH_387
16610    && flag_unsafe_math_optimizations && !optimize_size"
16611 {
16612   ix86_emit_i387_log1p (operands[0], operands[1]);
16613   DONE;
16614 })
16615
16616 (define_insn "*fxtractxf3"
16617   [(set (match_operand:XF 0 "register_operand" "=f")
16618         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16619                    UNSPEC_XTRACT_FRACT))
16620    (set (match_operand:XF 1 "register_operand" "=u")
16621         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16622   "TARGET_USE_FANCY_MATH_387
16623    && flag_unsafe_math_optimizations"
16624   "fxtract"
16625   [(set_attr "type" "fpspc")
16626    (set_attr "mode" "XF")])
16627
16628 (define_expand "logbsf2"
16629   [(set (match_dup 2)
16630         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16631    (parallel [(set (match_dup 3)
16632                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16633               (set (match_dup 4)
16634                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16635    (set (match_operand:SF 0 "register_operand" "")
16636         (float_truncate:SF (match_dup 4)))]
16637   "TARGET_USE_FANCY_MATH_387
16638    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16639    && flag_unsafe_math_optimizations"
16640 {
16641   operands[2] = gen_reg_rtx (XFmode);
16642   operands[3] = gen_reg_rtx (XFmode);
16643   operands[4] = gen_reg_rtx (XFmode);
16644 })
16645
16646 (define_expand "logbdf2"
16647   [(set (match_dup 2)
16648         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16649    (parallel [(set (match_dup 3)
16650                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16651               (set (match_dup 4)
16652                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16653    (set (match_operand:DF 0 "register_operand" "")
16654         (float_truncate:DF (match_dup 4)))]
16655   "TARGET_USE_FANCY_MATH_387
16656    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16657    && flag_unsafe_math_optimizations"
16658 {
16659   operands[2] = gen_reg_rtx (XFmode);
16660   operands[3] = gen_reg_rtx (XFmode);
16661   operands[4] = gen_reg_rtx (XFmode);
16662 })
16663
16664 (define_expand "logbxf2"
16665   [(parallel [(set (match_dup 2)
16666                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16667                               UNSPEC_XTRACT_FRACT))
16668               (set (match_operand:XF 0 "register_operand" "")
16669                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16670   "TARGET_USE_FANCY_MATH_387
16671    && flag_unsafe_math_optimizations"
16672 {
16673   operands[2] = gen_reg_rtx (XFmode);
16674 })
16675
16676 (define_expand "ilogbsi2"
16677   [(parallel [(set (match_dup 2)
16678                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16679                               UNSPEC_XTRACT_FRACT))
16680               (set (match_operand:XF 3 "register_operand" "")
16681                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16682    (parallel [(set (match_operand:SI 0 "register_operand" "")
16683                    (fix:SI (match_dup 3)))
16684               (clobber (reg:CC FLAGS_REG))])]
16685   "TARGET_USE_FANCY_MATH_387
16686    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16687    && flag_unsafe_math_optimizations && !optimize_size"
16688 {
16689   operands[2] = gen_reg_rtx (XFmode);
16690   operands[3] = gen_reg_rtx (XFmode);
16691 })
16692
16693 (define_insn "*f2xm1xf2"
16694   [(set (match_operand:XF 0 "register_operand" "=f")
16695         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16696          UNSPEC_F2XM1))]
16697   "TARGET_USE_FANCY_MATH_387
16698    && flag_unsafe_math_optimizations"
16699   "f2xm1"
16700   [(set_attr "type" "fpspc")
16701    (set_attr "mode" "XF")])
16702
16703 (define_insn "*fscalexf4"
16704   [(set (match_operand:XF 0 "register_operand" "=f")
16705         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16706                     (match_operand:XF 3 "register_operand" "1")]
16707                    UNSPEC_FSCALE_FRACT))
16708    (set (match_operand:XF 1 "register_operand" "=u")
16709         (unspec:XF [(match_dup 2) (match_dup 3)]
16710                    UNSPEC_FSCALE_EXP))]
16711   "TARGET_USE_FANCY_MATH_387
16712    && flag_unsafe_math_optimizations"
16713   "fscale"
16714   [(set_attr "type" "fpspc")
16715    (set_attr "mode" "XF")])
16716
16717 (define_expand "expsf2"
16718   [(set (match_dup 2)
16719         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16720    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16721    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16722    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16723    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16724    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16725    (parallel [(set (match_dup 10)
16726                    (unspec:XF [(match_dup 9) (match_dup 5)]
16727                               UNSPEC_FSCALE_FRACT))
16728               (set (match_dup 11)
16729                    (unspec:XF [(match_dup 9) (match_dup 5)]
16730                               UNSPEC_FSCALE_EXP))])
16731    (set (match_operand:SF 0 "register_operand" "")
16732         (float_truncate:SF (match_dup 10)))]
16733   "TARGET_USE_FANCY_MATH_387
16734    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16735    && flag_unsafe_math_optimizations && !optimize_size"
16736 {
16737   rtx temp;
16738   int i;
16739
16740   for (i=2; i<12; i++)
16741     operands[i] = gen_reg_rtx (XFmode);
16742   temp = standard_80387_constant_rtx (5); /* fldl2e */
16743   emit_move_insn (operands[3], temp);
16744   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16745 })
16746
16747 (define_expand "expdf2"
16748   [(set (match_dup 2)
16749         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16750    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16751    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16752    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16753    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16754    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16755    (parallel [(set (match_dup 10)
16756                    (unspec:XF [(match_dup 9) (match_dup 5)]
16757                               UNSPEC_FSCALE_FRACT))
16758               (set (match_dup 11)
16759                    (unspec:XF [(match_dup 9) (match_dup 5)]
16760                               UNSPEC_FSCALE_EXP))])
16761    (set (match_operand:DF 0 "register_operand" "")
16762         (float_truncate:DF (match_dup 10)))]
16763   "TARGET_USE_FANCY_MATH_387
16764    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16765    && flag_unsafe_math_optimizations && !optimize_size"
16766 {
16767   rtx temp;
16768   int i;
16769
16770   for (i=2; i<12; i++)
16771     operands[i] = gen_reg_rtx (XFmode);
16772   temp = standard_80387_constant_rtx (5); /* fldl2e */
16773   emit_move_insn (operands[3], temp);
16774   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16775 })
16776
16777 (define_expand "expxf2"
16778   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16779                                (match_dup 2)))
16780    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16781    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16782    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16783    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16784    (parallel [(set (match_operand:XF 0 "register_operand" "")
16785                    (unspec:XF [(match_dup 8) (match_dup 4)]
16786                               UNSPEC_FSCALE_FRACT))
16787               (set (match_dup 9)
16788                    (unspec:XF [(match_dup 8) (match_dup 4)]
16789                               UNSPEC_FSCALE_EXP))])]
16790   "TARGET_USE_FANCY_MATH_387
16791    && flag_unsafe_math_optimizations && !optimize_size"
16792 {
16793   rtx temp;
16794   int i;
16795
16796   for (i=2; i<10; i++)
16797     operands[i] = gen_reg_rtx (XFmode);
16798   temp = standard_80387_constant_rtx (5); /* fldl2e */
16799   emit_move_insn (operands[2], temp);
16800   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16801 })
16802
16803 (define_expand "exp10sf2"
16804   [(set (match_dup 2)
16805         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16806    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16807    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16808    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16809    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16810    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16811    (parallel [(set (match_dup 10)
16812                    (unspec:XF [(match_dup 9) (match_dup 5)]
16813                               UNSPEC_FSCALE_FRACT))
16814               (set (match_dup 11)
16815                    (unspec:XF [(match_dup 9) (match_dup 5)]
16816                               UNSPEC_FSCALE_EXP))])
16817    (set (match_operand:SF 0 "register_operand" "")
16818         (float_truncate:SF (match_dup 10)))]
16819   "TARGET_USE_FANCY_MATH_387
16820    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16821    && flag_unsafe_math_optimizations && !optimize_size"
16822 {
16823   rtx temp;
16824   int i;
16825
16826   for (i=2; i<12; i++)
16827     operands[i] = gen_reg_rtx (XFmode);
16828   temp = standard_80387_constant_rtx (6); /* fldl2t */
16829   emit_move_insn (operands[3], temp);
16830   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16831 })
16832
16833 (define_expand "exp10df2"
16834   [(set (match_dup 2)
16835         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16836    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16837    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16838    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16839    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16840    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16841    (parallel [(set (match_dup 10)
16842                    (unspec:XF [(match_dup 9) (match_dup 5)]
16843                               UNSPEC_FSCALE_FRACT))
16844               (set (match_dup 11)
16845                    (unspec:XF [(match_dup 9) (match_dup 5)]
16846                               UNSPEC_FSCALE_EXP))])
16847    (set (match_operand:DF 0 "register_operand" "")
16848         (float_truncate:DF (match_dup 10)))]
16849   "TARGET_USE_FANCY_MATH_387
16850    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16851    && flag_unsafe_math_optimizations && !optimize_size"
16852 {
16853   rtx temp;
16854   int i;
16855
16856   for (i=2; i<12; i++)
16857     operands[i] = gen_reg_rtx (XFmode);
16858   temp = standard_80387_constant_rtx (6); /* fldl2t */
16859   emit_move_insn (operands[3], temp);
16860   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16861 })
16862
16863 (define_expand "exp10xf2"
16864   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16865                                (match_dup 2)))
16866    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16867    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16868    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16869    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16870    (parallel [(set (match_operand:XF 0 "register_operand" "")
16871                    (unspec:XF [(match_dup 8) (match_dup 4)]
16872                               UNSPEC_FSCALE_FRACT))
16873               (set (match_dup 9)
16874                    (unspec:XF [(match_dup 8) (match_dup 4)]
16875                               UNSPEC_FSCALE_EXP))])]
16876   "TARGET_USE_FANCY_MATH_387
16877    && flag_unsafe_math_optimizations && !optimize_size"
16878 {
16879   rtx temp;
16880   int i;
16881
16882   for (i=2; i<10; i++)
16883     operands[i] = gen_reg_rtx (XFmode);
16884   temp = standard_80387_constant_rtx (6); /* fldl2t */
16885   emit_move_insn (operands[2], temp);
16886   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16887 })
16888
16889 (define_expand "exp2sf2"
16890   [(set (match_dup 2)
16891         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16892    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16893    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16894    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16895    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16896    (parallel [(set (match_dup 8)
16897                    (unspec:XF [(match_dup 7) (match_dup 3)]
16898                               UNSPEC_FSCALE_FRACT))
16899               (set (match_dup 9)
16900                    (unspec:XF [(match_dup 7) (match_dup 3)]
16901                               UNSPEC_FSCALE_EXP))])
16902    (set (match_operand:SF 0 "register_operand" "")
16903         (float_truncate:SF (match_dup 8)))]
16904   "TARGET_USE_FANCY_MATH_387
16905    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16906    && flag_unsafe_math_optimizations && !optimize_size"
16907 {
16908   int i;
16909
16910   for (i=2; i<10; i++)
16911     operands[i] = gen_reg_rtx (XFmode);
16912   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16913 })
16914
16915 (define_expand "exp2df2"
16916   [(set (match_dup 2)
16917         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16918    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16919    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16920    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16921    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16922    (parallel [(set (match_dup 8)
16923                    (unspec:XF [(match_dup 7) (match_dup 3)]
16924                               UNSPEC_FSCALE_FRACT))
16925               (set (match_dup 9)
16926                    (unspec:XF [(match_dup 7) (match_dup 3)]
16927                               UNSPEC_FSCALE_EXP))])
16928    (set (match_operand:DF 0 "register_operand" "")
16929         (float_truncate:DF (match_dup 8)))]
16930   "TARGET_USE_FANCY_MATH_387
16931    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16932    && flag_unsafe_math_optimizations && !optimize_size"
16933 {
16934   int i;
16935
16936   for (i=2; i<10; i++)
16937     operands[i] = gen_reg_rtx (XFmode);
16938   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16939 })
16940
16941 (define_expand "exp2xf2"
16942   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16943    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16944    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16945    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16946    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16947    (parallel [(set (match_operand:XF 0 "register_operand" "")
16948                    (unspec:XF [(match_dup 7) (match_dup 3)]
16949                               UNSPEC_FSCALE_FRACT))
16950               (set (match_dup 8)
16951                    (unspec:XF [(match_dup 7) (match_dup 3)]
16952                               UNSPEC_FSCALE_EXP))])]
16953   "TARGET_USE_FANCY_MATH_387
16954    && flag_unsafe_math_optimizations && !optimize_size"
16955 {
16956   int i;
16957
16958   for (i=2; i<9; i++)
16959     operands[i] = gen_reg_rtx (XFmode);
16960   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16961 })
16962
16963 (define_expand "expm1df2"
16964   [(set (match_dup 2)
16965         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16966    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16967    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16968    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16969    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16970    (parallel [(set (match_dup 8)
16971                    (unspec:XF [(match_dup 7) (match_dup 5)]
16972                               UNSPEC_FSCALE_FRACT))
16973                    (set (match_dup 9)
16974                    (unspec:XF [(match_dup 7) (match_dup 5)]
16975                               UNSPEC_FSCALE_EXP))])
16976    (parallel [(set (match_dup 11)
16977                    (unspec:XF [(match_dup 10) (match_dup 9)]
16978                               UNSPEC_FSCALE_FRACT))
16979               (set (match_dup 12)
16980                    (unspec:XF [(match_dup 10) (match_dup 9)]
16981                               UNSPEC_FSCALE_EXP))])
16982    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16983    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16984    (set (match_operand:DF 0 "register_operand" "")
16985         (float_truncate:DF (match_dup 14)))]
16986   "TARGET_USE_FANCY_MATH_387
16987    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16988    && flag_unsafe_math_optimizations && !optimize_size"
16989 {
16990   rtx temp;
16991   int i;
16992
16993   for (i=2; i<15; i++)
16994     operands[i] = gen_reg_rtx (XFmode);
16995   temp = standard_80387_constant_rtx (5); /* fldl2e */
16996   emit_move_insn (operands[3], temp);
16997   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16998 })
16999
17000 (define_expand "expm1sf2"
17001   [(set (match_dup 2)
17002         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17003    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17004    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17005    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17006    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17007    (parallel [(set (match_dup 8)
17008                    (unspec:XF [(match_dup 7) (match_dup 5)]
17009                               UNSPEC_FSCALE_FRACT))
17010                    (set (match_dup 9)
17011                    (unspec:XF [(match_dup 7) (match_dup 5)]
17012                               UNSPEC_FSCALE_EXP))])
17013    (parallel [(set (match_dup 11)
17014                    (unspec:XF [(match_dup 10) (match_dup 9)]
17015                               UNSPEC_FSCALE_FRACT))
17016               (set (match_dup 12)
17017                    (unspec:XF [(match_dup 10) (match_dup 9)]
17018                               UNSPEC_FSCALE_EXP))])
17019    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17020    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17021    (set (match_operand:SF 0 "register_operand" "")
17022         (float_truncate:SF (match_dup 14)))]
17023   "TARGET_USE_FANCY_MATH_387
17024    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17025    && flag_unsafe_math_optimizations && !optimize_size"
17026 {
17027   rtx temp;
17028   int i;
17029
17030   for (i=2; i<15; 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[10], CONST1_RTX (XFmode));  /* fld1 */
17035 })
17036
17037 (define_expand "expm1xf2"
17038   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17039                                (match_dup 2)))
17040    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17041    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17042    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17043    (parallel [(set (match_dup 7)
17044                    (unspec:XF [(match_dup 6) (match_dup 4)]
17045                               UNSPEC_FSCALE_FRACT))
17046                    (set (match_dup 8)
17047                    (unspec:XF [(match_dup 6) (match_dup 4)]
17048                               UNSPEC_FSCALE_EXP))])
17049    (parallel [(set (match_dup 10)
17050                    (unspec:XF [(match_dup 9) (match_dup 8)]
17051                               UNSPEC_FSCALE_FRACT))
17052               (set (match_dup 11)
17053                    (unspec:XF [(match_dup 9) (match_dup 8)]
17054                               UNSPEC_FSCALE_EXP))])
17055    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17056    (set (match_operand:XF 0 "register_operand" "")
17057         (plus:XF (match_dup 12) (match_dup 7)))]
17058   "TARGET_USE_FANCY_MATH_387
17059    && flag_unsafe_math_optimizations && !optimize_size"
17060 {
17061   rtx temp;
17062   int i;
17063
17064   for (i=2; i<13; i++)
17065     operands[i] = gen_reg_rtx (XFmode);
17066   temp = standard_80387_constant_rtx (5); /* fldl2e */
17067   emit_move_insn (operands[2], temp);
17068   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17069 })
17070
17071 (define_expand "ldexpdf3"
17072   [(set (match_dup 3)
17073         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17074    (set (match_dup 4)
17075         (float:XF (match_operand:SI 2 "register_operand" "")))
17076    (parallel [(set (match_dup 5)
17077                    (unspec:XF [(match_dup 3) (match_dup 4)]
17078                               UNSPEC_FSCALE_FRACT))
17079               (set (match_dup 6)
17080                    (unspec:XF [(match_dup 3) (match_dup 4)]
17081                               UNSPEC_FSCALE_EXP))])
17082    (set (match_operand:DF 0 "register_operand" "")
17083         (float_truncate:DF (match_dup 5)))]
17084   "TARGET_USE_FANCY_MATH_387
17085    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17086    && flag_unsafe_math_optimizations && !optimize_size"
17087 {
17088   int i;
17089
17090   for (i=3; i<7; i++)
17091     operands[i] = gen_reg_rtx (XFmode);
17092 })
17093
17094 (define_expand "ldexpsf3"
17095   [(set (match_dup 3)
17096         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17097    (set (match_dup 4)
17098         (float:XF (match_operand:SI 2 "register_operand" "")))
17099    (parallel [(set (match_dup 5)
17100                    (unspec:XF [(match_dup 3) (match_dup 4)]
17101                               UNSPEC_FSCALE_FRACT))
17102               (set (match_dup 6)
17103                    (unspec:XF [(match_dup 3) (match_dup 4)]
17104                               UNSPEC_FSCALE_EXP))])
17105    (set (match_operand:SF 0 "register_operand" "")
17106         (float_truncate:SF (match_dup 5)))]
17107   "TARGET_USE_FANCY_MATH_387
17108    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17109    && flag_unsafe_math_optimizations && !optimize_size"
17110 {
17111   int i;
17112
17113   for (i=3; i<7; i++)
17114     operands[i] = gen_reg_rtx (XFmode);
17115 })
17116
17117 (define_expand "ldexpxf3"
17118   [(set (match_dup 3)
17119         (float:XF (match_operand:SI 2 "register_operand" "")))
17120    (parallel [(set (match_operand:XF 0 " register_operand" "")
17121                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17122                                (match_dup 3)]
17123                               UNSPEC_FSCALE_FRACT))
17124               (set (match_dup 4)
17125                    (unspec:XF [(match_dup 1) (match_dup 3)]
17126                               UNSPEC_FSCALE_EXP))])]
17127   "TARGET_USE_FANCY_MATH_387
17128    && flag_unsafe_math_optimizations && !optimize_size"
17129 {
17130   int i;
17131
17132   for (i=3; i<5; i++)
17133     operands[i] = gen_reg_rtx (XFmode);
17134 })
17135 \f
17136
17137 (define_insn "frndintxf2"
17138   [(set (match_operand:XF 0 "register_operand" "=f")
17139         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17140          UNSPEC_FRNDINT))]
17141   "TARGET_USE_FANCY_MATH_387
17142    && flag_unsafe_math_optimizations"
17143   "frndint"
17144   [(set_attr "type" "fpspc")
17145    (set_attr "mode" "XF")])
17146
17147 (define_expand "rintdf2"
17148   [(use (match_operand:DF 0 "register_operand" ""))
17149    (use (match_operand:DF 1 "register_operand" ""))]
17150   "(TARGET_USE_FANCY_MATH_387
17151     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17152     && flag_unsafe_math_optimizations)
17153    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17154        && !flag_trapping_math
17155        && !optimize_size)"
17156 {
17157   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17158       && !flag_trapping_math
17159       && !optimize_size)
17160     ix86_expand_rint (operand0, operand1);
17161   else
17162     {
17163       rtx op0 = gen_reg_rtx (XFmode);
17164       rtx op1 = gen_reg_rtx (XFmode);
17165
17166       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17167       emit_insn (gen_frndintxf2 (op0, op1));
17168
17169       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17170     }
17171   DONE;
17172 })
17173
17174 (define_expand "rintsf2"
17175   [(use (match_operand:SF 0 "register_operand" ""))
17176    (use (match_operand:SF 1 "register_operand" ""))]
17177   "(TARGET_USE_FANCY_MATH_387
17178     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17179     && flag_unsafe_math_optimizations)
17180    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17181        && !flag_trapping_math
17182        && !optimize_size)"
17183 {
17184   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17185       && !flag_trapping_math
17186       && !optimize_size)
17187     ix86_expand_rint (operand0, operand1);
17188   else
17189     {
17190       rtx op0 = gen_reg_rtx (XFmode);
17191       rtx op1 = gen_reg_rtx (XFmode);
17192
17193       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17194       emit_insn (gen_frndintxf2 (op0, op1));
17195
17196       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17197     }
17198   DONE;
17199 })
17200
17201 (define_expand "rintxf2"
17202   [(use (match_operand:XF 0 "register_operand" ""))
17203    (use (match_operand:XF 1 "register_operand" ""))]
17204   "TARGET_USE_FANCY_MATH_387
17205    && flag_unsafe_math_optimizations && !optimize_size"
17206 {
17207   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17208   DONE;
17209 })
17210
17211 (define_expand "roundsf2"
17212   [(match_operand:SF 0 "register_operand" "")
17213    (match_operand:SF 1 "nonimmediate_operand" "")]
17214   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17215    && !flag_trapping_math && !flag_rounding_math
17216    && !optimize_size"
17217 {
17218   ix86_expand_round (operand0, operand1);
17219   DONE;
17220 })
17221
17222 (define_expand "rounddf2"
17223   [(match_operand:DF 0 "register_operand" "")
17224    (match_operand:DF 1 "nonimmediate_operand" "")]
17225   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17226    && !flag_trapping_math && !flag_rounding_math
17227    && !optimize_size"
17228 {
17229   if (TARGET_64BIT)
17230     ix86_expand_round (operand0, operand1);
17231   else
17232     ix86_expand_rounddf_32 (operand0, operand1);
17233   DONE;
17234 })
17235
17236 (define_insn_and_split "*fistdi2_1"
17237   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17238         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17239          UNSPEC_FIST))]
17240   "TARGET_USE_FANCY_MATH_387
17241    && !(reload_completed || reload_in_progress)"
17242   "#"
17243   "&& 1"
17244   [(const_int 0)]
17245 {
17246   if (memory_operand (operands[0], VOIDmode))
17247     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17248   else
17249     {
17250       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17251       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17252                                          operands[2]));
17253     }
17254   DONE;
17255 }
17256   [(set_attr "type" "fpspc")
17257    (set_attr "mode" "DI")])
17258
17259 (define_insn "fistdi2"
17260   [(set (match_operand:DI 0 "memory_operand" "=m")
17261         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17262          UNSPEC_FIST))
17263    (clobber (match_scratch:XF 2 "=&1f"))]
17264   "TARGET_USE_FANCY_MATH_387"
17265   "* return output_fix_trunc (insn, operands, 0);"
17266   [(set_attr "type" "fpspc")
17267    (set_attr "mode" "DI")])
17268
17269 (define_insn "fistdi2_with_temp"
17270   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17271         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17272          UNSPEC_FIST))
17273    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17274    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17275   "TARGET_USE_FANCY_MATH_387"
17276   "#"
17277   [(set_attr "type" "fpspc")
17278    (set_attr "mode" "DI")])
17279
17280 (define_split
17281   [(set (match_operand:DI 0 "register_operand" "")
17282         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17283          UNSPEC_FIST))
17284    (clobber (match_operand:DI 2 "memory_operand" ""))
17285    (clobber (match_scratch 3 ""))]
17286   "reload_completed"
17287   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17288               (clobber (match_dup 3))])
17289    (set (match_dup 0) (match_dup 2))]
17290   "")
17291
17292 (define_split
17293   [(set (match_operand:DI 0 "memory_operand" "")
17294         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17295          UNSPEC_FIST))
17296    (clobber (match_operand:DI 2 "memory_operand" ""))
17297    (clobber (match_scratch 3 ""))]
17298   "reload_completed"
17299   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17300               (clobber (match_dup 3))])]
17301   "")
17302
17303 (define_insn_and_split "*fist<mode>2_1"
17304   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17305         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17306          UNSPEC_FIST))]
17307   "TARGET_USE_FANCY_MATH_387
17308    && !(reload_completed || reload_in_progress)"
17309   "#"
17310   "&& 1"
17311   [(const_int 0)]
17312 {
17313   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17314   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17315                                         operands[2]));
17316   DONE;
17317 }
17318   [(set_attr "type" "fpspc")
17319    (set_attr "mode" "<MODE>")])
17320
17321 (define_insn "fist<mode>2"
17322   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17323         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17324          UNSPEC_FIST))]
17325   "TARGET_USE_FANCY_MATH_387"
17326   "* return output_fix_trunc (insn, operands, 0);"
17327   [(set_attr "type" "fpspc")
17328    (set_attr "mode" "<MODE>")])
17329
17330 (define_insn "fist<mode>2_with_temp"
17331   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17332         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17333          UNSPEC_FIST))
17334    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17335   "TARGET_USE_FANCY_MATH_387"
17336   "#"
17337   [(set_attr "type" "fpspc")
17338    (set_attr "mode" "<MODE>")])
17339
17340 (define_split
17341   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17342         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17343          UNSPEC_FIST))
17344    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17345   "reload_completed"
17346   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17347                        UNSPEC_FIST))
17348    (set (match_dup 0) (match_dup 2))]
17349   "")
17350
17351 (define_split
17352   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17353         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17354          UNSPEC_FIST))
17355    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17356   "reload_completed"
17357   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17358                        UNSPEC_FIST))]
17359   "")
17360
17361 (define_expand "lrintxf<mode>2"
17362   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17363      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17364       UNSPEC_FIST))]
17365   "TARGET_USE_FANCY_MATH_387"
17366   "")
17367
17368 (define_expand "lrint<mode>di2"
17369   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17370      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17371       UNSPEC_FIX_NOTRUNC))]
17372   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17373   "")
17374
17375 (define_expand "lrint<mode>si2"
17376   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17377      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17378       UNSPEC_FIX_NOTRUNC))]
17379   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17380   "")
17381
17382 (define_expand "lround<mode>di2"
17383   [(match_operand:DI 0 "nonimmediate_operand" "")
17384    (match_operand:SSEMODEF 1 "register_operand" "")]
17385   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17386    && !flag_trapping_math && !flag_rounding_math
17387    && !optimize_size"
17388 {
17389   ix86_expand_lround (operand0, operand1);
17390   DONE;
17391 })
17392
17393 (define_expand "lround<mode>si2"
17394   [(match_operand:SI 0 "nonimmediate_operand" "")
17395    (match_operand:SSEMODEF 1 "register_operand" "")]
17396   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17397    && !flag_trapping_math && !flag_rounding_math
17398    && !optimize_size"
17399 {
17400   ix86_expand_lround (operand0, operand1);
17401   DONE;
17402 })
17403
17404 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17405 (define_insn_and_split "frndintxf2_floor"
17406   [(set (match_operand:XF 0 "register_operand" "=f")
17407         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17408          UNSPEC_FRNDINT_FLOOR))
17409    (clobber (reg:CC FLAGS_REG))]
17410   "TARGET_USE_FANCY_MATH_387
17411    && flag_unsafe_math_optimizations
17412    && !(reload_completed || reload_in_progress)"
17413   "#"
17414   "&& 1"
17415   [(const_int 0)]
17416 {
17417   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17418
17419   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17420   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17421
17422   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17423                                         operands[2], operands[3]));
17424   DONE;
17425 }
17426   [(set_attr "type" "frndint")
17427    (set_attr "i387_cw" "floor")
17428    (set_attr "mode" "XF")])
17429
17430 (define_insn "frndintxf2_floor_i387"
17431   [(set (match_operand:XF 0 "register_operand" "=f")
17432         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17433          UNSPEC_FRNDINT_FLOOR))
17434    (use (match_operand:HI 2 "memory_operand" "m"))
17435    (use (match_operand:HI 3 "memory_operand" "m"))]
17436   "TARGET_USE_FANCY_MATH_387
17437    && flag_unsafe_math_optimizations"
17438   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17439   [(set_attr "type" "frndint")
17440    (set_attr "i387_cw" "floor")
17441    (set_attr "mode" "XF")])
17442
17443 (define_expand "floorxf2"
17444   [(use (match_operand:XF 0 "register_operand" ""))
17445    (use (match_operand:XF 1 "register_operand" ""))]
17446   "TARGET_USE_FANCY_MATH_387
17447    && flag_unsafe_math_optimizations && !optimize_size"
17448 {
17449   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17450   DONE;
17451 })
17452
17453 (define_expand "floordf2"
17454   [(use (match_operand:DF 0 "register_operand" ""))
17455    (use (match_operand:DF 1 "register_operand" ""))]
17456   "((TARGET_USE_FANCY_MATH_387
17457      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17458      && flag_unsafe_math_optimizations)
17459     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17460         && !flag_trapping_math))
17461    && !optimize_size"
17462 {
17463   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17464       && !flag_trapping_math)
17465     {
17466       if (TARGET_64BIT)
17467         ix86_expand_floorceil (operand0, operand1, true);
17468       else
17469         ix86_expand_floorceildf_32 (operand0, operand1, true);
17470     }
17471   else
17472     {
17473       rtx op0 = gen_reg_rtx (XFmode);
17474       rtx op1 = gen_reg_rtx (XFmode);
17475
17476       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17477       emit_insn (gen_frndintxf2_floor (op0, op1));
17478
17479       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17480     }
17481   DONE;
17482 })
17483
17484 (define_expand "floorsf2"
17485   [(use (match_operand:SF 0 "register_operand" ""))
17486    (use (match_operand:SF 1 "register_operand" ""))]
17487   "((TARGET_USE_FANCY_MATH_387
17488      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17489      && flag_unsafe_math_optimizations)
17490     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17491         && !flag_trapping_math))
17492    && !optimize_size"
17493 {
17494   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17495       && !flag_trapping_math)
17496     ix86_expand_floorceil (operand0, operand1, true);
17497   else
17498     {
17499       rtx op0 = gen_reg_rtx (XFmode);
17500       rtx op1 = gen_reg_rtx (XFmode);
17501
17502       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17503       emit_insn (gen_frndintxf2_floor (op0, op1));
17504
17505       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17506     }
17507   DONE;
17508 })
17509
17510 (define_insn_and_split "*fist<mode>2_floor_1"
17511   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17512         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17513          UNSPEC_FIST_FLOOR))
17514    (clobber (reg:CC FLAGS_REG))]
17515   "TARGET_USE_FANCY_MATH_387
17516    && flag_unsafe_math_optimizations
17517    && !(reload_completed || reload_in_progress)"
17518   "#"
17519   "&& 1"
17520   [(const_int 0)]
17521 {
17522   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17523
17524   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17525   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17526   if (memory_operand (operands[0], VOIDmode))
17527     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17528                                       operands[2], operands[3]));
17529   else
17530     {
17531       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17532       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17533                                                   operands[2], operands[3],
17534                                                   operands[4]));
17535     }
17536   DONE;
17537 }
17538   [(set_attr "type" "fistp")
17539    (set_attr "i387_cw" "floor")
17540    (set_attr "mode" "<MODE>")])
17541
17542 (define_insn "fistdi2_floor"
17543   [(set (match_operand:DI 0 "memory_operand" "=m")
17544         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17545          UNSPEC_FIST_FLOOR))
17546    (use (match_operand:HI 2 "memory_operand" "m"))
17547    (use (match_operand:HI 3 "memory_operand" "m"))
17548    (clobber (match_scratch:XF 4 "=&1f"))]
17549   "TARGET_USE_FANCY_MATH_387
17550    && flag_unsafe_math_optimizations"
17551   "* return output_fix_trunc (insn, operands, 0);"
17552   [(set_attr "type" "fistp")
17553    (set_attr "i387_cw" "floor")
17554    (set_attr "mode" "DI")])
17555
17556 (define_insn "fistdi2_floor_with_temp"
17557   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17558         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17559          UNSPEC_FIST_FLOOR))
17560    (use (match_operand:HI 2 "memory_operand" "m,m"))
17561    (use (match_operand:HI 3 "memory_operand" "m,m"))
17562    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17563    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17564   "TARGET_USE_FANCY_MATH_387
17565    && flag_unsafe_math_optimizations"
17566   "#"
17567   [(set_attr "type" "fistp")
17568    (set_attr "i387_cw" "floor")
17569    (set_attr "mode" "DI")])
17570
17571 (define_split
17572   [(set (match_operand:DI 0 "register_operand" "")
17573         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17574          UNSPEC_FIST_FLOOR))
17575    (use (match_operand:HI 2 "memory_operand" ""))
17576    (use (match_operand:HI 3 "memory_operand" ""))
17577    (clobber (match_operand:DI 4 "memory_operand" ""))
17578    (clobber (match_scratch 5 ""))]
17579   "reload_completed"
17580   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17581               (use (match_dup 2))
17582               (use (match_dup 3))
17583               (clobber (match_dup 5))])
17584    (set (match_dup 0) (match_dup 4))]
17585   "")
17586
17587 (define_split
17588   [(set (match_operand:DI 0 "memory_operand" "")
17589         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17590          UNSPEC_FIST_FLOOR))
17591    (use (match_operand:HI 2 "memory_operand" ""))
17592    (use (match_operand:HI 3 "memory_operand" ""))
17593    (clobber (match_operand:DI 4 "memory_operand" ""))
17594    (clobber (match_scratch 5 ""))]
17595   "reload_completed"
17596   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17597               (use (match_dup 2))
17598               (use (match_dup 3))
17599               (clobber (match_dup 5))])]
17600   "")
17601
17602 (define_insn "fist<mode>2_floor"
17603   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17604         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17605          UNSPEC_FIST_FLOOR))
17606    (use (match_operand:HI 2 "memory_operand" "m"))
17607    (use (match_operand:HI 3 "memory_operand" "m"))]
17608   "TARGET_USE_FANCY_MATH_387
17609    && flag_unsafe_math_optimizations"
17610   "* return output_fix_trunc (insn, operands, 0);"
17611   [(set_attr "type" "fistp")
17612    (set_attr "i387_cw" "floor")
17613    (set_attr "mode" "<MODE>")])
17614
17615 (define_insn "fist<mode>2_floor_with_temp"
17616   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17617         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17618          UNSPEC_FIST_FLOOR))
17619    (use (match_operand:HI 2 "memory_operand" "m,m"))
17620    (use (match_operand:HI 3 "memory_operand" "m,m"))
17621    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17622   "TARGET_USE_FANCY_MATH_387
17623    && flag_unsafe_math_optimizations"
17624   "#"
17625   [(set_attr "type" "fistp")
17626    (set_attr "i387_cw" "floor")
17627    (set_attr "mode" "<MODE>")])
17628
17629 (define_split
17630   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17631         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17632          UNSPEC_FIST_FLOOR))
17633    (use (match_operand:HI 2 "memory_operand" ""))
17634    (use (match_operand:HI 3 "memory_operand" ""))
17635    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17636   "reload_completed"
17637   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17638                                   UNSPEC_FIST_FLOOR))
17639               (use (match_dup 2))
17640               (use (match_dup 3))])
17641    (set (match_dup 0) (match_dup 4))]
17642   "")
17643
17644 (define_split
17645   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17646         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17647          UNSPEC_FIST_FLOOR))
17648    (use (match_operand:HI 2 "memory_operand" ""))
17649    (use (match_operand:HI 3 "memory_operand" ""))
17650    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17651   "reload_completed"
17652   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17653                                   UNSPEC_FIST_FLOOR))
17654               (use (match_dup 2))
17655               (use (match_dup 3))])]
17656   "")
17657
17658 (define_expand "lfloorxf<mode>2"
17659   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17660                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17661                     UNSPEC_FIST_FLOOR))
17662               (clobber (reg:CC FLAGS_REG))])]
17663   "TARGET_USE_FANCY_MATH_387
17664    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17665    && flag_unsafe_math_optimizations"
17666   "")
17667
17668 (define_expand "lfloor<mode>di2"
17669   [(match_operand:DI 0 "nonimmediate_operand" "")
17670    (match_operand:SSEMODEF 1 "register_operand" "")]
17671   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17672    && !flag_trapping_math
17673    && !optimize_size"
17674 {
17675   ix86_expand_lfloorceil (operand0, operand1, true);
17676   DONE;
17677 })
17678
17679 (define_expand "lfloor<mode>si2"
17680   [(match_operand:SI 0 "nonimmediate_operand" "")
17681    (match_operand:SSEMODEF 1 "register_operand" "")]
17682   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17683    && !flag_trapping_math
17684    && (!optimize_size || !TARGET_64BIT)"
17685 {
17686   ix86_expand_lfloorceil (operand0, operand1, true);
17687   DONE;
17688 })
17689
17690 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17691 (define_insn_and_split "frndintxf2_ceil"
17692   [(set (match_operand:XF 0 "register_operand" "=f")
17693         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17694          UNSPEC_FRNDINT_CEIL))
17695    (clobber (reg:CC FLAGS_REG))]
17696   "TARGET_USE_FANCY_MATH_387
17697    && flag_unsafe_math_optimizations
17698    && !(reload_completed || reload_in_progress)"
17699   "#"
17700   "&& 1"
17701   [(const_int 0)]
17702 {
17703   ix86_optimize_mode_switching[I387_CEIL] = 1;
17704
17705   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17706   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17707
17708   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17709                                        operands[2], operands[3]));
17710   DONE;
17711 }
17712   [(set_attr "type" "frndint")
17713    (set_attr "i387_cw" "ceil")
17714    (set_attr "mode" "XF")])
17715
17716 (define_insn "frndintxf2_ceil_i387"
17717   [(set (match_operand:XF 0 "register_operand" "=f")
17718         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17719          UNSPEC_FRNDINT_CEIL))
17720    (use (match_operand:HI 2 "memory_operand" "m"))
17721    (use (match_operand:HI 3 "memory_operand" "m"))]
17722   "TARGET_USE_FANCY_MATH_387
17723    && flag_unsafe_math_optimizations"
17724   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17725   [(set_attr "type" "frndint")
17726    (set_attr "i387_cw" "ceil")
17727    (set_attr "mode" "XF")])
17728
17729 (define_expand "ceilxf2"
17730   [(use (match_operand:XF 0 "register_operand" ""))
17731    (use (match_operand:XF 1 "register_operand" ""))]
17732   "TARGET_USE_FANCY_MATH_387
17733    && flag_unsafe_math_optimizations && !optimize_size"
17734 {
17735   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17736   DONE;
17737 })
17738
17739 (define_expand "ceildf2"
17740   [(use (match_operand:DF 0 "register_operand" ""))
17741    (use (match_operand:DF 1 "register_operand" ""))]
17742   "((TARGET_USE_FANCY_MATH_387
17743      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17744      && flag_unsafe_math_optimizations)
17745     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17746         && !flag_trapping_math))
17747    && !optimize_size"
17748 {
17749   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17750       && !flag_trapping_math)
17751     {
17752       if (TARGET_64BIT)
17753         ix86_expand_floorceil (operand0, operand1, false);
17754       else
17755         ix86_expand_floorceildf_32 (operand0, operand1, false);
17756     }
17757   else
17758     {
17759       rtx op0 = gen_reg_rtx (XFmode);
17760       rtx op1 = gen_reg_rtx (XFmode);
17761
17762       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17763       emit_insn (gen_frndintxf2_ceil (op0, op1));
17764
17765       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17766     }
17767   DONE;
17768 })
17769
17770 (define_expand "ceilsf2"
17771   [(use (match_operand:SF 0 "register_operand" ""))
17772    (use (match_operand:SF 1 "register_operand" ""))]
17773   "((TARGET_USE_FANCY_MATH_387
17774      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17775      && flag_unsafe_math_optimizations)
17776     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17777         && !flag_trapping_math))
17778    && !optimize_size"
17779 {
17780   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17781       && !flag_trapping_math)
17782     ix86_expand_floorceil (operand0, operand1, false);
17783   else
17784     {
17785       rtx op0 = gen_reg_rtx (XFmode);
17786       rtx op1 = gen_reg_rtx (XFmode);
17787
17788       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17789       emit_insn (gen_frndintxf2_ceil (op0, op1));
17790
17791       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17792     }
17793   DONE;
17794 })
17795
17796 (define_insn_and_split "*fist<mode>2_ceil_1"
17797   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17798         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17799          UNSPEC_FIST_CEIL))
17800    (clobber (reg:CC FLAGS_REG))]
17801   "TARGET_USE_FANCY_MATH_387
17802    && flag_unsafe_math_optimizations
17803    && !(reload_completed || reload_in_progress)"
17804   "#"
17805   "&& 1"
17806   [(const_int 0)]
17807 {
17808   ix86_optimize_mode_switching[I387_CEIL] = 1;
17809
17810   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17811   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17812   if (memory_operand (operands[0], VOIDmode))
17813     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17814                                      operands[2], operands[3]));
17815   else
17816     {
17817       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17818       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17819                                                  operands[2], operands[3],
17820                                                  operands[4]));
17821     }
17822   DONE;
17823 }
17824   [(set_attr "type" "fistp")
17825    (set_attr "i387_cw" "ceil")
17826    (set_attr "mode" "<MODE>")])
17827
17828 (define_insn "fistdi2_ceil"
17829   [(set (match_operand:DI 0 "memory_operand" "=m")
17830         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17831          UNSPEC_FIST_CEIL))
17832    (use (match_operand:HI 2 "memory_operand" "m"))
17833    (use (match_operand:HI 3 "memory_operand" "m"))
17834    (clobber (match_scratch:XF 4 "=&1f"))]
17835   "TARGET_USE_FANCY_MATH_387
17836    && flag_unsafe_math_optimizations"
17837   "* return output_fix_trunc (insn, operands, 0);"
17838   [(set_attr "type" "fistp")
17839    (set_attr "i387_cw" "ceil")
17840    (set_attr "mode" "DI")])
17841
17842 (define_insn "fistdi2_ceil_with_temp"
17843   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17844         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17845          UNSPEC_FIST_CEIL))
17846    (use (match_operand:HI 2 "memory_operand" "m,m"))
17847    (use (match_operand:HI 3 "memory_operand" "m,m"))
17848    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17849    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17850   "TARGET_USE_FANCY_MATH_387
17851    && flag_unsafe_math_optimizations"
17852   "#"
17853   [(set_attr "type" "fistp")
17854    (set_attr "i387_cw" "ceil")
17855    (set_attr "mode" "DI")])
17856
17857 (define_split
17858   [(set (match_operand:DI 0 "register_operand" "")
17859         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17860          UNSPEC_FIST_CEIL))
17861    (use (match_operand:HI 2 "memory_operand" ""))
17862    (use (match_operand:HI 3 "memory_operand" ""))
17863    (clobber (match_operand:DI 4 "memory_operand" ""))
17864    (clobber (match_scratch 5 ""))]
17865   "reload_completed"
17866   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17867               (use (match_dup 2))
17868               (use (match_dup 3))
17869               (clobber (match_dup 5))])
17870    (set (match_dup 0) (match_dup 4))]
17871   "")
17872
17873 (define_split
17874   [(set (match_operand:DI 0 "memory_operand" "")
17875         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17876          UNSPEC_FIST_CEIL))
17877    (use (match_operand:HI 2 "memory_operand" ""))
17878    (use (match_operand:HI 3 "memory_operand" ""))
17879    (clobber (match_operand:DI 4 "memory_operand" ""))
17880    (clobber (match_scratch 5 ""))]
17881   "reload_completed"
17882   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17883               (use (match_dup 2))
17884               (use (match_dup 3))
17885               (clobber (match_dup 5))])]
17886   "")
17887
17888 (define_insn "fist<mode>2_ceil"
17889   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17890         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17891          UNSPEC_FIST_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   "* return output_fix_trunc (insn, operands, 0);"
17897   [(set_attr "type" "fistp")
17898    (set_attr "i387_cw" "ceil")
17899    (set_attr "mode" "<MODE>")])
17900
17901 (define_insn "fist<mode>2_ceil_with_temp"
17902   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17903         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17904          UNSPEC_FIST_CEIL))
17905    (use (match_operand:HI 2 "memory_operand" "m,m"))
17906    (use (match_operand:HI 3 "memory_operand" "m,m"))
17907    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17908   "TARGET_USE_FANCY_MATH_387
17909    && flag_unsafe_math_optimizations"
17910   "#"
17911   [(set_attr "type" "fistp")
17912    (set_attr "i387_cw" "ceil")
17913    (set_attr "mode" "<MODE>")])
17914
17915 (define_split
17916   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17917         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17918          UNSPEC_FIST_CEIL))
17919    (use (match_operand:HI 2 "memory_operand" ""))
17920    (use (match_operand:HI 3 "memory_operand" ""))
17921    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17922   "reload_completed"
17923   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17924                                   UNSPEC_FIST_CEIL))
17925               (use (match_dup 2))
17926               (use (match_dup 3))])
17927    (set (match_dup 0) (match_dup 4))]
17928   "")
17929
17930 (define_split
17931   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17932         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17933          UNSPEC_FIST_CEIL))
17934    (use (match_operand:HI 2 "memory_operand" ""))
17935    (use (match_operand:HI 3 "memory_operand" ""))
17936    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17937   "reload_completed"
17938   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17939                                   UNSPEC_FIST_CEIL))
17940               (use (match_dup 2))
17941               (use (match_dup 3))])]
17942   "")
17943
17944 (define_expand "lceilxf<mode>2"
17945   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17946                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17947                     UNSPEC_FIST_CEIL))
17948               (clobber (reg:CC FLAGS_REG))])]
17949   "TARGET_USE_FANCY_MATH_387
17950    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17951    && flag_unsafe_math_optimizations"
17952   "")
17953
17954 (define_expand "lceil<mode>di2"
17955   [(match_operand:DI 0 "nonimmediate_operand" "")
17956    (match_operand:SSEMODEF 1 "register_operand" "")]
17957   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17958    && !flag_trapping_math"
17959 {
17960   ix86_expand_lfloorceil (operand0, operand1, false);
17961   DONE;
17962 })
17963
17964 (define_expand "lceil<mode>si2"
17965   [(match_operand:SI 0 "nonimmediate_operand" "")
17966    (match_operand:SSEMODEF 1 "register_operand" "")]
17967   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17968    && !flag_trapping_math"
17969 {
17970   ix86_expand_lfloorceil (operand0, operand1, false);
17971   DONE;
17972 })
17973
17974 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17975 (define_insn_and_split "frndintxf2_trunc"
17976   [(set (match_operand:XF 0 "register_operand" "=f")
17977         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17978          UNSPEC_FRNDINT_TRUNC))
17979    (clobber (reg:CC FLAGS_REG))]
17980   "TARGET_USE_FANCY_MATH_387
17981    && flag_unsafe_math_optimizations
17982    && !(reload_completed || reload_in_progress)"
17983   "#"
17984   "&& 1"
17985   [(const_int 0)]
17986 {
17987   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17988
17989   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17990   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17991
17992   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17993                                         operands[2], operands[3]));
17994   DONE;
17995 }
17996   [(set_attr "type" "frndint")
17997    (set_attr "i387_cw" "trunc")
17998    (set_attr "mode" "XF")])
17999
18000 (define_insn "frndintxf2_trunc_i387"
18001   [(set (match_operand:XF 0 "register_operand" "=f")
18002         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18003          UNSPEC_FRNDINT_TRUNC))
18004    (use (match_operand:HI 2 "memory_operand" "m"))
18005    (use (match_operand:HI 3 "memory_operand" "m"))]
18006   "TARGET_USE_FANCY_MATH_387
18007    && flag_unsafe_math_optimizations"
18008   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18009   [(set_attr "type" "frndint")
18010    (set_attr "i387_cw" "trunc")
18011    (set_attr "mode" "XF")])
18012
18013 (define_expand "btruncxf2"
18014   [(use (match_operand:XF 0 "register_operand" ""))
18015    (use (match_operand:XF 1 "register_operand" ""))]
18016   "TARGET_USE_FANCY_MATH_387
18017    && flag_unsafe_math_optimizations && !optimize_size"
18018 {
18019   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18020   DONE;
18021 })
18022
18023 (define_expand "btruncdf2"
18024   [(use (match_operand:DF 0 "register_operand" ""))
18025    (use (match_operand:DF 1 "register_operand" ""))]
18026   "((TARGET_USE_FANCY_MATH_387
18027      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18028      && flag_unsafe_math_optimizations)
18029     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18030         && !flag_trapping_math))
18031    && !optimize_size"
18032 {
18033   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18034       && !flag_trapping_math)
18035     {
18036       if (TARGET_64BIT)
18037         ix86_expand_trunc (operand0, operand1);
18038       else
18039         ix86_expand_truncdf_32 (operand0, operand1);
18040     }
18041   else
18042     {
18043       rtx op0 = gen_reg_rtx (XFmode);
18044       rtx op1 = gen_reg_rtx (XFmode);
18045
18046       emit_insn (gen_extenddfxf2 (op1, operands[1]));
18047       emit_insn (gen_frndintxf2_trunc (op0, op1));
18048
18049       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18050     }
18051   DONE;
18052 })
18053
18054 (define_expand "btruncsf2"
18055   [(use (match_operand:SF 0 "register_operand" ""))
18056    (use (match_operand:SF 1 "register_operand" ""))]
18057   "((TARGET_USE_FANCY_MATH_387
18058      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18059      && flag_unsafe_math_optimizations)
18060     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18061         && !flag_trapping_math))
18062    && !optimize_size"
18063 {
18064   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18065       && !flag_trapping_math)
18066     ix86_expand_trunc (operand0, operand1);
18067   else
18068     {
18069       rtx op0 = gen_reg_rtx (XFmode);
18070       rtx op1 = gen_reg_rtx (XFmode);
18071
18072       emit_insn (gen_extendsfxf2 (op1, operands[1]));
18073       emit_insn (gen_frndintxf2_trunc (op0, op1));
18074
18075       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18076     }
18077   DONE;
18078 })
18079
18080 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18081 (define_insn_and_split "frndintxf2_mask_pm"
18082   [(set (match_operand:XF 0 "register_operand" "=f")
18083         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18084          UNSPEC_FRNDINT_MASK_PM))
18085    (clobber (reg:CC FLAGS_REG))]
18086   "TARGET_USE_FANCY_MATH_387
18087    && flag_unsafe_math_optimizations
18088    && !(reload_completed || reload_in_progress)"
18089   "#"
18090   "&& 1"
18091   [(const_int 0)]
18092 {
18093   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18094
18095   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18096   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18097
18098   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18099                                           operands[2], operands[3]));
18100   DONE;
18101 }
18102   [(set_attr "type" "frndint")
18103    (set_attr "i387_cw" "mask_pm")
18104    (set_attr "mode" "XF")])
18105
18106 (define_insn "frndintxf2_mask_pm_i387"
18107   [(set (match_operand:XF 0 "register_operand" "=f")
18108         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18109          UNSPEC_FRNDINT_MASK_PM))
18110    (use (match_operand:HI 2 "memory_operand" "m"))
18111    (use (match_operand:HI 3 "memory_operand" "m"))]
18112   "TARGET_USE_FANCY_MATH_387
18113    && flag_unsafe_math_optimizations"
18114   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18115   [(set_attr "type" "frndint")
18116    (set_attr "i387_cw" "mask_pm")
18117    (set_attr "mode" "XF")])
18118
18119 (define_expand "nearbyintxf2"
18120   [(use (match_operand:XF 0 "register_operand" ""))
18121    (use (match_operand:XF 1 "register_operand" ""))]
18122   "TARGET_USE_FANCY_MATH_387
18123    && flag_unsafe_math_optimizations"
18124 {
18125   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18126
18127   DONE;
18128 })
18129
18130 (define_expand "nearbyintdf2"
18131   [(use (match_operand:DF 0 "register_operand" ""))
18132    (use (match_operand:DF 1 "register_operand" ""))]
18133   "TARGET_USE_FANCY_MATH_387
18134    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18135    && flag_unsafe_math_optimizations"
18136 {
18137   rtx op0 = gen_reg_rtx (XFmode);
18138   rtx op1 = gen_reg_rtx (XFmode);
18139
18140   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18141   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18142
18143   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18144   DONE;
18145 })
18146
18147 (define_expand "nearbyintsf2"
18148   [(use (match_operand:SF 0 "register_operand" ""))
18149    (use (match_operand:SF 1 "register_operand" ""))]
18150   "TARGET_USE_FANCY_MATH_387
18151    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18152    && flag_unsafe_math_optimizations"
18153 {
18154   rtx op0 = gen_reg_rtx (XFmode);
18155   rtx op1 = gen_reg_rtx (XFmode);
18156
18157   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18158   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18159
18160   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18161   DONE;
18162 })
18163
18164 \f
18165 ;; Block operation instructions
18166
18167 (define_insn "cld"
18168  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18169  ""
18170  "cld"
18171   [(set_attr "type" "cld")])
18172
18173 (define_expand "movmemsi"
18174   [(use (match_operand:BLK 0 "memory_operand" ""))
18175    (use (match_operand:BLK 1 "memory_operand" ""))
18176    (use (match_operand:SI 2 "nonmemory_operand" ""))
18177    (use (match_operand:SI 3 "const_int_operand" ""))]
18178   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18179 {
18180  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18181    DONE;
18182  else
18183    FAIL;
18184 })
18185
18186 (define_expand "movmemdi"
18187   [(use (match_operand:BLK 0 "memory_operand" ""))
18188    (use (match_operand:BLK 1 "memory_operand" ""))
18189    (use (match_operand:DI 2 "nonmemory_operand" ""))
18190    (use (match_operand:DI 3 "const_int_operand" ""))]
18191   "TARGET_64BIT"
18192 {
18193  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18194    DONE;
18195  else
18196    FAIL;
18197 })
18198
18199 ;; Most CPUs don't like single string operations
18200 ;; Handle this case here to simplify previous expander.
18201
18202 (define_expand "strmov"
18203   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18204    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18205    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18206               (clobber (reg:CC FLAGS_REG))])
18207    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18208               (clobber (reg:CC FLAGS_REG))])]
18209   ""
18210 {
18211   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18212
18213   /* If .md ever supports :P for Pmode, these can be directly
18214      in the pattern above.  */
18215   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18216   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18217
18218   if (TARGET_SINGLE_STRINGOP || optimize_size)
18219     {
18220       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18221                                       operands[2], operands[3],
18222                                       operands[5], operands[6]));
18223       DONE;
18224     }
18225
18226   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18227 })
18228
18229 (define_expand "strmov_singleop"
18230   [(parallel [(set (match_operand 1 "memory_operand" "")
18231                    (match_operand 3 "memory_operand" ""))
18232               (set (match_operand 0 "register_operand" "")
18233                    (match_operand 4 "" ""))
18234               (set (match_operand 2 "register_operand" "")
18235                    (match_operand 5 "" ""))
18236               (use (reg:SI DIRFLAG_REG))])]
18237   "TARGET_SINGLE_STRINGOP || optimize_size"
18238   "")
18239
18240 (define_insn "*strmovdi_rex_1"
18241   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18242         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18243    (set (match_operand:DI 0 "register_operand" "=D")
18244         (plus:DI (match_dup 2)
18245                  (const_int 8)))
18246    (set (match_operand:DI 1 "register_operand" "=S")
18247         (plus:DI (match_dup 3)
18248                  (const_int 8)))
18249    (use (reg:SI DIRFLAG_REG))]
18250   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18251   "movsq"
18252   [(set_attr "type" "str")
18253    (set_attr "mode" "DI")
18254    (set_attr "memory" "both")])
18255
18256 (define_insn "*strmovsi_1"
18257   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18258         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18259    (set (match_operand:SI 0 "register_operand" "=D")
18260         (plus:SI (match_dup 2)
18261                  (const_int 4)))
18262    (set (match_operand:SI 1 "register_operand" "=S")
18263         (plus:SI (match_dup 3)
18264                  (const_int 4)))
18265    (use (reg:SI DIRFLAG_REG))]
18266   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18267   "{movsl|movsd}"
18268   [(set_attr "type" "str")
18269    (set_attr "mode" "SI")
18270    (set_attr "memory" "both")])
18271
18272 (define_insn "*strmovsi_rex_1"
18273   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18274         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18275    (set (match_operand:DI 0 "register_operand" "=D")
18276         (plus:DI (match_dup 2)
18277                  (const_int 4)))
18278    (set (match_operand:DI 1 "register_operand" "=S")
18279         (plus:DI (match_dup 3)
18280                  (const_int 4)))
18281    (use (reg:SI DIRFLAG_REG))]
18282   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18283   "{movsl|movsd}"
18284   [(set_attr "type" "str")
18285    (set_attr "mode" "SI")
18286    (set_attr "memory" "both")])
18287
18288 (define_insn "*strmovhi_1"
18289   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18290         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18291    (set (match_operand:SI 0 "register_operand" "=D")
18292         (plus:SI (match_dup 2)
18293                  (const_int 2)))
18294    (set (match_operand:SI 1 "register_operand" "=S")
18295         (plus:SI (match_dup 3)
18296                  (const_int 2)))
18297    (use (reg:SI DIRFLAG_REG))]
18298   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18299   "movsw"
18300   [(set_attr "type" "str")
18301    (set_attr "memory" "both")
18302    (set_attr "mode" "HI")])
18303
18304 (define_insn "*strmovhi_rex_1"
18305   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18306         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18307    (set (match_operand:DI 0 "register_operand" "=D")
18308         (plus:DI (match_dup 2)
18309                  (const_int 2)))
18310    (set (match_operand:DI 1 "register_operand" "=S")
18311         (plus:DI (match_dup 3)
18312                  (const_int 2)))
18313    (use (reg:SI DIRFLAG_REG))]
18314   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18315   "movsw"
18316   [(set_attr "type" "str")
18317    (set_attr "memory" "both")
18318    (set_attr "mode" "HI")])
18319
18320 (define_insn "*strmovqi_1"
18321   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18322         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18323    (set (match_operand:SI 0 "register_operand" "=D")
18324         (plus:SI (match_dup 2)
18325                  (const_int 1)))
18326    (set (match_operand:SI 1 "register_operand" "=S")
18327         (plus:SI (match_dup 3)
18328                  (const_int 1)))
18329    (use (reg:SI DIRFLAG_REG))]
18330   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18331   "movsb"
18332   [(set_attr "type" "str")
18333    (set_attr "memory" "both")
18334    (set_attr "mode" "QI")])
18335
18336 (define_insn "*strmovqi_rex_1"
18337   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18338         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18339    (set (match_operand:DI 0 "register_operand" "=D")
18340         (plus:DI (match_dup 2)
18341                  (const_int 1)))
18342    (set (match_operand:DI 1 "register_operand" "=S")
18343         (plus:DI (match_dup 3)
18344                  (const_int 1)))
18345    (use (reg:SI DIRFLAG_REG))]
18346   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18347   "movsb"
18348   [(set_attr "type" "str")
18349    (set_attr "memory" "both")
18350    (set_attr "mode" "QI")])
18351
18352 (define_expand "rep_mov"
18353   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18354               (set (match_operand 0 "register_operand" "")
18355                    (match_operand 5 "" ""))
18356               (set (match_operand 2 "register_operand" "")
18357                    (match_operand 6 "" ""))
18358               (set (match_operand 1 "memory_operand" "")
18359                    (match_operand 3 "memory_operand" ""))
18360               (use (match_dup 4))
18361               (use (reg:SI DIRFLAG_REG))])]
18362   ""
18363   "")
18364
18365 (define_insn "*rep_movdi_rex64"
18366   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18367    (set (match_operand:DI 0 "register_operand" "=D")
18368         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18369                             (const_int 3))
18370                  (match_operand:DI 3 "register_operand" "0")))
18371    (set (match_operand:DI 1 "register_operand" "=S")
18372         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18373                  (match_operand:DI 4 "register_operand" "1")))
18374    (set (mem:BLK (match_dup 3))
18375         (mem:BLK (match_dup 4)))
18376    (use (match_dup 5))
18377    (use (reg:SI DIRFLAG_REG))]
18378   "TARGET_64BIT"
18379   "{rep\;movsq|rep movsq}"
18380   [(set_attr "type" "str")
18381    (set_attr "prefix_rep" "1")
18382    (set_attr "memory" "both")
18383    (set_attr "mode" "DI")])
18384
18385 (define_insn "*rep_movsi"
18386   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18387    (set (match_operand:SI 0 "register_operand" "=D")
18388         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18389                             (const_int 2))
18390                  (match_operand:SI 3 "register_operand" "0")))
18391    (set (match_operand:SI 1 "register_operand" "=S")
18392         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18393                  (match_operand:SI 4 "register_operand" "1")))
18394    (set (mem:BLK (match_dup 3))
18395         (mem:BLK (match_dup 4)))
18396    (use (match_dup 5))
18397    (use (reg:SI DIRFLAG_REG))]
18398   "!TARGET_64BIT"
18399   "{rep\;movsl|rep movsd}"
18400   [(set_attr "type" "str")
18401    (set_attr "prefix_rep" "1")
18402    (set_attr "memory" "both")
18403    (set_attr "mode" "SI")])
18404
18405 (define_insn "*rep_movsi_rex64"
18406   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18407    (set (match_operand:DI 0 "register_operand" "=D")
18408         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18409                             (const_int 2))
18410                  (match_operand:DI 3 "register_operand" "0")))
18411    (set (match_operand:DI 1 "register_operand" "=S")
18412         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18413                  (match_operand:DI 4 "register_operand" "1")))
18414    (set (mem:BLK (match_dup 3))
18415         (mem:BLK (match_dup 4)))
18416    (use (match_dup 5))
18417    (use (reg:SI DIRFLAG_REG))]
18418   "TARGET_64BIT"
18419   "{rep\;movsl|rep movsd}"
18420   [(set_attr "type" "str")
18421    (set_attr "prefix_rep" "1")
18422    (set_attr "memory" "both")
18423    (set_attr "mode" "SI")])
18424
18425 (define_insn "*rep_movqi"
18426   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18427    (set (match_operand:SI 0 "register_operand" "=D")
18428         (plus:SI (match_operand:SI 3 "register_operand" "0")
18429                  (match_operand:SI 5 "register_operand" "2")))
18430    (set (match_operand:SI 1 "register_operand" "=S")
18431         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18432    (set (mem:BLK (match_dup 3))
18433         (mem:BLK (match_dup 4)))
18434    (use (match_dup 5))
18435    (use (reg:SI DIRFLAG_REG))]
18436   "!TARGET_64BIT"
18437   "{rep\;movsb|rep movsb}"
18438   [(set_attr "type" "str")
18439    (set_attr "prefix_rep" "1")
18440    (set_attr "memory" "both")
18441    (set_attr "mode" "SI")])
18442
18443 (define_insn "*rep_movqi_rex64"
18444   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18445    (set (match_operand:DI 0 "register_operand" "=D")
18446         (plus:DI (match_operand:DI 3 "register_operand" "0")
18447                  (match_operand:DI 5 "register_operand" "2")))
18448    (set (match_operand:DI 1 "register_operand" "=S")
18449         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18450    (set (mem:BLK (match_dup 3))
18451         (mem:BLK (match_dup 4)))
18452    (use (match_dup 5))
18453    (use (reg:SI DIRFLAG_REG))]
18454   "TARGET_64BIT"
18455   "{rep\;movsb|rep movsb}"
18456   [(set_attr "type" "str")
18457    (set_attr "prefix_rep" "1")
18458    (set_attr "memory" "both")
18459    (set_attr "mode" "SI")])
18460
18461 (define_expand "setmemsi"
18462    [(use (match_operand:BLK 0 "memory_operand" ""))
18463     (use (match_operand:SI 1 "nonmemory_operand" ""))
18464     (use (match_operand 2 "const_int_operand" ""))
18465     (use (match_operand 3 "const_int_operand" ""))]
18466   ""
18467 {
18468  /* If value to set is not zero, use the library routine.  */
18469  if (operands[2] != const0_rtx)
18470    FAIL;
18471
18472  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18473    DONE;
18474  else
18475    FAIL;
18476 })
18477
18478 (define_expand "setmemdi"
18479    [(use (match_operand:BLK 0 "memory_operand" ""))
18480     (use (match_operand:DI 1 "nonmemory_operand" ""))
18481     (use (match_operand 2 "const_int_operand" ""))
18482     (use (match_operand 3 "const_int_operand" ""))]
18483   "TARGET_64BIT"
18484 {
18485  /* If value to set is not zero, use the library routine.  */
18486  if (operands[2] != const0_rtx)
18487    FAIL;
18488
18489  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18490    DONE;
18491  else
18492    FAIL;
18493 })
18494
18495 ;; Most CPUs don't like single string operations
18496 ;; Handle this case here to simplify previous expander.
18497
18498 (define_expand "strset"
18499   [(set (match_operand 1 "memory_operand" "")
18500         (match_operand 2 "register_operand" ""))
18501    (parallel [(set (match_operand 0 "register_operand" "")
18502                    (match_dup 3))
18503               (clobber (reg:CC FLAGS_REG))])]
18504   ""
18505 {
18506   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18507     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18508
18509   /* If .md ever supports :P for Pmode, this can be directly
18510      in the pattern above.  */
18511   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18512                               GEN_INT (GET_MODE_SIZE (GET_MODE
18513                                                       (operands[2]))));
18514   if (TARGET_SINGLE_STRINGOP || optimize_size)
18515     {
18516       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18517                                       operands[3]));
18518       DONE;
18519     }
18520 })
18521
18522 (define_expand "strset_singleop"
18523   [(parallel [(set (match_operand 1 "memory_operand" "")
18524                    (match_operand 2 "register_operand" ""))
18525               (set (match_operand 0 "register_operand" "")
18526                    (match_operand 3 "" ""))
18527               (use (reg:SI DIRFLAG_REG))])]
18528   "TARGET_SINGLE_STRINGOP || optimize_size"
18529   "")
18530
18531 (define_insn "*strsetdi_rex_1"
18532   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18533         (match_operand:DI 2 "register_operand" "a"))
18534    (set (match_operand:DI 0 "register_operand" "=D")
18535         (plus:DI (match_dup 1)
18536                  (const_int 8)))
18537    (use (reg:SI DIRFLAG_REG))]
18538   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18539   "stosq"
18540   [(set_attr "type" "str")
18541    (set_attr "memory" "store")
18542    (set_attr "mode" "DI")])
18543
18544 (define_insn "*strsetsi_1"
18545   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18546         (match_operand:SI 2 "register_operand" "a"))
18547    (set (match_operand:SI 0 "register_operand" "=D")
18548         (plus:SI (match_dup 1)
18549                  (const_int 4)))
18550    (use (reg:SI DIRFLAG_REG))]
18551   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18552   "{stosl|stosd}"
18553   [(set_attr "type" "str")
18554    (set_attr "memory" "store")
18555    (set_attr "mode" "SI")])
18556
18557 (define_insn "*strsetsi_rex_1"
18558   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18559         (match_operand:SI 2 "register_operand" "a"))
18560    (set (match_operand:DI 0 "register_operand" "=D")
18561         (plus:DI (match_dup 1)
18562                  (const_int 4)))
18563    (use (reg:SI DIRFLAG_REG))]
18564   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18565   "{stosl|stosd}"
18566   [(set_attr "type" "str")
18567    (set_attr "memory" "store")
18568    (set_attr "mode" "SI")])
18569
18570 (define_insn "*strsethi_1"
18571   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18572         (match_operand:HI 2 "register_operand" "a"))
18573    (set (match_operand:SI 0 "register_operand" "=D")
18574         (plus:SI (match_dup 1)
18575                  (const_int 2)))
18576    (use (reg:SI DIRFLAG_REG))]
18577   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18578   "stosw"
18579   [(set_attr "type" "str")
18580    (set_attr "memory" "store")
18581    (set_attr "mode" "HI")])
18582
18583 (define_insn "*strsethi_rex_1"
18584   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18585         (match_operand:HI 2 "register_operand" "a"))
18586    (set (match_operand:DI 0 "register_operand" "=D")
18587         (plus:DI (match_dup 1)
18588                  (const_int 2)))
18589    (use (reg:SI DIRFLAG_REG))]
18590   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18591   "stosw"
18592   [(set_attr "type" "str")
18593    (set_attr "memory" "store")
18594    (set_attr "mode" "HI")])
18595
18596 (define_insn "*strsetqi_1"
18597   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18598         (match_operand:QI 2 "register_operand" "a"))
18599    (set (match_operand:SI 0 "register_operand" "=D")
18600         (plus:SI (match_dup 1)
18601                  (const_int 1)))
18602    (use (reg:SI DIRFLAG_REG))]
18603   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18604   "stosb"
18605   [(set_attr "type" "str")
18606    (set_attr "memory" "store")
18607    (set_attr "mode" "QI")])
18608
18609 (define_insn "*strsetqi_rex_1"
18610   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18611         (match_operand:QI 2 "register_operand" "a"))
18612    (set (match_operand:DI 0 "register_operand" "=D")
18613         (plus:DI (match_dup 1)
18614                  (const_int 1)))
18615    (use (reg:SI DIRFLAG_REG))]
18616   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18617   "stosb"
18618   [(set_attr "type" "str")
18619    (set_attr "memory" "store")
18620    (set_attr "mode" "QI")])
18621
18622 (define_expand "rep_stos"
18623   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18624               (set (match_operand 0 "register_operand" "")
18625                    (match_operand 4 "" ""))
18626               (set (match_operand 2 "memory_operand" "") (const_int 0))
18627               (use (match_operand 3 "register_operand" ""))
18628               (use (match_dup 1))
18629               (use (reg:SI DIRFLAG_REG))])]
18630   ""
18631   "")
18632
18633 (define_insn "*rep_stosdi_rex64"
18634   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18635    (set (match_operand:DI 0 "register_operand" "=D")
18636         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18637                             (const_int 3))
18638                  (match_operand:DI 3 "register_operand" "0")))
18639    (set (mem:BLK (match_dup 3))
18640         (const_int 0))
18641    (use (match_operand:DI 2 "register_operand" "a"))
18642    (use (match_dup 4))
18643    (use (reg:SI DIRFLAG_REG))]
18644   "TARGET_64BIT"
18645   "{rep\;stosq|rep stosq}"
18646   [(set_attr "type" "str")
18647    (set_attr "prefix_rep" "1")
18648    (set_attr "memory" "store")
18649    (set_attr "mode" "DI")])
18650
18651 (define_insn "*rep_stossi"
18652   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18653    (set (match_operand:SI 0 "register_operand" "=D")
18654         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18655                             (const_int 2))
18656                  (match_operand:SI 3 "register_operand" "0")))
18657    (set (mem:BLK (match_dup 3))
18658         (const_int 0))
18659    (use (match_operand:SI 2 "register_operand" "a"))
18660    (use (match_dup 4))
18661    (use (reg:SI DIRFLAG_REG))]
18662   "!TARGET_64BIT"
18663   "{rep\;stosl|rep stosd}"
18664   [(set_attr "type" "str")
18665    (set_attr "prefix_rep" "1")
18666    (set_attr "memory" "store")
18667    (set_attr "mode" "SI")])
18668
18669 (define_insn "*rep_stossi_rex64"
18670   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18671    (set (match_operand:DI 0 "register_operand" "=D")
18672         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18673                             (const_int 2))
18674                  (match_operand:DI 3 "register_operand" "0")))
18675    (set (mem:BLK (match_dup 3))
18676         (const_int 0))
18677    (use (match_operand:SI 2 "register_operand" "a"))
18678    (use (match_dup 4))
18679    (use (reg:SI DIRFLAG_REG))]
18680   "TARGET_64BIT"
18681   "{rep\;stosl|rep stosd}"
18682   [(set_attr "type" "str")
18683    (set_attr "prefix_rep" "1")
18684    (set_attr "memory" "store")
18685    (set_attr "mode" "SI")])
18686
18687 (define_insn "*rep_stosqi"
18688   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18689    (set (match_operand:SI 0 "register_operand" "=D")
18690         (plus:SI (match_operand:SI 3 "register_operand" "0")
18691                  (match_operand:SI 4 "register_operand" "1")))
18692    (set (mem:BLK (match_dup 3))
18693         (const_int 0))
18694    (use (match_operand:QI 2 "register_operand" "a"))
18695    (use (match_dup 4))
18696    (use (reg:SI DIRFLAG_REG))]
18697   "!TARGET_64BIT"
18698   "{rep\;stosb|rep stosb}"
18699   [(set_attr "type" "str")
18700    (set_attr "prefix_rep" "1")
18701    (set_attr "memory" "store")
18702    (set_attr "mode" "QI")])
18703
18704 (define_insn "*rep_stosqi_rex64"
18705   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18706    (set (match_operand:DI 0 "register_operand" "=D")
18707         (plus:DI (match_operand:DI 3 "register_operand" "0")
18708                  (match_operand:DI 4 "register_operand" "1")))
18709    (set (mem:BLK (match_dup 3))
18710         (const_int 0))
18711    (use (match_operand:QI 2 "register_operand" "a"))
18712    (use (match_dup 4))
18713    (use (reg:SI DIRFLAG_REG))]
18714   "TARGET_64BIT"
18715   "{rep\;stosb|rep stosb}"
18716   [(set_attr "type" "str")
18717    (set_attr "prefix_rep" "1")
18718    (set_attr "memory" "store")
18719    (set_attr "mode" "QI")])
18720
18721 (define_expand "cmpstrnsi"
18722   [(set (match_operand:SI 0 "register_operand" "")
18723         (compare:SI (match_operand:BLK 1 "general_operand" "")
18724                     (match_operand:BLK 2 "general_operand" "")))
18725    (use (match_operand 3 "general_operand" ""))
18726    (use (match_operand 4 "immediate_operand" ""))]
18727   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18728 {
18729   rtx addr1, addr2, out, outlow, count, countreg, align;
18730
18731   /* Can't use this if the user has appropriated esi or edi.  */
18732   if (global_regs[4] || global_regs[5])
18733     FAIL;
18734
18735   out = operands[0];
18736   if (GET_CODE (out) != REG)
18737     out = gen_reg_rtx (SImode);
18738
18739   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18740   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18741   if (addr1 != XEXP (operands[1], 0))
18742     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18743   if (addr2 != XEXP (operands[2], 0))
18744     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18745
18746   count = operands[3];
18747   countreg = ix86_zero_extend_to_Pmode (count);
18748
18749   /* %%% Iff we are testing strict equality, we can use known alignment
18750      to good advantage.  This may be possible with combine, particularly
18751      once cc0 is dead.  */
18752   align = operands[4];
18753
18754   emit_insn (gen_cld ());
18755   if (GET_CODE (count) == CONST_INT)
18756     {
18757       if (INTVAL (count) == 0)
18758         {
18759           emit_move_insn (operands[0], const0_rtx);
18760           DONE;
18761         }
18762       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18763                                      operands[1], operands[2]));
18764     }
18765   else
18766     {
18767       if (TARGET_64BIT)
18768         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18769       else
18770         emit_insn (gen_cmpsi_1 (countreg, countreg));
18771       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18772                                   operands[1], operands[2]));
18773     }
18774
18775   outlow = gen_lowpart (QImode, out);
18776   emit_insn (gen_cmpintqi (outlow));
18777   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18778
18779   if (operands[0] != out)
18780     emit_move_insn (operands[0], out);
18781
18782   DONE;
18783 })
18784
18785 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18786
18787 (define_expand "cmpintqi"
18788   [(set (match_dup 1)
18789         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18790    (set (match_dup 2)
18791         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18792    (parallel [(set (match_operand:QI 0 "register_operand" "")
18793                    (minus:QI (match_dup 1)
18794                              (match_dup 2)))
18795               (clobber (reg:CC FLAGS_REG))])]
18796   ""
18797   "operands[1] = gen_reg_rtx (QImode);
18798    operands[2] = gen_reg_rtx (QImode);")
18799
18800 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18801 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18802
18803 (define_expand "cmpstrnqi_nz_1"
18804   [(parallel [(set (reg:CC FLAGS_REG)
18805                    (compare:CC (match_operand 4 "memory_operand" "")
18806                                (match_operand 5 "memory_operand" "")))
18807               (use (match_operand 2 "register_operand" ""))
18808               (use (match_operand:SI 3 "immediate_operand" ""))
18809               (use (reg:SI DIRFLAG_REG))
18810               (clobber (match_operand 0 "register_operand" ""))
18811               (clobber (match_operand 1 "register_operand" ""))
18812               (clobber (match_dup 2))])]
18813   ""
18814   "")
18815
18816 (define_insn "*cmpstrnqi_nz_1"
18817   [(set (reg:CC FLAGS_REG)
18818         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18819                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18820    (use (match_operand:SI 6 "register_operand" "2"))
18821    (use (match_operand:SI 3 "immediate_operand" "i"))
18822    (use (reg:SI DIRFLAG_REG))
18823    (clobber (match_operand:SI 0 "register_operand" "=S"))
18824    (clobber (match_operand:SI 1 "register_operand" "=D"))
18825    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18826   "!TARGET_64BIT"
18827   "repz{\;| }cmpsb"
18828   [(set_attr "type" "str")
18829    (set_attr "mode" "QI")
18830    (set_attr "prefix_rep" "1")])
18831
18832 (define_insn "*cmpstrnqi_nz_rex_1"
18833   [(set (reg:CC FLAGS_REG)
18834         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18835                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18836    (use (match_operand:DI 6 "register_operand" "2"))
18837    (use (match_operand:SI 3 "immediate_operand" "i"))
18838    (use (reg:SI DIRFLAG_REG))
18839    (clobber (match_operand:DI 0 "register_operand" "=S"))
18840    (clobber (match_operand:DI 1 "register_operand" "=D"))
18841    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18842   "TARGET_64BIT"
18843   "repz{\;| }cmpsb"
18844   [(set_attr "type" "str")
18845    (set_attr "mode" "QI")
18846    (set_attr "prefix_rep" "1")])
18847
18848 ;; The same, but the count is not known to not be zero.
18849
18850 (define_expand "cmpstrnqi_1"
18851   [(parallel [(set (reg:CC FLAGS_REG)
18852                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18853                                      (const_int 0))
18854                   (compare:CC (match_operand 4 "memory_operand" "")
18855                               (match_operand 5 "memory_operand" ""))
18856                   (const_int 0)))
18857               (use (match_operand:SI 3 "immediate_operand" ""))
18858               (use (reg:CC FLAGS_REG))
18859               (use (reg:SI DIRFLAG_REG))
18860               (clobber (match_operand 0 "register_operand" ""))
18861               (clobber (match_operand 1 "register_operand" ""))
18862               (clobber (match_dup 2))])]
18863   ""
18864   "")
18865
18866 (define_insn "*cmpstrnqi_1"
18867   [(set (reg:CC FLAGS_REG)
18868         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18869                              (const_int 0))
18870           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18871                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18872           (const_int 0)))
18873    (use (match_operand:SI 3 "immediate_operand" "i"))
18874    (use (reg:CC FLAGS_REG))
18875    (use (reg:SI DIRFLAG_REG))
18876    (clobber (match_operand:SI 0 "register_operand" "=S"))
18877    (clobber (match_operand:SI 1 "register_operand" "=D"))
18878    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18879   "!TARGET_64BIT"
18880   "repz{\;| }cmpsb"
18881   [(set_attr "type" "str")
18882    (set_attr "mode" "QI")
18883    (set_attr "prefix_rep" "1")])
18884
18885 (define_insn "*cmpstrnqi_rex_1"
18886   [(set (reg:CC FLAGS_REG)
18887         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18888                              (const_int 0))
18889           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18890                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18891           (const_int 0)))
18892    (use (match_operand:SI 3 "immediate_operand" "i"))
18893    (use (reg:CC FLAGS_REG))
18894    (use (reg:SI DIRFLAG_REG))
18895    (clobber (match_operand:DI 0 "register_operand" "=S"))
18896    (clobber (match_operand:DI 1 "register_operand" "=D"))
18897    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18898   "TARGET_64BIT"
18899   "repz{\;| }cmpsb"
18900   [(set_attr "type" "str")
18901    (set_attr "mode" "QI")
18902    (set_attr "prefix_rep" "1")])
18903
18904 (define_expand "strlensi"
18905   [(set (match_operand:SI 0 "register_operand" "")
18906         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18907                     (match_operand:QI 2 "immediate_operand" "")
18908                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18909   ""
18910 {
18911  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18912    DONE;
18913  else
18914    FAIL;
18915 })
18916
18917 (define_expand "strlendi"
18918   [(set (match_operand:DI 0 "register_operand" "")
18919         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18920                     (match_operand:QI 2 "immediate_operand" "")
18921                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18922   ""
18923 {
18924  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18925    DONE;
18926  else
18927    FAIL;
18928 })
18929
18930 (define_expand "strlenqi_1"
18931   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18932               (use (reg:SI DIRFLAG_REG))
18933               (clobber (match_operand 1 "register_operand" ""))
18934               (clobber (reg:CC FLAGS_REG))])]
18935   ""
18936   "")
18937
18938 (define_insn "*strlenqi_1"
18939   [(set (match_operand:SI 0 "register_operand" "=&c")
18940         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18941                     (match_operand:QI 2 "register_operand" "a")
18942                     (match_operand:SI 3 "immediate_operand" "i")
18943                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18944    (use (reg:SI DIRFLAG_REG))
18945    (clobber (match_operand:SI 1 "register_operand" "=D"))
18946    (clobber (reg:CC FLAGS_REG))]
18947   "!TARGET_64BIT"
18948   "repnz{\;| }scasb"
18949   [(set_attr "type" "str")
18950    (set_attr "mode" "QI")
18951    (set_attr "prefix_rep" "1")])
18952
18953 (define_insn "*strlenqi_rex_1"
18954   [(set (match_operand:DI 0 "register_operand" "=&c")
18955         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18956                     (match_operand:QI 2 "register_operand" "a")
18957                     (match_operand:DI 3 "immediate_operand" "i")
18958                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18959    (use (reg:SI DIRFLAG_REG))
18960    (clobber (match_operand:DI 1 "register_operand" "=D"))
18961    (clobber (reg:CC FLAGS_REG))]
18962   "TARGET_64BIT"
18963   "repnz{\;| }scasb"
18964   [(set_attr "type" "str")
18965    (set_attr "mode" "QI")
18966    (set_attr "prefix_rep" "1")])
18967
18968 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18969 ;; handled in combine, but it is not currently up to the task.
18970 ;; When used for their truth value, the cmpstrn* expanders generate
18971 ;; code like this:
18972 ;;
18973 ;;   repz cmpsb
18974 ;;   seta       %al
18975 ;;   setb       %dl
18976 ;;   cmpb       %al, %dl
18977 ;;   jcc        label
18978 ;;
18979 ;; The intermediate three instructions are unnecessary.
18980
18981 ;; This one handles cmpstrn*_nz_1...
18982 (define_peephole2
18983   [(parallel[
18984      (set (reg:CC FLAGS_REG)
18985           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18986                       (mem:BLK (match_operand 5 "register_operand" ""))))
18987      (use (match_operand 6 "register_operand" ""))
18988      (use (match_operand:SI 3 "immediate_operand" ""))
18989      (use (reg:SI DIRFLAG_REG))
18990      (clobber (match_operand 0 "register_operand" ""))
18991      (clobber (match_operand 1 "register_operand" ""))
18992      (clobber (match_operand 2 "register_operand" ""))])
18993    (set (match_operand:QI 7 "register_operand" "")
18994         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18995    (set (match_operand:QI 8 "register_operand" "")
18996         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18997    (set (reg FLAGS_REG)
18998         (compare (match_dup 7) (match_dup 8)))
18999   ]
19000   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19001   [(parallel[
19002      (set (reg:CC FLAGS_REG)
19003           (compare:CC (mem:BLK (match_dup 4))
19004                       (mem:BLK (match_dup 5))))
19005      (use (match_dup 6))
19006      (use (match_dup 3))
19007      (use (reg:SI DIRFLAG_REG))
19008      (clobber (match_dup 0))
19009      (clobber (match_dup 1))
19010      (clobber (match_dup 2))])]
19011   "")
19012
19013 ;; ...and this one handles cmpstrn*_1.
19014 (define_peephole2
19015   [(parallel[
19016      (set (reg:CC FLAGS_REG)
19017           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19018                                (const_int 0))
19019             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19020                         (mem:BLK (match_operand 5 "register_operand" "")))
19021             (const_int 0)))
19022      (use (match_operand:SI 3 "immediate_operand" ""))
19023      (use (reg:CC FLAGS_REG))
19024      (use (reg:SI DIRFLAG_REG))
19025      (clobber (match_operand 0 "register_operand" ""))
19026      (clobber (match_operand 1 "register_operand" ""))
19027      (clobber (match_operand 2 "register_operand" ""))])
19028    (set (match_operand:QI 7 "register_operand" "")
19029         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19030    (set (match_operand:QI 8 "register_operand" "")
19031         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19032    (set (reg FLAGS_REG)
19033         (compare (match_dup 7) (match_dup 8)))
19034   ]
19035   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19036   [(parallel[
19037      (set (reg:CC FLAGS_REG)
19038           (if_then_else:CC (ne (match_dup 6)
19039                                (const_int 0))
19040             (compare:CC (mem:BLK (match_dup 4))
19041                         (mem:BLK (match_dup 5)))
19042             (const_int 0)))
19043      (use (match_dup 3))
19044      (use (reg:CC FLAGS_REG))
19045      (use (reg:SI DIRFLAG_REG))
19046      (clobber (match_dup 0))
19047      (clobber (match_dup 1))
19048      (clobber (match_dup 2))])]
19049   "")
19050
19051
19052 \f
19053 ;; Conditional move instructions.
19054
19055 (define_expand "movdicc"
19056   [(set (match_operand:DI 0 "register_operand" "")
19057         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19058                          (match_operand:DI 2 "general_operand" "")
19059                          (match_operand:DI 3 "general_operand" "")))]
19060   "TARGET_64BIT"
19061   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19062
19063 (define_insn "x86_movdicc_0_m1_rex64"
19064   [(set (match_operand:DI 0 "register_operand" "=r")
19065         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19066           (const_int -1)
19067           (const_int 0)))
19068    (clobber (reg:CC FLAGS_REG))]
19069   "TARGET_64BIT"
19070   "sbb{q}\t%0, %0"
19071   ; Since we don't have the proper number of operands for an alu insn,
19072   ; fill in all the blanks.
19073   [(set_attr "type" "alu")
19074    (set_attr "pent_pair" "pu")
19075    (set_attr "memory" "none")
19076    (set_attr "imm_disp" "false")
19077    (set_attr "mode" "DI")
19078    (set_attr "length_immediate" "0")])
19079
19080 (define_insn "*movdicc_c_rex64"
19081   [(set (match_operand:DI 0 "register_operand" "=r,r")
19082         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19083                                 [(reg FLAGS_REG) (const_int 0)])
19084                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19085                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19086   "TARGET_64BIT && TARGET_CMOVE
19087    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19088   "@
19089    cmov%O2%C1\t{%2, %0|%0, %2}
19090    cmov%O2%c1\t{%3, %0|%0, %3}"
19091   [(set_attr "type" "icmov")
19092    (set_attr "mode" "DI")])
19093
19094 (define_expand "movsicc"
19095   [(set (match_operand:SI 0 "register_operand" "")
19096         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19097                          (match_operand:SI 2 "general_operand" "")
19098                          (match_operand:SI 3 "general_operand" "")))]
19099   ""
19100   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19101
19102 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19103 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19104 ;; So just document what we're doing explicitly.
19105
19106 (define_insn "x86_movsicc_0_m1"
19107   [(set (match_operand:SI 0 "register_operand" "=r")
19108         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19109           (const_int -1)
19110           (const_int 0)))
19111    (clobber (reg:CC FLAGS_REG))]
19112   ""
19113   "sbb{l}\t%0, %0"
19114   ; Since we don't have the proper number of operands for an alu insn,
19115   ; fill in all the blanks.
19116   [(set_attr "type" "alu")
19117    (set_attr "pent_pair" "pu")
19118    (set_attr "memory" "none")
19119    (set_attr "imm_disp" "false")
19120    (set_attr "mode" "SI")
19121    (set_attr "length_immediate" "0")])
19122
19123 (define_insn "*movsicc_noc"
19124   [(set (match_operand:SI 0 "register_operand" "=r,r")
19125         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19126                                 [(reg FLAGS_REG) (const_int 0)])
19127                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19128                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19129   "TARGET_CMOVE
19130    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19131   "@
19132    cmov%O2%C1\t{%2, %0|%0, %2}
19133    cmov%O2%c1\t{%3, %0|%0, %3}"
19134   [(set_attr "type" "icmov")
19135    (set_attr "mode" "SI")])
19136
19137 (define_expand "movhicc"
19138   [(set (match_operand:HI 0 "register_operand" "")
19139         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19140                          (match_operand:HI 2 "general_operand" "")
19141                          (match_operand:HI 3 "general_operand" "")))]
19142   "TARGET_HIMODE_MATH"
19143   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19144
19145 (define_insn "*movhicc_noc"
19146   [(set (match_operand:HI 0 "register_operand" "=r,r")
19147         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19148                                 [(reg FLAGS_REG) (const_int 0)])
19149                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19150                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19151   "TARGET_CMOVE
19152    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19153   "@
19154    cmov%O2%C1\t{%2, %0|%0, %2}
19155    cmov%O2%c1\t{%3, %0|%0, %3}"
19156   [(set_attr "type" "icmov")
19157    (set_attr "mode" "HI")])
19158
19159 (define_expand "movqicc"
19160   [(set (match_operand:QI 0 "register_operand" "")
19161         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19162                          (match_operand:QI 2 "general_operand" "")
19163                          (match_operand:QI 3 "general_operand" "")))]
19164   "TARGET_QIMODE_MATH"
19165   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19166
19167 (define_insn_and_split "*movqicc_noc"
19168   [(set (match_operand:QI 0 "register_operand" "=r,r")
19169         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19170                                 [(match_operand 4 "flags_reg_operand" "")
19171                                  (const_int 0)])
19172                       (match_operand:QI 2 "register_operand" "r,0")
19173                       (match_operand:QI 3 "register_operand" "0,r")))]
19174   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19175   "#"
19176   "&& reload_completed"
19177   [(set (match_dup 0)
19178         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19179                       (match_dup 2)
19180                       (match_dup 3)))]
19181   "operands[0] = gen_lowpart (SImode, operands[0]);
19182    operands[2] = gen_lowpart (SImode, operands[2]);
19183    operands[3] = gen_lowpart (SImode, operands[3]);"
19184   [(set_attr "type" "icmov")
19185    (set_attr "mode" "SI")])
19186
19187 (define_expand "movsfcc"
19188   [(set (match_operand:SF 0 "register_operand" "")
19189         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19190                          (match_operand:SF 2 "register_operand" "")
19191                          (match_operand:SF 3 "register_operand" "")))]
19192   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19193   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19194
19195 (define_insn "*movsfcc_1_387"
19196   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19197         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19198                                 [(reg FLAGS_REG) (const_int 0)])
19199                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19200                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19201   "TARGET_80387 && TARGET_CMOVE
19202    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19203   "@
19204    fcmov%F1\t{%2, %0|%0, %2}
19205    fcmov%f1\t{%3, %0|%0, %3}
19206    cmov%O2%C1\t{%2, %0|%0, %2}
19207    cmov%O2%c1\t{%3, %0|%0, %3}"
19208   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19209    (set_attr "mode" "SF,SF,SI,SI")])
19210
19211 (define_expand "movdfcc"
19212   [(set (match_operand:DF 0 "register_operand" "")
19213         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19214                          (match_operand:DF 2 "register_operand" "")
19215                          (match_operand:DF 3 "register_operand" "")))]
19216   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19217   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19218
19219 (define_insn "*movdfcc_1"
19220   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19221         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19222                                 [(reg FLAGS_REG) (const_int 0)])
19223                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19224                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19225   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19226    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19227   "@
19228    fcmov%F1\t{%2, %0|%0, %2}
19229    fcmov%f1\t{%3, %0|%0, %3}
19230    #
19231    #"
19232   [(set_attr "type" "fcmov,fcmov,multi,multi")
19233    (set_attr "mode" "DF")])
19234
19235 (define_insn "*movdfcc_1_rex64"
19236   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19237         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19238                                 [(reg FLAGS_REG) (const_int 0)])
19239                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19240                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19241   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19242    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19243   "@
19244    fcmov%F1\t{%2, %0|%0, %2}
19245    fcmov%f1\t{%3, %0|%0, %3}
19246    cmov%O2%C1\t{%2, %0|%0, %2}
19247    cmov%O2%c1\t{%3, %0|%0, %3}"
19248   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19249    (set_attr "mode" "DF")])
19250
19251 (define_split
19252   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19253         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19254                                 [(match_operand 4 "flags_reg_operand" "")
19255                                  (const_int 0)])
19256                       (match_operand:DF 2 "nonimmediate_operand" "")
19257                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19258   "!TARGET_64BIT && reload_completed"
19259   [(set (match_dup 2)
19260         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19261                       (match_dup 5)
19262                       (match_dup 7)))
19263    (set (match_dup 3)
19264         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19265                       (match_dup 6)
19266                       (match_dup 8)))]
19267   "split_di (operands+2, 1, operands+5, operands+6);
19268    split_di (operands+3, 1, operands+7, operands+8);
19269    split_di (operands, 1, operands+2, operands+3);")
19270
19271 (define_expand "movxfcc"
19272   [(set (match_operand:XF 0 "register_operand" "")
19273         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19274                          (match_operand:XF 2 "register_operand" "")
19275                          (match_operand:XF 3 "register_operand" "")))]
19276   "TARGET_80387 && TARGET_CMOVE"
19277   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19278
19279 (define_insn "*movxfcc_1"
19280   [(set (match_operand:XF 0 "register_operand" "=f,f")
19281         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19282                                 [(reg FLAGS_REG) (const_int 0)])
19283                       (match_operand:XF 2 "register_operand" "f,0")
19284                       (match_operand:XF 3 "register_operand" "0,f")))]
19285   "TARGET_80387 && TARGET_CMOVE"
19286   "@
19287    fcmov%F1\t{%2, %0|%0, %2}
19288    fcmov%f1\t{%3, %0|%0, %3}"
19289   [(set_attr "type" "fcmov")
19290    (set_attr "mode" "XF")])
19291
19292 ;; These versions of the min/max patterns are intentionally ignorant of
19293 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19294 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19295 ;; are undefined in this condition, we're certain this is correct.
19296
19297 (define_insn "sminsf3"
19298   [(set (match_operand:SF 0 "register_operand" "=x")
19299         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19300                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19301   "TARGET_SSE_MATH"
19302   "minss\t{%2, %0|%0, %2}"
19303   [(set_attr "type" "sseadd")
19304    (set_attr "mode" "SF")])
19305
19306 (define_insn "smaxsf3"
19307   [(set (match_operand:SF 0 "register_operand" "=x")
19308         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19309                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19310   "TARGET_SSE_MATH"
19311   "maxss\t{%2, %0|%0, %2}"
19312   [(set_attr "type" "sseadd")
19313    (set_attr "mode" "SF")])
19314
19315 (define_insn "smindf3"
19316   [(set (match_operand:DF 0 "register_operand" "=x")
19317         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19318                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19319   "TARGET_SSE2 && TARGET_SSE_MATH"
19320   "minsd\t{%2, %0|%0, %2}"
19321   [(set_attr "type" "sseadd")
19322    (set_attr "mode" "DF")])
19323
19324 (define_insn "smaxdf3"
19325   [(set (match_operand:DF 0 "register_operand" "=x")
19326         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19327                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19328   "TARGET_SSE2 && TARGET_SSE_MATH"
19329   "maxsd\t{%2, %0|%0, %2}"
19330   [(set_attr "type" "sseadd")
19331    (set_attr "mode" "DF")])
19332
19333 ;; These versions of the min/max patterns implement exactly the operations
19334 ;;   min = (op1 < op2 ? op1 : op2)
19335 ;;   max = (!(op1 < op2) ? op1 : op2)
19336 ;; Their operands are not commutative, and thus they may be used in the
19337 ;; presence of -0.0 and NaN.
19338
19339 (define_insn "*ieee_sminsf3"
19340   [(set (match_operand:SF 0 "register_operand" "=x")
19341         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19342                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19343                    UNSPEC_IEEE_MIN))]
19344   "TARGET_SSE_MATH"
19345   "minss\t{%2, %0|%0, %2}"
19346   [(set_attr "type" "sseadd")
19347    (set_attr "mode" "SF")])
19348
19349 (define_insn "*ieee_smaxsf3"
19350   [(set (match_operand:SF 0 "register_operand" "=x")
19351         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19352                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19353                    UNSPEC_IEEE_MAX))]
19354   "TARGET_SSE_MATH"
19355   "maxss\t{%2, %0|%0, %2}"
19356   [(set_attr "type" "sseadd")
19357    (set_attr "mode" "SF")])
19358
19359 (define_insn "*ieee_smindf3"
19360   [(set (match_operand:DF 0 "register_operand" "=x")
19361         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19362                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19363                    UNSPEC_IEEE_MIN))]
19364   "TARGET_SSE2 && TARGET_SSE_MATH"
19365   "minsd\t{%2, %0|%0, %2}"
19366   [(set_attr "type" "sseadd")
19367    (set_attr "mode" "DF")])
19368
19369 (define_insn "*ieee_smaxdf3"
19370   [(set (match_operand:DF 0 "register_operand" "=x")
19371         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19372                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19373                    UNSPEC_IEEE_MAX))]
19374   "TARGET_SSE2 && TARGET_SSE_MATH"
19375   "maxsd\t{%2, %0|%0, %2}"
19376   [(set_attr "type" "sseadd")
19377    (set_attr "mode" "DF")])
19378
19379 ;; Make two stack loads independent:
19380 ;;   fld aa              fld aa
19381 ;;   fld %st(0)     ->   fld bb
19382 ;;   fmul bb             fmul %st(1), %st
19383 ;;
19384 ;; Actually we only match the last two instructions for simplicity.
19385 (define_peephole2
19386   [(set (match_operand 0 "fp_register_operand" "")
19387         (match_operand 1 "fp_register_operand" ""))
19388    (set (match_dup 0)
19389         (match_operator 2 "binary_fp_operator"
19390            [(match_dup 0)
19391             (match_operand 3 "memory_operand" "")]))]
19392   "REGNO (operands[0]) != REGNO (operands[1])"
19393   [(set (match_dup 0) (match_dup 3))
19394    (set (match_dup 0) (match_dup 4))]
19395
19396   ;; The % modifier is not operational anymore in peephole2's, so we have to
19397   ;; swap the operands manually in the case of addition and multiplication.
19398   "if (COMMUTATIVE_ARITH_P (operands[2]))
19399      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19400                                  operands[0], operands[1]);
19401    else
19402      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19403                                  operands[1], operands[0]);")
19404
19405 ;; Conditional addition patterns
19406 (define_expand "addqicc"
19407   [(match_operand:QI 0 "register_operand" "")
19408    (match_operand 1 "comparison_operator" "")
19409    (match_operand:QI 2 "register_operand" "")
19410    (match_operand:QI 3 "const_int_operand" "")]
19411   ""
19412   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19413
19414 (define_expand "addhicc"
19415   [(match_operand:HI 0 "register_operand" "")
19416    (match_operand 1 "comparison_operator" "")
19417    (match_operand:HI 2 "register_operand" "")
19418    (match_operand:HI 3 "const_int_operand" "")]
19419   ""
19420   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19421
19422 (define_expand "addsicc"
19423   [(match_operand:SI 0 "register_operand" "")
19424    (match_operand 1 "comparison_operator" "")
19425    (match_operand:SI 2 "register_operand" "")
19426    (match_operand:SI 3 "const_int_operand" "")]
19427   ""
19428   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19429
19430 (define_expand "adddicc"
19431   [(match_operand:DI 0 "register_operand" "")
19432    (match_operand 1 "comparison_operator" "")
19433    (match_operand:DI 2 "register_operand" "")
19434    (match_operand:DI 3 "const_int_operand" "")]
19435   "TARGET_64BIT"
19436   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19437
19438 \f
19439 ;; Misc patterns (?)
19440
19441 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19442 ;; Otherwise there will be nothing to keep
19443 ;;
19444 ;; [(set (reg ebp) (reg esp))]
19445 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19446 ;;  (clobber (eflags)]
19447 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19448 ;;
19449 ;; in proper program order.
19450 (define_insn "pro_epilogue_adjust_stack_1"
19451   [(set (match_operand:SI 0 "register_operand" "=r,r")
19452         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19453                  (match_operand:SI 2 "immediate_operand" "i,i")))
19454    (clobber (reg:CC FLAGS_REG))
19455    (clobber (mem:BLK (scratch)))]
19456   "!TARGET_64BIT"
19457 {
19458   switch (get_attr_type (insn))
19459     {
19460     case TYPE_IMOV:
19461       return "mov{l}\t{%1, %0|%0, %1}";
19462
19463     case TYPE_ALU:
19464       if (GET_CODE (operands[2]) == CONST_INT
19465           && (INTVAL (operands[2]) == 128
19466               || (INTVAL (operands[2]) < 0
19467                   && INTVAL (operands[2]) != -128)))
19468         {
19469           operands[2] = GEN_INT (-INTVAL (operands[2]));
19470           return "sub{l}\t{%2, %0|%0, %2}";
19471         }
19472       return "add{l}\t{%2, %0|%0, %2}";
19473
19474     case TYPE_LEA:
19475       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19476       return "lea{l}\t{%a2, %0|%0, %a2}";
19477
19478     default:
19479       gcc_unreachable ();
19480     }
19481 }
19482   [(set (attr "type")
19483         (cond [(eq_attr "alternative" "0")
19484                  (const_string "alu")
19485                (match_operand:SI 2 "const0_operand" "")
19486                  (const_string "imov")
19487               ]
19488               (const_string "lea")))
19489    (set_attr "mode" "SI")])
19490
19491 (define_insn "pro_epilogue_adjust_stack_rex64"
19492   [(set (match_operand:DI 0 "register_operand" "=r,r")
19493         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19494                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19495    (clobber (reg:CC FLAGS_REG))
19496    (clobber (mem:BLK (scratch)))]
19497   "TARGET_64BIT"
19498 {
19499   switch (get_attr_type (insn))
19500     {
19501     case TYPE_IMOV:
19502       return "mov{q}\t{%1, %0|%0, %1}";
19503
19504     case TYPE_ALU:
19505       if (GET_CODE (operands[2]) == CONST_INT
19506           /* Avoid overflows.  */
19507           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19508           && (INTVAL (operands[2]) == 128
19509               || (INTVAL (operands[2]) < 0
19510                   && INTVAL (operands[2]) != -128)))
19511         {
19512           operands[2] = GEN_INT (-INTVAL (operands[2]));
19513           return "sub{q}\t{%2, %0|%0, %2}";
19514         }
19515       return "add{q}\t{%2, %0|%0, %2}";
19516
19517     case TYPE_LEA:
19518       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19519       return "lea{q}\t{%a2, %0|%0, %a2}";
19520
19521     default:
19522       gcc_unreachable ();
19523     }
19524 }
19525   [(set (attr "type")
19526         (cond [(eq_attr "alternative" "0")
19527                  (const_string "alu")
19528                (match_operand:DI 2 "const0_operand" "")
19529                  (const_string "imov")
19530               ]
19531               (const_string "lea")))
19532    (set_attr "mode" "DI")])
19533
19534 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19535   [(set (match_operand:DI 0 "register_operand" "=r,r")
19536         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19537                  (match_operand:DI 3 "immediate_operand" "i,i")))
19538    (use (match_operand:DI 2 "register_operand" "r,r"))
19539    (clobber (reg:CC FLAGS_REG))
19540    (clobber (mem:BLK (scratch)))]
19541   "TARGET_64BIT"
19542 {
19543   switch (get_attr_type (insn))
19544     {
19545     case TYPE_ALU:
19546       return "add{q}\t{%2, %0|%0, %2}";
19547
19548     case TYPE_LEA:
19549       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19550       return "lea{q}\t{%a2, %0|%0, %a2}";
19551
19552     default:
19553       gcc_unreachable ();
19554     }
19555 }
19556   [(set_attr "type" "alu,lea")
19557    (set_attr "mode" "DI")])
19558
19559 (define_expand "allocate_stack_worker"
19560   [(match_operand:SI 0 "register_operand" "")]
19561   "TARGET_STACK_PROBE"
19562 {
19563   if (reload_completed)
19564     {
19565       if (TARGET_64BIT)
19566         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19567       else
19568         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19569     }
19570   else
19571     {
19572       if (TARGET_64BIT)
19573         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19574       else
19575         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19576     }
19577   DONE;
19578 })
19579
19580 (define_insn "allocate_stack_worker_1"
19581   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19582     UNSPECV_STACK_PROBE)
19583    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19584    (clobber (match_scratch:SI 1 "=0"))
19585    (clobber (reg:CC FLAGS_REG))]
19586   "!TARGET_64BIT && TARGET_STACK_PROBE"
19587   "call\t__alloca"
19588   [(set_attr "type" "multi")
19589    (set_attr "length" "5")])
19590
19591 (define_expand "allocate_stack_worker_postreload"
19592   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19593                                     UNSPECV_STACK_PROBE)
19594               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19595               (clobber (match_dup 0))
19596               (clobber (reg:CC FLAGS_REG))])]
19597   ""
19598   "")
19599
19600 (define_insn "allocate_stack_worker_rex64"
19601   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19602     UNSPECV_STACK_PROBE)
19603    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19604    (clobber (match_scratch:DI 1 "=0"))
19605    (clobber (reg:CC FLAGS_REG))]
19606   "TARGET_64BIT && TARGET_STACK_PROBE"
19607   "call\t__alloca"
19608   [(set_attr "type" "multi")
19609    (set_attr "length" "5")])
19610
19611 (define_expand "allocate_stack_worker_rex64_postreload"
19612   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19613                                     UNSPECV_STACK_PROBE)
19614               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19615               (clobber (match_dup 0))
19616               (clobber (reg:CC FLAGS_REG))])]
19617   ""
19618   "")
19619
19620 (define_expand "allocate_stack"
19621   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19622                    (minus:SI (reg:SI SP_REG)
19623                              (match_operand:SI 1 "general_operand" "")))
19624               (clobber (reg:CC FLAGS_REG))])
19625    (parallel [(set (reg:SI SP_REG)
19626                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19627               (clobber (reg:CC FLAGS_REG))])]
19628   "TARGET_STACK_PROBE"
19629 {
19630 #ifdef CHECK_STACK_LIMIT
19631   if (GET_CODE (operands[1]) == CONST_INT
19632       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19633     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19634                            operands[1]));
19635   else
19636 #endif
19637     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19638                                                             operands[1])));
19639
19640   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19641   DONE;
19642 })
19643
19644 (define_expand "builtin_setjmp_receiver"
19645   [(label_ref (match_operand 0 "" ""))]
19646   "!TARGET_64BIT && flag_pic"
19647 {
19648   if (TARGET_MACHO)
19649     {
19650       rtx xops[3];
19651       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19652       rtx label_rtx = gen_label_rtx ();
19653       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19654       xops[0] = xops[1] = picreg;
19655       xops[2] = gen_rtx_CONST (SImode,
19656                   gen_rtx_MINUS (SImode,
19657                     gen_rtx_LABEL_REF (SImode, label_rtx),
19658                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19659       ix86_expand_binary_operator (MINUS, SImode, xops);
19660     }
19661   else
19662     emit_insn (gen_set_got (pic_offset_table_rtx));
19663   DONE;
19664 })
19665 \f
19666 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19667
19668 (define_split
19669   [(set (match_operand 0 "register_operand" "")
19670         (match_operator 3 "promotable_binary_operator"
19671            [(match_operand 1 "register_operand" "")
19672             (match_operand 2 "aligned_operand" "")]))
19673    (clobber (reg:CC FLAGS_REG))]
19674   "! TARGET_PARTIAL_REG_STALL && reload_completed
19675    && ((GET_MODE (operands[0]) == HImode
19676         && ((!optimize_size && !TARGET_FAST_PREFIX)
19677             /* ??? next two lines just !satisfies_constraint_K (...) */
19678             || GET_CODE (operands[2]) != CONST_INT
19679             || satisfies_constraint_K (operands[2])))
19680        || (GET_MODE (operands[0]) == QImode
19681            && (TARGET_PROMOTE_QImode || optimize_size)))"
19682   [(parallel [(set (match_dup 0)
19683                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19684               (clobber (reg:CC FLAGS_REG))])]
19685   "operands[0] = gen_lowpart (SImode, operands[0]);
19686    operands[1] = gen_lowpart (SImode, operands[1]);
19687    if (GET_CODE (operands[3]) != ASHIFT)
19688      operands[2] = gen_lowpart (SImode, operands[2]);
19689    PUT_MODE (operands[3], SImode);")
19690
19691 ; Promote the QImode tests, as i386 has encoding of the AND
19692 ; instruction with 32-bit sign-extended immediate and thus the
19693 ; instruction size is unchanged, except in the %eax case for
19694 ; which it is increased by one byte, hence the ! optimize_size.
19695 (define_split
19696   [(set (match_operand 0 "flags_reg_operand" "")
19697         (match_operator 2 "compare_operator"
19698           [(and (match_operand 3 "aligned_operand" "")
19699                 (match_operand 4 "const_int_operand" ""))
19700            (const_int 0)]))
19701    (set (match_operand 1 "register_operand" "")
19702         (and (match_dup 3) (match_dup 4)))]
19703   "! TARGET_PARTIAL_REG_STALL && reload_completed
19704    /* Ensure that the operand will remain sign-extended immediate.  */
19705    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19706    && ! optimize_size
19707    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19708        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19709   [(parallel [(set (match_dup 0)
19710                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19711                                     (const_int 0)]))
19712               (set (match_dup 1)
19713                    (and:SI (match_dup 3) (match_dup 4)))])]
19714 {
19715   operands[4]
19716     = gen_int_mode (INTVAL (operands[4])
19717                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19718   operands[1] = gen_lowpart (SImode, operands[1]);
19719   operands[3] = gen_lowpart (SImode, operands[3]);
19720 })
19721
19722 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19723 ; the TEST instruction with 32-bit sign-extended immediate and thus
19724 ; the instruction size would at least double, which is not what we
19725 ; want even with ! optimize_size.
19726 (define_split
19727   [(set (match_operand 0 "flags_reg_operand" "")
19728         (match_operator 1 "compare_operator"
19729           [(and (match_operand:HI 2 "aligned_operand" "")
19730                 (match_operand:HI 3 "const_int_operand" ""))
19731            (const_int 0)]))]
19732   "! TARGET_PARTIAL_REG_STALL && reload_completed
19733    /* Ensure that the operand will remain sign-extended immediate.  */
19734    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19735    && ! TARGET_FAST_PREFIX
19736    && ! optimize_size"
19737   [(set (match_dup 0)
19738         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19739                          (const_int 0)]))]
19740 {
19741   operands[3]
19742     = gen_int_mode (INTVAL (operands[3])
19743                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19744   operands[2] = gen_lowpart (SImode, operands[2]);
19745 })
19746
19747 (define_split
19748   [(set (match_operand 0 "register_operand" "")
19749         (neg (match_operand 1 "register_operand" "")))
19750    (clobber (reg:CC FLAGS_REG))]
19751   "! TARGET_PARTIAL_REG_STALL && reload_completed
19752    && (GET_MODE (operands[0]) == HImode
19753        || (GET_MODE (operands[0]) == QImode
19754            && (TARGET_PROMOTE_QImode || optimize_size)))"
19755   [(parallel [(set (match_dup 0)
19756                    (neg:SI (match_dup 1)))
19757               (clobber (reg:CC FLAGS_REG))])]
19758   "operands[0] = gen_lowpart (SImode, operands[0]);
19759    operands[1] = gen_lowpart (SImode, operands[1]);")
19760
19761 (define_split
19762   [(set (match_operand 0 "register_operand" "")
19763         (not (match_operand 1 "register_operand" "")))]
19764   "! TARGET_PARTIAL_REG_STALL && reload_completed
19765    && (GET_MODE (operands[0]) == HImode
19766        || (GET_MODE (operands[0]) == QImode
19767            && (TARGET_PROMOTE_QImode || optimize_size)))"
19768   [(set (match_dup 0)
19769         (not:SI (match_dup 1)))]
19770   "operands[0] = gen_lowpart (SImode, operands[0]);
19771    operands[1] = gen_lowpart (SImode, operands[1]);")
19772
19773 (define_split
19774   [(set (match_operand 0 "register_operand" "")
19775         (if_then_else (match_operator 1 "comparison_operator"
19776                                 [(reg FLAGS_REG) (const_int 0)])
19777                       (match_operand 2 "register_operand" "")
19778                       (match_operand 3 "register_operand" "")))]
19779   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19780    && (GET_MODE (operands[0]) == HImode
19781        || (GET_MODE (operands[0]) == QImode
19782            && (TARGET_PROMOTE_QImode || optimize_size)))"
19783   [(set (match_dup 0)
19784         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19785   "operands[0] = gen_lowpart (SImode, operands[0]);
19786    operands[2] = gen_lowpart (SImode, operands[2]);
19787    operands[3] = gen_lowpart (SImode, operands[3]);")
19788
19789 \f
19790 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19791 ;; transform a complex memory operation into two memory to register operations.
19792
19793 ;; Don't push memory operands
19794 (define_peephole2
19795   [(set (match_operand:SI 0 "push_operand" "")
19796         (match_operand:SI 1 "memory_operand" ""))
19797    (match_scratch:SI 2 "r")]
19798   "!optimize_size && !TARGET_PUSH_MEMORY
19799    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19800   [(set (match_dup 2) (match_dup 1))
19801    (set (match_dup 0) (match_dup 2))]
19802   "")
19803
19804 (define_peephole2
19805   [(set (match_operand:DI 0 "push_operand" "")
19806         (match_operand:DI 1 "memory_operand" ""))
19807    (match_scratch:DI 2 "r")]
19808   "!optimize_size && !TARGET_PUSH_MEMORY
19809    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19810   [(set (match_dup 2) (match_dup 1))
19811    (set (match_dup 0) (match_dup 2))]
19812   "")
19813
19814 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19815 ;; SImode pushes.
19816 (define_peephole2
19817   [(set (match_operand:SF 0 "push_operand" "")
19818         (match_operand:SF 1 "memory_operand" ""))
19819    (match_scratch:SF 2 "r")]
19820   "!optimize_size && !TARGET_PUSH_MEMORY
19821    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19822   [(set (match_dup 2) (match_dup 1))
19823    (set (match_dup 0) (match_dup 2))]
19824   "")
19825
19826 (define_peephole2
19827   [(set (match_operand:HI 0 "push_operand" "")
19828         (match_operand:HI 1 "memory_operand" ""))
19829    (match_scratch:HI 2 "r")]
19830   "!optimize_size && !TARGET_PUSH_MEMORY
19831    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19832   [(set (match_dup 2) (match_dup 1))
19833    (set (match_dup 0) (match_dup 2))]
19834   "")
19835
19836 (define_peephole2
19837   [(set (match_operand:QI 0 "push_operand" "")
19838         (match_operand:QI 1 "memory_operand" ""))
19839    (match_scratch:QI 2 "q")]
19840   "!optimize_size && !TARGET_PUSH_MEMORY
19841    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19842   [(set (match_dup 2) (match_dup 1))
19843    (set (match_dup 0) (match_dup 2))]
19844   "")
19845
19846 ;; Don't move an immediate directly to memory when the instruction
19847 ;; gets too big.
19848 (define_peephole2
19849   [(match_scratch:SI 1 "r")
19850    (set (match_operand:SI 0 "memory_operand" "")
19851         (const_int 0))]
19852   "! optimize_size
19853    && ! TARGET_USE_MOV0
19854    && TARGET_SPLIT_LONG_MOVES
19855    && get_attr_length (insn) >= ix86_cost->large_insn
19856    && peep2_regno_dead_p (0, FLAGS_REG)"
19857   [(parallel [(set (match_dup 1) (const_int 0))
19858               (clobber (reg:CC FLAGS_REG))])
19859    (set (match_dup 0) (match_dup 1))]
19860   "")
19861
19862 (define_peephole2
19863   [(match_scratch:HI 1 "r")
19864    (set (match_operand:HI 0 "memory_operand" "")
19865         (const_int 0))]
19866   "! optimize_size
19867    && ! TARGET_USE_MOV0
19868    && TARGET_SPLIT_LONG_MOVES
19869    && get_attr_length (insn) >= ix86_cost->large_insn
19870    && peep2_regno_dead_p (0, FLAGS_REG)"
19871   [(parallel [(set (match_dup 2) (const_int 0))
19872               (clobber (reg:CC FLAGS_REG))])
19873    (set (match_dup 0) (match_dup 1))]
19874   "operands[2] = gen_lowpart (SImode, operands[1]);")
19875
19876 (define_peephole2
19877   [(match_scratch:QI 1 "q")
19878    (set (match_operand:QI 0 "memory_operand" "")
19879         (const_int 0))]
19880   "! optimize_size
19881    && ! TARGET_USE_MOV0
19882    && TARGET_SPLIT_LONG_MOVES
19883    && get_attr_length (insn) >= ix86_cost->large_insn
19884    && peep2_regno_dead_p (0, FLAGS_REG)"
19885   [(parallel [(set (match_dup 2) (const_int 0))
19886               (clobber (reg:CC FLAGS_REG))])
19887    (set (match_dup 0) (match_dup 1))]
19888   "operands[2] = gen_lowpart (SImode, operands[1]);")
19889
19890 (define_peephole2
19891   [(match_scratch:SI 2 "r")
19892    (set (match_operand:SI 0 "memory_operand" "")
19893         (match_operand:SI 1 "immediate_operand" ""))]
19894   "! optimize_size
19895    && get_attr_length (insn) >= ix86_cost->large_insn
19896    && TARGET_SPLIT_LONG_MOVES"
19897   [(set (match_dup 2) (match_dup 1))
19898    (set (match_dup 0) (match_dup 2))]
19899   "")
19900
19901 (define_peephole2
19902   [(match_scratch:HI 2 "r")
19903    (set (match_operand:HI 0 "memory_operand" "")
19904         (match_operand:HI 1 "immediate_operand" ""))]
19905   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19906   && TARGET_SPLIT_LONG_MOVES"
19907   [(set (match_dup 2) (match_dup 1))
19908    (set (match_dup 0) (match_dup 2))]
19909   "")
19910
19911 (define_peephole2
19912   [(match_scratch:QI 2 "q")
19913    (set (match_operand:QI 0 "memory_operand" "")
19914         (match_operand:QI 1 "immediate_operand" ""))]
19915   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19916   && TARGET_SPLIT_LONG_MOVES"
19917   [(set (match_dup 2) (match_dup 1))
19918    (set (match_dup 0) (match_dup 2))]
19919   "")
19920
19921 ;; Don't compare memory with zero, load and use a test instead.
19922 (define_peephole2
19923   [(set (match_operand 0 "flags_reg_operand" "")
19924         (match_operator 1 "compare_operator"
19925           [(match_operand:SI 2 "memory_operand" "")
19926            (const_int 0)]))
19927    (match_scratch:SI 3 "r")]
19928   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19929   [(set (match_dup 3) (match_dup 2))
19930    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19931   "")
19932
19933 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19934 ;; Don't split NOTs with a displacement operand, because resulting XOR
19935 ;; will not be pairable anyway.
19936 ;;
19937 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19938 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19939 ;; so this split helps here as well.
19940 ;;
19941 ;; Note: Can't do this as a regular split because we can't get proper
19942 ;; lifetime information then.
19943
19944 (define_peephole2
19945   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19946         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19947   "!optimize_size
19948    && peep2_regno_dead_p (0, FLAGS_REG)
19949    && ((TARGET_PENTIUM
19950         && (GET_CODE (operands[0]) != MEM
19951             || !memory_displacement_operand (operands[0], SImode)))
19952        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19953   [(parallel [(set (match_dup 0)
19954                    (xor:SI (match_dup 1) (const_int -1)))
19955               (clobber (reg:CC FLAGS_REG))])]
19956   "")
19957
19958 (define_peephole2
19959   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19960         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19961   "!optimize_size
19962    && peep2_regno_dead_p (0, FLAGS_REG)
19963    && ((TARGET_PENTIUM
19964         && (GET_CODE (operands[0]) != MEM
19965             || !memory_displacement_operand (operands[0], HImode)))
19966        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19967   [(parallel [(set (match_dup 0)
19968                    (xor:HI (match_dup 1) (const_int -1)))
19969               (clobber (reg:CC FLAGS_REG))])]
19970   "")
19971
19972 (define_peephole2
19973   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19974         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19975   "!optimize_size
19976    && peep2_regno_dead_p (0, FLAGS_REG)
19977    && ((TARGET_PENTIUM
19978         && (GET_CODE (operands[0]) != MEM
19979             || !memory_displacement_operand (operands[0], QImode)))
19980        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19981   [(parallel [(set (match_dup 0)
19982                    (xor:QI (match_dup 1) (const_int -1)))
19983               (clobber (reg:CC FLAGS_REG))])]
19984   "")
19985
19986 ;; Non pairable "test imm, reg" instructions can be translated to
19987 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19988 ;; byte opcode instead of two, have a short form for byte operands),
19989 ;; so do it for other CPUs as well.  Given that the value was dead,
19990 ;; this should not create any new dependencies.  Pass on the sub-word
19991 ;; versions if we're concerned about partial register stalls.
19992
19993 (define_peephole2
19994   [(set (match_operand 0 "flags_reg_operand" "")
19995         (match_operator 1 "compare_operator"
19996           [(and:SI (match_operand:SI 2 "register_operand" "")
19997                    (match_operand:SI 3 "immediate_operand" ""))
19998            (const_int 0)]))]
19999   "ix86_match_ccmode (insn, CCNOmode)
20000    && (true_regnum (operands[2]) != 0
20001        || satisfies_constraint_K (operands[3]))
20002    && peep2_reg_dead_p (1, operands[2])"
20003   [(parallel
20004      [(set (match_dup 0)
20005            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20006                             (const_int 0)]))
20007       (set (match_dup 2)
20008            (and:SI (match_dup 2) (match_dup 3)))])]
20009   "")
20010
20011 ;; We don't need to handle HImode case, because it will be promoted to SImode
20012 ;; on ! TARGET_PARTIAL_REG_STALL
20013
20014 (define_peephole2
20015   [(set (match_operand 0 "flags_reg_operand" "")
20016         (match_operator 1 "compare_operator"
20017           [(and:QI (match_operand:QI 2 "register_operand" "")
20018                    (match_operand:QI 3 "immediate_operand" ""))
20019            (const_int 0)]))]
20020   "! TARGET_PARTIAL_REG_STALL
20021    && ix86_match_ccmode (insn, CCNOmode)
20022    && true_regnum (operands[2]) != 0
20023    && peep2_reg_dead_p (1, operands[2])"
20024   [(parallel
20025      [(set (match_dup 0)
20026            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20027                             (const_int 0)]))
20028       (set (match_dup 2)
20029            (and:QI (match_dup 2) (match_dup 3)))])]
20030   "")
20031
20032 (define_peephole2
20033   [(set (match_operand 0 "flags_reg_operand" "")
20034         (match_operator 1 "compare_operator"
20035           [(and:SI
20036              (zero_extract:SI
20037                (match_operand 2 "ext_register_operand" "")
20038                (const_int 8)
20039                (const_int 8))
20040              (match_operand 3 "const_int_operand" ""))
20041            (const_int 0)]))]
20042   "! TARGET_PARTIAL_REG_STALL
20043    && ix86_match_ccmode (insn, CCNOmode)
20044    && true_regnum (operands[2]) != 0
20045    && peep2_reg_dead_p (1, operands[2])"
20046   [(parallel [(set (match_dup 0)
20047                    (match_op_dup 1
20048                      [(and:SI
20049                         (zero_extract:SI
20050                           (match_dup 2)
20051                           (const_int 8)
20052                           (const_int 8))
20053                         (match_dup 3))
20054                       (const_int 0)]))
20055               (set (zero_extract:SI (match_dup 2)
20056                                     (const_int 8)
20057                                     (const_int 8))
20058                    (and:SI
20059                      (zero_extract:SI
20060                        (match_dup 2)
20061                        (const_int 8)
20062                        (const_int 8))
20063                      (match_dup 3)))])]
20064   "")
20065
20066 ;; Don't do logical operations with memory inputs.
20067 (define_peephole2
20068   [(match_scratch:SI 2 "r")
20069    (parallel [(set (match_operand:SI 0 "register_operand" "")
20070                    (match_operator:SI 3 "arith_or_logical_operator"
20071                      [(match_dup 0)
20072                       (match_operand:SI 1 "memory_operand" "")]))
20073               (clobber (reg:CC FLAGS_REG))])]
20074   "! optimize_size && ! TARGET_READ_MODIFY"
20075   [(set (match_dup 2) (match_dup 1))
20076    (parallel [(set (match_dup 0)
20077                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20078               (clobber (reg:CC FLAGS_REG))])]
20079   "")
20080
20081 (define_peephole2
20082   [(match_scratch:SI 2 "r")
20083    (parallel [(set (match_operand:SI 0 "register_operand" "")
20084                    (match_operator:SI 3 "arith_or_logical_operator"
20085                      [(match_operand:SI 1 "memory_operand" "")
20086                       (match_dup 0)]))
20087               (clobber (reg:CC FLAGS_REG))])]
20088   "! optimize_size && ! TARGET_READ_MODIFY"
20089   [(set (match_dup 2) (match_dup 1))
20090    (parallel [(set (match_dup 0)
20091                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20092               (clobber (reg:CC FLAGS_REG))])]
20093   "")
20094
20095 ; Don't do logical operations with memory outputs
20096 ;
20097 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20098 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20099 ; the same decoder scheduling characteristics as the original.
20100
20101 (define_peephole2
20102   [(match_scratch:SI 2 "r")
20103    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20104                    (match_operator:SI 3 "arith_or_logical_operator"
20105                      [(match_dup 0)
20106                       (match_operand:SI 1 "nonmemory_operand" "")]))
20107               (clobber (reg:CC FLAGS_REG))])]
20108   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20109   [(set (match_dup 2) (match_dup 0))
20110    (parallel [(set (match_dup 2)
20111                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20112               (clobber (reg:CC FLAGS_REG))])
20113    (set (match_dup 0) (match_dup 2))]
20114   "")
20115
20116 (define_peephole2
20117   [(match_scratch:SI 2 "r")
20118    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20119                    (match_operator:SI 3 "arith_or_logical_operator"
20120                      [(match_operand:SI 1 "nonmemory_operand" "")
20121                       (match_dup 0)]))
20122               (clobber (reg:CC FLAGS_REG))])]
20123   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20124   [(set (match_dup 2) (match_dup 0))
20125    (parallel [(set (match_dup 2)
20126                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20127               (clobber (reg:CC FLAGS_REG))])
20128    (set (match_dup 0) (match_dup 2))]
20129   "")
20130
20131 ;; Attempt to always use XOR for zeroing registers.
20132 (define_peephole2
20133   [(set (match_operand 0 "register_operand" "")
20134         (match_operand 1 "const0_operand" ""))]
20135   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20136    && (! TARGET_USE_MOV0 || optimize_size)
20137    && GENERAL_REG_P (operands[0])
20138    && peep2_regno_dead_p (0, FLAGS_REG)"
20139   [(parallel [(set (match_dup 0) (const_int 0))
20140               (clobber (reg:CC FLAGS_REG))])]
20141 {
20142   operands[0] = gen_lowpart (word_mode, operands[0]);
20143 })
20144
20145 (define_peephole2
20146   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20147         (const_int 0))]
20148   "(GET_MODE (operands[0]) == QImode
20149     || GET_MODE (operands[0]) == HImode)
20150    && (! TARGET_USE_MOV0 || optimize_size)
20151    && peep2_regno_dead_p (0, FLAGS_REG)"
20152   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20153               (clobber (reg:CC FLAGS_REG))])])
20154
20155 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20156 (define_peephole2
20157   [(set (match_operand 0 "register_operand" "")
20158         (const_int -1))]
20159   "(GET_MODE (operands[0]) == HImode
20160     || GET_MODE (operands[0]) == SImode
20161     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20162    && (optimize_size || TARGET_PENTIUM)
20163    && peep2_regno_dead_p (0, FLAGS_REG)"
20164   [(parallel [(set (match_dup 0) (const_int -1))
20165               (clobber (reg:CC FLAGS_REG))])]
20166   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20167                               operands[0]);")
20168
20169 ;; Attempt to convert simple leas to adds. These can be created by
20170 ;; move expanders.
20171 (define_peephole2
20172   [(set (match_operand:SI 0 "register_operand" "")
20173         (plus:SI (match_dup 0)
20174                  (match_operand:SI 1 "nonmemory_operand" "")))]
20175   "peep2_regno_dead_p (0, FLAGS_REG)"
20176   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20177               (clobber (reg:CC FLAGS_REG))])]
20178   "")
20179
20180 (define_peephole2
20181   [(set (match_operand:SI 0 "register_operand" "")
20182         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20183                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20184   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20185   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20186               (clobber (reg:CC FLAGS_REG))])]
20187   "operands[2] = gen_lowpart (SImode, operands[2]);")
20188
20189 (define_peephole2
20190   [(set (match_operand:DI 0 "register_operand" "")
20191         (plus:DI (match_dup 0)
20192                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20193   "peep2_regno_dead_p (0, FLAGS_REG)"
20194   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20195               (clobber (reg:CC FLAGS_REG))])]
20196   "")
20197
20198 (define_peephole2
20199   [(set (match_operand:SI 0 "register_operand" "")
20200         (mult:SI (match_dup 0)
20201                  (match_operand:SI 1 "const_int_operand" "")))]
20202   "exact_log2 (INTVAL (operands[1])) >= 0
20203    && peep2_regno_dead_p (0, FLAGS_REG)"
20204   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20205               (clobber (reg:CC FLAGS_REG))])]
20206   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20207
20208 (define_peephole2
20209   [(set (match_operand:DI 0 "register_operand" "")
20210         (mult:DI (match_dup 0)
20211                  (match_operand:DI 1 "const_int_operand" "")))]
20212   "exact_log2 (INTVAL (operands[1])) >= 0
20213    && peep2_regno_dead_p (0, FLAGS_REG)"
20214   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20215               (clobber (reg:CC FLAGS_REG))])]
20216   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20217
20218 (define_peephole2
20219   [(set (match_operand:SI 0 "register_operand" "")
20220         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20221                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20222   "exact_log2 (INTVAL (operands[2])) >= 0
20223    && REGNO (operands[0]) == REGNO (operands[1])
20224    && peep2_regno_dead_p (0, FLAGS_REG)"
20225   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20226               (clobber (reg:CC FLAGS_REG))])]
20227   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20228
20229 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20230 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20231 ;; many CPUs it is also faster, since special hardware to avoid esp
20232 ;; dependencies is present.
20233
20234 ;; While some of these conversions may be done using splitters, we use peepholes
20235 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20236
20237 ;; Convert prologue esp subtractions to push.
20238 ;; We need register to push.  In order to keep verify_flow_info happy we have
20239 ;; two choices
20240 ;; - use scratch and clobber it in order to avoid dependencies
20241 ;; - use already live register
20242 ;; We can't use the second way right now, since there is no reliable way how to
20243 ;; verify that given register is live.  First choice will also most likely in
20244 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20245 ;; call clobbered registers are dead.  We may want to use base pointer as an
20246 ;; alternative when no register is available later.
20247
20248 (define_peephole2
20249   [(match_scratch:SI 0 "r")
20250    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20251               (clobber (reg:CC FLAGS_REG))
20252               (clobber (mem:BLK (scratch)))])]
20253   "optimize_size || !TARGET_SUB_ESP_4"
20254   [(clobber (match_dup 0))
20255    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20256               (clobber (mem:BLK (scratch)))])])
20257
20258 (define_peephole2
20259   [(match_scratch:SI 0 "r")
20260    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20261               (clobber (reg:CC FLAGS_REG))
20262               (clobber (mem:BLK (scratch)))])]
20263   "optimize_size || !TARGET_SUB_ESP_8"
20264   [(clobber (match_dup 0))
20265    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20266    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20267               (clobber (mem:BLK (scratch)))])])
20268
20269 ;; Convert esp subtractions to push.
20270 (define_peephole2
20271   [(match_scratch:SI 0 "r")
20272    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20273               (clobber (reg:CC FLAGS_REG))])]
20274   "optimize_size || !TARGET_SUB_ESP_4"
20275   [(clobber (match_dup 0))
20276    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20277
20278 (define_peephole2
20279   [(match_scratch:SI 0 "r")
20280    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20281               (clobber (reg:CC FLAGS_REG))])]
20282   "optimize_size || !TARGET_SUB_ESP_8"
20283   [(clobber (match_dup 0))
20284    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20285    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20286
20287 ;; Convert epilogue deallocator to pop.
20288 (define_peephole2
20289   [(match_scratch:SI 0 "r")
20290    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20291               (clobber (reg:CC FLAGS_REG))
20292               (clobber (mem:BLK (scratch)))])]
20293   "optimize_size || !TARGET_ADD_ESP_4"
20294   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20295               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20296               (clobber (mem:BLK (scratch)))])]
20297   "")
20298
20299 ;; Two pops case is tricky, since pop causes dependency on destination register.
20300 ;; We use two registers if available.
20301 (define_peephole2
20302   [(match_scratch:SI 0 "r")
20303    (match_scratch:SI 1 "r")
20304    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20305               (clobber (reg:CC FLAGS_REG))
20306               (clobber (mem:BLK (scratch)))])]
20307   "optimize_size || !TARGET_ADD_ESP_8"
20308   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20309               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20310               (clobber (mem:BLK (scratch)))])
20311    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20312               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20313   "")
20314
20315 (define_peephole2
20316   [(match_scratch:SI 0 "r")
20317    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20318               (clobber (reg:CC FLAGS_REG))
20319               (clobber (mem:BLK (scratch)))])]
20320   "optimize_size"
20321   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20322               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20323               (clobber (mem:BLK (scratch)))])
20324    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20325               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20326   "")
20327
20328 ;; Convert esp additions to pop.
20329 (define_peephole2
20330   [(match_scratch:SI 0 "r")
20331    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20332               (clobber (reg:CC FLAGS_REG))])]
20333   ""
20334   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20335               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20336   "")
20337
20338 ;; Two pops case is tricky, since pop causes dependency on destination register.
20339 ;; We use two registers if available.
20340 (define_peephole2
20341   [(match_scratch:SI 0 "r")
20342    (match_scratch:SI 1 "r")
20343    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20344               (clobber (reg:CC FLAGS_REG))])]
20345   ""
20346   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20347               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20348    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20349               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20350   "")
20351
20352 (define_peephole2
20353   [(match_scratch:SI 0 "r")
20354    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20355               (clobber (reg:CC FLAGS_REG))])]
20356   "optimize_size"
20357   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20358               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20359    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20360               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20361   "")
20362 \f
20363 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20364 ;; required and register dies.  Similarly for 128 to plus -128.
20365 (define_peephole2
20366   [(set (match_operand 0 "flags_reg_operand" "")
20367         (match_operator 1 "compare_operator"
20368           [(match_operand 2 "register_operand" "")
20369            (match_operand 3 "const_int_operand" "")]))]
20370   "(INTVAL (operands[3]) == -1
20371     || INTVAL (operands[3]) == 1
20372     || INTVAL (operands[3]) == 128)
20373    && ix86_match_ccmode (insn, CCGCmode)
20374    && peep2_reg_dead_p (1, operands[2])"
20375   [(parallel [(set (match_dup 0)
20376                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20377               (clobber (match_dup 2))])]
20378   "")
20379 \f
20380 (define_peephole2
20381   [(match_scratch:DI 0 "r")
20382    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20383               (clobber (reg:CC FLAGS_REG))
20384               (clobber (mem:BLK (scratch)))])]
20385   "optimize_size || !TARGET_SUB_ESP_4"
20386   [(clobber (match_dup 0))
20387    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20388               (clobber (mem:BLK (scratch)))])])
20389
20390 (define_peephole2
20391   [(match_scratch:DI 0 "r")
20392    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20393               (clobber (reg:CC FLAGS_REG))
20394               (clobber (mem:BLK (scratch)))])]
20395   "optimize_size || !TARGET_SUB_ESP_8"
20396   [(clobber (match_dup 0))
20397    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20398    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20399               (clobber (mem:BLK (scratch)))])])
20400
20401 ;; Convert esp subtractions to push.
20402 (define_peephole2
20403   [(match_scratch:DI 0 "r")
20404    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20405               (clobber (reg:CC FLAGS_REG))])]
20406   "optimize_size || !TARGET_SUB_ESP_4"
20407   [(clobber (match_dup 0))
20408    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20409
20410 (define_peephole2
20411   [(match_scratch:DI 0 "r")
20412    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20413               (clobber (reg:CC FLAGS_REG))])]
20414   "optimize_size || !TARGET_SUB_ESP_8"
20415   [(clobber (match_dup 0))
20416    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20417    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20418
20419 ;; Convert epilogue deallocator to pop.
20420 (define_peephole2
20421   [(match_scratch:DI 0 "r")
20422    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20423               (clobber (reg:CC FLAGS_REG))
20424               (clobber (mem:BLK (scratch)))])]
20425   "optimize_size || !TARGET_ADD_ESP_4"
20426   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20427               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20428               (clobber (mem:BLK (scratch)))])]
20429   "")
20430
20431 ;; Two pops case is tricky, since pop causes dependency on destination register.
20432 ;; We use two registers if available.
20433 (define_peephole2
20434   [(match_scratch:DI 0 "r")
20435    (match_scratch:DI 1 "r")
20436    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20437               (clobber (reg:CC FLAGS_REG))
20438               (clobber (mem:BLK (scratch)))])]
20439   "optimize_size || !TARGET_ADD_ESP_8"
20440   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20441               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20442               (clobber (mem:BLK (scratch)))])
20443    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20444               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20445   "")
20446
20447 (define_peephole2
20448   [(match_scratch:DI 0 "r")
20449    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20450               (clobber (reg:CC FLAGS_REG))
20451               (clobber (mem:BLK (scratch)))])]
20452   "optimize_size"
20453   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20454               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20455               (clobber (mem:BLK (scratch)))])
20456    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20457               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20458   "")
20459
20460 ;; Convert esp additions to pop.
20461 (define_peephole2
20462   [(match_scratch:DI 0 "r")
20463    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20464               (clobber (reg:CC FLAGS_REG))])]
20465   ""
20466   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20467               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20468   "")
20469
20470 ;; Two pops case is tricky, since pop causes dependency on destination register.
20471 ;; We use two registers if available.
20472 (define_peephole2
20473   [(match_scratch:DI 0 "r")
20474    (match_scratch:DI 1 "r")
20475    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20476               (clobber (reg:CC FLAGS_REG))])]
20477   ""
20478   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20479               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20480    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20481               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20482   "")
20483
20484 (define_peephole2
20485   [(match_scratch:DI 0 "r")
20486    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20487               (clobber (reg:CC FLAGS_REG))])]
20488   "optimize_size"
20489   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20490               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20491    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20492               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20493   "")
20494 \f
20495 ;; Convert imul by three, five and nine into lea
20496 (define_peephole2
20497   [(parallel
20498     [(set (match_operand:SI 0 "register_operand" "")
20499           (mult:SI (match_operand:SI 1 "register_operand" "")
20500                    (match_operand:SI 2 "const_int_operand" "")))
20501      (clobber (reg:CC FLAGS_REG))])]
20502   "INTVAL (operands[2]) == 3
20503    || INTVAL (operands[2]) == 5
20504    || INTVAL (operands[2]) == 9"
20505   [(set (match_dup 0)
20506         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20507                  (match_dup 1)))]
20508   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20509
20510 (define_peephole2
20511   [(parallel
20512     [(set (match_operand:SI 0 "register_operand" "")
20513           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20514                    (match_operand:SI 2 "const_int_operand" "")))
20515      (clobber (reg:CC FLAGS_REG))])]
20516   "!optimize_size
20517    && (INTVAL (operands[2]) == 3
20518        || INTVAL (operands[2]) == 5
20519        || INTVAL (operands[2]) == 9)"
20520   [(set (match_dup 0) (match_dup 1))
20521    (set (match_dup 0)
20522         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20523                  (match_dup 0)))]
20524   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20525
20526 (define_peephole2
20527   [(parallel
20528     [(set (match_operand:DI 0 "register_operand" "")
20529           (mult:DI (match_operand:DI 1 "register_operand" "")
20530                    (match_operand:DI 2 "const_int_operand" "")))
20531      (clobber (reg:CC FLAGS_REG))])]
20532   "TARGET_64BIT
20533    && (INTVAL (operands[2]) == 3
20534        || INTVAL (operands[2]) == 5
20535        || INTVAL (operands[2]) == 9)"
20536   [(set (match_dup 0)
20537         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20538                  (match_dup 1)))]
20539   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20540
20541 (define_peephole2
20542   [(parallel
20543     [(set (match_operand:DI 0 "register_operand" "")
20544           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20545                    (match_operand:DI 2 "const_int_operand" "")))
20546      (clobber (reg:CC FLAGS_REG))])]
20547   "TARGET_64BIT
20548    && !optimize_size
20549    && (INTVAL (operands[2]) == 3
20550        || INTVAL (operands[2]) == 5
20551        || INTVAL (operands[2]) == 9)"
20552   [(set (match_dup 0) (match_dup 1))
20553    (set (match_dup 0)
20554         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20555                  (match_dup 0)))]
20556   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20557
20558 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20559 ;; imul $32bit_imm, reg, reg is direct decoded.
20560 (define_peephole2
20561   [(match_scratch:DI 3 "r")
20562    (parallel [(set (match_operand:DI 0 "register_operand" "")
20563                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20564                             (match_operand:DI 2 "immediate_operand" "")))
20565               (clobber (reg:CC FLAGS_REG))])]
20566   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20567    && !satisfies_constraint_K (operands[2])"
20568   [(set (match_dup 3) (match_dup 1))
20569    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20570               (clobber (reg:CC FLAGS_REG))])]
20571 "")
20572
20573 (define_peephole2
20574   [(match_scratch:SI 3 "r")
20575    (parallel [(set (match_operand:SI 0 "register_operand" "")
20576                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20577                             (match_operand:SI 2 "immediate_operand" "")))
20578               (clobber (reg:CC FLAGS_REG))])]
20579   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20580    && !satisfies_constraint_K (operands[2])"
20581   [(set (match_dup 3) (match_dup 1))
20582    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20583               (clobber (reg:CC FLAGS_REG))])]
20584 "")
20585
20586 (define_peephole2
20587   [(match_scratch:SI 3 "r")
20588    (parallel [(set (match_operand:DI 0 "register_operand" "")
20589                    (zero_extend:DI
20590                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20591                               (match_operand:SI 2 "immediate_operand" ""))))
20592               (clobber (reg:CC FLAGS_REG))])]
20593   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20594    && !satisfies_constraint_K (operands[2])"
20595   [(set (match_dup 3) (match_dup 1))
20596    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20597               (clobber (reg:CC FLAGS_REG))])]
20598 "")
20599
20600 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20601 ;; Convert it into imul reg, reg
20602 ;; It would be better to force assembler to encode instruction using long
20603 ;; immediate, but there is apparently no way to do so.
20604 (define_peephole2
20605   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20606                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20607                             (match_operand:DI 2 "const_int_operand" "")))
20608               (clobber (reg:CC FLAGS_REG))])
20609    (match_scratch:DI 3 "r")]
20610   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20611    && satisfies_constraint_K (operands[2])"
20612   [(set (match_dup 3) (match_dup 2))
20613    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20614               (clobber (reg:CC FLAGS_REG))])]
20615 {
20616   if (!rtx_equal_p (operands[0], operands[1]))
20617     emit_move_insn (operands[0], operands[1]);
20618 })
20619
20620 (define_peephole2
20621   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20622                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20623                             (match_operand:SI 2 "const_int_operand" "")))
20624               (clobber (reg:CC FLAGS_REG))])
20625    (match_scratch:SI 3 "r")]
20626   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20627    && satisfies_constraint_K (operands[2])"
20628   [(set (match_dup 3) (match_dup 2))
20629    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20630               (clobber (reg:CC FLAGS_REG))])]
20631 {
20632   if (!rtx_equal_p (operands[0], operands[1]))
20633     emit_move_insn (operands[0], operands[1]);
20634 })
20635
20636 (define_peephole2
20637   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20638                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20639                             (match_operand:HI 2 "immediate_operand" "")))
20640               (clobber (reg:CC FLAGS_REG))])
20641    (match_scratch:HI 3 "r")]
20642   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20643   [(set (match_dup 3) (match_dup 2))
20644    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20645               (clobber (reg:CC FLAGS_REG))])]
20646 {
20647   if (!rtx_equal_p (operands[0], operands[1]))
20648     emit_move_insn (operands[0], operands[1]);
20649 })
20650
20651 ;; After splitting up read-modify operations, array accesses with memory
20652 ;; operands might end up in form:
20653 ;;  sall    $2, %eax
20654 ;;  movl    4(%esp), %edx
20655 ;;  addl    %edx, %eax
20656 ;; instead of pre-splitting:
20657 ;;  sall    $2, %eax
20658 ;;  addl    4(%esp), %eax
20659 ;; Turn it into:
20660 ;;  movl    4(%esp), %edx
20661 ;;  leal    (%edx,%eax,4), %eax
20662
20663 (define_peephole2
20664   [(parallel [(set (match_operand 0 "register_operand" "")
20665                    (ashift (match_operand 1 "register_operand" "")
20666                            (match_operand 2 "const_int_operand" "")))
20667                (clobber (reg:CC FLAGS_REG))])
20668    (set (match_operand 3 "register_operand")
20669         (match_operand 4 "x86_64_general_operand" ""))
20670    (parallel [(set (match_operand 5 "register_operand" "")
20671                    (plus (match_operand 6 "register_operand" "")
20672                          (match_operand 7 "register_operand" "")))
20673                    (clobber (reg:CC FLAGS_REG))])]
20674   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20675    /* Validate MODE for lea.  */
20676    && ((!TARGET_PARTIAL_REG_STALL
20677         && (GET_MODE (operands[0]) == QImode
20678             || GET_MODE (operands[0]) == HImode))
20679        || GET_MODE (operands[0]) == SImode
20680        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20681    /* We reorder load and the shift.  */
20682    && !rtx_equal_p (operands[1], operands[3])
20683    && !reg_overlap_mentioned_p (operands[0], operands[4])
20684    /* Last PLUS must consist of operand 0 and 3.  */
20685    && !rtx_equal_p (operands[0], operands[3])
20686    && (rtx_equal_p (operands[3], operands[6])
20687        || rtx_equal_p (operands[3], operands[7]))
20688    && (rtx_equal_p (operands[0], operands[6])
20689        || rtx_equal_p (operands[0], operands[7]))
20690    /* The intermediate operand 0 must die or be same as output.  */
20691    && (rtx_equal_p (operands[0], operands[5])
20692        || peep2_reg_dead_p (3, operands[0]))"
20693   [(set (match_dup 3) (match_dup 4))
20694    (set (match_dup 0) (match_dup 1))]
20695 {
20696   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20697   int scale = 1 << INTVAL (operands[2]);
20698   rtx index = gen_lowpart (Pmode, operands[1]);
20699   rtx base = gen_lowpart (Pmode, operands[3]);
20700   rtx dest = gen_lowpart (mode, operands[5]);
20701
20702   operands[1] = gen_rtx_PLUS (Pmode, base,
20703                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20704   if (mode != Pmode)
20705     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20706   operands[0] = dest;
20707 })
20708 \f
20709 ;; Call-value patterns last so that the wildcard operand does not
20710 ;; disrupt insn-recog's switch tables.
20711
20712 (define_insn "*call_value_pop_0"
20713   [(set (match_operand 0 "" "")
20714         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20715               (match_operand:SI 2 "" "")))
20716    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20717                             (match_operand:SI 3 "immediate_operand" "")))]
20718   "!TARGET_64BIT"
20719 {
20720   if (SIBLING_CALL_P (insn))
20721     return "jmp\t%P1";
20722   else
20723     return "call\t%P1";
20724 }
20725   [(set_attr "type" "callv")])
20726
20727 (define_insn "*call_value_pop_1"
20728   [(set (match_operand 0 "" "")
20729         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20730               (match_operand:SI 2 "" "")))
20731    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20732                             (match_operand:SI 3 "immediate_operand" "i")))]
20733   "!TARGET_64BIT"
20734 {
20735   if (constant_call_address_operand (operands[1], Pmode))
20736     {
20737       if (SIBLING_CALL_P (insn))
20738         return "jmp\t%P1";
20739       else
20740         return "call\t%P1";
20741     }
20742   if (SIBLING_CALL_P (insn))
20743     return "jmp\t%A1";
20744   else
20745     return "call\t%A1";
20746 }
20747   [(set_attr "type" "callv")])
20748
20749 (define_insn "*call_value_0"
20750   [(set (match_operand 0 "" "")
20751         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20752               (match_operand:SI 2 "" "")))]
20753   "!TARGET_64BIT"
20754 {
20755   if (SIBLING_CALL_P (insn))
20756     return "jmp\t%P1";
20757   else
20758     return "call\t%P1";
20759 }
20760   [(set_attr "type" "callv")])
20761
20762 (define_insn "*call_value_0_rex64"
20763   [(set (match_operand 0 "" "")
20764         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20765               (match_operand:DI 2 "const_int_operand" "")))]
20766   "TARGET_64BIT"
20767 {
20768   if (SIBLING_CALL_P (insn))
20769     return "jmp\t%P1";
20770   else
20771     return "call\t%P1";
20772 }
20773   [(set_attr "type" "callv")])
20774
20775 (define_insn "*call_value_1"
20776   [(set (match_operand 0 "" "")
20777         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20778               (match_operand:SI 2 "" "")))]
20779   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20780 {
20781   if (constant_call_address_operand (operands[1], Pmode))
20782     return "call\t%P1";
20783   return "call\t%A1";
20784 }
20785   [(set_attr "type" "callv")])
20786
20787 (define_insn "*sibcall_value_1"
20788   [(set (match_operand 0 "" "")
20789         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20790               (match_operand:SI 2 "" "")))]
20791   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20792 {
20793   if (constant_call_address_operand (operands[1], Pmode))
20794     return "jmp\t%P1";
20795   return "jmp\t%A1";
20796 }
20797   [(set_attr "type" "callv")])
20798
20799 (define_insn "*call_value_1_rex64"
20800   [(set (match_operand 0 "" "")
20801         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20802               (match_operand:DI 2 "" "")))]
20803   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20804 {
20805   if (constant_call_address_operand (operands[1], Pmode))
20806     return "call\t%P1";
20807   return "call\t%A1";
20808 }
20809   [(set_attr "type" "callv")])
20810
20811 (define_insn "*sibcall_value_1_rex64"
20812   [(set (match_operand 0 "" "")
20813         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20814               (match_operand:DI 2 "" "")))]
20815   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20816   "jmp\t%P1"
20817   [(set_attr "type" "callv")])
20818
20819 (define_insn "*sibcall_value_1_rex64_v"
20820   [(set (match_operand 0 "" "")
20821         (call (mem:QI (reg:DI R11_REG))
20822               (match_operand:DI 1 "" "")))]
20823   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20824   "jmp\t*%%r11"
20825   [(set_attr "type" "callv")])
20826 \f
20827 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20828 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20829 ;; caught for use by garbage collectors and the like.  Using an insn that
20830 ;; maps to SIGILL makes it more likely the program will rightfully die.
20831 ;; Keeping with tradition, "6" is in honor of #UD.
20832 (define_insn "trap"
20833   [(trap_if (const_int 1) (const_int 6))]
20834   ""
20835   { return ASM_SHORT "0x0b0f"; }
20836   [(set_attr "length" "2")])
20837
20838 (define_expand "sse_prologue_save"
20839   [(parallel [(set (match_operand:BLK 0 "" "")
20840                    (unspec:BLK [(reg:DI 22)
20841                                 (reg:DI 23)
20842                                 (reg:DI 24)
20843                                 (reg:DI 25)
20844                                 (reg:DI 26)
20845                                 (reg:DI 27)
20846                                 (reg:DI 28)
20847                                 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20848               (use (match_operand:DI 1 "register_operand" ""))
20849               (use (match_operand:DI 2 "immediate_operand" ""))
20850               (use (label_ref:DI (match_operand 3 "" "")))])]
20851   "TARGET_64BIT"
20852   "")
20853
20854 (define_insn "*sse_prologue_save_insn"
20855   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20856                           (match_operand:DI 4 "const_int_operand" "n")))
20857         (unspec:BLK [(reg:DI 22)
20858                      (reg:DI 23)
20859                      (reg:DI 24)
20860                      (reg:DI 25)
20861                      (reg:DI 26)
20862                      (reg:DI 27)
20863                      (reg:DI 28)
20864                      (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20865    (use (match_operand:DI 1 "register_operand" "r"))
20866    (use (match_operand:DI 2 "const_int_operand" "i"))
20867    (use (label_ref:DI (match_operand 3 "" "X")))]
20868   "TARGET_64BIT
20869    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20870    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20871   "*
20872 {
20873   int i;
20874   operands[0] = gen_rtx_MEM (Pmode,
20875                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20876   output_asm_insn (\"jmp\\t%A1\", operands);
20877   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20878     {
20879       operands[4] = adjust_address (operands[0], DImode, i*16);
20880       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20881       PUT_MODE (operands[4], TImode);
20882       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20883         output_asm_insn (\"rex\", operands);
20884       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20885     }
20886   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20887                              CODE_LABEL_NUMBER (operands[3]));
20888   RET;
20889 }
20890   "
20891   [(set_attr "type" "other")
20892    (set_attr "length_immediate" "0")
20893    (set_attr "length_address" "0")
20894    (set_attr "length" "135")
20895    (set_attr "memory" "store")
20896    (set_attr "modrm" "0")
20897    (set_attr "mode" "DI")])
20898
20899 (define_expand "prefetch"
20900   [(prefetch (match_operand 0 "address_operand" "")
20901              (match_operand:SI 1 "const_int_operand" "")
20902              (match_operand:SI 2 "const_int_operand" ""))]
20903   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20904 {
20905   int rw = INTVAL (operands[1]);
20906   int locality = INTVAL (operands[2]);
20907
20908   gcc_assert (rw == 0 || rw == 1);
20909   gcc_assert (locality >= 0 && locality <= 3);
20910   gcc_assert (GET_MODE (operands[0]) == Pmode
20911               || GET_MODE (operands[0]) == VOIDmode);
20912
20913   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20914      supported by SSE counterpart or the SSE prefetch is not available
20915      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20916      of locality.  */
20917   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20918     operands[2] = GEN_INT (3);
20919   else
20920     operands[1] = const0_rtx;
20921 })
20922
20923 (define_insn "*prefetch_sse"
20924   [(prefetch (match_operand:SI 0 "address_operand" "p")
20925              (const_int 0)
20926              (match_operand:SI 1 "const_int_operand" ""))]
20927   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20928 {
20929   static const char * const patterns[4] = {
20930    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20931   };
20932
20933   int locality = INTVAL (operands[1]);
20934   gcc_assert (locality >= 0 && locality <= 3);
20935
20936   return patterns[locality];
20937 }
20938   [(set_attr "type" "sse")
20939    (set_attr "memory" "none")])
20940
20941 (define_insn "*prefetch_sse_rex"
20942   [(prefetch (match_operand:DI 0 "address_operand" "p")
20943              (const_int 0)
20944              (match_operand:SI 1 "const_int_operand" ""))]
20945   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20946 {
20947   static const char * const patterns[4] = {
20948    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20949   };
20950
20951   int locality = INTVAL (operands[1]);
20952   gcc_assert (locality >= 0 && locality <= 3);
20953
20954   return patterns[locality];
20955 }
20956   [(set_attr "type" "sse")
20957    (set_attr "memory" "none")])
20958
20959 (define_insn "*prefetch_3dnow"
20960   [(prefetch (match_operand:SI 0 "address_operand" "p")
20961              (match_operand:SI 1 "const_int_operand" "n")
20962              (const_int 3))]
20963   "TARGET_3DNOW && !TARGET_64BIT"
20964 {
20965   if (INTVAL (operands[1]) == 0)
20966     return "prefetch\t%a0";
20967   else
20968     return "prefetchw\t%a0";
20969 }
20970   [(set_attr "type" "mmx")
20971    (set_attr "memory" "none")])
20972
20973 (define_insn "*prefetch_3dnow_rex"
20974   [(prefetch (match_operand:DI 0 "address_operand" "p")
20975              (match_operand:SI 1 "const_int_operand" "n")
20976              (const_int 3))]
20977   "TARGET_3DNOW && TARGET_64BIT"
20978 {
20979   if (INTVAL (operands[1]) == 0)
20980     return "prefetch\t%a0";
20981   else
20982     return "prefetchw\t%a0";
20983 }
20984   [(set_attr "type" "mmx")
20985    (set_attr "memory" "none")])
20986
20987 (define_expand "stack_protect_set"
20988   [(match_operand 0 "memory_operand" "")
20989    (match_operand 1 "memory_operand" "")]
20990   ""
20991 {
20992 #ifdef TARGET_THREAD_SSP_OFFSET
20993   if (TARGET_64BIT)
20994     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20995                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20996   else
20997     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20998                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20999 #else
21000   if (TARGET_64BIT)
21001     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21002   else
21003     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21004 #endif
21005   DONE;
21006 })
21007
21008 (define_insn "stack_protect_set_si"
21009   [(set (match_operand:SI 0 "memory_operand" "=m")
21010         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21011    (set (match_scratch:SI 2 "=&r") (const_int 0))
21012    (clobber (reg:CC FLAGS_REG))]
21013   ""
21014   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21015   [(set_attr "type" "multi")])
21016
21017 (define_insn "stack_protect_set_di"
21018   [(set (match_operand:DI 0 "memory_operand" "=m")
21019         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21020    (set (match_scratch:DI 2 "=&r") (const_int 0))
21021    (clobber (reg:CC FLAGS_REG))]
21022   "TARGET_64BIT"
21023   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21024   [(set_attr "type" "multi")])
21025
21026 (define_insn "stack_tls_protect_set_si"
21027   [(set (match_operand:SI 0 "memory_operand" "=m")
21028         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21029    (set (match_scratch:SI 2 "=&r") (const_int 0))
21030    (clobber (reg:CC FLAGS_REG))]
21031   ""
21032   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21033   [(set_attr "type" "multi")])
21034
21035 (define_insn "stack_tls_protect_set_di"
21036   [(set (match_operand:DI 0 "memory_operand" "=m")
21037         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21038    (set (match_scratch:DI 2 "=&r") (const_int 0))
21039    (clobber (reg:CC FLAGS_REG))]
21040   "TARGET_64BIT"
21041   {
21042      /* The kernel uses a different segment register for performance reasons; a
21043         system call would not have to trash the userspace segment register,
21044         which would be expensive */
21045      if (ix86_cmodel != CM_KERNEL)
21046         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21047      else
21048         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21049   }
21050   [(set_attr "type" "multi")])
21051
21052 (define_expand "stack_protect_test"
21053   [(match_operand 0 "memory_operand" "")
21054    (match_operand 1 "memory_operand" "")
21055    (match_operand 2 "" "")]
21056   ""
21057 {
21058   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21059   ix86_compare_op0 = operands[0];
21060   ix86_compare_op1 = operands[1];
21061   ix86_compare_emitted = flags;
21062
21063 #ifdef TARGET_THREAD_SSP_OFFSET
21064   if (TARGET_64BIT)
21065     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21066                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21067   else
21068     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21069                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21070 #else
21071   if (TARGET_64BIT)
21072     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21073   else
21074     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21075 #endif
21076   emit_jump_insn (gen_beq (operands[2]));
21077   DONE;
21078 })
21079
21080 (define_insn "stack_protect_test_si"
21081   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21082         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21083                      (match_operand:SI 2 "memory_operand" "m")]
21084                     UNSPEC_SP_TEST))
21085    (clobber (match_scratch:SI 3 "=&r"))]
21086   ""
21087   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21088   [(set_attr "type" "multi")])
21089
21090 (define_insn "stack_protect_test_di"
21091   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21092         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21093                      (match_operand:DI 2 "memory_operand" "m")]
21094                     UNSPEC_SP_TEST))
21095    (clobber (match_scratch:DI 3 "=&r"))]
21096   "TARGET_64BIT"
21097   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21098   [(set_attr "type" "multi")])
21099
21100 (define_insn "stack_tls_protect_test_si"
21101   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21102         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21103                      (match_operand:SI 2 "const_int_operand" "i")]
21104                     UNSPEC_SP_TLS_TEST))
21105    (clobber (match_scratch:SI 3 "=r"))]
21106   ""
21107   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21108   [(set_attr "type" "multi")])
21109
21110 (define_insn "stack_tls_protect_test_di"
21111   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21112         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21113                      (match_operand:DI 2 "const_int_operand" "i")]
21114                     UNSPEC_SP_TLS_TEST))
21115    (clobber (match_scratch:DI 3 "=r"))]
21116   "TARGET_64BIT"
21117   {
21118      /* The kernel uses a different segment register for performance reasons; a
21119         system call would not have to trash the userspace segment register,
21120         which would be expensive */
21121      if (ix86_cmodel != CM_KERNEL)
21122         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21123      else
21124         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21125   }
21126   [(set_attr "type" "multi")])
21127
21128 (include "mmx.md")
21129 (include "sse.md")
21130 (include "sync.md")