OSDN Git Service

a518aaeaca9d7da467e5cb485f34e36bf58c8c7e
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, 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 COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
23 ;;
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26 ;;
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28 ;;
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
31 ;;     operands[1].
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
39 ;;
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;;     %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
46
47 ;; UNSPEC usage:
48
49 (define_constants
50   [; Relocation specifiers
51    (UNSPEC_GOT                  0)
52    (UNSPEC_GOTOFF               1)
53    (UNSPEC_GOTPCREL             2)
54    (UNSPEC_GOTTPOFF             3)
55    (UNSPEC_TPOFF                4)
56    (UNSPEC_NTPOFF               5)
57    (UNSPEC_DTPOFF               6)
58    (UNSPEC_GOTNTPOFF            7)
59    (UNSPEC_INDNTPOFF            8)
60    (UNSPEC_PLTOFF               9)
61
62    ; Prologue support
63    (UNSPEC_STACK_ALLOC          11)
64    (UNSPEC_SET_GOT              12)
65    (UNSPEC_SSE_PROLOGUE_SAVE    13)
66    (UNSPEC_REG_SAVE             14)
67    (UNSPEC_DEF_CFA              15)
68    (UNSPEC_SET_RIP              16)
69    (UNSPEC_SET_GOT_OFFSET       17)
70
71    ; TLS support
72    (UNSPEC_TP                   18)
73    (UNSPEC_TLS_GD               19)
74    (UNSPEC_TLS_LD_BASE          20)
75    (UNSPEC_TLSDESC              21)
76
77    ; Other random patterns
78    (UNSPEC_SCAS                 30)
79    (UNSPEC_FNSTSW               31)
80    (UNSPEC_SAHF                 32)
81    (UNSPEC_FSTCW                33)
82    (UNSPEC_ADD_CARRY            34)
83    (UNSPEC_FLDCW                35)
84    (UNSPEC_REP                  36)
85    (UNSPEC_EH_RETURN            37)
86    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
87    (UNSPEC_TRUNC_NOOP           39)
88
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          40)
91    (UNSPEC_MASKMOV              41)
92    (UNSPEC_MOVMSK               42)
93    (UNSPEC_MOVNT                43)
94    (UNSPEC_MOVU                 44)
95    (UNSPEC_RCP                  45)
96    (UNSPEC_RSQRT                46)
97    (UNSPEC_SFENCE               47)
98    (UNSPEC_NOP                  48)     ; prevents combiner cleverness
99    (UNSPEC_PFRCP                49)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDDQU                47)
108
109    ; Generic math support
110    (UNSPEC_COPYSIGN             50)
111    (UNSPEC_IEEE_MIN             51)     ; not commutative
112    (UNSPEC_IEEE_MAX             52)     ; not commutative
113
114    ; x87 Floating point
115    (UNSPEC_SIN                  60)
116    (UNSPEC_COS                  61)
117    (UNSPEC_FPATAN               62)
118    (UNSPEC_FYL2X                63)
119    (UNSPEC_FYL2XP1              64)
120    (UNSPEC_FRNDINT              65)
121    (UNSPEC_FIST                 66)
122    (UNSPEC_F2XM1                67)
123    (UNSPEC_TAN                  68)
124    (UNSPEC_FXAM                 69)
125
126    ; x87 Rounding
127    (UNSPEC_FRNDINT_FLOOR        70)
128    (UNSPEC_FRNDINT_CEIL         71)
129    (UNSPEC_FRNDINT_TRUNC        72)
130    (UNSPEC_FRNDINT_MASK_PM      73)
131    (UNSPEC_FIST_FLOOR           74)
132    (UNSPEC_FIST_CEIL            75)
133
134    ; x87 Double output FP
135    (UNSPEC_SINCOS_COS           80)
136    (UNSPEC_SINCOS_SIN           81)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
145
146    (UNSPEC_C2_FLAG              95)
147
148    ; SSP patterns
149    (UNSPEC_SP_SET               100)
150    (UNSPEC_SP_TEST              101)
151    (UNSPEC_SP_TLS_SET           102)
152    (UNSPEC_SP_TLS_TEST          103)
153
154    ; SSSE3
155    (UNSPEC_PSHUFB               120)
156    (UNSPEC_PSIGN                121)
157    (UNSPEC_PALIGNR              122)
158
159    ; For SSE4A support
160    (UNSPEC_EXTRQI               130)
161    (UNSPEC_EXTRQ                131)   
162    (UNSPEC_INSERTQI             132)
163    (UNSPEC_INSERTQ              133)
164
165    ; For SSE4.1 support
166    (UNSPEC_BLENDV               134)
167    (UNSPEC_INSERTPS             135)
168    (UNSPEC_DP                   136)
169    (UNSPEC_MOVNTDQA             137)
170    (UNSPEC_MPSADBW              138)
171    (UNSPEC_PHMINPOSUW           139)
172    (UNSPEC_PTEST                140)
173    (UNSPEC_ROUND                141)
174
175    ; For SSE4.2 support
176    (UNSPEC_CRC32                143)
177    (UNSPEC_PCMPESTR             144)
178    (UNSPEC_PCMPISTR             145)
179   ])
180
181 (define_constants
182   [(UNSPECV_BLOCKAGE            0)
183    (UNSPECV_STACK_PROBE         1)
184    (UNSPECV_EMMS                2)
185    (UNSPECV_LDMXCSR             3)
186    (UNSPECV_STMXCSR             4)
187    (UNSPECV_FEMMS               5)
188    (UNSPECV_CLFLUSH             6)
189    (UNSPECV_ALIGN               7)
190    (UNSPECV_MONITOR             8)
191    (UNSPECV_MWAIT               9)
192    (UNSPECV_CMPXCHG_1           10)
193    (UNSPECV_CMPXCHG_2           11)
194    (UNSPECV_XCHG                12)
195    (UNSPECV_LOCK                13)
196    (UNSPECV_PROLOGUE_USE        14)
197   ])
198
199 ;; Registers by name.
200 (define_constants
201   [(BP_REG                       6)
202    (SP_REG                       7)
203    (FLAGS_REG                   17)
204    (FPSR_REG                    18)
205    (FPCR_REG                    19)
206    (R10_REG                     39)
207    (R11_REG                     40)
208   ])
209
210 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
211 ;; from i386.c.
212
213 ;; In C guard expressions, put expressions which may be compile-time
214 ;; constants first.  This allows for better optimization.  For
215 ;; example, write "TARGET_64BIT && reload_completed", not
216 ;; "reload_completed && TARGET_64BIT".
217
218 \f
219 ;; Processor type.  This attribute must exactly match the processor_type
220 ;; enumeration in i386.h.
221 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
222                     nocona,core2,generic32,generic64,amdfam10"
223   (const (symbol_ref "ix86_tune")))
224
225 ;; A basic instruction type.  Refinements due to arguments to be
226 ;; provided in other attributes.
227 (define_attr "type"
228   "other,multi,
229    alu,alu1,negnot,imov,imovx,lea,
230    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
231    icmp,test,ibr,setcc,icmov,
232    push,pop,call,callv,leave,
233    str,bitmanip,
234    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
235    sselog,sselog1,sseiadd,sseishft,sseimul,
236    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
237    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
238   (const_string "other"))
239
240 ;; Main data type used by the insn
241 (define_attr "mode"
242   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
243   (const_string "unknown"))
244
245 ;; The CPU unit operations uses.
246 (define_attr "unit" "integer,i387,sse,mmx,unknown"
247   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
248            (const_string "i387")
249          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
250                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
251            (const_string "sse")
252          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
253            (const_string "mmx")
254          (eq_attr "type" "other")
255            (const_string "unknown")]
256          (const_string "integer")))
257
258 ;; The (bounding maximum) length of an instruction immediate.
259 (define_attr "length_immediate" ""
260   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
261                           bitmanip")
262            (const_int 0)
263          (eq_attr "unit" "i387,sse,mmx")
264            (const_int 0)
265          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
266                           imul,icmp,push,pop")
267            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
268          (eq_attr "type" "imov,test")
269            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
270          (eq_attr "type" "call")
271            (if_then_else (match_operand 0 "constant_call_address_operand" "")
272              (const_int 4)
273              (const_int 0))
274          (eq_attr "type" "callv")
275            (if_then_else (match_operand 1 "constant_call_address_operand" "")
276              (const_int 4)
277              (const_int 0))
278          ;; We don't know the size before shorten_branches.  Expect
279          ;; the instruction to fit for better scheduling.
280          (eq_attr "type" "ibr")
281            (const_int 1)
282          ]
283          (symbol_ref "/* Update immediate_length and other attributes! */
284                       gcc_unreachable (),1")))
285
286 ;; The (bounding maximum) length of an instruction address.
287 (define_attr "length_address" ""
288   (cond [(eq_attr "type" "str,other,multi,fxch")
289            (const_int 0)
290          (and (eq_attr "type" "call")
291               (match_operand 0 "constant_call_address_operand" ""))
292              (const_int 0)
293          (and (eq_attr "type" "callv")
294               (match_operand 1 "constant_call_address_operand" ""))
295              (const_int 0)
296          ]
297          (symbol_ref "ix86_attr_length_address_default (insn)")))
298
299 ;; Set when length prefix is used.
300 (define_attr "prefix_data16" ""
301   (if_then_else (ior (eq_attr "mode" "HI")
302                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
303     (const_int 1)
304     (const_int 0)))
305
306 ;; Set when string REP prefix is used.
307 (define_attr "prefix_rep" ""
308   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
309     (const_int 1)
310     (const_int 0)))
311
312 ;; Set when 0f opcode prefix is used.
313 (define_attr "prefix_0f" ""
314   (if_then_else
315     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
316          (eq_attr "unit" "sse,mmx"))
317     (const_int 1)
318     (const_int 0)))
319
320 ;; Set when REX opcode prefix is used.
321 (define_attr "prefix_rex" ""
322   (cond [(and (eq_attr "mode" "DI")
323               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
324            (const_int 1)
325          (and (eq_attr "mode" "QI")
326               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
327                   (const_int 0)))
328            (const_int 1)
329          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
330              (const_int 0))
331            (const_int 1)
332         ]
333         (const_int 0)))
334
335 ;; There are also additional prefixes in SSSE3.
336 (define_attr "prefix_extra" "" (const_int 0))
337
338 ;; Set when modrm byte is used.
339 (define_attr "modrm" ""
340   (cond [(eq_attr "type" "str,leave")
341            (const_int 0)
342          (eq_attr "unit" "i387")
343            (const_int 0)
344          (and (eq_attr "type" "incdec")
345               (ior (match_operand:SI 1 "register_operand" "")
346                    (match_operand:HI 1 "register_operand" "")))
347            (const_int 0)
348          (and (eq_attr "type" "push")
349               (not (match_operand 1 "memory_operand" "")))
350            (const_int 0)
351          (and (eq_attr "type" "pop")
352               (not (match_operand 0 "memory_operand" "")))
353            (const_int 0)
354          (and (eq_attr "type" "imov")
355               (ior (and (match_operand 0 "register_operand" "")
356                         (match_operand 1 "immediate_operand" ""))
357                    (ior (and (match_operand 0 "ax_reg_operand" "")
358                              (match_operand 1 "memory_displacement_only_operand" ""))
359                         (and (match_operand 0 "memory_displacement_only_operand" "")
360                              (match_operand 1 "ax_reg_operand" "")))))
361            (const_int 0)
362          (and (eq_attr "type" "call")
363               (match_operand 0 "constant_call_address_operand" ""))
364              (const_int 0)
365          (and (eq_attr "type" "callv")
366               (match_operand 1 "constant_call_address_operand" ""))
367              (const_int 0)
368          ]
369          (const_int 1)))
370
371 ;; The (bounding maximum) length of an instruction in bytes.
372 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
373 ;; Later we may want to split them and compute proper length as for
374 ;; other insns.
375 (define_attr "length" ""
376   (cond [(eq_attr "type" "other,multi,fistp,frndint")
377            (const_int 16)
378          (eq_attr "type" "fcmp")
379            (const_int 4)
380          (eq_attr "unit" "i387")
381            (plus (const_int 2)
382                  (plus (attr "prefix_data16")
383                        (attr "length_address")))]
384          (plus (plus (attr "modrm")
385                      (plus (attr "prefix_0f")
386                            (plus (attr "prefix_rex")
387                                  (plus (attr "prefix_extra")
388                                        (const_int 1)))))
389                (plus (attr "prefix_rep")
390                      (plus (attr "prefix_data16")
391                            (plus (attr "length_immediate")
392                                  (attr "length_address")))))))
393
394 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
395 ;; `store' if there is a simple memory reference therein, or `unknown'
396 ;; if the instruction is complex.
397
398 (define_attr "memory" "none,load,store,both,unknown"
399   (cond [(eq_attr "type" "other,multi,str")
400            (const_string "unknown")
401          (eq_attr "type" "lea,fcmov,fpspc")
402            (const_string "none")
403          (eq_attr "type" "fistp,leave")
404            (const_string "both")
405          (eq_attr "type" "frndint")
406            (const_string "load")
407          (eq_attr "type" "push")
408            (if_then_else (match_operand 1 "memory_operand" "")
409              (const_string "both")
410              (const_string "store"))
411          (eq_attr "type" "pop")
412            (if_then_else (match_operand 0 "memory_operand" "")
413              (const_string "both")
414              (const_string "load"))
415          (eq_attr "type" "setcc")
416            (if_then_else (match_operand 0 "memory_operand" "")
417              (const_string "store")
418              (const_string "none"))
419          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
420            (if_then_else (ior (match_operand 0 "memory_operand" "")
421                               (match_operand 1 "memory_operand" ""))
422              (const_string "load")
423              (const_string "none"))
424          (eq_attr "type" "ibr")
425            (if_then_else (match_operand 0 "memory_operand" "")
426              (const_string "load")
427              (const_string "none"))
428          (eq_attr "type" "call")
429            (if_then_else (match_operand 0 "constant_call_address_operand" "")
430              (const_string "none")
431              (const_string "load"))
432          (eq_attr "type" "callv")
433            (if_then_else (match_operand 1 "constant_call_address_operand" "")
434              (const_string "none")
435              (const_string "load"))
436          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
437               (match_operand 1 "memory_operand" ""))
438            (const_string "both")
439          (and (match_operand 0 "memory_operand" "")
440               (match_operand 1 "memory_operand" ""))
441            (const_string "both")
442          (match_operand 0 "memory_operand" "")
443            (const_string "store")
444          (match_operand 1 "memory_operand" "")
445            (const_string "load")
446          (and (eq_attr "type"
447                  "!alu1,negnot,ishift1,
448                    imov,imovx,icmp,test,bitmanip,
449                    fmov,fcmp,fsgn,
450                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
451                    mmx,mmxmov,mmxcmp,mmxcvt")
452               (match_operand 2 "memory_operand" ""))
453            (const_string "load")
454          (and (eq_attr "type" "icmov")
455               (match_operand 3 "memory_operand" ""))
456            (const_string "load")
457         ]
458         (const_string "none")))
459
460 ;; Indicates if an instruction has both an immediate and a displacement.
461
462 (define_attr "imm_disp" "false,true,unknown"
463   (cond [(eq_attr "type" "other,multi")
464            (const_string "unknown")
465          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
466               (and (match_operand 0 "memory_displacement_operand" "")
467                    (match_operand 1 "immediate_operand" "")))
468            (const_string "true")
469          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
470               (and (match_operand 0 "memory_displacement_operand" "")
471                    (match_operand 2 "immediate_operand" "")))
472            (const_string "true")
473         ]
474         (const_string "false")))
475
476 ;; Indicates if an FP operation has an integer source.
477
478 (define_attr "fp_int_src" "false,true"
479   (const_string "false"))
480
481 ;; Defines rounding mode of an FP operation.
482
483 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
484   (const_string "any"))
485
486 ;; Describe a user's asm statement.
487 (define_asm_attributes
488   [(set_attr "length" "128")
489    (set_attr "type" "multi")])
490
491 (define_code_iterator plusminus [plus minus])
492
493 ;; Base name for define_insn and insn mnemonic.
494 (define_code_attr addsub [(plus "add") (minus "sub")])
495
496 ;; Mark commutative operators as such in constraints.
497 (define_code_attr comm [(plus "%") (minus "")])
498
499 ;; All single word integer modes.
500 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
501
502 ;; Instruction suffix for integer modes.
503 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
504
505 ;; Register class for integer modes.
506 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
507
508 ;; Immediate operand constraint for integer modes.
509 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
510
511 ;; General operand predicate for integer modes.
512 (define_mode_attr general_operand
513         [(QI "general_operand")
514          (HI "general_operand")
515          (SI "general_operand")
516          (DI "x86_64_general_operand")])
517
518 ;; All x87 floating point modes
519 (define_mode_iterator X87MODEF [SF DF XF])
520
521 ;; x87 SFmode and DFMode floating point modes
522 (define_mode_iterator X87MODEF12 [SF DF])
523
524 ;; All integer modes handled by x87 fisttp operator.
525 (define_mode_iterator X87MODEI [HI SI DI])
526
527 ;; All integer modes handled by integer x87 operators.
528 (define_mode_iterator X87MODEI12 [HI SI])
529
530 ;; All SSE floating point modes
531 (define_mode_iterator SSEMODEF [SF DF])
532
533 ;; All integer modes handled by SSE cvtts?2si* operators.
534 (define_mode_iterator SSEMODEI24 [SI DI])
535
536 ;; SSE asm suffix for floating point modes
537 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
538
539 ;; SSE vector mode corresponding to a scalar mode
540 (define_mode_attr ssevecmode
541   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
542 \f
543 ;; Scheduling descriptions
544
545 (include "pentium.md")
546 (include "ppro.md")
547 (include "k6.md")
548 (include "athlon.md")
549 (include "geode.md")
550
551 \f
552 ;; Operand and operator predicates and constraints
553
554 (include "predicates.md")
555 (include "constraints.md")
556
557 \f
558 ;; Compare instructions.
559
560 ;; All compare insns have expanders that save the operands away without
561 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
562 ;; after the cmp) will actually emit the cmpM.
563
564 (define_expand "cmpti"
565   [(set (reg:CC FLAGS_REG)
566         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
567                     (match_operand:TI 1 "x86_64_general_operand" "")))]
568   "TARGET_64BIT"
569 {
570   if (MEM_P (operands[0]) && MEM_P (operands[1]))
571     operands[0] = force_reg (TImode, operands[0]);
572   ix86_compare_op0 = operands[0];
573   ix86_compare_op1 = operands[1];
574   DONE;
575 })
576
577 (define_expand "cmpdi"
578   [(set (reg:CC FLAGS_REG)
579         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
580                     (match_operand:DI 1 "x86_64_general_operand" "")))]
581   ""
582 {
583   if (MEM_P (operands[0]) && MEM_P (operands[1]))
584     operands[0] = force_reg (DImode, operands[0]);
585   ix86_compare_op0 = operands[0];
586   ix86_compare_op1 = operands[1];
587   DONE;
588 })
589
590 (define_expand "cmpsi"
591   [(set (reg:CC FLAGS_REG)
592         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
593                     (match_operand:SI 1 "general_operand" "")))]
594   ""
595 {
596   if (MEM_P (operands[0]) && MEM_P (operands[1]))
597     operands[0] = force_reg (SImode, operands[0]);
598   ix86_compare_op0 = operands[0];
599   ix86_compare_op1 = operands[1];
600   DONE;
601 })
602
603 (define_expand "cmphi"
604   [(set (reg:CC FLAGS_REG)
605         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
606                     (match_operand:HI 1 "general_operand" "")))]
607   ""
608 {
609   if (MEM_P (operands[0]) && MEM_P (operands[1]))
610     operands[0] = force_reg (HImode, operands[0]);
611   ix86_compare_op0 = operands[0];
612   ix86_compare_op1 = operands[1];
613   DONE;
614 })
615
616 (define_expand "cmpqi"
617   [(set (reg:CC FLAGS_REG)
618         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
619                     (match_operand:QI 1 "general_operand" "")))]
620   "TARGET_QIMODE_MATH"
621 {
622   if (MEM_P (operands[0]) && MEM_P (operands[1]))
623     operands[0] = force_reg (QImode, operands[0]);
624   ix86_compare_op0 = operands[0];
625   ix86_compare_op1 = operands[1];
626   DONE;
627 })
628
629 (define_insn "cmpdi_ccno_1_rex64"
630   [(set (reg FLAGS_REG)
631         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
632                  (match_operand:DI 1 "const0_operand" "n,n")))]
633   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
634   "@
635    test{q}\t%0, %0
636    cmp{q}\t{%1, %0|%0, %1}"
637   [(set_attr "type" "test,icmp")
638    (set_attr "length_immediate" "0,1")
639    (set_attr "mode" "DI")])
640
641 (define_insn "*cmpdi_minus_1_rex64"
642   [(set (reg FLAGS_REG)
643         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
644                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
645                  (const_int 0)))]
646   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
647   "cmp{q}\t{%1, %0|%0, %1}"
648   [(set_attr "type" "icmp")
649    (set_attr "mode" "DI")])
650
651 (define_expand "cmpdi_1_rex64"
652   [(set (reg:CC FLAGS_REG)
653         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
654                     (match_operand:DI 1 "general_operand" "")))]
655   "TARGET_64BIT"
656   "")
657
658 (define_insn "cmpdi_1_insn_rex64"
659   [(set (reg FLAGS_REG)
660         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
661                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
662   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
663   "cmp{q}\t{%1, %0|%0, %1}"
664   [(set_attr "type" "icmp")
665    (set_attr "mode" "DI")])
666
667
668 (define_insn "*cmpsi_ccno_1"
669   [(set (reg FLAGS_REG)
670         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
671                  (match_operand:SI 1 "const0_operand" "n,n")))]
672   "ix86_match_ccmode (insn, CCNOmode)"
673   "@
674    test{l}\t%0, %0
675    cmp{l}\t{%1, %0|%0, %1}"
676   [(set_attr "type" "test,icmp")
677    (set_attr "length_immediate" "0,1")
678    (set_attr "mode" "SI")])
679
680 (define_insn "*cmpsi_minus_1"
681   [(set (reg FLAGS_REG)
682         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
683                            (match_operand:SI 1 "general_operand" "ri,mr"))
684                  (const_int 0)))]
685   "ix86_match_ccmode (insn, CCGOCmode)"
686   "cmp{l}\t{%1, %0|%0, %1}"
687   [(set_attr "type" "icmp")
688    (set_attr "mode" "SI")])
689
690 (define_expand "cmpsi_1"
691   [(set (reg:CC FLAGS_REG)
692         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
693                     (match_operand:SI 1 "general_operand" "ri,mr")))]
694   ""
695   "")
696
697 (define_insn "*cmpsi_1_insn"
698   [(set (reg FLAGS_REG)
699         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
700                  (match_operand:SI 1 "general_operand" "ri,mr")))]
701   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
702     && ix86_match_ccmode (insn, CCmode)"
703   "cmp{l}\t{%1, %0|%0, %1}"
704   [(set_attr "type" "icmp")
705    (set_attr "mode" "SI")])
706
707 (define_insn "*cmphi_ccno_1"
708   [(set (reg FLAGS_REG)
709         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
710                  (match_operand:HI 1 "const0_operand" "n,n")))]
711   "ix86_match_ccmode (insn, CCNOmode)"
712   "@
713    test{w}\t%0, %0
714    cmp{w}\t{%1, %0|%0, %1}"
715   [(set_attr "type" "test,icmp")
716    (set_attr "length_immediate" "0,1")
717    (set_attr "mode" "HI")])
718
719 (define_insn "*cmphi_minus_1"
720   [(set (reg FLAGS_REG)
721         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
722                            (match_operand:HI 1 "general_operand" "ri,mr"))
723                  (const_int 0)))]
724   "ix86_match_ccmode (insn, CCGOCmode)"
725   "cmp{w}\t{%1, %0|%0, %1}"
726   [(set_attr "type" "icmp")
727    (set_attr "mode" "HI")])
728
729 (define_insn "*cmphi_1"
730   [(set (reg FLAGS_REG)
731         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
732                  (match_operand:HI 1 "general_operand" "ri,mr")))]
733   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
734    && ix86_match_ccmode (insn, CCmode)"
735   "cmp{w}\t{%1, %0|%0, %1}"
736   [(set_attr "type" "icmp")
737    (set_attr "mode" "HI")])
738
739 (define_insn "*cmpqi_ccno_1"
740   [(set (reg FLAGS_REG)
741         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
742                  (match_operand:QI 1 "const0_operand" "n,n")))]
743   "ix86_match_ccmode (insn, CCNOmode)"
744   "@
745    test{b}\t%0, %0
746    cmp{b}\t{$0, %0|%0, 0}"
747   [(set_attr "type" "test,icmp")
748    (set_attr "length_immediate" "0,1")
749    (set_attr "mode" "QI")])
750
751 (define_insn "*cmpqi_1"
752   [(set (reg FLAGS_REG)
753         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
754                  (match_operand:QI 1 "general_operand" "qi,mq")))]
755   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
756     && ix86_match_ccmode (insn, CCmode)"
757   "cmp{b}\t{%1, %0|%0, %1}"
758   [(set_attr "type" "icmp")
759    (set_attr "mode" "QI")])
760
761 (define_insn "*cmpqi_minus_1"
762   [(set (reg FLAGS_REG)
763         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
764                            (match_operand:QI 1 "general_operand" "qi,mq"))
765                  (const_int 0)))]
766   "ix86_match_ccmode (insn, CCGOCmode)"
767   "cmp{b}\t{%1, %0|%0, %1}"
768   [(set_attr "type" "icmp")
769    (set_attr "mode" "QI")])
770
771 (define_insn "*cmpqi_ext_1"
772   [(set (reg FLAGS_REG)
773         (compare
774           (match_operand:QI 0 "general_operand" "Qm")
775           (subreg:QI
776             (zero_extract:SI
777               (match_operand 1 "ext_register_operand" "Q")
778               (const_int 8)
779               (const_int 8)) 0)))]
780   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
781   "cmp{b}\t{%h1, %0|%0, %h1}"
782   [(set_attr "type" "icmp")
783    (set_attr "mode" "QI")])
784
785 (define_insn "*cmpqi_ext_1_rex64"
786   [(set (reg FLAGS_REG)
787         (compare
788           (match_operand:QI 0 "register_operand" "Q")
789           (subreg:QI
790             (zero_extract:SI
791               (match_operand 1 "ext_register_operand" "Q")
792               (const_int 8)
793               (const_int 8)) 0)))]
794   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
795   "cmp{b}\t{%h1, %0|%0, %h1}"
796   [(set_attr "type" "icmp")
797    (set_attr "mode" "QI")])
798
799 (define_insn "*cmpqi_ext_2"
800   [(set (reg FLAGS_REG)
801         (compare
802           (subreg:QI
803             (zero_extract:SI
804               (match_operand 0 "ext_register_operand" "Q")
805               (const_int 8)
806               (const_int 8)) 0)
807           (match_operand:QI 1 "const0_operand" "n")))]
808   "ix86_match_ccmode (insn, CCNOmode)"
809   "test{b}\t%h0, %h0"
810   [(set_attr "type" "test")
811    (set_attr "length_immediate" "0")
812    (set_attr "mode" "QI")])
813
814 (define_expand "cmpqi_ext_3"
815   [(set (reg:CC FLAGS_REG)
816         (compare:CC
817           (subreg:QI
818             (zero_extract:SI
819               (match_operand 0 "ext_register_operand" "")
820               (const_int 8)
821               (const_int 8)) 0)
822           (match_operand:QI 1 "general_operand" "")))]
823   ""
824   "")
825
826 (define_insn "cmpqi_ext_3_insn"
827   [(set (reg FLAGS_REG)
828         (compare
829           (subreg:QI
830             (zero_extract:SI
831               (match_operand 0 "ext_register_operand" "Q")
832               (const_int 8)
833               (const_int 8)) 0)
834           (match_operand:QI 1 "general_operand" "Qmn")))]
835   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
836   "cmp{b}\t{%1, %h0|%h0, %1}"
837   [(set_attr "type" "icmp")
838    (set_attr "mode" "QI")])
839
840 (define_insn "cmpqi_ext_3_insn_rex64"
841   [(set (reg FLAGS_REG)
842         (compare
843           (subreg:QI
844             (zero_extract:SI
845               (match_operand 0 "ext_register_operand" "Q")
846               (const_int 8)
847               (const_int 8)) 0)
848           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
849   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
850   "cmp{b}\t{%1, %h0|%h0, %1}"
851   [(set_attr "type" "icmp")
852    (set_attr "mode" "QI")])
853
854 (define_insn "*cmpqi_ext_4"
855   [(set (reg FLAGS_REG)
856         (compare
857           (subreg:QI
858             (zero_extract:SI
859               (match_operand 0 "ext_register_operand" "Q")
860               (const_int 8)
861               (const_int 8)) 0)
862           (subreg:QI
863             (zero_extract:SI
864               (match_operand 1 "ext_register_operand" "Q")
865               (const_int 8)
866               (const_int 8)) 0)))]
867   "ix86_match_ccmode (insn, CCmode)"
868   "cmp{b}\t{%h1, %h0|%h0, %h1}"
869   [(set_attr "type" "icmp")
870    (set_attr "mode" "QI")])
871
872 ;; These implement float point compares.
873 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
874 ;; which would allow mix and match FP modes on the compares.  Which is what
875 ;; the old patterns did, but with many more of them.
876
877 (define_expand "cmpxf"
878   [(set (reg:CC FLAGS_REG)
879         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
880                     (match_operand:XF 1 "nonmemory_operand" "")))]
881   "TARGET_80387"
882 {
883   ix86_compare_op0 = operands[0];
884   ix86_compare_op1 = operands[1];
885   DONE;
886 })
887
888 (define_expand "cmp<mode>"
889   [(set (reg:CC FLAGS_REG)
890         (compare:CC (match_operand:SSEMODEF 0 "cmp_fp_expander_operand" "")
891                     (match_operand:SSEMODEF 1 "cmp_fp_expander_operand" "")))]
892   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
893 {
894   ix86_compare_op0 = operands[0];
895   ix86_compare_op1 = operands[1];
896   DONE;
897 })
898
899 ;; FP compares, step 1:
900 ;; Set the FP condition codes.
901 ;;
902 ;; CCFPmode     compare with exceptions
903 ;; CCFPUmode    compare with no exceptions
904
905 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
906 ;; used to manage the reg stack popping would not be preserved.
907
908 (define_insn "*cmpfp_0"
909   [(set (match_operand:HI 0 "register_operand" "=a")
910         (unspec:HI
911           [(compare:CCFP
912              (match_operand 1 "register_operand" "f")
913              (match_operand 2 "const0_operand" "X"))]
914         UNSPEC_FNSTSW))]
915   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
916    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
917   "* return output_fp_compare (insn, operands, 0, 0);"
918   [(set_attr "type" "multi")
919    (set_attr "unit" "i387")
920    (set (attr "mode")
921      (cond [(match_operand:SF 1 "" "")
922               (const_string "SF")
923             (match_operand:DF 1 "" "")
924               (const_string "DF")
925            ]
926            (const_string "XF")))])
927
928 (define_insn_and_split "*cmpfp_0_cc"
929   [(set (reg:CCFP FLAGS_REG)
930         (compare:CCFP
931           (match_operand 1 "register_operand" "f")
932           (match_operand 2 "const0_operand" "X")))
933    (clobber (match_operand:HI 0 "register_operand" "=a"))]
934   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
935    && TARGET_SAHF && !TARGET_CMOVE
936    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
937   "#"
938   "&& reload_completed"
939   [(set (match_dup 0)
940         (unspec:HI
941           [(compare:CCFP (match_dup 1)(match_dup 2))]
942         UNSPEC_FNSTSW))
943    (set (reg:CC FLAGS_REG)
944         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
945   ""
946   [(set_attr "type" "multi")
947    (set_attr "unit" "i387")
948    (set (attr "mode")
949      (cond [(match_operand:SF 1 "" "")
950               (const_string "SF")
951             (match_operand:DF 1 "" "")
952               (const_string "DF")
953            ]
954            (const_string "XF")))])
955
956 (define_insn "*cmpfp_xf"
957   [(set (match_operand:HI 0 "register_operand" "=a")
958         (unspec:HI
959           [(compare:CCFP
960              (match_operand:XF 1 "register_operand" "f")
961              (match_operand:XF 2 "register_operand" "f"))]
962           UNSPEC_FNSTSW))]
963   "TARGET_80387"
964   "* return output_fp_compare (insn, operands, 0, 0);"
965   [(set_attr "type" "multi")
966    (set_attr "unit" "i387")
967    (set_attr "mode" "XF")])
968
969 (define_insn_and_split "*cmpfp_xf_cc"
970   [(set (reg:CCFP FLAGS_REG)
971         (compare:CCFP
972           (match_operand:XF 1 "register_operand" "f")
973           (match_operand:XF 2 "register_operand" "f")))
974    (clobber (match_operand:HI 0 "register_operand" "=a"))]
975   "TARGET_80387
976    && TARGET_SAHF && !TARGET_CMOVE"
977   "#"
978   "&& reload_completed"
979   [(set (match_dup 0)
980         (unspec:HI
981           [(compare:CCFP (match_dup 1)(match_dup 2))]
982         UNSPEC_FNSTSW))
983    (set (reg:CC FLAGS_REG)
984         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
985   ""
986   [(set_attr "type" "multi")
987    (set_attr "unit" "i387")
988    (set_attr "mode" "XF")])
989
990 (define_insn "*cmpfp_<mode>"
991   [(set (match_operand:HI 0 "register_operand" "=a")
992         (unspec:HI
993           [(compare:CCFP
994              (match_operand:X87MODEF12 1 "register_operand" "f")
995              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm"))]
996           UNSPEC_FNSTSW))]
997   "TARGET_80387"
998   "* return output_fp_compare (insn, operands, 0, 0);"
999   [(set_attr "type" "multi")
1000    (set_attr "unit" "i387")
1001    (set_attr "mode" "<MODE>")])
1002
1003 (define_insn_and_split "*cmpfp_<mode>_cc"
1004   [(set (reg:CCFP FLAGS_REG)
1005         (compare:CCFP
1006           (match_operand:X87MODEF12 1 "register_operand" "f")
1007           (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm")))
1008    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1009   "TARGET_80387
1010    && TARGET_SAHF && !TARGET_CMOVE"
1011   "#"
1012   "&& reload_completed"
1013   [(set (match_dup 0)
1014         (unspec:HI
1015           [(compare:CCFP (match_dup 1)(match_dup 2))]
1016         UNSPEC_FNSTSW))
1017    (set (reg:CC FLAGS_REG)
1018         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1019   ""
1020   [(set_attr "type" "multi")
1021    (set_attr "unit" "i387")
1022    (set_attr "mode" "<MODE>")])
1023
1024 (define_insn "*cmpfp_u"
1025   [(set (match_operand:HI 0 "register_operand" "=a")
1026         (unspec:HI
1027           [(compare:CCFPU
1028              (match_operand 1 "register_operand" "f")
1029              (match_operand 2 "register_operand" "f"))]
1030           UNSPEC_FNSTSW))]
1031   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1032    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1033   "* return output_fp_compare (insn, operands, 0, 1);"
1034   [(set_attr "type" "multi")
1035    (set_attr "unit" "i387")
1036    (set (attr "mode")
1037      (cond [(match_operand:SF 1 "" "")
1038               (const_string "SF")
1039             (match_operand:DF 1 "" "")
1040               (const_string "DF")
1041            ]
1042            (const_string "XF")))])
1043
1044 (define_insn_and_split "*cmpfp_u_cc"
1045   [(set (reg:CCFPU FLAGS_REG)
1046         (compare:CCFPU
1047           (match_operand 1 "register_operand" "f")
1048           (match_operand 2 "register_operand" "f")))
1049    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1050   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1051    && TARGET_SAHF && !TARGET_CMOVE
1052    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1053   "#"
1054   "&& reload_completed"
1055   [(set (match_dup 0)
1056         (unspec:HI
1057           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1058         UNSPEC_FNSTSW))
1059    (set (reg:CC FLAGS_REG)
1060         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1061   ""
1062   [(set_attr "type" "multi")
1063    (set_attr "unit" "i387")
1064    (set (attr "mode")
1065      (cond [(match_operand:SF 1 "" "")
1066               (const_string "SF")
1067             (match_operand:DF 1 "" "")
1068               (const_string "DF")
1069            ]
1070            (const_string "XF")))])
1071
1072 (define_insn "*cmpfp_<mode>"
1073   [(set (match_operand:HI 0 "register_operand" "=a")
1074         (unspec:HI
1075           [(compare:CCFP
1076              (match_operand 1 "register_operand" "f")
1077              (match_operator 3 "float_operator"
1078                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1079           UNSPEC_FNSTSW))]
1080   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1081    && TARGET_USE_<MODE>MODE_FIOP
1082    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1083   "* return output_fp_compare (insn, operands, 0, 0);"
1084   [(set_attr "type" "multi")
1085    (set_attr "unit" "i387")
1086    (set_attr "fp_int_src" "true")
1087    (set_attr "mode" "<MODE>")])
1088
1089 (define_insn_and_split "*cmpfp_<mode>_cc"
1090   [(set (reg:CCFP FLAGS_REG)
1091         (compare:CCFP
1092           (match_operand 1 "register_operand" "f")
1093           (match_operator 3 "float_operator"
1094             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1095    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1096   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1097    && TARGET_SAHF && !TARGET_CMOVE
1098    && TARGET_USE_<MODE>MODE_FIOP
1099    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1100   "#"
1101   "&& reload_completed"
1102   [(set (match_dup 0)
1103         (unspec:HI
1104           [(compare:CCFP
1105              (match_dup 1)
1106              (match_op_dup 3 [(match_dup 2)]))]
1107         UNSPEC_FNSTSW))
1108    (set (reg:CC FLAGS_REG)
1109         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1110   ""
1111   [(set_attr "type" "multi")
1112    (set_attr "unit" "i387")
1113    (set_attr "fp_int_src" "true")
1114    (set_attr "mode" "<MODE>")])
1115
1116 ;; FP compares, step 2
1117 ;; Move the fpsw to ax.
1118
1119 (define_insn "x86_fnstsw_1"
1120   [(set (match_operand:HI 0 "register_operand" "=a")
1121         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1122   "TARGET_80387"
1123   "fnstsw\t%0"
1124   [(set_attr "length" "2")
1125    (set_attr "mode" "SI")
1126    (set_attr "unit" "i387")])
1127
1128 ;; FP compares, step 3
1129 ;; Get ax into flags, general case.
1130
1131 (define_insn "x86_sahf_1"
1132   [(set (reg:CC FLAGS_REG)
1133         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1134                    UNSPEC_SAHF))]
1135   "TARGET_SAHF"
1136 {
1137 #ifdef HAVE_AS_IX86_SAHF
1138   return "sahf";
1139 #else
1140   return ".byte\t0x9e";
1141 #endif
1142 }
1143   [(set_attr "length" "1")
1144    (set_attr "athlon_decode" "vector")
1145    (set_attr "amdfam10_decode" "direct")
1146    (set_attr "mode" "SI")])
1147
1148 ;; Pentium Pro can do steps 1 through 3 in one go.
1149 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
1150 (define_insn "*cmpfp_i_mixed"
1151   [(set (reg:CCFP FLAGS_REG)
1152         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1153                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1154   "TARGET_MIX_SSE_I387
1155    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1156    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1157   "* return output_fp_compare (insn, operands, 1, 0);"
1158   [(set_attr "type" "fcmp,ssecomi")
1159    (set (attr "mode")
1160      (if_then_else (match_operand:SF 1 "" "")
1161         (const_string "SF")
1162         (const_string "DF")))
1163    (set_attr "athlon_decode" "vector")
1164    (set_attr "amdfam10_decode" "direct")])
1165
1166 (define_insn "*cmpfp_i_sse"
1167   [(set (reg:CCFP FLAGS_REG)
1168         (compare:CCFP (match_operand 0 "register_operand" "x")
1169                       (match_operand 1 "nonimmediate_operand" "xm")))]
1170   "TARGET_SSE_MATH
1171    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1172    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1173   "* return output_fp_compare (insn, operands, 1, 0);"
1174   [(set_attr "type" "ssecomi")
1175    (set (attr "mode")
1176      (if_then_else (match_operand:SF 1 "" "")
1177         (const_string "SF")
1178         (const_string "DF")))
1179    (set_attr "athlon_decode" "vector")
1180    (set_attr "amdfam10_decode" "direct")])
1181
1182 (define_insn "*cmpfp_i_i387"
1183   [(set (reg:CCFP FLAGS_REG)
1184         (compare:CCFP (match_operand 0 "register_operand" "f")
1185                       (match_operand 1 "register_operand" "f")))]
1186   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1187    && TARGET_CMOVE
1188    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1189    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1190   "* return output_fp_compare (insn, operands, 1, 0);"
1191   [(set_attr "type" "fcmp")
1192    (set (attr "mode")
1193      (cond [(match_operand:SF 1 "" "")
1194               (const_string "SF")
1195             (match_operand:DF 1 "" "")
1196               (const_string "DF")
1197            ]
1198            (const_string "XF")))
1199    (set_attr "athlon_decode" "vector")
1200    (set_attr "amdfam10_decode" "direct")])
1201
1202 (define_insn "*cmpfp_iu_mixed"
1203   [(set (reg:CCFPU FLAGS_REG)
1204         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1205                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1206   "TARGET_MIX_SSE_I387
1207    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1208    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1209   "* return output_fp_compare (insn, operands, 1, 1);"
1210   [(set_attr "type" "fcmp,ssecomi")
1211    (set (attr "mode")
1212      (if_then_else (match_operand:SF 1 "" "")
1213         (const_string "SF")
1214         (const_string "DF")))
1215    (set_attr "athlon_decode" "vector")
1216    (set_attr "amdfam10_decode" "direct")])
1217
1218 (define_insn "*cmpfp_iu_sse"
1219   [(set (reg:CCFPU FLAGS_REG)
1220         (compare:CCFPU (match_operand 0 "register_operand" "x")
1221                        (match_operand 1 "nonimmediate_operand" "xm")))]
1222   "TARGET_SSE_MATH
1223    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1224    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1225   "* return output_fp_compare (insn, operands, 1, 1);"
1226   [(set_attr "type" "ssecomi")
1227    (set (attr "mode")
1228      (if_then_else (match_operand:SF 1 "" "")
1229         (const_string "SF")
1230         (const_string "DF")))
1231    (set_attr "athlon_decode" "vector")
1232    (set_attr "amdfam10_decode" "direct")])
1233
1234 (define_insn "*cmpfp_iu_387"
1235   [(set (reg:CCFPU FLAGS_REG)
1236         (compare:CCFPU (match_operand 0 "register_operand" "f")
1237                        (match_operand 1 "register_operand" "f")))]
1238   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1239    && TARGET_CMOVE
1240    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1241    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1242   "* return output_fp_compare (insn, operands, 1, 1);"
1243   [(set_attr "type" "fcmp")
1244    (set (attr "mode")
1245      (cond [(match_operand:SF 1 "" "")
1246               (const_string "SF")
1247             (match_operand:DF 1 "" "")
1248               (const_string "DF")
1249            ]
1250            (const_string "XF")))
1251    (set_attr "athlon_decode" "vector")
1252    (set_attr "amdfam10_decode" "direct")])
1253 \f
1254 ;; Move instructions.
1255
1256 ;; General case of fullword move.
1257
1258 (define_expand "movsi"
1259   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1260         (match_operand:SI 1 "general_operand" ""))]
1261   ""
1262   "ix86_expand_move (SImode, operands); DONE;")
1263
1264 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1265 ;; general_operand.
1266 ;;
1267 ;; %%% We don't use a post-inc memory reference because x86 is not a
1268 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1269 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1270 ;; targets without our curiosities, and it is just as easy to represent
1271 ;; this differently.
1272
1273 (define_insn "*pushsi2"
1274   [(set (match_operand:SI 0 "push_operand" "=<")
1275         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1276   "!TARGET_64BIT"
1277   "push{l}\t%1"
1278   [(set_attr "type" "push")
1279    (set_attr "mode" "SI")])
1280
1281 ;; For 64BIT abi we always round up to 8 bytes.
1282 (define_insn "*pushsi2_rex64"
1283   [(set (match_operand:SI 0 "push_operand" "=X")
1284         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1285   "TARGET_64BIT"
1286   "push{q}\t%q1"
1287   [(set_attr "type" "push")
1288    (set_attr "mode" "SI")])
1289
1290 (define_insn "*pushsi2_prologue"
1291   [(set (match_operand:SI 0 "push_operand" "=<")
1292         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1293    (clobber (mem:BLK (scratch)))]
1294   "!TARGET_64BIT"
1295   "push{l}\t%1"
1296   [(set_attr "type" "push")
1297    (set_attr "mode" "SI")])
1298
1299 (define_insn "*popsi1_epilogue"
1300   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1301         (mem:SI (reg:SI SP_REG)))
1302    (set (reg:SI SP_REG)
1303         (plus:SI (reg:SI SP_REG) (const_int 4)))
1304    (clobber (mem:BLK (scratch)))]
1305   "!TARGET_64BIT"
1306   "pop{l}\t%0"
1307   [(set_attr "type" "pop")
1308    (set_attr "mode" "SI")])
1309
1310 (define_insn "popsi1"
1311   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1312         (mem:SI (reg:SI SP_REG)))
1313    (set (reg:SI SP_REG)
1314         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1315   "!TARGET_64BIT"
1316   "pop{l}\t%0"
1317   [(set_attr "type" "pop")
1318    (set_attr "mode" "SI")])
1319
1320 (define_insn "*movsi_xor"
1321   [(set (match_operand:SI 0 "register_operand" "=r")
1322         (match_operand:SI 1 "const0_operand" "i"))
1323    (clobber (reg:CC FLAGS_REG))]
1324   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1325   "xor{l}\t%0, %0"
1326   [(set_attr "type" "alu1")
1327    (set_attr "mode" "SI")
1328    (set_attr "length_immediate" "0")])
1329
1330 (define_insn "*movsi_or"
1331   [(set (match_operand:SI 0 "register_operand" "=r")
1332         (match_operand:SI 1 "immediate_operand" "i"))
1333    (clobber (reg:CC FLAGS_REG))]
1334   "reload_completed
1335    && operands[1] == constm1_rtx
1336    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1337 {
1338   operands[1] = constm1_rtx;
1339   return "or{l}\t{%1, %0|%0, %1}";
1340 }
1341   [(set_attr "type" "alu1")
1342    (set_attr "mode" "SI")
1343    (set_attr "length_immediate" "1")])
1344
1345 (define_insn "*movsi_1"
1346   [(set (match_operand:SI 0 "nonimmediate_operand"
1347                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1348         (match_operand:SI 1 "general_operand"
1349                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1350   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1351 {
1352   switch (get_attr_type (insn))
1353     {
1354     case TYPE_SSELOG1:
1355       if (get_attr_mode (insn) == MODE_TI)
1356         return "pxor\t%0, %0";
1357       return "xorps\t%0, %0";
1358
1359     case TYPE_SSEMOV:
1360       switch (get_attr_mode (insn))
1361         {
1362         case MODE_TI:
1363           return "movdqa\t{%1, %0|%0, %1}";
1364         case MODE_V4SF:
1365           return "movaps\t{%1, %0|%0, %1}";
1366         case MODE_SI:
1367           return "movd\t{%1, %0|%0, %1}";
1368         case MODE_SF:
1369           return "movss\t{%1, %0|%0, %1}";
1370         default:
1371           gcc_unreachable ();
1372         }
1373
1374     case TYPE_MMXADD:
1375       return "pxor\t%0, %0";
1376
1377     case TYPE_MMXMOV:
1378       if (get_attr_mode (insn) == MODE_DI)
1379         return "movq\t{%1, %0|%0, %1}";
1380       return "movd\t{%1, %0|%0, %1}";
1381
1382     case TYPE_LEA:
1383       return "lea{l}\t{%1, %0|%0, %1}";
1384
1385     default:
1386       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1387       return "mov{l}\t{%1, %0|%0, %1}";
1388     }
1389 }
1390   [(set (attr "type")
1391      (cond [(eq_attr "alternative" "2")
1392               (const_string "mmxadd")
1393             (eq_attr "alternative" "3,4,5")
1394               (const_string "mmxmov")
1395             (eq_attr "alternative" "6")
1396               (const_string "sselog1")
1397             (eq_attr "alternative" "7,8,9,10,11")
1398               (const_string "ssemov")
1399             (match_operand:DI 1 "pic_32bit_operand" "")
1400               (const_string "lea")
1401            ]
1402            (const_string "imov")))
1403    (set (attr "mode")
1404      (cond [(eq_attr "alternative" "2,3")
1405               (const_string "DI")
1406             (eq_attr "alternative" "6,7")
1407               (if_then_else
1408                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1409                 (const_string "V4SF")
1410                 (const_string "TI"))
1411             (and (eq_attr "alternative" "8,9,10,11")
1412                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1413               (const_string "SF")
1414            ]
1415            (const_string "SI")))])
1416
1417 ;; Stores and loads of ax to arbitrary constant address.
1418 ;; We fake an second form of instruction to force reload to load address
1419 ;; into register when rax is not available
1420 (define_insn "*movabssi_1_rex64"
1421   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1422         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1423   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1424   "@
1425    movabs{l}\t{%1, %P0|%P0, %1}
1426    mov{l}\t{%1, %a0|%a0, %1}"
1427   [(set_attr "type" "imov")
1428    (set_attr "modrm" "0,*")
1429    (set_attr "length_address" "8,0")
1430    (set_attr "length_immediate" "0,*")
1431    (set_attr "memory" "store")
1432    (set_attr "mode" "SI")])
1433
1434 (define_insn "*movabssi_2_rex64"
1435   [(set (match_operand:SI 0 "register_operand" "=a,r")
1436         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1437   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1438   "@
1439    movabs{l}\t{%P1, %0|%0, %P1}
1440    mov{l}\t{%a1, %0|%0, %a1}"
1441   [(set_attr "type" "imov")
1442    (set_attr "modrm" "0,*")
1443    (set_attr "length_address" "8,0")
1444    (set_attr "length_immediate" "0")
1445    (set_attr "memory" "load")
1446    (set_attr "mode" "SI")])
1447
1448 (define_insn "*swapsi"
1449   [(set (match_operand:SI 0 "register_operand" "+r")
1450         (match_operand:SI 1 "register_operand" "+r"))
1451    (set (match_dup 1)
1452         (match_dup 0))]
1453   ""
1454   "xchg{l}\t%1, %0"
1455   [(set_attr "type" "imov")
1456    (set_attr "mode" "SI")
1457    (set_attr "pent_pair" "np")
1458    (set_attr "athlon_decode" "vector")
1459    (set_attr "amdfam10_decode" "double")])   
1460
1461 (define_expand "movhi"
1462   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1463         (match_operand:HI 1 "general_operand" ""))]
1464   ""
1465   "ix86_expand_move (HImode, operands); DONE;")
1466
1467 (define_insn "*pushhi2"
1468   [(set (match_operand:HI 0 "push_operand" "=X")
1469         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1470   "!TARGET_64BIT"
1471   "push{l}\t%k1"
1472   [(set_attr "type" "push")
1473    (set_attr "mode" "SI")])
1474
1475 ;; For 64BIT abi we always round up to 8 bytes.
1476 (define_insn "*pushhi2_rex64"
1477   [(set (match_operand:HI 0 "push_operand" "=X")
1478         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1479   "TARGET_64BIT"
1480   "push{q}\t%q1"
1481   [(set_attr "type" "push")
1482    (set_attr "mode" "DI")])
1483
1484 (define_insn "*movhi_1"
1485   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1486         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1487   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1488 {
1489   switch (get_attr_type (insn))
1490     {
1491     case TYPE_IMOVX:
1492       /* movzwl is faster than movw on p2 due to partial word stalls,
1493          though not as fast as an aligned movl.  */
1494       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1495     default:
1496       if (get_attr_mode (insn) == MODE_SI)
1497         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1498       else
1499         return "mov{w}\t{%1, %0|%0, %1}";
1500     }
1501 }
1502   [(set (attr "type")
1503      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1504               (const_string "imov")
1505             (and (eq_attr "alternative" "0")
1506                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1507                           (const_int 0))
1508                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1509                           (const_int 0))))
1510               (const_string "imov")
1511             (and (eq_attr "alternative" "1,2")
1512                  (match_operand:HI 1 "aligned_operand" ""))
1513               (const_string "imov")
1514             (and (ne (symbol_ref "TARGET_MOVX")
1515                      (const_int 0))
1516                  (eq_attr "alternative" "0,2"))
1517               (const_string "imovx")
1518            ]
1519            (const_string "imov")))
1520     (set (attr "mode")
1521       (cond [(eq_attr "type" "imovx")
1522                (const_string "SI")
1523              (and (eq_attr "alternative" "1,2")
1524                   (match_operand:HI 1 "aligned_operand" ""))
1525                (const_string "SI")
1526              (and (eq_attr "alternative" "0")
1527                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1528                            (const_int 0))
1529                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1530                            (const_int 0))))
1531                (const_string "SI")
1532             ]
1533             (const_string "HI")))])
1534
1535 ;; Stores and loads of ax to arbitrary constant address.
1536 ;; We fake an second form of instruction to force reload to load address
1537 ;; into register when rax is not available
1538 (define_insn "*movabshi_1_rex64"
1539   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1540         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1541   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1542   "@
1543    movabs{w}\t{%1, %P0|%P0, %1}
1544    mov{w}\t{%1, %a0|%a0, %1}"
1545   [(set_attr "type" "imov")
1546    (set_attr "modrm" "0,*")
1547    (set_attr "length_address" "8,0")
1548    (set_attr "length_immediate" "0,*")
1549    (set_attr "memory" "store")
1550    (set_attr "mode" "HI")])
1551
1552 (define_insn "*movabshi_2_rex64"
1553   [(set (match_operand:HI 0 "register_operand" "=a,r")
1554         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1555   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1556   "@
1557    movabs{w}\t{%P1, %0|%0, %P1}
1558    mov{w}\t{%a1, %0|%0, %a1}"
1559   [(set_attr "type" "imov")
1560    (set_attr "modrm" "0,*")
1561    (set_attr "length_address" "8,0")
1562    (set_attr "length_immediate" "0")
1563    (set_attr "memory" "load")
1564    (set_attr "mode" "HI")])
1565
1566 (define_insn "*swaphi_1"
1567   [(set (match_operand:HI 0 "register_operand" "+r")
1568         (match_operand:HI 1 "register_operand" "+r"))
1569    (set (match_dup 1)
1570         (match_dup 0))]
1571   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1572   "xchg{l}\t%k1, %k0"
1573   [(set_attr "type" "imov")
1574    (set_attr "mode" "SI")
1575    (set_attr "pent_pair" "np")
1576    (set_attr "athlon_decode" "vector")
1577    (set_attr "amdfam10_decode" "double")])   
1578
1579 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1580 (define_insn "*swaphi_2"
1581   [(set (match_operand:HI 0 "register_operand" "+r")
1582         (match_operand:HI 1 "register_operand" "+r"))
1583    (set (match_dup 1)
1584         (match_dup 0))]
1585   "TARGET_PARTIAL_REG_STALL"
1586   "xchg{w}\t%1, %0"
1587   [(set_attr "type" "imov")
1588    (set_attr "mode" "HI")
1589    (set_attr "pent_pair" "np")
1590    (set_attr "athlon_decode" "vector")])
1591
1592 (define_expand "movstricthi"
1593   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1594         (match_operand:HI 1 "general_operand" ""))]
1595   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1596 {
1597   /* Don't generate memory->memory moves, go through a register */
1598   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1599     operands[1] = force_reg (HImode, operands[1]);
1600 })
1601
1602 (define_insn "*movstricthi_1"
1603   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1604         (match_operand:HI 1 "general_operand" "rn,m"))]
1605   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1606    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1607   "mov{w}\t{%1, %0|%0, %1}"
1608   [(set_attr "type" "imov")
1609    (set_attr "mode" "HI")])
1610
1611 (define_insn "*movstricthi_xor"
1612   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1613         (match_operand:HI 1 "const0_operand" "i"))
1614    (clobber (reg:CC FLAGS_REG))]
1615   "reload_completed
1616    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1617   "xor{w}\t%0, %0"
1618   [(set_attr "type" "alu1")
1619    (set_attr "mode" "HI")
1620    (set_attr "length_immediate" "0")])
1621
1622 (define_expand "movqi"
1623   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1624         (match_operand:QI 1 "general_operand" ""))]
1625   ""
1626   "ix86_expand_move (QImode, operands); DONE;")
1627
1628 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1629 ;; "push a byte".  But actually we use pushl, which has the effect
1630 ;; of rounding the amount pushed up to a word.
1631
1632 (define_insn "*pushqi2"
1633   [(set (match_operand:QI 0 "push_operand" "=X")
1634         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1635   "!TARGET_64BIT"
1636   "push{l}\t%k1"
1637   [(set_attr "type" "push")
1638    (set_attr "mode" "SI")])
1639
1640 ;; For 64BIT abi we always round up to 8 bytes.
1641 (define_insn "*pushqi2_rex64"
1642   [(set (match_operand:QI 0 "push_operand" "=X")
1643         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1644   "TARGET_64BIT"
1645   "push{q}\t%q1"
1646   [(set_attr "type" "push")
1647    (set_attr "mode" "DI")])
1648
1649 ;; Situation is quite tricky about when to choose full sized (SImode) move
1650 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1651 ;; partial register dependency machines (such as AMD Athlon), where QImode
1652 ;; moves issue extra dependency and for partial register stalls machines
1653 ;; that don't use QImode patterns (and QImode move cause stall on the next
1654 ;; instruction).
1655 ;;
1656 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1657 ;; register stall machines with, where we use QImode instructions, since
1658 ;; partial register stall can be caused there.  Then we use movzx.
1659 (define_insn "*movqi_1"
1660   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1661         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1662   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1663 {
1664   switch (get_attr_type (insn))
1665     {
1666     case TYPE_IMOVX:
1667       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1668       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1669     default:
1670       if (get_attr_mode (insn) == MODE_SI)
1671         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1672       else
1673         return "mov{b}\t{%1, %0|%0, %1}";
1674     }
1675 }
1676   [(set (attr "type")
1677      (cond [(and (eq_attr "alternative" "5")
1678                  (not (match_operand:QI 1 "aligned_operand" "")))
1679               (const_string "imovx")
1680             (ne (symbol_ref "optimize_size") (const_int 0))
1681               (const_string "imov")
1682             (and (eq_attr "alternative" "3")
1683                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1684                           (const_int 0))
1685                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1686                           (const_int 0))))
1687               (const_string "imov")
1688             (eq_attr "alternative" "3,5")
1689               (const_string "imovx")
1690             (and (ne (symbol_ref "TARGET_MOVX")
1691                      (const_int 0))
1692                  (eq_attr "alternative" "2"))
1693               (const_string "imovx")
1694            ]
1695            (const_string "imov")))
1696    (set (attr "mode")
1697       (cond [(eq_attr "alternative" "3,4,5")
1698                (const_string "SI")
1699              (eq_attr "alternative" "6")
1700                (const_string "QI")
1701              (eq_attr "type" "imovx")
1702                (const_string "SI")
1703              (and (eq_attr "type" "imov")
1704                   (and (eq_attr "alternative" "0,1")
1705                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1706                                 (const_int 0))
1707                             (and (eq (symbol_ref "optimize_size")
1708                                      (const_int 0))
1709                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1710                                      (const_int 0))))))
1711                (const_string "SI")
1712              ;; Avoid partial register stalls when not using QImode arithmetic
1713              (and (eq_attr "type" "imov")
1714                   (and (eq_attr "alternative" "0,1")
1715                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1716                                 (const_int 0))
1717                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1718                                 (const_int 0)))))
1719                (const_string "SI")
1720            ]
1721            (const_string "QI")))])
1722
1723 (define_expand "reload_outqi"
1724   [(parallel [(match_operand:QI 0 "" "=m")
1725               (match_operand:QI 1 "register_operand" "r")
1726               (match_operand:QI 2 "register_operand" "=&q")])]
1727   ""
1728 {
1729   rtx op0, op1, op2;
1730   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1731
1732   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1733   if (! q_regs_operand (op1, QImode))
1734     {
1735       emit_insn (gen_movqi (op2, op1));
1736       op1 = op2;
1737     }
1738   emit_insn (gen_movqi (op0, op1));
1739   DONE;
1740 })
1741
1742 (define_insn "*swapqi_1"
1743   [(set (match_operand:QI 0 "register_operand" "+r")
1744         (match_operand:QI 1 "register_operand" "+r"))
1745    (set (match_dup 1)
1746         (match_dup 0))]
1747   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1748   "xchg{l}\t%k1, %k0"
1749   [(set_attr "type" "imov")
1750    (set_attr "mode" "SI")
1751    (set_attr "pent_pair" "np")
1752    (set_attr "athlon_decode" "vector")
1753    (set_attr "amdfam10_decode" "vector")])   
1754
1755 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1756 (define_insn "*swapqi_2"
1757   [(set (match_operand:QI 0 "register_operand" "+q")
1758         (match_operand:QI 1 "register_operand" "+q"))
1759    (set (match_dup 1)
1760         (match_dup 0))]
1761   "TARGET_PARTIAL_REG_STALL"
1762   "xchg{b}\t%1, %0"
1763   [(set_attr "type" "imov")
1764    (set_attr "mode" "QI")
1765    (set_attr "pent_pair" "np")
1766    (set_attr "athlon_decode" "vector")])
1767
1768 (define_expand "movstrictqi"
1769   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1770         (match_operand:QI 1 "general_operand" ""))]
1771   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1772 {
1773   /* Don't generate memory->memory moves, go through a register.  */
1774   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1775     operands[1] = force_reg (QImode, operands[1]);
1776 })
1777
1778 (define_insn "*movstrictqi_1"
1779   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1780         (match_operand:QI 1 "general_operand" "*qn,m"))]
1781   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1782    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1783   "mov{b}\t{%1, %0|%0, %1}"
1784   [(set_attr "type" "imov")
1785    (set_attr "mode" "QI")])
1786
1787 (define_insn "*movstrictqi_xor"
1788   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1789         (match_operand:QI 1 "const0_operand" "i"))
1790    (clobber (reg:CC FLAGS_REG))]
1791   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1792   "xor{b}\t%0, %0"
1793   [(set_attr "type" "alu1")
1794    (set_attr "mode" "QI")
1795    (set_attr "length_immediate" "0")])
1796
1797 (define_insn "*movsi_extv_1"
1798   [(set (match_operand:SI 0 "register_operand" "=R")
1799         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1800                          (const_int 8)
1801                          (const_int 8)))]
1802   ""
1803   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1804   [(set_attr "type" "imovx")
1805    (set_attr "mode" "SI")])
1806
1807 (define_insn "*movhi_extv_1"
1808   [(set (match_operand:HI 0 "register_operand" "=R")
1809         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1810                          (const_int 8)
1811                          (const_int 8)))]
1812   ""
1813   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1814   [(set_attr "type" "imovx")
1815    (set_attr "mode" "SI")])
1816
1817 (define_insn "*movqi_extv_1"
1818   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1819         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1820                          (const_int 8)
1821                          (const_int 8)))]
1822   "!TARGET_64BIT"
1823 {
1824   switch (get_attr_type (insn))
1825     {
1826     case TYPE_IMOVX:
1827       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1828     default:
1829       return "mov{b}\t{%h1, %0|%0, %h1}";
1830     }
1831 }
1832   [(set (attr "type")
1833      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1834                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1835                              (ne (symbol_ref "TARGET_MOVX")
1836                                  (const_int 0))))
1837         (const_string "imovx")
1838         (const_string "imov")))
1839    (set (attr "mode")
1840      (if_then_else (eq_attr "type" "imovx")
1841         (const_string "SI")
1842         (const_string "QI")))])
1843
1844 (define_insn "*movqi_extv_1_rex64"
1845   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1846         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1847                          (const_int 8)
1848                          (const_int 8)))]
1849   "TARGET_64BIT"
1850 {
1851   switch (get_attr_type (insn))
1852     {
1853     case TYPE_IMOVX:
1854       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1855     default:
1856       return "mov{b}\t{%h1, %0|%0, %h1}";
1857     }
1858 }
1859   [(set (attr "type")
1860      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1861                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1862                              (ne (symbol_ref "TARGET_MOVX")
1863                                  (const_int 0))))
1864         (const_string "imovx")
1865         (const_string "imov")))
1866    (set (attr "mode")
1867      (if_then_else (eq_attr "type" "imovx")
1868         (const_string "SI")
1869         (const_string "QI")))])
1870
1871 ;; Stores and loads of ax to arbitrary constant address.
1872 ;; We fake an second form of instruction to force reload to load address
1873 ;; into register when rax is not available
1874 (define_insn "*movabsqi_1_rex64"
1875   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1876         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1877   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1878   "@
1879    movabs{b}\t{%1, %P0|%P0, %1}
1880    mov{b}\t{%1, %a0|%a0, %1}"
1881   [(set_attr "type" "imov")
1882    (set_attr "modrm" "0,*")
1883    (set_attr "length_address" "8,0")
1884    (set_attr "length_immediate" "0,*")
1885    (set_attr "memory" "store")
1886    (set_attr "mode" "QI")])
1887
1888 (define_insn "*movabsqi_2_rex64"
1889   [(set (match_operand:QI 0 "register_operand" "=a,r")
1890         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1891   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1892   "@
1893    movabs{b}\t{%P1, %0|%0, %P1}
1894    mov{b}\t{%a1, %0|%0, %a1}"
1895   [(set_attr "type" "imov")
1896    (set_attr "modrm" "0,*")
1897    (set_attr "length_address" "8,0")
1898    (set_attr "length_immediate" "0")
1899    (set_attr "memory" "load")
1900    (set_attr "mode" "QI")])
1901
1902 (define_insn "*movdi_extzv_1"
1903   [(set (match_operand:DI 0 "register_operand" "=R")
1904         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1905                          (const_int 8)
1906                          (const_int 8)))]
1907   "TARGET_64BIT"
1908   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1909   [(set_attr "type" "imovx")
1910    (set_attr "mode" "DI")])
1911
1912 (define_insn "*movsi_extzv_1"
1913   [(set (match_operand:SI 0 "register_operand" "=R")
1914         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1915                          (const_int 8)
1916                          (const_int 8)))]
1917   ""
1918   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1919   [(set_attr "type" "imovx")
1920    (set_attr "mode" "SI")])
1921
1922 (define_insn "*movqi_extzv_2"
1923   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1924         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1925                                     (const_int 8)
1926                                     (const_int 8)) 0))]
1927   "!TARGET_64BIT"
1928 {
1929   switch (get_attr_type (insn))
1930     {
1931     case TYPE_IMOVX:
1932       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1933     default:
1934       return "mov{b}\t{%h1, %0|%0, %h1}";
1935     }
1936 }
1937   [(set (attr "type")
1938      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1939                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1940                              (ne (symbol_ref "TARGET_MOVX")
1941                                  (const_int 0))))
1942         (const_string "imovx")
1943         (const_string "imov")))
1944    (set (attr "mode")
1945      (if_then_else (eq_attr "type" "imovx")
1946         (const_string "SI")
1947         (const_string "QI")))])
1948
1949 (define_insn "*movqi_extzv_2_rex64"
1950   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1951         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1952                                     (const_int 8)
1953                                     (const_int 8)) 0))]
1954   "TARGET_64BIT"
1955 {
1956   switch (get_attr_type (insn))
1957     {
1958     case TYPE_IMOVX:
1959       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1960     default:
1961       return "mov{b}\t{%h1, %0|%0, %h1}";
1962     }
1963 }
1964   [(set (attr "type")
1965      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1966                         (ne (symbol_ref "TARGET_MOVX")
1967                             (const_int 0)))
1968         (const_string "imovx")
1969         (const_string "imov")))
1970    (set (attr "mode")
1971      (if_then_else (eq_attr "type" "imovx")
1972         (const_string "SI")
1973         (const_string "QI")))])
1974
1975 (define_insn "movsi_insv_1"
1976   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1977                          (const_int 8)
1978                          (const_int 8))
1979         (match_operand:SI 1 "general_operand" "Qmn"))]
1980   "!TARGET_64BIT"
1981   "mov{b}\t{%b1, %h0|%h0, %b1}"
1982   [(set_attr "type" "imov")
1983    (set_attr "mode" "QI")])
1984
1985 (define_insn "*movsi_insv_1_rex64"
1986   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1987                          (const_int 8)
1988                          (const_int 8))
1989         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1990   "TARGET_64BIT"
1991   "mov{b}\t{%b1, %h0|%h0, %b1}"
1992   [(set_attr "type" "imov")
1993    (set_attr "mode" "QI")])
1994
1995 (define_insn "movdi_insv_1_rex64"
1996   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1997                          (const_int 8)
1998                          (const_int 8))
1999         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2000   "TARGET_64BIT"
2001   "mov{b}\t{%b1, %h0|%h0, %b1}"
2002   [(set_attr "type" "imov")
2003    (set_attr "mode" "QI")])
2004
2005 (define_insn "*movqi_insv_2"
2006   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2007                          (const_int 8)
2008                          (const_int 8))
2009         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2010                      (const_int 8)))]
2011   ""
2012   "mov{b}\t{%h1, %h0|%h0, %h1}"
2013   [(set_attr "type" "imov")
2014    (set_attr "mode" "QI")])
2015
2016 (define_expand "movdi"
2017   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2018         (match_operand:DI 1 "general_operand" ""))]
2019   ""
2020   "ix86_expand_move (DImode, operands); DONE;")
2021
2022 (define_insn "*pushdi"
2023   [(set (match_operand:DI 0 "push_operand" "=<")
2024         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2025   "!TARGET_64BIT"
2026   "#")
2027
2028 (define_insn "*pushdi2_rex64"
2029   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2030         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2031   "TARGET_64BIT"
2032   "@
2033    push{q}\t%1
2034    #"
2035   [(set_attr "type" "push,multi")
2036    (set_attr "mode" "DI")])
2037
2038 ;; Convert impossible pushes of immediate to existing instructions.
2039 ;; First try to get scratch register and go through it.  In case this
2040 ;; fails, push sign extended lower part first and then overwrite
2041 ;; upper part by 32bit move.
2042 (define_peephole2
2043   [(match_scratch:DI 2 "r")
2044    (set (match_operand:DI 0 "push_operand" "")
2045         (match_operand:DI 1 "immediate_operand" ""))]
2046   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2047    && !x86_64_immediate_operand (operands[1], DImode)"
2048   [(set (match_dup 2) (match_dup 1))
2049    (set (match_dup 0) (match_dup 2))]
2050   "")
2051
2052 ;; We need to define this as both peepholer and splitter for case
2053 ;; peephole2 pass is not run.
2054 ;; "&& 1" is needed to keep it from matching the previous pattern.
2055 (define_peephole2
2056   [(set (match_operand:DI 0 "push_operand" "")
2057         (match_operand:DI 1 "immediate_operand" ""))]
2058   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2059    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2060   [(set (match_dup 0) (match_dup 1))
2061    (set (match_dup 2) (match_dup 3))]
2062   "split_di (operands + 1, 1, operands + 2, operands + 3);
2063    operands[1] = gen_lowpart (DImode, operands[2]);
2064    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2065                                                     GEN_INT (4)));
2066   ")
2067
2068 (define_split
2069   [(set (match_operand:DI 0 "push_operand" "")
2070         (match_operand:DI 1 "immediate_operand" ""))]
2071   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2072                     ? epilogue_completed : reload_completed)
2073    && !symbolic_operand (operands[1], DImode)
2074    && !x86_64_immediate_operand (operands[1], DImode)"
2075   [(set (match_dup 0) (match_dup 1))
2076    (set (match_dup 2) (match_dup 3))]
2077   "split_di (operands + 1, 1, operands + 2, operands + 3);
2078    operands[1] = gen_lowpart (DImode, operands[2]);
2079    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2080                                                     GEN_INT (4)));
2081   ")
2082
2083 (define_insn "*pushdi2_prologue_rex64"
2084   [(set (match_operand:DI 0 "push_operand" "=<")
2085         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2086    (clobber (mem:BLK (scratch)))]
2087   "TARGET_64BIT"
2088   "push{q}\t%1"
2089   [(set_attr "type" "push")
2090    (set_attr "mode" "DI")])
2091
2092 (define_insn "*popdi1_epilogue_rex64"
2093   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2094         (mem:DI (reg:DI SP_REG)))
2095    (set (reg:DI SP_REG)
2096         (plus:DI (reg:DI SP_REG) (const_int 8)))
2097    (clobber (mem:BLK (scratch)))]
2098   "TARGET_64BIT"
2099   "pop{q}\t%0"
2100   [(set_attr "type" "pop")
2101    (set_attr "mode" "DI")])
2102
2103 (define_insn "popdi1"
2104   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2105         (mem:DI (reg:DI SP_REG)))
2106    (set (reg:DI SP_REG)
2107         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2108   "TARGET_64BIT"
2109   "pop{q}\t%0"
2110   [(set_attr "type" "pop")
2111    (set_attr "mode" "DI")])
2112
2113 (define_insn "*movdi_xor_rex64"
2114   [(set (match_operand:DI 0 "register_operand" "=r")
2115         (match_operand:DI 1 "const0_operand" "i"))
2116    (clobber (reg:CC FLAGS_REG))]
2117   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2118    && reload_completed"
2119   "xor{l}\t%k0, %k0";
2120   [(set_attr "type" "alu1")
2121    (set_attr "mode" "SI")
2122    (set_attr "length_immediate" "0")])
2123
2124 (define_insn "*movdi_or_rex64"
2125   [(set (match_operand:DI 0 "register_operand" "=r")
2126         (match_operand:DI 1 "const_int_operand" "i"))
2127    (clobber (reg:CC FLAGS_REG))]
2128   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2129    && reload_completed
2130    && operands[1] == constm1_rtx"
2131 {
2132   operands[1] = constm1_rtx;
2133   return "or{q}\t{%1, %0|%0, %1}";
2134 }
2135   [(set_attr "type" "alu1")
2136    (set_attr "mode" "DI")
2137    (set_attr "length_immediate" "1")])
2138
2139 (define_insn "*movdi_2"
2140   [(set (match_operand:DI 0 "nonimmediate_operand"
2141                         "=r  ,o  ,*y,m*y,*y,*Yt,m  ,*Yt,*Yt,*x,m ,*x,*x")
2142         (match_operand:DI 1 "general_operand"
2143                         "riFo,riF,C ,*y ,m ,C  ,*Yt,*Yt,m  ,C ,*x,*x,m "))]
2144   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2145   "@
2146    #
2147    #
2148    pxor\t%0, %0
2149    movq\t{%1, %0|%0, %1}
2150    movq\t{%1, %0|%0, %1}
2151    pxor\t%0, %0
2152    movq\t{%1, %0|%0, %1}
2153    movdqa\t{%1, %0|%0, %1}
2154    movq\t{%1, %0|%0, %1}
2155    xorps\t%0, %0
2156    movlps\t{%1, %0|%0, %1}
2157    movaps\t{%1, %0|%0, %1}
2158    movlps\t{%1, %0|%0, %1}"
2159   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2160    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2161
2162 (define_split
2163   [(set (match_operand:DI 0 "push_operand" "")
2164         (match_operand:DI 1 "general_operand" ""))]
2165   "!TARGET_64BIT && reload_completed
2166    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2167   [(const_int 0)]
2168   "ix86_split_long_move (operands); DONE;")
2169
2170 ;; %%% This multiword shite has got to go.
2171 (define_split
2172   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2173         (match_operand:DI 1 "general_operand" ""))]
2174   "!TARGET_64BIT && reload_completed
2175    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2176    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2177   [(const_int 0)]
2178   "ix86_split_long_move (operands); DONE;")
2179
2180 (define_insn "*movdi_1_rex64"
2181   [(set (match_operand:DI 0 "nonimmediate_operand"
2182           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2183         (match_operand:DI 1 "general_operand"
2184           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2185   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2186 {
2187   switch (get_attr_type (insn))
2188     {
2189     case TYPE_SSECVT:
2190       if (SSE_REG_P (operands[0]))
2191         return "movq2dq\t{%1, %0|%0, %1}";
2192       else
2193         return "movdq2q\t{%1, %0|%0, %1}";
2194
2195     case TYPE_SSEMOV:
2196       if (get_attr_mode (insn) == MODE_TI)
2197         return "movdqa\t{%1, %0|%0, %1}";
2198       /* FALLTHRU */
2199
2200     case TYPE_MMXMOV:
2201       /* Moves from and into integer register is done using movd
2202          opcode with REX prefix.  */
2203       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2204         return "movd\t{%1, %0|%0, %1}";
2205       return "movq\t{%1, %0|%0, %1}";
2206
2207     case TYPE_SSELOG1:
2208     case TYPE_MMXADD:
2209       return "pxor\t%0, %0";
2210
2211     case TYPE_MULTI:
2212       return "#";
2213
2214     case TYPE_LEA:
2215       return "lea{q}\t{%a1, %0|%0, %a1}";
2216
2217     default:
2218       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2219       if (get_attr_mode (insn) == MODE_SI)
2220         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2221       else if (which_alternative == 2)
2222         return "movabs{q}\t{%1, %0|%0, %1}";
2223       else
2224         return "mov{q}\t{%1, %0|%0, %1}";
2225     }
2226 }
2227   [(set (attr "type")
2228      (cond [(eq_attr "alternative" "5")
2229               (const_string "mmxadd")
2230             (eq_attr "alternative" "6,7,8,9,10")
2231               (const_string "mmxmov")
2232             (eq_attr "alternative" "11")
2233               (const_string "sselog1")
2234             (eq_attr "alternative" "12,13,14,15,16")
2235               (const_string "ssemov")
2236             (eq_attr "alternative" "17,18")
2237               (const_string "ssecvt")
2238             (eq_attr "alternative" "4")
2239               (const_string "multi")
2240             (match_operand:DI 1 "pic_32bit_operand" "")
2241               (const_string "lea")
2242            ]
2243            (const_string "imov")))
2244    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2245    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2246    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2247
2248 ;; Stores and loads of ax to arbitrary constant address.
2249 ;; We fake an second form of instruction to force reload to load address
2250 ;; into register when rax is not available
2251 (define_insn "*movabsdi_1_rex64"
2252   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2253         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2254   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2255   "@
2256    movabs{q}\t{%1, %P0|%P0, %1}
2257    mov{q}\t{%1, %a0|%a0, %1}"
2258   [(set_attr "type" "imov")
2259    (set_attr "modrm" "0,*")
2260    (set_attr "length_address" "8,0")
2261    (set_attr "length_immediate" "0,*")
2262    (set_attr "memory" "store")
2263    (set_attr "mode" "DI")])
2264
2265 (define_insn "*movabsdi_2_rex64"
2266   [(set (match_operand:DI 0 "register_operand" "=a,r")
2267         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2268   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2269   "@
2270    movabs{q}\t{%P1, %0|%0, %P1}
2271    mov{q}\t{%a1, %0|%0, %a1}"
2272   [(set_attr "type" "imov")
2273    (set_attr "modrm" "0,*")
2274    (set_attr "length_address" "8,0")
2275    (set_attr "length_immediate" "0")
2276    (set_attr "memory" "load")
2277    (set_attr "mode" "DI")])
2278
2279 ;; Convert impossible stores of immediate to existing instructions.
2280 ;; First try to get scratch register and go through it.  In case this
2281 ;; fails, move by 32bit parts.
2282 (define_peephole2
2283   [(match_scratch:DI 2 "r")
2284    (set (match_operand:DI 0 "memory_operand" "")
2285         (match_operand:DI 1 "immediate_operand" ""))]
2286   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2287    && !x86_64_immediate_operand (operands[1], DImode)"
2288   [(set (match_dup 2) (match_dup 1))
2289    (set (match_dup 0) (match_dup 2))]
2290   "")
2291
2292 ;; We need to define this as both peepholer and splitter for case
2293 ;; peephole2 pass is not run.
2294 ;; "&& 1" is needed to keep it from matching the previous pattern.
2295 (define_peephole2
2296   [(set (match_operand:DI 0 "memory_operand" "")
2297         (match_operand:DI 1 "immediate_operand" ""))]
2298   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2299    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2300   [(set (match_dup 2) (match_dup 3))
2301    (set (match_dup 4) (match_dup 5))]
2302   "split_di (operands, 2, operands + 2, operands + 4);")
2303
2304 (define_split
2305   [(set (match_operand:DI 0 "memory_operand" "")
2306         (match_operand:DI 1 "immediate_operand" ""))]
2307   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2308                     ? epilogue_completed : reload_completed)
2309    && !symbolic_operand (operands[1], DImode)
2310    && !x86_64_immediate_operand (operands[1], DImode)"
2311   [(set (match_dup 2) (match_dup 3))
2312    (set (match_dup 4) (match_dup 5))]
2313   "split_di (operands, 2, operands + 2, operands + 4);")
2314
2315 (define_insn "*swapdi_rex64"
2316   [(set (match_operand:DI 0 "register_operand" "+r")
2317         (match_operand:DI 1 "register_operand" "+r"))
2318    (set (match_dup 1)
2319         (match_dup 0))]
2320   "TARGET_64BIT"
2321   "xchg{q}\t%1, %0"
2322   [(set_attr "type" "imov")
2323    (set_attr "mode" "DI")
2324    (set_attr "pent_pair" "np")
2325    (set_attr "athlon_decode" "vector")
2326    (set_attr "amdfam10_decode" "double")])   
2327
2328 (define_expand "movti"
2329   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2330         (match_operand:TI 1 "nonimmediate_operand" ""))]
2331   "TARGET_SSE || TARGET_64BIT"
2332 {
2333   if (TARGET_64BIT)
2334     ix86_expand_move (TImode, operands);
2335   else if (push_operand (operands[0], TImode))
2336     ix86_expand_push (TImode, operands[1]);
2337   else
2338     ix86_expand_vector_move (TImode, operands);
2339   DONE;
2340 })
2341
2342 (define_insn "*movti_internal"
2343   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2344         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2345   "TARGET_SSE && !TARGET_64BIT
2346    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2347 {
2348   switch (which_alternative)
2349     {
2350     case 0:
2351       if (get_attr_mode (insn) == MODE_V4SF)
2352         return "xorps\t%0, %0";
2353       else
2354         return "pxor\t%0, %0";
2355     case 1:
2356     case 2:
2357       if (get_attr_mode (insn) == MODE_V4SF)
2358         return "movaps\t{%1, %0|%0, %1}";
2359       else
2360         return "movdqa\t{%1, %0|%0, %1}";
2361     default:
2362       gcc_unreachable ();
2363     }
2364 }
2365   [(set_attr "type" "sselog1,ssemov,ssemov")
2366    (set (attr "mode")
2367         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2368                     (ne (symbol_ref "optimize_size") (const_int 0)))
2369                  (const_string "V4SF")
2370                (and (eq_attr "alternative" "2")
2371                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2372                         (const_int 0)))
2373                  (const_string "V4SF")]
2374               (const_string "TI")))])
2375
2376 (define_insn "*movti_rex64"
2377   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2378         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2379   "TARGET_64BIT
2380    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2381 {
2382   switch (which_alternative)
2383     {
2384     case 0:
2385     case 1:
2386       return "#";
2387     case 2:
2388       if (get_attr_mode (insn) == MODE_V4SF)
2389         return "xorps\t%0, %0";
2390       else
2391         return "pxor\t%0, %0";
2392     case 3:
2393     case 4:
2394       if (get_attr_mode (insn) == MODE_V4SF)
2395         return "movaps\t{%1, %0|%0, %1}";
2396       else
2397         return "movdqa\t{%1, %0|%0, %1}";
2398     default:
2399       gcc_unreachable ();
2400     }
2401 }
2402   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2403    (set (attr "mode")
2404         (cond [(eq_attr "alternative" "2,3")
2405                  (if_then_else
2406                    (ne (symbol_ref "optimize_size")
2407                        (const_int 0))
2408                    (const_string "V4SF")
2409                    (const_string "TI"))
2410                (eq_attr "alternative" "4")
2411                  (if_then_else
2412                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2413                             (const_int 0))
2414                         (ne (symbol_ref "optimize_size")
2415                             (const_int 0)))
2416                    (const_string "V4SF")
2417                    (const_string "TI"))]
2418                (const_string "DI")))])
2419
2420 (define_split
2421   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2422         (match_operand:TI 1 "general_operand" ""))]
2423   "reload_completed && !SSE_REG_P (operands[0])
2424    && !SSE_REG_P (operands[1])"
2425   [(const_int 0)]
2426   "ix86_split_long_move (operands); DONE;")
2427
2428 ;; This expands to what emit_move_complex would generate if we didn't
2429 ;; have a movti pattern.  Having this avoids problems with reload on
2430 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2431 ;; to have around all the time.
2432 (define_expand "movcdi"
2433   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2434         (match_operand:CDI 1 "general_operand" ""))]
2435   ""
2436 {
2437   if (push_operand (operands[0], CDImode))
2438     emit_move_complex_push (CDImode, operands[0], operands[1]);
2439   else
2440     emit_move_complex_parts (operands[0], operands[1]);
2441   DONE;
2442 })
2443
2444 (define_expand "movsf"
2445   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2446         (match_operand:SF 1 "general_operand" ""))]
2447   ""
2448   "ix86_expand_move (SFmode, operands); DONE;")
2449
2450 (define_insn "*pushsf"
2451   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2452         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2453   "!TARGET_64BIT"
2454 {
2455   /* Anything else should be already split before reg-stack.  */
2456   gcc_assert (which_alternative == 1);
2457   return "push{l}\t%1";
2458 }
2459   [(set_attr "type" "multi,push,multi")
2460    (set_attr "unit" "i387,*,*")
2461    (set_attr "mode" "SF,SI,SF")])
2462
2463 (define_insn "*pushsf_rex64"
2464   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2465         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2466   "TARGET_64BIT"
2467 {
2468   /* Anything else should be already split before reg-stack.  */
2469   gcc_assert (which_alternative == 1);
2470   return "push{q}\t%q1";
2471 }
2472   [(set_attr "type" "multi,push,multi")
2473    (set_attr "unit" "i387,*,*")
2474    (set_attr "mode" "SF,DI,SF")])
2475
2476 (define_split
2477   [(set (match_operand:SF 0 "push_operand" "")
2478         (match_operand:SF 1 "memory_operand" ""))]
2479   "reload_completed
2480    && MEM_P (operands[1])
2481    && (operands[2] = find_constant_src (insn))"
2482   [(set (match_dup 0)
2483         (match_dup 2))])
2484
2485
2486 ;; %%% Kill this when call knows how to work this out.
2487 (define_split
2488   [(set (match_operand:SF 0 "push_operand" "")
2489         (match_operand:SF 1 "any_fp_register_operand" ""))]
2490   "!TARGET_64BIT"
2491   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2492    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2493
2494 (define_split
2495   [(set (match_operand:SF 0 "push_operand" "")
2496         (match_operand:SF 1 "any_fp_register_operand" ""))]
2497   "TARGET_64BIT"
2498   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2499    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2500
2501 (define_insn "*movsf_1"
2502   [(set (match_operand:SF 0 "nonimmediate_operand"
2503           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2504         (match_operand:SF 1 "general_operand"
2505           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2506   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2507    && (reload_in_progress || reload_completed
2508        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2509        || (!TARGET_SSE_MATH && optimize_size
2510            && standard_80387_constant_p (operands[1]))
2511        || GET_CODE (operands[1]) != CONST_DOUBLE
2512        || memory_operand (operands[0], SFmode))"
2513 {
2514   switch (which_alternative)
2515     {
2516     case 0:
2517     case 1:
2518       return output_387_reg_move (insn, operands);
2519
2520     case 2:
2521       return standard_80387_constant_opcode (operands[1]);
2522
2523     case 3:
2524     case 4:
2525       return "mov{l}\t{%1, %0|%0, %1}";
2526     case 5:
2527       if (get_attr_mode (insn) == MODE_TI)
2528         return "pxor\t%0, %0";
2529       else
2530         return "xorps\t%0, %0";
2531     case 6:
2532       if (get_attr_mode (insn) == MODE_V4SF)
2533         return "movaps\t{%1, %0|%0, %1}";
2534       else
2535         return "movss\t{%1, %0|%0, %1}";
2536     case 7: case 8:
2537       return "movss\t{%1, %0|%0, %1}";
2538
2539     case 9: case 10:
2540     case 12: case 13: case 14: case 15:
2541       return "movd\t{%1, %0|%0, %1}";
2542
2543     case 11:
2544       return "movq\t{%1, %0|%0, %1}";
2545
2546     default:
2547       gcc_unreachable ();
2548     }
2549 }
2550   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2551    (set (attr "mode")
2552         (cond [(eq_attr "alternative" "3,4,9,10")
2553                  (const_string "SI")
2554                (eq_attr "alternative" "5")
2555                  (if_then_else
2556                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2557                                  (const_int 0))
2558                              (ne (symbol_ref "TARGET_SSE2")
2559                                  (const_int 0)))
2560                         (eq (symbol_ref "optimize_size")
2561                             (const_int 0)))
2562                    (const_string "TI")
2563                    (const_string "V4SF"))
2564                /* For architectures resolving dependencies on
2565                   whole SSE registers use APS move to break dependency
2566                   chains, otherwise use short move to avoid extra work.
2567
2568                   Do the same for architectures resolving dependencies on
2569                   the parts.  While in DF mode it is better to always handle
2570                   just register parts, the SF mode is different due to lack
2571                   of instructions to load just part of the register.  It is
2572                   better to maintain the whole registers in single format
2573                   to avoid problems on using packed logical operations.  */
2574                (eq_attr "alternative" "6")
2575                  (if_then_else
2576                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2577                             (const_int 0))
2578                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2579                             (const_int 0)))
2580                    (const_string "V4SF")
2581                    (const_string "SF"))
2582                (eq_attr "alternative" "11")
2583                  (const_string "DI")]
2584                (const_string "SF")))])
2585
2586 (define_insn "*swapsf"
2587   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2588         (match_operand:SF 1 "fp_register_operand" "+f"))
2589    (set (match_dup 1)
2590         (match_dup 0))]
2591   "reload_completed || TARGET_80387"
2592 {
2593   if (STACK_TOP_P (operands[0]))
2594     return "fxch\t%1";
2595   else
2596     return "fxch\t%0";
2597 }
2598   [(set_attr "type" "fxch")
2599    (set_attr "mode" "SF")])
2600
2601 (define_expand "movdf"
2602   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2603         (match_operand:DF 1 "general_operand" ""))]
2604   ""
2605   "ix86_expand_move (DFmode, operands); DONE;")
2606
2607 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2608 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2609 ;; On the average, pushdf using integers can be still shorter.  Allow this
2610 ;; pattern for optimize_size too.
2611
2612 (define_insn "*pushdf_nointeger"
2613   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2614         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Yt"))]
2615   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2616 {
2617   /* This insn should be already split before reg-stack.  */
2618   gcc_unreachable ();
2619 }
2620   [(set_attr "type" "multi")
2621    (set_attr "unit" "i387,*,*,*")
2622    (set_attr "mode" "DF,SI,SI,DF")])
2623
2624 (define_insn "*pushdf_integer"
2625   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2626         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Yt"))]
2627   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2628 {
2629   /* This insn should be already split before reg-stack.  */
2630   gcc_unreachable ();
2631 }
2632   [(set_attr "type" "multi")
2633    (set_attr "unit" "i387,*,*")
2634    (set_attr "mode" "DF,SI,DF")])
2635
2636 ;; %%% Kill this when call knows how to work this out.
2637 (define_split
2638   [(set (match_operand:DF 0 "push_operand" "")
2639         (match_operand:DF 1 "any_fp_register_operand" ""))]
2640   "!TARGET_64BIT && reload_completed"
2641   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2642    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2643   "")
2644
2645 (define_split
2646   [(set (match_operand:DF 0 "push_operand" "")
2647         (match_operand:DF 1 "any_fp_register_operand" ""))]
2648   "TARGET_64BIT && reload_completed"
2649   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2650    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2651   "")
2652
2653 (define_split
2654   [(set (match_operand:DF 0 "push_operand" "")
2655         (match_operand:DF 1 "general_operand" ""))]
2656   "reload_completed"
2657   [(const_int 0)]
2658   "ix86_split_long_move (operands); DONE;")
2659
2660 ;; Moving is usually shorter when only FP registers are used. This separate
2661 ;; movdf pattern avoids the use of integer registers for FP operations
2662 ;; when optimizing for size.
2663
2664 (define_insn "*movdf_nointeger"
2665   [(set (match_operand:DF 0 "nonimmediate_operand"
2666                         "=f,m,f,*r  ,o  ,Yt*x,Yt*x,Yt*x ,m  ")
2667         (match_operand:DF 1 "general_operand"
2668                         "fm,f,G,*roF,F*r,C   ,Yt*x,mYt*x,Yt*x"))]
2669   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2670    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2671    && (reload_in_progress || reload_completed
2672        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2673        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2674            && standard_80387_constant_p (operands[1]))
2675        || GET_CODE (operands[1]) != CONST_DOUBLE
2676        || memory_operand (operands[0], DFmode))"
2677 {
2678   switch (which_alternative)
2679     {
2680     case 0:
2681     case 1:
2682       return output_387_reg_move (insn, operands);
2683
2684     case 2:
2685       return standard_80387_constant_opcode (operands[1]);
2686
2687     case 3:
2688     case 4:
2689       return "#";
2690     case 5:
2691       switch (get_attr_mode (insn))
2692         {
2693         case MODE_V4SF:
2694           return "xorps\t%0, %0";
2695         case MODE_V2DF:
2696           return "xorpd\t%0, %0";
2697         case MODE_TI:
2698           return "pxor\t%0, %0";
2699         default:
2700           gcc_unreachable ();
2701         }
2702     case 6:
2703     case 7:
2704     case 8:
2705       switch (get_attr_mode (insn))
2706         {
2707         case MODE_V4SF:
2708           return "movaps\t{%1, %0|%0, %1}";
2709         case MODE_V2DF:
2710           return "movapd\t{%1, %0|%0, %1}";
2711         case MODE_TI:
2712           return "movdqa\t{%1, %0|%0, %1}";
2713         case MODE_DI:
2714           return "movq\t{%1, %0|%0, %1}";
2715         case MODE_DF:
2716           return "movsd\t{%1, %0|%0, %1}";
2717         case MODE_V1DF:
2718           return "movlpd\t{%1, %0|%0, %1}";
2719         case MODE_V2SF:
2720           return "movlps\t{%1, %0|%0, %1}";
2721         default:
2722           gcc_unreachable ();
2723         }
2724
2725     default:
2726       gcc_unreachable ();
2727     }
2728 }
2729   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2730    (set (attr "mode")
2731         (cond [(eq_attr "alternative" "0,1,2")
2732                  (const_string "DF")
2733                (eq_attr "alternative" "3,4")
2734                  (const_string "SI")
2735
2736                /* For SSE1, we have many fewer alternatives.  */
2737                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2738                  (cond [(eq_attr "alternative" "5,6")
2739                           (const_string "V4SF")
2740                        ]
2741                    (const_string "V2SF"))
2742
2743                /* xorps is one byte shorter.  */
2744                (eq_attr "alternative" "5")
2745                  (cond [(ne (symbol_ref "optimize_size")
2746                             (const_int 0))
2747                           (const_string "V4SF")
2748                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2749                             (const_int 0))
2750                           (const_string "TI")
2751                        ]
2752                        (const_string "V2DF"))
2753
2754                /* For architectures resolving dependencies on
2755                   whole SSE registers use APD move to break dependency
2756                   chains, otherwise use short move to avoid extra work.
2757
2758                   movaps encodes one byte shorter.  */
2759                (eq_attr "alternative" "6")
2760                  (cond
2761                    [(ne (symbol_ref "optimize_size")
2762                         (const_int 0))
2763                       (const_string "V4SF")
2764                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2765                         (const_int 0))
2766                       (const_string "V2DF")
2767                    ]
2768                    (const_string "DF"))
2769                /* For architectures resolving dependencies on register
2770                   parts we may avoid extra work to zero out upper part
2771                   of register.  */
2772                (eq_attr "alternative" "7")
2773                  (if_then_else
2774                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2775                        (const_int 0))
2776                    (const_string "V1DF")
2777                    (const_string "DF"))
2778               ]
2779               (const_string "DF")))])
2780
2781 (define_insn "*movdf_integer_rex64"
2782   [(set (match_operand:DF 0 "nonimmediate_operand"
2783                 "=f,m,f,r  ,m ,Yt*x,Yt*x,Yt*x,m   ,Yi,r ")
2784         (match_operand:DF 1 "general_operand"
2785                 "fm,f,G,rmF,Fr,C   ,Yt*x,m   ,Yt*x,r ,Yi"))]
2786   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2787    && (reload_in_progress || reload_completed
2788        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2789        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2790            && standard_80387_constant_p (operands[1]))
2791        || GET_CODE (operands[1]) != CONST_DOUBLE
2792        || memory_operand (operands[0], DFmode))"
2793 {
2794   switch (which_alternative)
2795     {
2796     case 0:
2797     case 1:
2798       return output_387_reg_move (insn, operands);
2799
2800     case 2:
2801       return standard_80387_constant_opcode (operands[1]);
2802
2803     case 3:
2804     case 4:
2805       return "#";
2806
2807     case 5:
2808       switch (get_attr_mode (insn))
2809         {
2810         case MODE_V4SF:
2811           return "xorps\t%0, %0";
2812         case MODE_V2DF:
2813           return "xorpd\t%0, %0";
2814         case MODE_TI:
2815           return "pxor\t%0, %0";
2816         default:
2817           gcc_unreachable ();
2818         }
2819     case 6:
2820     case 7:
2821     case 8:
2822       switch (get_attr_mode (insn))
2823         {
2824         case MODE_V4SF:
2825           return "movaps\t{%1, %0|%0, %1}";
2826         case MODE_V2DF:
2827           return "movapd\t{%1, %0|%0, %1}";
2828         case MODE_TI:
2829           return "movdqa\t{%1, %0|%0, %1}";
2830         case MODE_DI:
2831           return "movq\t{%1, %0|%0, %1}";
2832         case MODE_DF:
2833           return "movsd\t{%1, %0|%0, %1}";
2834         case MODE_V1DF:
2835           return "movlpd\t{%1, %0|%0, %1}";
2836         case MODE_V2SF:
2837           return "movlps\t{%1, %0|%0, %1}";
2838         default:
2839           gcc_unreachable ();
2840         }
2841
2842     case 9:
2843     case 10:
2844       return "movd\t{%1, %0|%0, %1}";
2845
2846     default:
2847       gcc_unreachable();
2848     }
2849 }
2850   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2851    (set (attr "mode")
2852         (cond [(eq_attr "alternative" "0,1,2")
2853                  (const_string "DF")
2854                (eq_attr "alternative" "3,4,9,10")
2855                  (const_string "DI")
2856
2857                /* For SSE1, we have many fewer alternatives.  */
2858                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2859                  (cond [(eq_attr "alternative" "5,6")
2860                           (const_string "V4SF")
2861                        ]
2862                    (const_string "V2SF"))
2863
2864                /* xorps is one byte shorter.  */
2865                (eq_attr "alternative" "5")
2866                  (cond [(ne (symbol_ref "optimize_size")
2867                             (const_int 0))
2868                           (const_string "V4SF")
2869                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2870                             (const_int 0))
2871                           (const_string "TI")
2872                        ]
2873                        (const_string "V2DF"))
2874
2875                /* For architectures resolving dependencies on
2876                   whole SSE registers use APD move to break dependency
2877                   chains, otherwise use short move to avoid extra work.
2878
2879                   movaps encodes one byte shorter.  */
2880                (eq_attr "alternative" "6")
2881                  (cond
2882                    [(ne (symbol_ref "optimize_size")
2883                         (const_int 0))
2884                       (const_string "V4SF")
2885                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2886                         (const_int 0))
2887                       (const_string "V2DF")
2888                    ]
2889                    (const_string "DF"))
2890                /* For architectures resolving dependencies on register
2891                   parts we may avoid extra work to zero out upper part
2892                   of register.  */
2893                (eq_attr "alternative" "7")
2894                  (if_then_else
2895                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2896                        (const_int 0))
2897                    (const_string "V1DF")
2898                    (const_string "DF"))
2899               ]
2900               (const_string "DF")))])
2901
2902 (define_insn "*movdf_integer"
2903   [(set (match_operand:DF 0 "nonimmediate_operand"
2904                 "=f,m,f,r  ,o ,Yt*x,Yt*x,Yt*x,m   ")
2905         (match_operand:DF 1 "general_operand"
2906                 "fm,f,G,roF,Fr,C   ,Yt*x,m   ,Yt*x"))]
2907   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2908    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2909    && (reload_in_progress || reload_completed
2910        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2911        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2912            && standard_80387_constant_p (operands[1]))
2913        || GET_CODE (operands[1]) != CONST_DOUBLE
2914        || memory_operand (operands[0], DFmode))"
2915 {
2916   switch (which_alternative)
2917     {
2918     case 0:
2919     case 1:
2920       return output_387_reg_move (insn, operands);
2921
2922     case 2:
2923       return standard_80387_constant_opcode (operands[1]);
2924
2925     case 3:
2926     case 4:
2927       return "#";
2928
2929     case 5:
2930       switch (get_attr_mode (insn))
2931         {
2932         case MODE_V4SF:
2933           return "xorps\t%0, %0";
2934         case MODE_V2DF:
2935           return "xorpd\t%0, %0";
2936         case MODE_TI:
2937           return "pxor\t%0, %0";
2938         default:
2939           gcc_unreachable ();
2940         }
2941     case 6:
2942     case 7:
2943     case 8:
2944       switch (get_attr_mode (insn))
2945         {
2946         case MODE_V4SF:
2947           return "movaps\t{%1, %0|%0, %1}";
2948         case MODE_V2DF:
2949           return "movapd\t{%1, %0|%0, %1}";
2950         case MODE_TI:
2951           return "movdqa\t{%1, %0|%0, %1}";
2952         case MODE_DI:
2953           return "movq\t{%1, %0|%0, %1}";
2954         case MODE_DF:
2955           return "movsd\t{%1, %0|%0, %1}";
2956         case MODE_V1DF:
2957           return "movlpd\t{%1, %0|%0, %1}";
2958         case MODE_V2SF:
2959           return "movlps\t{%1, %0|%0, %1}";
2960         default:
2961           gcc_unreachable ();
2962         }
2963
2964     default:
2965       gcc_unreachable();
2966     }
2967 }
2968   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2969    (set (attr "mode")
2970         (cond [(eq_attr "alternative" "0,1,2")
2971                  (const_string "DF")
2972                (eq_attr "alternative" "3,4")
2973                  (const_string "SI")
2974
2975                /* For SSE1, we have many fewer alternatives.  */
2976                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2977                  (cond [(eq_attr "alternative" "5,6")
2978                           (const_string "V4SF")
2979                        ]
2980                    (const_string "V2SF"))
2981
2982                /* xorps is one byte shorter.  */
2983                (eq_attr "alternative" "5")
2984                  (cond [(ne (symbol_ref "optimize_size")
2985                             (const_int 0))
2986                           (const_string "V4SF")
2987                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2988                             (const_int 0))
2989                           (const_string "TI")
2990                        ]
2991                        (const_string "V2DF"))
2992
2993                /* For architectures resolving dependencies on
2994                   whole SSE registers use APD move to break dependency
2995                   chains, otherwise use short move to avoid extra work.
2996
2997                   movaps encodes one byte shorter.  */
2998                (eq_attr "alternative" "6")
2999                  (cond
3000                    [(ne (symbol_ref "optimize_size")
3001                         (const_int 0))
3002                       (const_string "V4SF")
3003                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3004                         (const_int 0))
3005                       (const_string "V2DF")
3006                    ]
3007                    (const_string "DF"))
3008                /* For architectures resolving dependencies on register
3009                   parts we may avoid extra work to zero out upper part
3010                   of register.  */
3011                (eq_attr "alternative" "7")
3012                  (if_then_else
3013                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3014                        (const_int 0))
3015                    (const_string "V1DF")
3016                    (const_string "DF"))
3017               ]
3018               (const_string "DF")))])
3019
3020 (define_split
3021   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3022         (match_operand:DF 1 "general_operand" ""))]
3023   "reload_completed
3024    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3025    && ! (ANY_FP_REG_P (operands[0]) ||
3026          (GET_CODE (operands[0]) == SUBREG
3027           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3028    && ! (ANY_FP_REG_P (operands[1]) ||
3029          (GET_CODE (operands[1]) == SUBREG
3030           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3031   [(const_int 0)]
3032   "ix86_split_long_move (operands); DONE;")
3033
3034 (define_insn "*swapdf"
3035   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3036         (match_operand:DF 1 "fp_register_operand" "+f"))
3037    (set (match_dup 1)
3038         (match_dup 0))]
3039   "reload_completed || TARGET_80387"
3040 {
3041   if (STACK_TOP_P (operands[0]))
3042     return "fxch\t%1";
3043   else
3044     return "fxch\t%0";
3045 }
3046   [(set_attr "type" "fxch")
3047    (set_attr "mode" "DF")])
3048
3049 (define_expand "movxf"
3050   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3051         (match_operand:XF 1 "general_operand" ""))]
3052   ""
3053   "ix86_expand_move (XFmode, operands); DONE;")
3054
3055 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3056 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3057 ;; Pushing using integer instructions is longer except for constants
3058 ;; and direct memory references.
3059 ;; (assuming that any given constant is pushed only once, but this ought to be
3060 ;;  handled elsewhere).
3061
3062 (define_insn "*pushxf_nointeger"
3063   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3064         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3065   "optimize_size"
3066 {
3067   /* This insn should be already split before reg-stack.  */
3068   gcc_unreachable ();
3069 }
3070   [(set_attr "type" "multi")
3071    (set_attr "unit" "i387,*,*")
3072    (set_attr "mode" "XF,SI,SI")])
3073
3074 (define_insn "*pushxf_integer"
3075   [(set (match_operand:XF 0 "push_operand" "=<,<")
3076         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3077   "!optimize_size"
3078 {
3079   /* This insn should be already split before reg-stack.  */
3080   gcc_unreachable ();
3081 }
3082   [(set_attr "type" "multi")
3083    (set_attr "unit" "i387,*")
3084    (set_attr "mode" "XF,SI")])
3085
3086 (define_split
3087   [(set (match_operand 0 "push_operand" "")
3088         (match_operand 1 "general_operand" ""))]
3089   "reload_completed
3090    && (GET_MODE (operands[0]) == XFmode
3091        || GET_MODE (operands[0]) == DFmode)
3092    && !ANY_FP_REG_P (operands[1])"
3093   [(const_int 0)]
3094   "ix86_split_long_move (operands); DONE;")
3095
3096 (define_split
3097   [(set (match_operand:XF 0 "push_operand" "")
3098         (match_operand:XF 1 "any_fp_register_operand" ""))]
3099   "!TARGET_64BIT"
3100   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3101    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3102   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3103
3104 (define_split
3105   [(set (match_operand:XF 0 "push_operand" "")
3106         (match_operand:XF 1 "any_fp_register_operand" ""))]
3107   "TARGET_64BIT"
3108   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3109    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3110   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3111
3112 ;; Do not use integer registers when optimizing for size
3113 (define_insn "*movxf_nointeger"
3114   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3115         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3116   "optimize_size
3117    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3118    && (reload_in_progress || reload_completed
3119        || (optimize_size && standard_80387_constant_p (operands[1]))
3120        || GET_CODE (operands[1]) != CONST_DOUBLE
3121        || memory_operand (operands[0], XFmode))"
3122 {
3123   switch (which_alternative)
3124     {
3125     case 0:
3126     case 1:
3127       return output_387_reg_move (insn, operands);
3128
3129     case 2:
3130       return standard_80387_constant_opcode (operands[1]);
3131
3132     case 3: case 4:
3133       return "#";
3134     default:
3135       gcc_unreachable ();
3136     }
3137 }
3138   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3139    (set_attr "mode" "XF,XF,XF,SI,SI")])
3140
3141 (define_insn "*movxf_integer"
3142   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3143         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3144   "!optimize_size
3145    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3146    && (reload_in_progress || reload_completed
3147        || (optimize_size && standard_80387_constant_p (operands[1]))
3148        || GET_CODE (operands[1]) != CONST_DOUBLE
3149        || memory_operand (operands[0], XFmode))"
3150 {
3151   switch (which_alternative)
3152     {
3153     case 0:
3154     case 1:
3155       return output_387_reg_move (insn, operands);
3156
3157     case 2:
3158       return standard_80387_constant_opcode (operands[1]);
3159
3160     case 3: case 4:
3161       return "#";
3162
3163     default:
3164       gcc_unreachable ();
3165     }
3166 }
3167   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3168    (set_attr "mode" "XF,XF,XF,SI,SI")])
3169
3170 (define_expand "movtf"
3171   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3172         (match_operand:TF 1 "nonimmediate_operand" ""))]
3173   "TARGET_64BIT"
3174 {
3175   ix86_expand_move (TFmode, operands);
3176   DONE;
3177 })
3178
3179 (define_insn "*movtf_internal"
3180   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3181         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3182   "TARGET_64BIT
3183    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3184 {
3185   switch (which_alternative)
3186     {
3187     case 0:
3188     case 1:
3189       if (get_attr_mode (insn) == MODE_V4SF)
3190         return "movaps\t{%1, %0|%0, %1}";
3191       else
3192         return "movdqa\t{%1, %0|%0, %1}";
3193     case 2:
3194       if (get_attr_mode (insn) == MODE_V4SF)
3195         return "xorps\t%0, %0";
3196       else
3197         return "pxor\t%0, %0";
3198     case 3:
3199     case 4:
3200         return "#";
3201     default:
3202       gcc_unreachable ();
3203     }
3204 }
3205   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3206    (set (attr "mode")
3207         (cond [(eq_attr "alternative" "0,2")
3208                  (if_then_else
3209                    (ne (symbol_ref "optimize_size")
3210                        (const_int 0))
3211                    (const_string "V4SF")
3212                    (const_string "TI"))
3213                (eq_attr "alternative" "1")
3214                  (if_then_else
3215                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3216                             (const_int 0))
3217                         (ne (symbol_ref "optimize_size")
3218                             (const_int 0)))
3219                    (const_string "V4SF")
3220                    (const_string "TI"))]
3221                (const_string "DI")))])
3222
3223 (define_split
3224   [(set (match_operand 0 "nonimmediate_operand" "")
3225         (match_operand 1 "general_operand" ""))]
3226   "reload_completed
3227    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3228    && GET_MODE (operands[0]) == XFmode
3229    && ! (ANY_FP_REG_P (operands[0]) ||
3230          (GET_CODE (operands[0]) == SUBREG
3231           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3232    && ! (ANY_FP_REG_P (operands[1]) ||
3233          (GET_CODE (operands[1]) == SUBREG
3234           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3235   [(const_int 0)]
3236   "ix86_split_long_move (operands); DONE;")
3237
3238 (define_split
3239   [(set (match_operand 0 "register_operand" "")
3240         (match_operand 1 "memory_operand" ""))]
3241   "reload_completed
3242    && MEM_P (operands[1])
3243    && (GET_MODE (operands[0]) == TFmode
3244        || GET_MODE (operands[0]) == XFmode
3245        || GET_MODE (operands[0]) == SFmode
3246        || GET_MODE (operands[0]) == DFmode)
3247    && (operands[2] = find_constant_src (insn))"
3248   [(set (match_dup 0) (match_dup 2))]
3249 {
3250   rtx c = operands[2];
3251   rtx r = operands[0];
3252
3253   if (GET_CODE (r) == SUBREG)
3254     r = SUBREG_REG (r);
3255
3256   if (SSE_REG_P (r))
3257     {
3258       if (!standard_sse_constant_p (c))
3259         FAIL;
3260     }
3261   else if (FP_REG_P (r))
3262     {
3263       if (!standard_80387_constant_p (c))
3264         FAIL;
3265     }
3266   else if (MMX_REG_P (r))
3267     FAIL;
3268 })
3269
3270 (define_split
3271   [(set (match_operand 0 "register_operand" "")
3272         (float_extend (match_operand 1 "memory_operand" "")))]
3273   "reload_completed
3274    && MEM_P (operands[1])
3275    && (GET_MODE (operands[0]) == TFmode
3276        || GET_MODE (operands[0]) == XFmode
3277        || GET_MODE (operands[0]) == SFmode
3278        || GET_MODE (operands[0]) == DFmode)
3279    && (operands[2] = find_constant_src (insn))"
3280   [(set (match_dup 0) (match_dup 2))]
3281 {
3282   rtx c = operands[2];
3283   rtx r = operands[0];
3284
3285   if (GET_CODE (r) == SUBREG)
3286     r = SUBREG_REG (r);
3287
3288   if (SSE_REG_P (r))
3289     {
3290       if (!standard_sse_constant_p (c))
3291         FAIL;
3292     }
3293   else if (FP_REG_P (r))
3294     {
3295       if (!standard_80387_constant_p (c))
3296         FAIL;
3297     }
3298   else if (MMX_REG_P (r))
3299     FAIL;
3300 })
3301
3302 (define_insn "swapxf"
3303   [(set (match_operand:XF 0 "register_operand" "+f")
3304         (match_operand:XF 1 "register_operand" "+f"))
3305    (set (match_dup 1)
3306         (match_dup 0))]
3307   "TARGET_80387"
3308 {
3309   if (STACK_TOP_P (operands[0]))
3310     return "fxch\t%1";
3311   else
3312     return "fxch\t%0";
3313 }
3314   [(set_attr "type" "fxch")
3315    (set_attr "mode" "XF")])
3316
3317 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3318 (define_split
3319   [(set (match_operand:X87MODEF 0 "register_operand" "")
3320         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3321   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3322    && (standard_80387_constant_p (operands[1]) == 8
3323        || standard_80387_constant_p (operands[1]) == 9)"
3324   [(set (match_dup 0)(match_dup 1))
3325    (set (match_dup 0)
3326         (neg:X87MODEF (match_dup 0)))]
3327 {
3328   REAL_VALUE_TYPE r;
3329
3330   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3331   if (real_isnegzero (&r))
3332     operands[1] = CONST0_RTX (<MODE>mode);
3333   else
3334     operands[1] = CONST1_RTX (<MODE>mode);
3335 })
3336
3337 (define_split
3338   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3339         (match_operand:TF 1 "general_operand" ""))]
3340   "reload_completed
3341    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3342   [(const_int 0)]
3343   "ix86_split_long_move (operands); DONE;")
3344 \f
3345 ;; Zero extension instructions
3346
3347 (define_expand "zero_extendhisi2"
3348   [(set (match_operand:SI 0 "register_operand" "")
3349      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3350   ""
3351 {
3352   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3353     {
3354       operands[1] = force_reg (HImode, operands[1]);
3355       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3356       DONE;
3357     }
3358 })
3359
3360 (define_insn "zero_extendhisi2_and"
3361   [(set (match_operand:SI 0 "register_operand" "=r")
3362      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3363    (clobber (reg:CC FLAGS_REG))]
3364   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3365   "#"
3366   [(set_attr "type" "alu1")
3367    (set_attr "mode" "SI")])
3368
3369 (define_split
3370   [(set (match_operand:SI 0 "register_operand" "")
3371         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3372    (clobber (reg:CC FLAGS_REG))]
3373   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3374   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3375               (clobber (reg:CC FLAGS_REG))])]
3376   "")
3377
3378 (define_insn "*zero_extendhisi2_movzwl"
3379   [(set (match_operand:SI 0 "register_operand" "=r")
3380      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3381   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3382   "movz{wl|x}\t{%1, %0|%0, %1}"
3383   [(set_attr "type" "imovx")
3384    (set_attr "mode" "SI")])
3385
3386 (define_expand "zero_extendqihi2"
3387   [(parallel
3388     [(set (match_operand:HI 0 "register_operand" "")
3389        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3390      (clobber (reg:CC FLAGS_REG))])]
3391   ""
3392   "")
3393
3394 (define_insn "*zero_extendqihi2_and"
3395   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3396      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3397    (clobber (reg:CC FLAGS_REG))]
3398   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3399   "#"
3400   [(set_attr "type" "alu1")
3401    (set_attr "mode" "HI")])
3402
3403 (define_insn "*zero_extendqihi2_movzbw_and"
3404   [(set (match_operand:HI 0 "register_operand" "=r,r")
3405      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3406    (clobber (reg:CC FLAGS_REG))]
3407   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3408   "#"
3409   [(set_attr "type" "imovx,alu1")
3410    (set_attr "mode" "HI")])
3411
3412 ; zero extend to SImode here to avoid partial register stalls
3413 (define_insn "*zero_extendqihi2_movzbl"
3414   [(set (match_operand:HI 0 "register_operand" "=r")
3415      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3416   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3417   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3418   [(set_attr "type" "imovx")
3419    (set_attr "mode" "SI")])
3420
3421 ;; For the movzbw case strip only the clobber
3422 (define_split
3423   [(set (match_operand:HI 0 "register_operand" "")
3424         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3425    (clobber (reg:CC FLAGS_REG))]
3426   "reload_completed
3427    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3428    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3429   [(set (match_operand:HI 0 "register_operand" "")
3430         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3431
3432 ;; When source and destination does not overlap, clear destination
3433 ;; first and then do the movb
3434 (define_split
3435   [(set (match_operand:HI 0 "register_operand" "")
3436         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3437    (clobber (reg:CC FLAGS_REG))]
3438   "reload_completed
3439    && ANY_QI_REG_P (operands[0])
3440    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3441    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3442   [(set (match_dup 0) (const_int 0))
3443    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3444   "operands[2] = gen_lowpart (QImode, operands[0]);")
3445
3446 ;; Rest is handled by single and.
3447 (define_split
3448   [(set (match_operand:HI 0 "register_operand" "")
3449         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3450    (clobber (reg:CC FLAGS_REG))]
3451   "reload_completed
3452    && true_regnum (operands[0]) == true_regnum (operands[1])"
3453   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3454               (clobber (reg:CC FLAGS_REG))])]
3455   "")
3456
3457 (define_expand "zero_extendqisi2"
3458   [(parallel
3459     [(set (match_operand:SI 0 "register_operand" "")
3460        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3461      (clobber (reg:CC FLAGS_REG))])]
3462   ""
3463   "")
3464
3465 (define_insn "*zero_extendqisi2_and"
3466   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3467      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3468    (clobber (reg:CC FLAGS_REG))]
3469   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3470   "#"
3471   [(set_attr "type" "alu1")
3472    (set_attr "mode" "SI")])
3473
3474 (define_insn "*zero_extendqisi2_movzbw_and"
3475   [(set (match_operand:SI 0 "register_operand" "=r,r")
3476      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3477    (clobber (reg:CC FLAGS_REG))]
3478   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3479   "#"
3480   [(set_attr "type" "imovx,alu1")
3481    (set_attr "mode" "SI")])
3482
3483 (define_insn "*zero_extendqisi2_movzbw"
3484   [(set (match_operand:SI 0 "register_operand" "=r")
3485      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3486   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3487   "movz{bl|x}\t{%1, %0|%0, %1}"
3488   [(set_attr "type" "imovx")
3489    (set_attr "mode" "SI")])
3490
3491 ;; For the movzbl case strip only the clobber
3492 (define_split
3493   [(set (match_operand:SI 0 "register_operand" "")
3494         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3495    (clobber (reg:CC FLAGS_REG))]
3496   "reload_completed
3497    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3498    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3499   [(set (match_dup 0)
3500         (zero_extend:SI (match_dup 1)))])
3501
3502 ;; When source and destination does not overlap, clear destination
3503 ;; first and then do the movb
3504 (define_split
3505   [(set (match_operand:SI 0 "register_operand" "")
3506         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3507    (clobber (reg:CC FLAGS_REG))]
3508   "reload_completed
3509    && ANY_QI_REG_P (operands[0])
3510    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3511    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3512    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3513   [(set (match_dup 0) (const_int 0))
3514    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3515   "operands[2] = gen_lowpart (QImode, operands[0]);")
3516
3517 ;; Rest is handled by single and.
3518 (define_split
3519   [(set (match_operand:SI 0 "register_operand" "")
3520         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3521    (clobber (reg:CC FLAGS_REG))]
3522   "reload_completed
3523    && true_regnum (operands[0]) == true_regnum (operands[1])"
3524   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3525               (clobber (reg:CC FLAGS_REG))])]
3526   "")
3527
3528 ;; %%% Kill me once multi-word ops are sane.
3529 (define_expand "zero_extendsidi2"
3530   [(set (match_operand:DI 0 "register_operand" "=r")
3531      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3532   ""
3533 {
3534   if (!TARGET_64BIT)
3535     {
3536       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3537       DONE;
3538     }
3539 })
3540
3541 (define_insn "zero_extendsidi2_32"
3542   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Yt")
3543         (zero_extend:DI
3544          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3545    (clobber (reg:CC FLAGS_REG))]
3546   "!TARGET_64BIT"
3547   "@
3548    #
3549    #
3550    #
3551    movd\t{%1, %0|%0, %1}
3552    movd\t{%1, %0|%0, %1}
3553    movd\t{%1, %0|%0, %1}
3554    movd\t{%1, %0|%0, %1}"
3555   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3556    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3557
3558 (define_insn "zero_extendsidi2_rex64"
3559   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Yt")
3560      (zero_extend:DI
3561        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3562   "TARGET_64BIT"
3563   "@
3564    mov\t{%k1, %k0|%k0, %k1}
3565    #
3566    movd\t{%1, %0|%0, %1}
3567    movd\t{%1, %0|%0, %1}
3568    movd\t{%1, %0|%0, %1}
3569    movd\t{%1, %0|%0, %1}"
3570   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3571    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3572
3573 (define_split
3574   [(set (match_operand:DI 0 "memory_operand" "")
3575      (zero_extend:DI (match_dup 0)))]
3576   "TARGET_64BIT"
3577   [(set (match_dup 4) (const_int 0))]
3578   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3579
3580 (define_split
3581   [(set (match_operand:DI 0 "register_operand" "")
3582         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3583    (clobber (reg:CC FLAGS_REG))]
3584   "!TARGET_64BIT && reload_completed
3585    && true_regnum (operands[0]) == true_regnum (operands[1])"
3586   [(set (match_dup 4) (const_int 0))]
3587   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3588
3589 (define_split
3590   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3591         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3592    (clobber (reg:CC FLAGS_REG))]
3593   "!TARGET_64BIT && reload_completed
3594    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3595   [(set (match_dup 3) (match_dup 1))
3596    (set (match_dup 4) (const_int 0))]
3597   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3598
3599 (define_insn "zero_extendhidi2"
3600   [(set (match_operand:DI 0 "register_operand" "=r")
3601      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3602   "TARGET_64BIT"
3603   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3604   [(set_attr "type" "imovx")
3605    (set_attr "mode" "DI")])
3606
3607 (define_insn "zero_extendqidi2"
3608   [(set (match_operand:DI 0 "register_operand" "=r")
3609      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3610   "TARGET_64BIT"
3611   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3612   [(set_attr "type" "imovx")
3613    (set_attr "mode" "DI")])
3614 \f
3615 ;; Sign extension instructions
3616
3617 (define_expand "extendsidi2"
3618   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3619                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3620               (clobber (reg:CC FLAGS_REG))
3621               (clobber (match_scratch:SI 2 ""))])]
3622   ""
3623 {
3624   if (TARGET_64BIT)
3625     {
3626       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3627       DONE;
3628     }
3629 })
3630
3631 (define_insn "*extendsidi2_1"
3632   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3633         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3634    (clobber (reg:CC FLAGS_REG))
3635    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3636   "!TARGET_64BIT"
3637   "#")
3638
3639 (define_insn "extendsidi2_rex64"
3640   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3641         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3642   "TARGET_64BIT"
3643   "@
3644    {cltq|cdqe}
3645    movs{lq|x}\t{%1,%0|%0, %1}"
3646   [(set_attr "type" "imovx")
3647    (set_attr "mode" "DI")
3648    (set_attr "prefix_0f" "0")
3649    (set_attr "modrm" "0,1")])
3650
3651 (define_insn "extendhidi2"
3652   [(set (match_operand:DI 0 "register_operand" "=r")
3653         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3654   "TARGET_64BIT"
3655   "movs{wq|x}\t{%1,%0|%0, %1}"
3656   [(set_attr "type" "imovx")
3657    (set_attr "mode" "DI")])
3658
3659 (define_insn "extendqidi2"
3660   [(set (match_operand:DI 0 "register_operand" "=r")
3661         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3662   "TARGET_64BIT"
3663   "movs{bq|x}\t{%1,%0|%0, %1}"
3664    [(set_attr "type" "imovx")
3665     (set_attr "mode" "DI")])
3666
3667 ;; Extend to memory case when source register does die.
3668 (define_split
3669   [(set (match_operand:DI 0 "memory_operand" "")
3670         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3671    (clobber (reg:CC FLAGS_REG))
3672    (clobber (match_operand:SI 2 "register_operand" ""))]
3673   "(reload_completed
3674     && dead_or_set_p (insn, operands[1])
3675     && !reg_mentioned_p (operands[1], operands[0]))"
3676   [(set (match_dup 3) (match_dup 1))
3677    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3678               (clobber (reg:CC FLAGS_REG))])
3679    (set (match_dup 4) (match_dup 1))]
3680   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3681
3682 ;; Extend to memory case when source register does not die.
3683 (define_split
3684   [(set (match_operand:DI 0 "memory_operand" "")
3685         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3686    (clobber (reg:CC FLAGS_REG))
3687    (clobber (match_operand:SI 2 "register_operand" ""))]
3688   "reload_completed"
3689   [(const_int 0)]
3690 {
3691   split_di (&operands[0], 1, &operands[3], &operands[4]);
3692
3693   emit_move_insn (operands[3], operands[1]);
3694
3695   /* Generate a cltd if possible and doing so it profitable.  */
3696   if ((optimize_size || TARGET_USE_CLTD)
3697       && true_regnum (operands[1]) == 0
3698       && true_regnum (operands[2]) == 1)
3699     {
3700       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3701     }
3702   else
3703     {
3704       emit_move_insn (operands[2], operands[1]);
3705       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3706     }
3707   emit_move_insn (operands[4], operands[2]);
3708   DONE;
3709 })
3710
3711 ;; Extend to register case.  Optimize case where source and destination
3712 ;; registers match and cases where we can use cltd.
3713 (define_split
3714   [(set (match_operand:DI 0 "register_operand" "")
3715         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3716    (clobber (reg:CC FLAGS_REG))
3717    (clobber (match_scratch:SI 2 ""))]
3718   "reload_completed"
3719   [(const_int 0)]
3720 {
3721   split_di (&operands[0], 1, &operands[3], &operands[4]);
3722
3723   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3724     emit_move_insn (operands[3], operands[1]);
3725
3726   /* Generate a cltd if possible and doing so it profitable.  */
3727   if ((optimize_size || TARGET_USE_CLTD)
3728       && true_regnum (operands[3]) == 0)
3729     {
3730       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3731       DONE;
3732     }
3733
3734   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3735     emit_move_insn (operands[4], operands[1]);
3736
3737   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3738   DONE;
3739 })
3740
3741 (define_insn "extendhisi2"
3742   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3743         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3744   ""
3745 {
3746   switch (get_attr_prefix_0f (insn))
3747     {
3748     case 0:
3749       return "{cwtl|cwde}";
3750     default:
3751       return "movs{wl|x}\t{%1,%0|%0, %1}";
3752     }
3753 }
3754   [(set_attr "type" "imovx")
3755    (set_attr "mode" "SI")
3756    (set (attr "prefix_0f")
3757      ;; movsx is short decodable while cwtl is vector decoded.
3758      (if_then_else (and (eq_attr "cpu" "!k6")
3759                         (eq_attr "alternative" "0"))
3760         (const_string "0")
3761         (const_string "1")))
3762    (set (attr "modrm")
3763      (if_then_else (eq_attr "prefix_0f" "0")
3764         (const_string "0")
3765         (const_string "1")))])
3766
3767 (define_insn "*extendhisi2_zext"
3768   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3769         (zero_extend:DI
3770           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3771   "TARGET_64BIT"
3772 {
3773   switch (get_attr_prefix_0f (insn))
3774     {
3775     case 0:
3776       return "{cwtl|cwde}";
3777     default:
3778       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3779     }
3780 }
3781   [(set_attr "type" "imovx")
3782    (set_attr "mode" "SI")
3783    (set (attr "prefix_0f")
3784      ;; movsx is short decodable while cwtl is vector decoded.
3785      (if_then_else (and (eq_attr "cpu" "!k6")
3786                         (eq_attr "alternative" "0"))
3787         (const_string "0")
3788         (const_string "1")))
3789    (set (attr "modrm")
3790      (if_then_else (eq_attr "prefix_0f" "0")
3791         (const_string "0")
3792         (const_string "1")))])
3793
3794 (define_insn "extendqihi2"
3795   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3796         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3797   ""
3798 {
3799   switch (get_attr_prefix_0f (insn))
3800     {
3801     case 0:
3802       return "{cbtw|cbw}";
3803     default:
3804       return "movs{bw|x}\t{%1,%0|%0, %1}";
3805     }
3806 }
3807   [(set_attr "type" "imovx")
3808    (set_attr "mode" "HI")
3809    (set (attr "prefix_0f")
3810      ;; movsx is short decodable while cwtl is vector decoded.
3811      (if_then_else (and (eq_attr "cpu" "!k6")
3812                         (eq_attr "alternative" "0"))
3813         (const_string "0")
3814         (const_string "1")))
3815    (set (attr "modrm")
3816      (if_then_else (eq_attr "prefix_0f" "0")
3817         (const_string "0")
3818         (const_string "1")))])
3819
3820 (define_insn "extendqisi2"
3821   [(set (match_operand:SI 0 "register_operand" "=r")
3822         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3823   ""
3824   "movs{bl|x}\t{%1,%0|%0, %1}"
3825    [(set_attr "type" "imovx")
3826     (set_attr "mode" "SI")])
3827
3828 (define_insn "*extendqisi2_zext"
3829   [(set (match_operand:DI 0 "register_operand" "=r")
3830         (zero_extend:DI
3831           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3832   "TARGET_64BIT"
3833   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3834    [(set_attr "type" "imovx")
3835     (set_attr "mode" "SI")])
3836 \f
3837 ;; Conversions between float and double.
3838
3839 ;; These are all no-ops in the model used for the 80387.  So just
3840 ;; emit moves.
3841
3842 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3843 (define_insn "*dummy_extendsfdf2"
3844   [(set (match_operand:DF 0 "push_operand" "=<")
3845         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3846   "0"
3847   "#")
3848
3849 (define_split
3850   [(set (match_operand:DF 0 "push_operand" "")
3851         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3852   "!TARGET_64BIT"
3853   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3854    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3855
3856 (define_split
3857   [(set (match_operand:DF 0 "push_operand" "")
3858         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3859   "TARGET_64BIT"
3860   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3861    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3862
3863 (define_insn "*dummy_extendsfxf2"
3864   [(set (match_operand:XF 0 "push_operand" "=<")
3865         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3866   "0"
3867   "#")
3868
3869 (define_split
3870   [(set (match_operand:XF 0 "push_operand" "")
3871         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3872   ""
3873   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3874    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3875   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3876
3877 (define_split
3878   [(set (match_operand:XF 0 "push_operand" "")
3879         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3880   "TARGET_64BIT"
3881   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3882    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3883   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3884
3885 (define_split
3886   [(set (match_operand:XF 0 "push_operand" "")
3887         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3888   ""
3889   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3890    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3891   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3892
3893 (define_split
3894   [(set (match_operand:XF 0 "push_operand" "")
3895         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3896   "TARGET_64BIT"
3897   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3898    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3899   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3900
3901 (define_expand "extendsfdf2"
3902   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3903         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3904   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3905 {
3906   /* ??? Needed for compress_float_constant since all fp constants
3907      are LEGITIMATE_CONSTANT_P.  */
3908   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3909     {
3910       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3911           && standard_80387_constant_p (operands[1]) > 0)
3912         {
3913           operands[1] = simplify_const_unary_operation
3914             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3915           emit_move_insn_1 (operands[0], operands[1]);
3916           DONE;
3917         }
3918       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3919     }
3920 })
3921
3922 (define_insn "*extendsfdf2_mixed"
3923   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3924         (float_extend:DF
3925           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3926   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3927 {
3928   switch (which_alternative)
3929     {
3930     case 0:
3931     case 1:
3932       return output_387_reg_move (insn, operands);
3933
3934     case 2:
3935       return "cvtss2sd\t{%1, %0|%0, %1}";
3936
3937     default:
3938       gcc_unreachable ();
3939     }
3940 }
3941   [(set_attr "type" "fmov,fmov,ssecvt")
3942    (set_attr "mode" "SF,XF,DF")])
3943
3944 (define_insn "*extendsfdf2_sse"
3945   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3946         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3947   "TARGET_SSE2 && TARGET_SSE_MATH"
3948   "cvtss2sd\t{%1, %0|%0, %1}"
3949   [(set_attr "type" "ssecvt")
3950    (set_attr "mode" "DF")])
3951
3952 (define_insn "*extendsfdf2_i387"
3953   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3954         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3955   "TARGET_80387"
3956   "* return output_387_reg_move (insn, operands);"
3957   [(set_attr "type" "fmov")
3958    (set_attr "mode" "SF,XF")])
3959
3960 (define_expand "extend<mode>xf2"
3961   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3962         (float_extend:XF (match_operand:X87MODEF12 1 "general_operand" "")))]
3963   "TARGET_80387"
3964 {
3965   /* ??? Needed for compress_float_constant since all fp constants
3966      are LEGITIMATE_CONSTANT_P.  */
3967   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3968     {
3969       if (standard_80387_constant_p (operands[1]) > 0)
3970         {
3971           operands[1] = simplify_const_unary_operation
3972             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3973           emit_move_insn_1 (operands[0], operands[1]);
3974           DONE;
3975         }
3976       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3977     }
3978 })
3979
3980 (define_insn "*extend<mode>xf2_i387"
3981   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3982         (float_extend:XF
3983           (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,f")))]
3984   "TARGET_80387"
3985   "* return output_387_reg_move (insn, operands);"
3986   [(set_attr "type" "fmov")
3987    (set_attr "mode" "<MODE>,XF")])
3988
3989 ;; %%% This seems bad bad news.
3990 ;; This cannot output into an f-reg because there is no way to be sure
3991 ;; of truncating in that case.  Otherwise this is just like a simple move
3992 ;; insn.  So we pretend we can output to a reg in order to get better
3993 ;; register preferencing, but we really use a stack slot.
3994
3995 ;; Conversion from DFmode to SFmode.
3996
3997 (define_expand "truncdfsf2"
3998   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3999         (float_truncate:SF
4000           (match_operand:DF 1 "nonimmediate_operand" "")))]
4001   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4002 {
4003   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4004     ;
4005   else if (flag_unsafe_math_optimizations)
4006     ;
4007   else
4008     {
4009       rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
4010       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4011       DONE;
4012     }
4013 })
4014
4015 (define_expand "truncdfsf2_with_temp"
4016   [(parallel [(set (match_operand:SF 0 "" "")
4017                    (float_truncate:SF (match_operand:DF 1 "" "")))
4018               (clobber (match_operand:SF 2 "" ""))])]
4019   "")
4020
4021 (define_insn "*truncdfsf_fast_mixed"
4022   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
4023         (float_truncate:SF
4024           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4025   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4026 {
4027   switch (which_alternative)
4028     {
4029     case 0:
4030     case 1:
4031       return output_387_reg_move (insn, operands);
4032     case 2:
4033       return "cvtsd2ss\t{%1, %0|%0, %1}";
4034     default:
4035       gcc_unreachable ();
4036     }
4037 }
4038   [(set_attr "type" "fmov,fmov,ssecvt")
4039    (set_attr "mode" "SF")])
4040
4041 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4042 ;; because nothing we do here is unsafe.
4043 (define_insn "*truncdfsf_fast_sse"
4044   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4045         (float_truncate:SF
4046           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4047   "TARGET_SSE2 && TARGET_SSE_MATH"
4048   "cvtsd2ss\t{%1, %0|%0, %1}"
4049   [(set_attr "type" "ssecvt")
4050    (set_attr "mode" "SF")])
4051
4052 (define_insn "*truncdfsf_fast_i387"
4053   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4054         (float_truncate:SF
4055           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4056   "TARGET_80387 && flag_unsafe_math_optimizations"
4057   "* return output_387_reg_move (insn, operands);"
4058   [(set_attr "type" "fmov")
4059    (set_attr "mode" "SF")])
4060
4061 (define_insn "*truncdfsf_mixed"
4062   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Yt")
4063         (float_truncate:SF
4064           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ytm")))
4065    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4066   "TARGET_MIX_SSE_I387"
4067 {
4068   switch (which_alternative)
4069     {
4070     case 0:
4071       return output_387_reg_move (insn, operands);
4072
4073     case 1:
4074       return "#";
4075     case 2:
4076       return "cvtsd2ss\t{%1, %0|%0, %1}";
4077     default:
4078       gcc_unreachable ();
4079     }
4080 }
4081   [(set_attr "type" "fmov,multi,ssecvt")
4082    (set_attr "unit" "*,i387,*")
4083    (set_attr "mode" "SF")])
4084
4085 (define_insn "*truncdfsf_i387"
4086   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4087         (float_truncate:SF
4088           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4089    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4090   "TARGET_80387"
4091 {
4092   switch (which_alternative)
4093     {
4094     case 0:
4095       return output_387_reg_move (insn, operands);
4096
4097     case 1:
4098       return "#";
4099     default:
4100       gcc_unreachable ();
4101     }
4102 }
4103   [(set_attr "type" "fmov,multi")
4104    (set_attr "unit" "*,i387")
4105    (set_attr "mode" "SF")])
4106
4107 (define_insn "*truncdfsf2_i387_1"
4108   [(set (match_operand:SF 0 "memory_operand" "=m")
4109         (float_truncate:SF
4110           (match_operand:DF 1 "register_operand" "f")))]
4111   "TARGET_80387
4112    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4113    && !TARGET_MIX_SSE_I387"
4114   "* return output_387_reg_move (insn, operands);"
4115   [(set_attr "type" "fmov")
4116    (set_attr "mode" "SF")])
4117
4118 (define_split
4119   [(set (match_operand:SF 0 "register_operand" "")
4120         (float_truncate:SF
4121          (match_operand:DF 1 "fp_register_operand" "")))
4122    (clobber (match_operand 2 "" ""))]
4123   "reload_completed"
4124   [(set (match_dup 2) (match_dup 1))
4125    (set (match_dup 0) (match_dup 2))]
4126 {
4127   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4128 })
4129
4130 ;; Conversion from XFmode to {SF,DF}mode
4131
4132 (define_expand "truncxf<mode>2"
4133   [(parallel [(set (match_operand:X87MODEF12 0 "nonimmediate_operand" "")
4134                    (float_truncate:X87MODEF12
4135                      (match_operand:XF 1 "register_operand" "")))
4136               (clobber (match_dup 2))])]
4137   "TARGET_80387"
4138 {
4139   if (flag_unsafe_math_optimizations)
4140     {
4141       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4142       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4143       if (reg != operands[0])
4144         emit_move_insn (operands[0], reg);
4145       DONE;
4146     }
4147   else
4148     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_VIRTUAL);
4149 })
4150
4151 (define_insn "*truncxfsf2_mixed"
4152   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4153         (float_truncate:SF
4154           (match_operand:XF 1 "register_operand" "f,f")))
4155    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4156   "TARGET_80387"
4157 {
4158   gcc_assert (!which_alternative);
4159   return output_387_reg_move (insn, operands);
4160 }
4161   [(set_attr "type" "fmov,multi")
4162    (set_attr "unit" "*,i387")
4163    (set_attr "mode" "SF")])
4164
4165 (define_insn "*truncxfdf2_mixed"
4166   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fYt*r")
4167         (float_truncate:DF
4168           (match_operand:XF 1 "register_operand" "f,f")))
4169    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4170   "TARGET_80387"
4171 {
4172   gcc_assert (!which_alternative);
4173   return output_387_reg_move (insn, operands);
4174 }
4175   [(set_attr "type" "fmov,multi")
4176    (set_attr "unit" "*,i387")
4177    (set_attr "mode" "DF")])
4178
4179 (define_insn "truncxf<mode>2_i387_noop"
4180   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
4181         (float_truncate:X87MODEF12
4182           (match_operand:XF 1 "register_operand" "f")))]
4183   "TARGET_80387 && flag_unsafe_math_optimizations"
4184   "* return output_387_reg_move (insn, operands);"
4185   [(set_attr "type" "fmov")
4186    (set_attr "mode" "<MODE>")])
4187
4188 (define_insn "*truncxf<mode>2_i387"
4189   [(set (match_operand:X87MODEF12 0 "memory_operand" "=m")
4190         (float_truncate:X87MODEF12
4191           (match_operand:XF 1 "register_operand" "f")))]
4192   "TARGET_80387"
4193   "* return output_387_reg_move (insn, operands);"
4194   [(set_attr "type" "fmov")
4195    (set_attr "mode" "<MODE>")])
4196
4197 (define_split
4198   [(set (match_operand:X87MODEF12 0 "register_operand" "")
4199         (float_truncate:X87MODEF12
4200           (match_operand:XF 1 "register_operand" "")))
4201    (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4202   "TARGET_80387 && reload_completed"
4203   [(set (match_dup 2) (float_truncate:X87MODEF12 (match_dup 1)))
4204    (set (match_dup 0) (match_dup 2))]
4205   "")
4206
4207 (define_split
4208   [(set (match_operand:X87MODEF12 0 "memory_operand" "")
4209         (float_truncate:X87MODEF12
4210           (match_operand:XF 1 "register_operand" "")))
4211    (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4212   "TARGET_80387"
4213   [(set (match_dup 0) (float_truncate:X87MODEF12 (match_dup 1)))]
4214   "")
4215 \f
4216 ;; Signed conversion to DImode.
4217
4218 (define_expand "fix_truncxfdi2"
4219   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4220                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4221               (clobber (reg:CC FLAGS_REG))])]
4222   "TARGET_80387"
4223 {
4224   if (TARGET_FISTTP)
4225    {
4226      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4227      DONE;
4228    }
4229 })
4230
4231 (define_expand "fix_trunc<mode>di2"
4232   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4233                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4234               (clobber (reg:CC FLAGS_REG))])]
4235   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4236 {
4237   if (TARGET_FISTTP
4238       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4239    {
4240      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4241      DONE;
4242    }
4243   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4244    {
4245      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4246      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4247      if (out != operands[0])
4248         emit_move_insn (operands[0], out);
4249      DONE;
4250    }
4251 })
4252
4253 ;; Signed conversion to SImode.
4254
4255 (define_expand "fix_truncxfsi2"
4256   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4257                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4258               (clobber (reg:CC FLAGS_REG))])]
4259   "TARGET_80387"
4260 {
4261   if (TARGET_FISTTP)
4262    {
4263      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4264      DONE;
4265    }
4266 })
4267
4268 (define_expand "fix_trunc<mode>si2"
4269   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4270                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4271               (clobber (reg:CC FLAGS_REG))])]
4272   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4273 {
4274   if (TARGET_FISTTP
4275       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4276    {
4277      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4278      DONE;
4279    }
4280   if (SSE_FLOAT_MODE_P (<MODE>mode))
4281    {
4282      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4283      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4284      if (out != operands[0])
4285         emit_move_insn (operands[0], out);
4286      DONE;
4287    }
4288 })
4289
4290 ;; Signed conversion to HImode.
4291
4292 (define_expand "fix_trunc<mode>hi2"
4293   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4294                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4295               (clobber (reg:CC FLAGS_REG))])]
4296   "TARGET_80387
4297    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4298 {
4299   if (TARGET_FISTTP)
4300    {
4301      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4302      DONE;
4303    }
4304 })
4305
4306 ;; Unsigned conversion to SImode.
4307
4308 (define_expand "fixuns_trunc<mode>si2"
4309   [(parallel
4310     [(set (match_operand:SI 0 "register_operand" "")
4311           (unsigned_fix:SI
4312             (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4313      (use (match_dup 2))
4314      (clobber (match_scratch:<ssevecmode> 3 ""))
4315      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4316   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4317 {
4318   enum machine_mode mode = <MODE>mode;
4319   enum machine_mode vecmode = <ssevecmode>mode;
4320   REAL_VALUE_TYPE TWO31r;
4321   rtx two31;
4322
4323   real_ldexp (&TWO31r, &dconst1, 31);
4324   two31 = const_double_from_real_value (TWO31r, mode);
4325   two31 = ix86_build_const_vector (mode, true, two31);
4326   operands[2] = force_reg (vecmode, two31);
4327 })
4328
4329 (define_insn_and_split "*fixuns_trunc<mode>_1"
4330   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4331         (unsigned_fix:SI
4332           (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4333    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4334    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4335    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4336   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4337   "#"
4338   "&& reload_completed"
4339   [(const_int 0)]
4340 {
4341   ix86_split_convert_uns_si_sse (operands);
4342   DONE;
4343 })
4344
4345 ;; Unsigned conversion to HImode.
4346 ;; Without these patterns, we'll try the unsigned SI conversion which
4347 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4348
4349 (define_expand "fixuns_trunc<mode>hi2"
4350   [(set (match_dup 2)
4351         (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4352    (set (match_operand:HI 0 "nonimmediate_operand" "")
4353         (subreg:HI (match_dup 2) 0))]
4354   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4355   "operands[2] = gen_reg_rtx (SImode);")
4356
4357 ;; When SSE is available, it is always faster to use it!
4358 (define_insn "fix_trunc<mode>di_sse"
4359   [(set (match_operand:DI 0 "register_operand" "=r,r")
4360         (fix:DI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4361   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4362    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4363   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4364   [(set_attr "type" "sseicvt")
4365    (set_attr "mode" "<MODE>")
4366    (set_attr "athlon_decode" "double,vector")
4367    (set_attr "amdfam10_decode" "double,double")])
4368
4369 (define_insn "fix_trunc<mode>si_sse"
4370   [(set (match_operand:SI 0 "register_operand" "=r,r")
4371         (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4372   "SSE_FLOAT_MODE_P (<MODE>mode)
4373    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4374   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4375   [(set_attr "type" "sseicvt")
4376    (set_attr "mode" "<MODE>")
4377    (set_attr "athlon_decode" "double,vector")
4378    (set_attr "amdfam10_decode" "double,double")])
4379
4380 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4381 (define_peephole2
4382   [(set (match_operand:SSEMODEF 0 "register_operand" "")
4383         (match_operand:SSEMODEF 1 "memory_operand" ""))
4384    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4385         (fix:SSEMODEI24 (match_dup 0)))]
4386   "TARGET_SHORTEN_X87_SSE
4387    && peep2_reg_dead_p (2, operands[0])"
4388   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4389   "")
4390
4391 ;; Avoid vector decoded forms of the instruction.
4392 (define_peephole2
4393   [(match_scratch:DF 2 "Yt")
4394    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4395         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4396   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4397   [(set (match_dup 2) (match_dup 1))
4398    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4399   "")
4400
4401 (define_peephole2
4402   [(match_scratch:SF 2 "x")
4403    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4404         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4405   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4406   [(set (match_dup 2) (match_dup 1))
4407    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4408   "")
4409
4410 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4411   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4412         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4413   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4414    && TARGET_FISTTP
4415    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4416          && (TARGET_64BIT || <MODE>mode != DImode))
4417         && TARGET_SSE_MATH)
4418    && !(reload_completed || reload_in_progress)"
4419   "#"
4420   "&& 1"
4421   [(const_int 0)]
4422 {
4423   if (memory_operand (operands[0], VOIDmode))
4424     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4425   else
4426     {
4427       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4428       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4429                                                             operands[1],
4430                                                             operands[2]));
4431     }
4432   DONE;
4433 }
4434   [(set_attr "type" "fisttp")
4435    (set_attr "mode" "<MODE>")])
4436
4437 (define_insn "fix_trunc<mode>_i387_fisttp"
4438   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4439         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4440    (clobber (match_scratch:XF 2 "=&1f"))]
4441   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4442    && TARGET_FISTTP
4443    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4444          && (TARGET_64BIT || <MODE>mode != DImode))
4445         && TARGET_SSE_MATH)"
4446   "* return output_fix_trunc (insn, operands, 1);"
4447   [(set_attr "type" "fisttp")
4448    (set_attr "mode" "<MODE>")])
4449
4450 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4451   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4452         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4453    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4454    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4455   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4456    && TARGET_FISTTP
4457    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4458         && (TARGET_64BIT || <MODE>mode != DImode))
4459         && TARGET_SSE_MATH)"
4460   "#"
4461   [(set_attr "type" "fisttp")
4462    (set_attr "mode" "<MODE>")])
4463
4464 (define_split
4465   [(set (match_operand:X87MODEI 0 "register_operand" "")
4466         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4467    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4468    (clobber (match_scratch 3 ""))]
4469   "reload_completed"
4470   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4471               (clobber (match_dup 3))])
4472    (set (match_dup 0) (match_dup 2))]
4473   "")
4474
4475 (define_split
4476   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4477         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4478    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4479    (clobber (match_scratch 3 ""))]
4480   "reload_completed"
4481   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4482               (clobber (match_dup 3))])]
4483   "")
4484
4485 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4486 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4487 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4488 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4489 ;; function in i386.c.
4490 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4491   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4492         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4493    (clobber (reg:CC FLAGS_REG))]
4494   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4495    && !TARGET_FISTTP
4496    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4497          && (TARGET_64BIT || <MODE>mode != DImode))
4498    && !(reload_completed || reload_in_progress)"
4499   "#"
4500   "&& 1"
4501   [(const_int 0)]
4502 {
4503   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4504
4505   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4506   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4507   if (memory_operand (operands[0], VOIDmode))
4508     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4509                                          operands[2], operands[3]));
4510   else
4511     {
4512       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4513       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4514                                                      operands[2], operands[3],
4515                                                      operands[4]));
4516     }
4517   DONE;
4518 }
4519   [(set_attr "type" "fistp")
4520    (set_attr "i387_cw" "trunc")
4521    (set_attr "mode" "<MODE>")])
4522
4523 (define_insn "fix_truncdi_i387"
4524   [(set (match_operand:DI 0 "memory_operand" "=m")
4525         (fix:DI (match_operand 1 "register_operand" "f")))
4526    (use (match_operand:HI 2 "memory_operand" "m"))
4527    (use (match_operand:HI 3 "memory_operand" "m"))
4528    (clobber (match_scratch:XF 4 "=&1f"))]
4529   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4530    && !TARGET_FISTTP
4531    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4532   "* return output_fix_trunc (insn, operands, 0);"
4533   [(set_attr "type" "fistp")
4534    (set_attr "i387_cw" "trunc")
4535    (set_attr "mode" "DI")])
4536
4537 (define_insn "fix_truncdi_i387_with_temp"
4538   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4539         (fix:DI (match_operand 1 "register_operand" "f,f")))
4540    (use (match_operand:HI 2 "memory_operand" "m,m"))
4541    (use (match_operand:HI 3 "memory_operand" "m,m"))
4542    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4543    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4544   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4545    && !TARGET_FISTTP
4546    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4547   "#"
4548   [(set_attr "type" "fistp")
4549    (set_attr "i387_cw" "trunc")
4550    (set_attr "mode" "DI")])
4551
4552 (define_split
4553   [(set (match_operand:DI 0 "register_operand" "")
4554         (fix:DI (match_operand 1 "register_operand" "")))
4555    (use (match_operand:HI 2 "memory_operand" ""))
4556    (use (match_operand:HI 3 "memory_operand" ""))
4557    (clobber (match_operand:DI 4 "memory_operand" ""))
4558    (clobber (match_scratch 5 ""))]
4559   "reload_completed"
4560   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4561               (use (match_dup 2))
4562               (use (match_dup 3))
4563               (clobber (match_dup 5))])
4564    (set (match_dup 0) (match_dup 4))]
4565   "")
4566
4567 (define_split
4568   [(set (match_operand:DI 0 "memory_operand" "")
4569         (fix:DI (match_operand 1 "register_operand" "")))
4570    (use (match_operand:HI 2 "memory_operand" ""))
4571    (use (match_operand:HI 3 "memory_operand" ""))
4572    (clobber (match_operand:DI 4 "memory_operand" ""))
4573    (clobber (match_scratch 5 ""))]
4574   "reload_completed"
4575   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4576               (use (match_dup 2))
4577               (use (match_dup 3))
4578               (clobber (match_dup 5))])]
4579   "")
4580
4581 (define_insn "fix_trunc<mode>_i387"
4582   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4583         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4584    (use (match_operand:HI 2 "memory_operand" "m"))
4585    (use (match_operand:HI 3 "memory_operand" "m"))]
4586   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4587    && !TARGET_FISTTP
4588    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4589   "* return output_fix_trunc (insn, operands, 0);"
4590   [(set_attr "type" "fistp")
4591    (set_attr "i387_cw" "trunc")
4592    (set_attr "mode" "<MODE>")])
4593
4594 (define_insn "fix_trunc<mode>_i387_with_temp"
4595   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4596         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4597    (use (match_operand:HI 2 "memory_operand" "m,m"))
4598    (use (match_operand:HI 3 "memory_operand" "m,m"))
4599    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4600   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4601    && !TARGET_FISTTP
4602    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4603   "#"
4604   [(set_attr "type" "fistp")
4605    (set_attr "i387_cw" "trunc")
4606    (set_attr "mode" "<MODE>")])
4607
4608 (define_split
4609   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4610         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4611    (use (match_operand:HI 2 "memory_operand" ""))
4612    (use (match_operand:HI 3 "memory_operand" ""))
4613    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4614   "reload_completed"
4615   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4616               (use (match_dup 2))
4617               (use (match_dup 3))])
4618    (set (match_dup 0) (match_dup 4))]
4619   "")
4620
4621 (define_split
4622   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4623         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4624    (use (match_operand:HI 2 "memory_operand" ""))
4625    (use (match_operand:HI 3 "memory_operand" ""))
4626    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4627   "reload_completed"
4628   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4629               (use (match_dup 2))
4630               (use (match_dup 3))])]
4631   "")
4632
4633 (define_insn "x86_fnstcw_1"
4634   [(set (match_operand:HI 0 "memory_operand" "=m")
4635         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4636   "TARGET_80387"
4637   "fnstcw\t%0"
4638   [(set_attr "length" "2")
4639    (set_attr "mode" "HI")
4640    (set_attr "unit" "i387")])
4641
4642 (define_insn "x86_fldcw_1"
4643   [(set (reg:HI FPCR_REG)
4644         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4645   "TARGET_80387"
4646   "fldcw\t%0"
4647   [(set_attr "length" "2")
4648    (set_attr "mode" "HI")
4649    (set_attr "unit" "i387")
4650    (set_attr "athlon_decode" "vector")
4651    (set_attr "amdfam10_decode" "vector")])   
4652 \f
4653 ;; Conversion between fixed point and floating point.
4654
4655 ;; Even though we only accept memory inputs, the backend _really_
4656 ;; wants to be able to do this between registers.
4657
4658 (define_expand "floathi<mode>2"
4659   [(set (match_operand:SSEMODEF 0 "register_operand" "")
4660         (float:SSEMODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4661   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4662 {
4663   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4664     {
4665       emit_insn
4666         (gen_floatsi<mode>2 (operands[0],
4667                              convert_to_mode (SImode, operands[1], 0)));
4668       DONE;
4669     }
4670 })
4671
4672 (define_insn "*floathi<mode>2_i387"
4673   [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4674         (float:X87MODEF12
4675           (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4676   "TARGET_80387
4677    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4678        || TARGET_MIX_SSE_I387)"
4679   "@
4680    fild%z1\t%1
4681    #"
4682   [(set_attr "type" "fmov,multi")
4683    (set_attr "mode" "<MODE>")
4684    (set_attr "unit" "*,i387")
4685    (set_attr "fp_int_src" "true")])
4686
4687 (define_expand "floatsi<mode>2"
4688   [(set (match_operand:SSEMODEF 0 "register_operand" "")
4689         (float:SSEMODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4690   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4691   "")
4692
4693 (define_insn "*floatsisf2_mixed"
4694   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4695         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4696   "TARGET_MIX_SSE_I387"
4697   "@
4698    fild%z1\t%1
4699    #
4700    cvtsi2ss\t{%1, %0|%0, %1}
4701    cvtsi2ss\t{%1, %0|%0, %1}"
4702   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4703    (set_attr "mode" "SF")
4704    (set_attr "unit" "*,i387,*,*")
4705    (set_attr "athlon_decode" "*,*,vector,double")
4706    (set_attr "amdfam10_decode" "*,*,vector,double")
4707    (set_attr "fp_int_src" "true")])
4708
4709 (define_insn "*floatsisf2_sse"
4710   [(set (match_operand:SF 0 "register_operand" "=x,x")
4711         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4712   "TARGET_SSE_MATH"
4713   "cvtsi2ss\t{%1, %0|%0, %1}"
4714   [(set_attr "type" "sseicvt")
4715    (set_attr "mode" "SF")
4716    (set_attr "athlon_decode" "vector,double")
4717    (set_attr "amdfam10_decode" "vector,double")
4718    (set_attr "fp_int_src" "true")])
4719
4720 (define_insn "*floatsidf2_mixed"
4721   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4722         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4723   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4724   "@
4725    fild%z1\t%1
4726    #
4727    cvtsi2sd\t{%1, %0|%0, %1}
4728    cvtsi2sd\t{%1, %0|%0, %1}"
4729   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4730    (set_attr "mode" "DF")
4731    (set_attr "unit" "*,i387,*,*")
4732    (set_attr "athlon_decode" "*,*,double,direct")
4733    (set_attr "amdfam10_decode" "*,*,vector,double")
4734    (set_attr "fp_int_src" "true")])
4735
4736 (define_insn "*floatsidf2_sse"
4737   [(set (match_operand:DF 0 "register_operand" "=x,x")
4738         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4739   "TARGET_SSE2 && TARGET_SSE_MATH"
4740   "cvtsi2sd\t{%1, %0|%0, %1}"
4741   [(set_attr "type" "sseicvt")
4742    (set_attr "mode" "DF")
4743    (set_attr "athlon_decode" "double,direct")
4744    (set_attr "amdfam10_decode" "vector,double")
4745    (set_attr "fp_int_src" "true")])
4746
4747 (define_insn "*floatsi<mode>2_i387"
4748   [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4749         (float:X87MODEF12
4750           (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4751   "TARGET_80387"
4752   "@
4753    fild%z1\t%1
4754    #"
4755   [(set_attr "type" "fmov,multi")
4756    (set_attr "mode" "<MODE>")
4757    (set_attr "unit" "*,i387")
4758    (set_attr "fp_int_src" "true")])
4759
4760 (define_expand "floatdisf2"
4761   [(set (match_operand:SF 0 "register_operand" "")
4762         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4763   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4764   "")
4765
4766 (define_insn "*floatdisf2_mixed"
4767   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4768         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4769   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4770   "@
4771    fild%z1\t%1
4772    #
4773    cvtsi2ss{q}\t{%1, %0|%0, %1}
4774    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4775   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4776    (set_attr "mode" "SF")
4777    (set_attr "unit" "*,i387,*,*")
4778    (set_attr "athlon_decode" "*,*,vector,double")
4779    (set_attr "amdfam10_decode" "*,*,vector,double")
4780    (set_attr "fp_int_src" "true")])
4781
4782 (define_insn "*floatdisf2_sse"
4783   [(set (match_operand:SF 0 "register_operand" "=x,x")
4784         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4785   "TARGET_64BIT && TARGET_SSE_MATH"
4786   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4787   [(set_attr "type" "sseicvt")
4788    (set_attr "mode" "SF")
4789    (set_attr "athlon_decode" "vector,double")
4790    (set_attr "amdfam10_decode" "vector,double")
4791    (set_attr "fp_int_src" "true")])
4792
4793 (define_expand "floatdidf2"
4794   [(set (match_operand:DF 0 "register_operand" "")
4795         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4796   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4797 {
4798   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4799     {
4800       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4801       DONE;
4802     }
4803 })
4804
4805 (define_insn "*floatdidf2_mixed"
4806   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4807         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4808   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4809   "@
4810    fild%z1\t%1
4811    #
4812    cvtsi2sd{q}\t{%1, %0|%0, %1}
4813    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4814   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4815    (set_attr "mode" "DF")
4816    (set_attr "unit" "*,i387,*,*")
4817    (set_attr "athlon_decode" "*,*,double,direct")
4818    (set_attr "amdfam10_decode" "*,*,vector,double")
4819    (set_attr "fp_int_src" "true")])
4820
4821 (define_insn "*floatdidf2_sse"
4822   [(set (match_operand:DF 0 "register_operand" "=x,x")
4823         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4824   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4825   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4826   [(set_attr "type" "sseicvt")
4827    (set_attr "mode" "DF")
4828    (set_attr "athlon_decode" "double,direct")
4829    (set_attr "amdfam10_decode" "vector,double")
4830    (set_attr "fp_int_src" "true")])
4831
4832 (define_insn "*floatdi<mode>2_i387"
4833   [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4834         (float:X87MODEF12
4835           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4836   "TARGET_80387"
4837   "@
4838    fild%z1\t%1
4839    #"
4840   [(set_attr "type" "fmov,multi")
4841    (set_attr "mode" "<MODE>")
4842    (set_attr "unit" "*,i387")
4843    (set_attr "fp_int_src" "true")])
4844
4845 (define_insn "float<mode>xf2"
4846   [(set (match_operand:XF 0 "register_operand" "=f,f")
4847         (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
4848   "TARGET_80387"
4849   "@
4850    fild%z1\t%1
4851    #"
4852   [(set_attr "type" "fmov,multi")
4853    (set_attr "mode" "XF")
4854    (set_attr "unit" "*,i387")
4855    (set_attr "fp_int_src" "true")])
4856
4857 ;; %%% Kill these when reload knows how to do it.
4858 (define_split
4859   [(set (match_operand 0 "fp_register_operand" "")
4860         (float (match_operand 1 "register_operand" "")))]
4861   "reload_completed
4862    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
4863   [(const_int 0)]
4864 {
4865   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4866   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4867   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4868   ix86_free_from_memory (GET_MODE (operands[1]));
4869   DONE;
4870 })
4871
4872 (define_expand "floatunssisf2"
4873   [(use (match_operand:SF 0 "register_operand" ""))
4874    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4875   "!TARGET_64BIT"
4876 {
4877   if (TARGET_SSE_MATH && TARGET_SSE2)
4878     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
4879   else
4880     x86_emit_floatuns (operands);
4881   DONE;
4882 })
4883
4884 (define_expand "floatunssidf2"
4885   [(use (match_operand:DF 0 "register_operand" ""))
4886    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4887   "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
4888   "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
4889
4890 (define_expand "floatunsdisf2"
4891   [(use (match_operand:SF 0 "register_operand" ""))
4892    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4893   "TARGET_64BIT && TARGET_SSE_MATH"
4894   "x86_emit_floatuns (operands); DONE;")
4895
4896 (define_expand "floatunsdidf2"
4897   [(use (match_operand:DF 0 "register_operand" ""))
4898    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4899   "TARGET_SSE_MATH && TARGET_SSE2
4900    && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
4901 {
4902   if (TARGET_64BIT)
4903     x86_emit_floatuns (operands);
4904   else
4905     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
4906   DONE;
4907 })
4908 \f
4909 ;; Add instructions
4910
4911 ;; %%% splits for addditi3
4912
4913 (define_expand "addti3"
4914   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4915         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4916                  (match_operand:TI 2 "x86_64_general_operand" "")))
4917    (clobber (reg:CC FLAGS_REG))]
4918   "TARGET_64BIT"
4919   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4920
4921 (define_insn "*addti3_1"
4922   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4923         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4924                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4925    (clobber (reg:CC FLAGS_REG))]
4926   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4927   "#")
4928
4929 (define_split
4930   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4931         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4932                  (match_operand:TI 2 "x86_64_general_operand" "")))
4933    (clobber (reg:CC FLAGS_REG))]
4934   "TARGET_64BIT && reload_completed"
4935   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4936                                           UNSPEC_ADD_CARRY))
4937               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4938    (parallel [(set (match_dup 3)
4939                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4940                                      (match_dup 4))
4941                             (match_dup 5)))
4942               (clobber (reg:CC FLAGS_REG))])]
4943   "split_ti (operands+0, 1, operands+0, operands+3);
4944    split_ti (operands+1, 1, operands+1, operands+4);
4945    split_ti (operands+2, 1, operands+2, operands+5);")
4946
4947 ;; %%% splits for addsidi3
4948 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4949 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4950 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4951
4952 (define_expand "adddi3"
4953   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4954         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4955                  (match_operand:DI 2 "x86_64_general_operand" "")))
4956    (clobber (reg:CC FLAGS_REG))]
4957   ""
4958   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4959
4960 (define_insn "*adddi3_1"
4961   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4962         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4963                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4964    (clobber (reg:CC FLAGS_REG))]
4965   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4966   "#")
4967
4968 (define_split
4969   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4970         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4971                  (match_operand:DI 2 "general_operand" "")))
4972    (clobber (reg:CC FLAGS_REG))]
4973   "!TARGET_64BIT && reload_completed"
4974   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4975                                           UNSPEC_ADD_CARRY))
4976               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4977    (parallel [(set (match_dup 3)
4978                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4979                                      (match_dup 4))
4980                             (match_dup 5)))
4981               (clobber (reg:CC FLAGS_REG))])]
4982   "split_di (operands+0, 1, operands+0, operands+3);
4983    split_di (operands+1, 1, operands+1, operands+4);
4984    split_di (operands+2, 1, operands+2, operands+5);")
4985
4986 (define_insn "adddi3_carry_rex64"
4987   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4988           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4989                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4990                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4991    (clobber (reg:CC FLAGS_REG))]
4992   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4993   "adc{q}\t{%2, %0|%0, %2}"
4994   [(set_attr "type" "alu")
4995    (set_attr "pent_pair" "pu")
4996    (set_attr "mode" "DI")])
4997
4998 (define_insn "*adddi3_cc_rex64"
4999   [(set (reg:CC FLAGS_REG)
5000         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5001                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5002                    UNSPEC_ADD_CARRY))
5003    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5004         (plus:DI (match_dup 1) (match_dup 2)))]
5005   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5006   "add{q}\t{%2, %0|%0, %2}"
5007   [(set_attr "type" "alu")
5008    (set_attr "mode" "DI")])
5009
5010 (define_insn "*<addsub><mode>3_cc_overflow"
5011   [(set (reg:CCC FLAGS_REG)
5012         (compare:CCC
5013             (plusminus:SWI
5014                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5015                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5016             (match_dup 1)))
5017    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5018         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5019   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5020   "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5021   [(set_attr "type" "alu")
5022    (set_attr "mode" "<MODE>")])
5023
5024 (define_insn "*add<mode>3_cconly_overflow"
5025   [(set (reg:CCC FLAGS_REG)
5026         (compare:CCC
5027                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5028                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5029                 (match_dup 1)))
5030    (clobber (match_scratch:SWI 0 "=<r>"))]
5031   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5032   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5033   [(set_attr "type" "alu")
5034    (set_attr "mode" "<MODE>")])
5035
5036 (define_insn "*sub<mode>3_cconly_overflow"
5037   [(set (reg:CCC FLAGS_REG)
5038         (compare:CCC
5039              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5040                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5041              (match_dup 0)))]
5042   ""
5043   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5044   [(set_attr "type" "icmp")
5045    (set_attr "mode" "<MODE>")])
5046
5047 (define_insn "*<addsub>si3_zext_cc_overflow"
5048   [(set (reg:CCC FLAGS_REG)
5049         (compare:CCC
5050             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5051                           (match_operand:SI 2 "general_operand" "g"))
5052             (match_dup 1)))
5053    (set (match_operand:DI 0 "register_operand" "=r")
5054         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5055   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5056   "<addsub>{l}\t{%2, %k0|%k0, %2}"
5057   [(set_attr "type" "alu")
5058    (set_attr "mode" "SI")])
5059
5060 (define_insn "addqi3_carry"
5061   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5062           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5063                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5064                    (match_operand:QI 2 "general_operand" "qi,qm")))
5065    (clobber (reg:CC FLAGS_REG))]
5066   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5067   "adc{b}\t{%2, %0|%0, %2}"
5068   [(set_attr "type" "alu")
5069    (set_attr "pent_pair" "pu")
5070    (set_attr "mode" "QI")])
5071
5072 (define_insn "addhi3_carry"
5073   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5074           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5075                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5076                    (match_operand:HI 2 "general_operand" "ri,rm")))
5077    (clobber (reg:CC FLAGS_REG))]
5078   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5079   "adc{w}\t{%2, %0|%0, %2}"
5080   [(set_attr "type" "alu")
5081    (set_attr "pent_pair" "pu")
5082    (set_attr "mode" "HI")])
5083
5084 (define_insn "addsi3_carry"
5085   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5086           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5087                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5088                    (match_operand:SI 2 "general_operand" "ri,rm")))
5089    (clobber (reg:CC FLAGS_REG))]
5090   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5091   "adc{l}\t{%2, %0|%0, %2}"
5092   [(set_attr "type" "alu")
5093    (set_attr "pent_pair" "pu")
5094    (set_attr "mode" "SI")])
5095
5096 (define_insn "*addsi3_carry_zext"
5097   [(set (match_operand:DI 0 "register_operand" "=r")
5098           (zero_extend:DI
5099             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5100                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5101                      (match_operand:SI 2 "general_operand" "g"))))
5102    (clobber (reg:CC FLAGS_REG))]
5103   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5104   "adc{l}\t{%2, %k0|%k0, %2}"
5105   [(set_attr "type" "alu")
5106    (set_attr "pent_pair" "pu")
5107    (set_attr "mode" "SI")])
5108
5109 (define_insn "*addsi3_cc"
5110   [(set (reg:CC FLAGS_REG)
5111         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5112                     (match_operand:SI 2 "general_operand" "ri,rm")]
5113                    UNSPEC_ADD_CARRY))
5114    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5115         (plus:SI (match_dup 1) (match_dup 2)))]
5116   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5117   "add{l}\t{%2, %0|%0, %2}"
5118   [(set_attr "type" "alu")
5119    (set_attr "mode" "SI")])
5120
5121 (define_insn "addqi3_cc"
5122   [(set (reg:CC FLAGS_REG)
5123         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5124                     (match_operand:QI 2 "general_operand" "qi,qm")]
5125                    UNSPEC_ADD_CARRY))
5126    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5127         (plus:QI (match_dup 1) (match_dup 2)))]
5128   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5129   "add{b}\t{%2, %0|%0, %2}"
5130   [(set_attr "type" "alu")
5131    (set_attr "mode" "QI")])
5132
5133 (define_expand "addsi3"
5134   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5135                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5136                             (match_operand:SI 2 "general_operand" "")))
5137               (clobber (reg:CC FLAGS_REG))])]
5138   ""
5139   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5140
5141 (define_insn "*lea_1"
5142   [(set (match_operand:SI 0 "register_operand" "=r")
5143         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5144   "!TARGET_64BIT"
5145   "lea{l}\t{%a1, %0|%0, %a1}"
5146   [(set_attr "type" "lea")
5147    (set_attr "mode" "SI")])
5148
5149 (define_insn "*lea_1_rex64"
5150   [(set (match_operand:SI 0 "register_operand" "=r")
5151         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5152   "TARGET_64BIT"
5153   "lea{l}\t{%a1, %0|%0, %a1}"
5154   [(set_attr "type" "lea")
5155    (set_attr "mode" "SI")])
5156
5157 (define_insn "*lea_1_zext"
5158   [(set (match_operand:DI 0 "register_operand" "=r")
5159         (zero_extend:DI
5160          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5161   "TARGET_64BIT"
5162   "lea{l}\t{%a1, %k0|%k0, %a1}"
5163   [(set_attr "type" "lea")
5164    (set_attr "mode" "SI")])
5165
5166 (define_insn "*lea_2_rex64"
5167   [(set (match_operand:DI 0 "register_operand" "=r")
5168         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5169   "TARGET_64BIT"
5170   "lea{q}\t{%a1, %0|%0, %a1}"
5171   [(set_attr "type" "lea")
5172    (set_attr "mode" "DI")])
5173
5174 ;; The lea patterns for non-Pmodes needs to be matched by several
5175 ;; insns converted to real lea by splitters.
5176
5177 (define_insn_and_split "*lea_general_1"
5178   [(set (match_operand 0 "register_operand" "=r")
5179         (plus (plus (match_operand 1 "index_register_operand" "l")
5180                     (match_operand 2 "register_operand" "r"))
5181               (match_operand 3 "immediate_operand" "i")))]
5182   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5183     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5184    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5185    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5186    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5187    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5188        || GET_MODE (operands[3]) == VOIDmode)"
5189   "#"
5190   "&& reload_completed"
5191   [(const_int 0)]
5192 {
5193   rtx pat;
5194   operands[0] = gen_lowpart (SImode, operands[0]);
5195   operands[1] = gen_lowpart (Pmode, operands[1]);
5196   operands[2] = gen_lowpart (Pmode, operands[2]);
5197   operands[3] = gen_lowpart (Pmode, operands[3]);
5198   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5199                       operands[3]);
5200   if (Pmode != SImode)
5201     pat = gen_rtx_SUBREG (SImode, pat, 0);
5202   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5203   DONE;
5204 }
5205   [(set_attr "type" "lea")
5206    (set_attr "mode" "SI")])
5207
5208 (define_insn_and_split "*lea_general_1_zext"
5209   [(set (match_operand:DI 0 "register_operand" "=r")
5210         (zero_extend:DI
5211           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5212                             (match_operand:SI 2 "register_operand" "r"))
5213                    (match_operand:SI 3 "immediate_operand" "i"))))]
5214   "TARGET_64BIT"
5215   "#"
5216   "&& reload_completed"
5217   [(set (match_dup 0)
5218         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5219                                                      (match_dup 2))
5220                                             (match_dup 3)) 0)))]
5221 {
5222   operands[1] = gen_lowpart (Pmode, operands[1]);
5223   operands[2] = gen_lowpart (Pmode, operands[2]);
5224   operands[3] = gen_lowpart (Pmode, operands[3]);
5225 }
5226   [(set_attr "type" "lea")
5227    (set_attr "mode" "SI")])
5228
5229 (define_insn_and_split "*lea_general_2"
5230   [(set (match_operand 0 "register_operand" "=r")
5231         (plus (mult (match_operand 1 "index_register_operand" "l")
5232                     (match_operand 2 "const248_operand" "i"))
5233               (match_operand 3 "nonmemory_operand" "ri")))]
5234   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5235     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5236    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5237    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5238    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5239        || GET_MODE (operands[3]) == VOIDmode)"
5240   "#"
5241   "&& reload_completed"
5242   [(const_int 0)]
5243 {
5244   rtx pat;
5245   operands[0] = gen_lowpart (SImode, operands[0]);
5246   operands[1] = gen_lowpart (Pmode, operands[1]);
5247   operands[3] = gen_lowpart (Pmode, operands[3]);
5248   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5249                       operands[3]);
5250   if (Pmode != SImode)
5251     pat = gen_rtx_SUBREG (SImode, pat, 0);
5252   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5253   DONE;
5254 }
5255   [(set_attr "type" "lea")
5256    (set_attr "mode" "SI")])
5257
5258 (define_insn_and_split "*lea_general_2_zext"
5259   [(set (match_operand:DI 0 "register_operand" "=r")
5260         (zero_extend:DI
5261           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5262                             (match_operand:SI 2 "const248_operand" "n"))
5263                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5264   "TARGET_64BIT"
5265   "#"
5266   "&& reload_completed"
5267   [(set (match_dup 0)
5268         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5269                                                      (match_dup 2))
5270                                             (match_dup 3)) 0)))]
5271 {
5272   operands[1] = gen_lowpart (Pmode, operands[1]);
5273   operands[3] = gen_lowpart (Pmode, operands[3]);
5274 }
5275   [(set_attr "type" "lea")
5276    (set_attr "mode" "SI")])
5277
5278 (define_insn_and_split "*lea_general_3"
5279   [(set (match_operand 0 "register_operand" "=r")
5280         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5281                           (match_operand 2 "const248_operand" "i"))
5282                     (match_operand 3 "register_operand" "r"))
5283               (match_operand 4 "immediate_operand" "i")))]
5284   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5285     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5286    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5287    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5288    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5289   "#"
5290   "&& reload_completed"
5291   [(const_int 0)]
5292 {
5293   rtx pat;
5294   operands[0] = gen_lowpart (SImode, operands[0]);
5295   operands[1] = gen_lowpart (Pmode, operands[1]);
5296   operands[3] = gen_lowpart (Pmode, operands[3]);
5297   operands[4] = gen_lowpart (Pmode, operands[4]);
5298   pat = gen_rtx_PLUS (Pmode,
5299                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5300                                                          operands[2]),
5301                                     operands[3]),
5302                       operands[4]);
5303   if (Pmode != SImode)
5304     pat = gen_rtx_SUBREG (SImode, pat, 0);
5305   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5306   DONE;
5307 }
5308   [(set_attr "type" "lea")
5309    (set_attr "mode" "SI")])
5310
5311 (define_insn_and_split "*lea_general_3_zext"
5312   [(set (match_operand:DI 0 "register_operand" "=r")
5313         (zero_extend:DI
5314           (plus:SI (plus:SI (mult:SI
5315                               (match_operand:SI 1 "index_register_operand" "l")
5316                               (match_operand:SI 2 "const248_operand" "n"))
5317                             (match_operand:SI 3 "register_operand" "r"))
5318                    (match_operand:SI 4 "immediate_operand" "i"))))]
5319   "TARGET_64BIT"
5320   "#"
5321   "&& reload_completed"
5322   [(set (match_dup 0)
5323         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5324                                                               (match_dup 2))
5325                                                      (match_dup 3))
5326                                             (match_dup 4)) 0)))]
5327 {
5328   operands[1] = gen_lowpart (Pmode, operands[1]);
5329   operands[3] = gen_lowpart (Pmode, operands[3]);
5330   operands[4] = gen_lowpart (Pmode, operands[4]);
5331 }
5332   [(set_attr "type" "lea")
5333    (set_attr "mode" "SI")])
5334
5335 (define_insn "*adddi_1_rex64"
5336   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5337         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5338                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5339    (clobber (reg:CC FLAGS_REG))]
5340   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5341 {
5342   switch (get_attr_type (insn))
5343     {
5344     case TYPE_LEA:
5345       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5346       return "lea{q}\t{%a2, %0|%0, %a2}";
5347
5348     case TYPE_INCDEC:
5349       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5350       if (operands[2] == const1_rtx)
5351         return "inc{q}\t%0";
5352       else
5353         {
5354           gcc_assert (operands[2] == constm1_rtx);
5355           return "dec{q}\t%0";
5356         }
5357
5358     default:
5359       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5360
5361       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5362          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5363       if (CONST_INT_P (operands[2])
5364           /* Avoid overflows.  */
5365           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5366           && (INTVAL (operands[2]) == 128
5367               || (INTVAL (operands[2]) < 0
5368                   && INTVAL (operands[2]) != -128)))
5369         {
5370           operands[2] = GEN_INT (-INTVAL (operands[2]));
5371           return "sub{q}\t{%2, %0|%0, %2}";
5372         }
5373       return "add{q}\t{%2, %0|%0, %2}";
5374     }
5375 }
5376   [(set (attr "type")
5377      (cond [(eq_attr "alternative" "2")
5378               (const_string "lea")
5379             ; Current assemblers are broken and do not allow @GOTOFF in
5380             ; ought but a memory context.
5381             (match_operand:DI 2 "pic_symbolic_operand" "")
5382               (const_string "lea")
5383             (match_operand:DI 2 "incdec_operand" "")
5384               (const_string "incdec")
5385            ]
5386            (const_string "alu")))
5387    (set_attr "mode" "DI")])
5388
5389 ;; Convert lea to the lea pattern to avoid flags dependency.
5390 (define_split
5391   [(set (match_operand:DI 0 "register_operand" "")
5392         (plus:DI (match_operand:DI 1 "register_operand" "")
5393                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5394    (clobber (reg:CC FLAGS_REG))]
5395   "TARGET_64BIT && reload_completed
5396    && true_regnum (operands[0]) != true_regnum (operands[1])"
5397   [(set (match_dup 0)
5398         (plus:DI (match_dup 1)
5399                  (match_dup 2)))]
5400   "")
5401
5402 (define_insn "*adddi_2_rex64"
5403   [(set (reg FLAGS_REG)
5404         (compare
5405           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5406                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5407           (const_int 0)))
5408    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5409         (plus:DI (match_dup 1) (match_dup 2)))]
5410   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5411    && ix86_binary_operator_ok (PLUS, DImode, operands)
5412    /* Current assemblers are broken and do not allow @GOTOFF in
5413       ought but a memory context.  */
5414    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5415 {
5416   switch (get_attr_type (insn))
5417     {
5418     case TYPE_INCDEC:
5419       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5420       if (operands[2] == const1_rtx)
5421         return "inc{q}\t%0";
5422       else
5423         {
5424           gcc_assert (operands[2] == constm1_rtx);
5425           return "dec{q}\t%0";
5426         }
5427
5428     default:
5429       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5430       /* ???? We ought to handle there the 32bit case too
5431          - do we need new constraint?  */
5432       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5433          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5434       if (CONST_INT_P (operands[2])
5435           /* Avoid overflows.  */
5436           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5437           && (INTVAL (operands[2]) == 128
5438               || (INTVAL (operands[2]) < 0
5439                   && INTVAL (operands[2]) != -128)))
5440         {
5441           operands[2] = GEN_INT (-INTVAL (operands[2]));
5442           return "sub{q}\t{%2, %0|%0, %2}";
5443         }
5444       return "add{q}\t{%2, %0|%0, %2}";
5445     }
5446 }
5447   [(set (attr "type")
5448      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5449         (const_string "incdec")
5450         (const_string "alu")))
5451    (set_attr "mode" "DI")])
5452
5453 (define_insn "*adddi_3_rex64"
5454   [(set (reg FLAGS_REG)
5455         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5456                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5457    (clobber (match_scratch:DI 0 "=r"))]
5458   "TARGET_64BIT
5459    && ix86_match_ccmode (insn, CCZmode)
5460    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5461    /* Current assemblers are broken and do not allow @GOTOFF in
5462       ought but a memory context.  */
5463    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5464 {
5465   switch (get_attr_type (insn))
5466     {
5467     case TYPE_INCDEC:
5468       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5469       if (operands[2] == const1_rtx)
5470         return "inc{q}\t%0";
5471       else
5472         {
5473           gcc_assert (operands[2] == constm1_rtx);
5474           return "dec{q}\t%0";
5475         }
5476
5477     default:
5478       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5479       /* ???? We ought to handle there the 32bit case too
5480          - do we need new constraint?  */
5481       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5482          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5483       if (CONST_INT_P (operands[2])
5484           /* Avoid overflows.  */
5485           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5486           && (INTVAL (operands[2]) == 128
5487               || (INTVAL (operands[2]) < 0
5488                   && INTVAL (operands[2]) != -128)))
5489         {
5490           operands[2] = GEN_INT (-INTVAL (operands[2]));
5491           return "sub{q}\t{%2, %0|%0, %2}";
5492         }
5493       return "add{q}\t{%2, %0|%0, %2}";
5494     }
5495 }
5496   [(set (attr "type")
5497      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5498         (const_string "incdec")
5499         (const_string "alu")))
5500    (set_attr "mode" "DI")])
5501
5502 ; For comparisons against 1, -1 and 128, we may generate better code
5503 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5504 ; is matched then.  We can't accept general immediate, because for
5505 ; case of overflows,  the result is messed up.
5506 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5507 ; when negated.
5508 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5509 ; only for comparisons not depending on it.
5510 (define_insn "*adddi_4_rex64"
5511   [(set (reg FLAGS_REG)
5512         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5513                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5514    (clobber (match_scratch:DI 0 "=rm"))]
5515   "TARGET_64BIT
5516    &&  ix86_match_ccmode (insn, CCGCmode)"
5517 {
5518   switch (get_attr_type (insn))
5519     {
5520     case TYPE_INCDEC:
5521       if (operands[2] == constm1_rtx)
5522         return "inc{q}\t%0";
5523       else
5524         {
5525           gcc_assert (operands[2] == const1_rtx);
5526           return "dec{q}\t%0";
5527         }
5528
5529     default:
5530       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5531       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5532          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5533       if ((INTVAL (operands[2]) == -128
5534            || (INTVAL (operands[2]) > 0
5535                && INTVAL (operands[2]) != 128))
5536           /* Avoid overflows.  */
5537           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5538         return "sub{q}\t{%2, %0|%0, %2}";
5539       operands[2] = GEN_INT (-INTVAL (operands[2]));
5540       return "add{q}\t{%2, %0|%0, %2}";
5541     }
5542 }
5543   [(set (attr "type")
5544      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5545         (const_string "incdec")
5546         (const_string "alu")))
5547    (set_attr "mode" "DI")])
5548
5549 (define_insn "*adddi_5_rex64"
5550   [(set (reg FLAGS_REG)
5551         (compare
5552           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5553                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5554           (const_int 0)))
5555    (clobber (match_scratch:DI 0 "=r"))]
5556   "TARGET_64BIT
5557    && ix86_match_ccmode (insn, CCGOCmode)
5558    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5559    /* Current assemblers are broken and do not allow @GOTOFF in
5560       ought but a memory context.  */
5561    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5562 {
5563   switch (get_attr_type (insn))
5564     {
5565     case TYPE_INCDEC:
5566       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5567       if (operands[2] == const1_rtx)
5568         return "inc{q}\t%0";
5569       else
5570         {
5571           gcc_assert (operands[2] == constm1_rtx);
5572           return "dec{q}\t%0";
5573         }
5574
5575     default:
5576       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5577       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5578          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5579       if (CONST_INT_P (operands[2])
5580           /* Avoid overflows.  */
5581           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5582           && (INTVAL (operands[2]) == 128
5583               || (INTVAL (operands[2]) < 0
5584                   && INTVAL (operands[2]) != -128)))
5585         {
5586           operands[2] = GEN_INT (-INTVAL (operands[2]));
5587           return "sub{q}\t{%2, %0|%0, %2}";
5588         }
5589       return "add{q}\t{%2, %0|%0, %2}";
5590     }
5591 }
5592   [(set (attr "type")
5593      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5594         (const_string "incdec")
5595         (const_string "alu")))
5596    (set_attr "mode" "DI")])
5597
5598
5599 (define_insn "*addsi_1"
5600   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5601         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5602                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5603    (clobber (reg:CC FLAGS_REG))]
5604   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5605 {
5606   switch (get_attr_type (insn))
5607     {
5608     case TYPE_LEA:
5609       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5610       return "lea{l}\t{%a2, %0|%0, %a2}";
5611
5612     case TYPE_INCDEC:
5613       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5614       if (operands[2] == const1_rtx)
5615         return "inc{l}\t%0";
5616       else
5617         {
5618           gcc_assert (operands[2] == constm1_rtx);
5619           return "dec{l}\t%0";
5620         }
5621
5622     default:
5623       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5624
5625       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5626          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5627       if (CONST_INT_P (operands[2])
5628           && (INTVAL (operands[2]) == 128
5629               || (INTVAL (operands[2]) < 0
5630                   && INTVAL (operands[2]) != -128)))
5631         {
5632           operands[2] = GEN_INT (-INTVAL (operands[2]));
5633           return "sub{l}\t{%2, %0|%0, %2}";
5634         }
5635       return "add{l}\t{%2, %0|%0, %2}";
5636     }
5637 }
5638   [(set (attr "type")
5639      (cond [(eq_attr "alternative" "2")
5640               (const_string "lea")
5641             ; Current assemblers are broken and do not allow @GOTOFF in
5642             ; ought but a memory context.
5643             (match_operand:SI 2 "pic_symbolic_operand" "")
5644               (const_string "lea")
5645             (match_operand:SI 2 "incdec_operand" "")
5646               (const_string "incdec")
5647            ]
5648            (const_string "alu")))
5649    (set_attr "mode" "SI")])
5650
5651 ;; Convert lea to the lea pattern to avoid flags dependency.
5652 (define_split
5653   [(set (match_operand 0 "register_operand" "")
5654         (plus (match_operand 1 "register_operand" "")
5655               (match_operand 2 "nonmemory_operand" "")))
5656    (clobber (reg:CC FLAGS_REG))]
5657   "reload_completed
5658    && true_regnum (operands[0]) != true_regnum (operands[1])"
5659   [(const_int 0)]
5660 {
5661   rtx pat;
5662   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5663      may confuse gen_lowpart.  */
5664   if (GET_MODE (operands[0]) != Pmode)
5665     {
5666       operands[1] = gen_lowpart (Pmode, operands[1]);
5667       operands[2] = gen_lowpart (Pmode, operands[2]);
5668     }
5669   operands[0] = gen_lowpart (SImode, operands[0]);
5670   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5671   if (Pmode != SImode)
5672     pat = gen_rtx_SUBREG (SImode, pat, 0);
5673   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5674   DONE;
5675 })
5676
5677 ;; It may seem that nonimmediate operand is proper one for operand 1.
5678 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5679 ;; we take care in ix86_binary_operator_ok to not allow two memory
5680 ;; operands so proper swapping will be done in reload.  This allow
5681 ;; patterns constructed from addsi_1 to match.
5682 (define_insn "addsi_1_zext"
5683   [(set (match_operand:DI 0 "register_operand" "=r,r")
5684         (zero_extend:DI
5685           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5686                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5687    (clobber (reg:CC FLAGS_REG))]
5688   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5689 {
5690   switch (get_attr_type (insn))
5691     {
5692     case TYPE_LEA:
5693       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5694       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5695
5696     case TYPE_INCDEC:
5697       if (operands[2] == const1_rtx)
5698         return "inc{l}\t%k0";
5699       else
5700         {
5701           gcc_assert (operands[2] == constm1_rtx);
5702           return "dec{l}\t%k0";
5703         }
5704
5705     default:
5706       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5707          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5708       if (CONST_INT_P (operands[2])
5709           && (INTVAL (operands[2]) == 128
5710               || (INTVAL (operands[2]) < 0
5711                   && INTVAL (operands[2]) != -128)))
5712         {
5713           operands[2] = GEN_INT (-INTVAL (operands[2]));
5714           return "sub{l}\t{%2, %k0|%k0, %2}";
5715         }
5716       return "add{l}\t{%2, %k0|%k0, %2}";
5717     }
5718 }
5719   [(set (attr "type")
5720      (cond [(eq_attr "alternative" "1")
5721               (const_string "lea")
5722             ; Current assemblers are broken and do not allow @GOTOFF in
5723             ; ought but a memory context.
5724             (match_operand:SI 2 "pic_symbolic_operand" "")
5725               (const_string "lea")
5726             (match_operand:SI 2 "incdec_operand" "")
5727               (const_string "incdec")
5728            ]
5729            (const_string "alu")))
5730    (set_attr "mode" "SI")])
5731
5732 ;; Convert lea to the lea pattern to avoid flags dependency.
5733 (define_split
5734   [(set (match_operand:DI 0 "register_operand" "")
5735         (zero_extend:DI
5736           (plus:SI (match_operand:SI 1 "register_operand" "")
5737                    (match_operand:SI 2 "nonmemory_operand" ""))))
5738    (clobber (reg:CC FLAGS_REG))]
5739   "TARGET_64BIT && reload_completed
5740    && true_regnum (operands[0]) != true_regnum (operands[1])"
5741   [(set (match_dup 0)
5742         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5743 {
5744   operands[1] = gen_lowpart (Pmode, operands[1]);
5745   operands[2] = gen_lowpart (Pmode, operands[2]);
5746 })
5747
5748 (define_insn "*addsi_2"
5749   [(set (reg FLAGS_REG)
5750         (compare
5751           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5752                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5753           (const_int 0)))
5754    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5755         (plus:SI (match_dup 1) (match_dup 2)))]
5756   "ix86_match_ccmode (insn, CCGOCmode)
5757    && ix86_binary_operator_ok (PLUS, SImode, operands)
5758    /* Current assemblers are broken and do not allow @GOTOFF in
5759       ought but a memory context.  */
5760    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5761 {
5762   switch (get_attr_type (insn))
5763     {
5764     case TYPE_INCDEC:
5765       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5766       if (operands[2] == const1_rtx)
5767         return "inc{l}\t%0";
5768       else
5769         {
5770           gcc_assert (operands[2] == constm1_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 (CONST_INT_P (operands[2])
5779           && (INTVAL (operands[2]) == 128
5780               || (INTVAL (operands[2]) < 0
5781                   && INTVAL (operands[2]) != -128)))
5782         {
5783           operands[2] = GEN_INT (-INTVAL (operands[2]));
5784           return "sub{l}\t{%2, %0|%0, %2}";
5785         }
5786       return "add{l}\t{%2, %0|%0, %2}";
5787     }
5788 }
5789   [(set (attr "type")
5790      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5791         (const_string "incdec")
5792         (const_string "alu")))
5793    (set_attr "mode" "SI")])
5794
5795 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5796 (define_insn "*addsi_2_zext"
5797   [(set (reg FLAGS_REG)
5798         (compare
5799           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5800                    (match_operand:SI 2 "general_operand" "rmni"))
5801           (const_int 0)))
5802    (set (match_operand:DI 0 "register_operand" "=r")
5803         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5804   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5805    && ix86_binary_operator_ok (PLUS, SImode, operands)
5806    /* Current assemblers are broken and do not allow @GOTOFF in
5807       ought but a memory context.  */
5808    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5809 {
5810   switch (get_attr_type (insn))
5811     {
5812     case TYPE_INCDEC:
5813       if (operands[2] == const1_rtx)
5814         return "inc{l}\t%k0";
5815       else
5816         {
5817           gcc_assert (operands[2] == constm1_rtx);
5818           return "dec{l}\t%k0";
5819         }
5820
5821     default:
5822       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5823          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5824       if (CONST_INT_P (operands[2])
5825           && (INTVAL (operands[2]) == 128
5826               || (INTVAL (operands[2]) < 0
5827                   && INTVAL (operands[2]) != -128)))
5828         {
5829           operands[2] = GEN_INT (-INTVAL (operands[2]));
5830           return "sub{l}\t{%2, %k0|%k0, %2}";
5831         }
5832       return "add{l}\t{%2, %k0|%k0, %2}";
5833     }
5834 }
5835   [(set (attr "type")
5836      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5837         (const_string "incdec")
5838         (const_string "alu")))
5839    (set_attr "mode" "SI")])
5840
5841 (define_insn "*addsi_3"
5842   [(set (reg FLAGS_REG)
5843         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5844                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5845    (clobber (match_scratch:SI 0 "=r"))]
5846   "ix86_match_ccmode (insn, CCZmode)
5847    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5848    /* Current assemblers are broken and do not allow @GOTOFF in
5849       ought but a memory context.  */
5850    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5851 {
5852   switch (get_attr_type (insn))
5853     {
5854     case TYPE_INCDEC:
5855       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5856       if (operands[2] == const1_rtx)
5857         return "inc{l}\t%0";
5858       else
5859         {
5860           gcc_assert (operands[2] == constm1_rtx);
5861           return "dec{l}\t%0";
5862         }
5863
5864     default:
5865       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5866       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5867          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5868       if (CONST_INT_P (operands[2])
5869           && (INTVAL (operands[2]) == 128
5870               || (INTVAL (operands[2]) < 0
5871                   && INTVAL (operands[2]) != -128)))
5872         {
5873           operands[2] = GEN_INT (-INTVAL (operands[2]));
5874           return "sub{l}\t{%2, %0|%0, %2}";
5875         }
5876       return "add{l}\t{%2, %0|%0, %2}";
5877     }
5878 }
5879   [(set (attr "type")
5880      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5881         (const_string "incdec")
5882         (const_string "alu")))
5883    (set_attr "mode" "SI")])
5884
5885 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5886 (define_insn "*addsi_3_zext"
5887   [(set (reg FLAGS_REG)
5888         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5889                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5890    (set (match_operand:DI 0 "register_operand" "=r")
5891         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5892   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5893    && ix86_binary_operator_ok (PLUS, SImode, operands)
5894    /* Current assemblers are broken and do not allow @GOTOFF in
5895       ought but a memory context.  */
5896    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5897 {
5898   switch (get_attr_type (insn))
5899     {
5900     case TYPE_INCDEC:
5901       if (operands[2] == const1_rtx)
5902         return "inc{l}\t%k0";
5903       else
5904         {
5905           gcc_assert (operands[2] == constm1_rtx);
5906           return "dec{l}\t%k0";
5907         }
5908
5909     default:
5910       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5911          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5912       if (CONST_INT_P (operands[2])
5913           && (INTVAL (operands[2]) == 128
5914               || (INTVAL (operands[2]) < 0
5915                   && INTVAL (operands[2]) != -128)))
5916         {
5917           operands[2] = GEN_INT (-INTVAL (operands[2]));
5918           return "sub{l}\t{%2, %k0|%k0, %2}";
5919         }
5920       return "add{l}\t{%2, %k0|%k0, %2}";
5921     }
5922 }
5923   [(set (attr "type")
5924      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5925         (const_string "incdec")
5926         (const_string "alu")))
5927    (set_attr "mode" "SI")])
5928
5929 ; For comparisons against 1, -1 and 128, we may generate better code
5930 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5931 ; is matched then.  We can't accept general immediate, because for
5932 ; case of overflows,  the result is messed up.
5933 ; This pattern also don't hold of 0x80000000, since the value overflows
5934 ; when negated.
5935 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5936 ; only for comparisons not depending on it.
5937 (define_insn "*addsi_4"
5938   [(set (reg FLAGS_REG)
5939         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5940                  (match_operand:SI 2 "const_int_operand" "n")))
5941    (clobber (match_scratch:SI 0 "=rm"))]
5942   "ix86_match_ccmode (insn, CCGCmode)
5943    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5944 {
5945   switch (get_attr_type (insn))
5946     {
5947     case TYPE_INCDEC:
5948       if (operands[2] == constm1_rtx)
5949         return "inc{l}\t%0";
5950       else
5951         {
5952           gcc_assert (operands[2] == const1_rtx);
5953           return "dec{l}\t%0";
5954         }
5955
5956     default:
5957       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5958       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5959          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5960       if ((INTVAL (operands[2]) == -128
5961            || (INTVAL (operands[2]) > 0
5962                && INTVAL (operands[2]) != 128)))
5963         return "sub{l}\t{%2, %0|%0, %2}";
5964       operands[2] = GEN_INT (-INTVAL (operands[2]));
5965       return "add{l}\t{%2, %0|%0, %2}";
5966     }
5967 }
5968   [(set (attr "type")
5969      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5970         (const_string "incdec")
5971         (const_string "alu")))
5972    (set_attr "mode" "SI")])
5973
5974 (define_insn "*addsi_5"
5975   [(set (reg FLAGS_REG)
5976         (compare
5977           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5978                    (match_operand:SI 2 "general_operand" "rmni"))
5979           (const_int 0)))
5980    (clobber (match_scratch:SI 0 "=r"))]
5981   "ix86_match_ccmode (insn, CCGOCmode)
5982    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5983    /* Current assemblers are broken and do not allow @GOTOFF in
5984       ought but a memory context.  */
5985    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5986 {
5987   switch (get_attr_type (insn))
5988     {
5989     case TYPE_INCDEC:
5990       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5991       if (operands[2] == const1_rtx)
5992         return "inc{l}\t%0";
5993       else
5994         {
5995           gcc_assert (operands[2] == constm1_rtx);
5996           return "dec{l}\t%0";
5997         }
5998
5999     default:
6000       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6001       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6003       if (CONST_INT_P (operands[2])
6004           && (INTVAL (operands[2]) == 128
6005               || (INTVAL (operands[2]) < 0
6006                   && INTVAL (operands[2]) != -128)))
6007         {
6008           operands[2] = GEN_INT (-INTVAL (operands[2]));
6009           return "sub{l}\t{%2, %0|%0, %2}";
6010         }
6011       return "add{l}\t{%2, %0|%0, %2}";
6012     }
6013 }
6014   [(set (attr "type")
6015      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6016         (const_string "incdec")
6017         (const_string "alu")))
6018    (set_attr "mode" "SI")])
6019
6020 (define_expand "addhi3"
6021   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6022                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6023                             (match_operand:HI 2 "general_operand" "")))
6024               (clobber (reg:CC FLAGS_REG))])]
6025   "TARGET_HIMODE_MATH"
6026   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6027
6028 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6029 ;; type optimizations enabled by define-splits.  This is not important
6030 ;; for PII, and in fact harmful because of partial register stalls.
6031
6032 (define_insn "*addhi_1_lea"
6033   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6034         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6035                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6036    (clobber (reg:CC FLAGS_REG))]
6037   "!TARGET_PARTIAL_REG_STALL
6038    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6039 {
6040   switch (get_attr_type (insn))
6041     {
6042     case TYPE_LEA:
6043       return "#";
6044     case TYPE_INCDEC:
6045       if (operands[2] == const1_rtx)
6046         return "inc{w}\t%0";
6047       else
6048         {
6049           gcc_assert (operands[2] == constm1_rtx);
6050           return "dec{w}\t%0";
6051         }
6052
6053     default:
6054       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6055          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6056       if (CONST_INT_P (operands[2])
6057           && (INTVAL (operands[2]) == 128
6058               || (INTVAL (operands[2]) < 0
6059                   && INTVAL (operands[2]) != -128)))
6060         {
6061           operands[2] = GEN_INT (-INTVAL (operands[2]));
6062           return "sub{w}\t{%2, %0|%0, %2}";
6063         }
6064       return "add{w}\t{%2, %0|%0, %2}";
6065     }
6066 }
6067   [(set (attr "type")
6068      (if_then_else (eq_attr "alternative" "2")
6069         (const_string "lea")
6070         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6071            (const_string "incdec")
6072            (const_string "alu"))))
6073    (set_attr "mode" "HI,HI,SI")])
6074
6075 (define_insn "*addhi_1"
6076   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6077         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6078                  (match_operand:HI 2 "general_operand" "ri,rm")))
6079    (clobber (reg:CC FLAGS_REG))]
6080   "TARGET_PARTIAL_REG_STALL
6081    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6082 {
6083   switch (get_attr_type (insn))
6084     {
6085     case TYPE_INCDEC:
6086       if (operands[2] == const1_rtx)
6087         return "inc{w}\t%0";
6088       else
6089         {
6090           gcc_assert (operands[2] == constm1_rtx);
6091           return "dec{w}\t%0";
6092         }
6093
6094     default:
6095       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6096          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6097       if (CONST_INT_P (operands[2])
6098           && (INTVAL (operands[2]) == 128
6099               || (INTVAL (operands[2]) < 0
6100                   && INTVAL (operands[2]) != -128)))
6101         {
6102           operands[2] = GEN_INT (-INTVAL (operands[2]));
6103           return "sub{w}\t{%2, %0|%0, %2}";
6104         }
6105       return "add{w}\t{%2, %0|%0, %2}";
6106     }
6107 }
6108   [(set (attr "type")
6109      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6110         (const_string "incdec")
6111         (const_string "alu")))
6112    (set_attr "mode" "HI")])
6113
6114 (define_insn "*addhi_2"
6115   [(set (reg FLAGS_REG)
6116         (compare
6117           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6118                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6119           (const_int 0)))
6120    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6121         (plus:HI (match_dup 1) (match_dup 2)))]
6122   "ix86_match_ccmode (insn, CCGOCmode)
6123    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6124 {
6125   switch (get_attr_type (insn))
6126     {
6127     case TYPE_INCDEC:
6128       if (operands[2] == const1_rtx)
6129         return "inc{w}\t%0";
6130       else
6131         {
6132           gcc_assert (operands[2] == constm1_rtx);
6133           return "dec{w}\t%0";
6134         }
6135
6136     default:
6137       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6138          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6139       if (CONST_INT_P (operands[2])
6140           && (INTVAL (operands[2]) == 128
6141               || (INTVAL (operands[2]) < 0
6142                   && INTVAL (operands[2]) != -128)))
6143         {
6144           operands[2] = GEN_INT (-INTVAL (operands[2]));
6145           return "sub{w}\t{%2, %0|%0, %2}";
6146         }
6147       return "add{w}\t{%2, %0|%0, %2}";
6148     }
6149 }
6150   [(set (attr "type")
6151      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6152         (const_string "incdec")
6153         (const_string "alu")))
6154    (set_attr "mode" "HI")])
6155
6156 (define_insn "*addhi_3"
6157   [(set (reg FLAGS_REG)
6158         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6159                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6160    (clobber (match_scratch:HI 0 "=r"))]
6161   "ix86_match_ccmode (insn, CCZmode)
6162    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6163 {
6164   switch (get_attr_type (insn))
6165     {
6166     case TYPE_INCDEC:
6167       if (operands[2] == const1_rtx)
6168         return "inc{w}\t%0";
6169       else
6170         {
6171           gcc_assert (operands[2] == constm1_rtx);
6172           return "dec{w}\t%0";
6173         }
6174
6175     default:
6176       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6177          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6178       if (CONST_INT_P (operands[2])
6179           && (INTVAL (operands[2]) == 128
6180               || (INTVAL (operands[2]) < 0
6181                   && INTVAL (operands[2]) != -128)))
6182         {
6183           operands[2] = GEN_INT (-INTVAL (operands[2]));
6184           return "sub{w}\t{%2, %0|%0, %2}";
6185         }
6186       return "add{w}\t{%2, %0|%0, %2}";
6187     }
6188 }
6189   [(set (attr "type")
6190      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6191         (const_string "incdec")
6192         (const_string "alu")))
6193    (set_attr "mode" "HI")])
6194
6195 ; See comments above addsi_4 for details.
6196 (define_insn "*addhi_4"
6197   [(set (reg FLAGS_REG)
6198         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6199                  (match_operand:HI 2 "const_int_operand" "n")))
6200    (clobber (match_scratch:HI 0 "=rm"))]
6201   "ix86_match_ccmode (insn, CCGCmode)
6202    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6203 {
6204   switch (get_attr_type (insn))
6205     {
6206     case TYPE_INCDEC:
6207       if (operands[2] == constm1_rtx)
6208         return "inc{w}\t%0";
6209       else
6210         {
6211           gcc_assert (operands[2] == const1_rtx);
6212           return "dec{w}\t%0";
6213         }
6214
6215     default:
6216       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6217       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6218          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6219       if ((INTVAL (operands[2]) == -128
6220            || (INTVAL (operands[2]) > 0
6221                && INTVAL (operands[2]) != 128)))
6222         return "sub{w}\t{%2, %0|%0, %2}";
6223       operands[2] = GEN_INT (-INTVAL (operands[2]));
6224       return "add{w}\t{%2, %0|%0, %2}";
6225     }
6226 }
6227   [(set (attr "type")
6228      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6229         (const_string "incdec")
6230         (const_string "alu")))
6231    (set_attr "mode" "SI")])
6232
6233
6234 (define_insn "*addhi_5"
6235   [(set (reg FLAGS_REG)
6236         (compare
6237           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6238                    (match_operand:HI 2 "general_operand" "rmni"))
6239           (const_int 0)))
6240    (clobber (match_scratch:HI 0 "=r"))]
6241   "ix86_match_ccmode (insn, CCGOCmode)
6242    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6243 {
6244   switch (get_attr_type (insn))
6245     {
6246     case TYPE_INCDEC:
6247       if (operands[2] == const1_rtx)
6248         return "inc{w}\t%0";
6249       else
6250         {
6251           gcc_assert (operands[2] == constm1_rtx);
6252           return "dec{w}\t%0";
6253         }
6254
6255     default:
6256       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6257          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6258       if (CONST_INT_P (operands[2])
6259           && (INTVAL (operands[2]) == 128
6260               || (INTVAL (operands[2]) < 0
6261                   && INTVAL (operands[2]) != -128)))
6262         {
6263           operands[2] = GEN_INT (-INTVAL (operands[2]));
6264           return "sub{w}\t{%2, %0|%0, %2}";
6265         }
6266       return "add{w}\t{%2, %0|%0, %2}";
6267     }
6268 }
6269   [(set (attr "type")
6270      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6271         (const_string "incdec")
6272         (const_string "alu")))
6273    (set_attr "mode" "HI")])
6274
6275 (define_expand "addqi3"
6276   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6277                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6278                             (match_operand:QI 2 "general_operand" "")))
6279               (clobber (reg:CC FLAGS_REG))])]
6280   "TARGET_QIMODE_MATH"
6281   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6282
6283 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6284 (define_insn "*addqi_1_lea"
6285   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6286         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6287                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6288    (clobber (reg:CC FLAGS_REG))]
6289   "!TARGET_PARTIAL_REG_STALL
6290    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6291 {
6292   int widen = (which_alternative == 2);
6293   switch (get_attr_type (insn))
6294     {
6295     case TYPE_LEA:
6296       return "#";
6297     case TYPE_INCDEC:
6298       if (operands[2] == const1_rtx)
6299         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6300       else
6301         {
6302           gcc_assert (operands[2] == constm1_rtx);
6303           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6304         }
6305
6306     default:
6307       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6308          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6309       if (CONST_INT_P (operands[2])
6310           && (INTVAL (operands[2]) == 128
6311               || (INTVAL (operands[2]) < 0
6312                   && INTVAL (operands[2]) != -128)))
6313         {
6314           operands[2] = GEN_INT (-INTVAL (operands[2]));
6315           if (widen)
6316             return "sub{l}\t{%2, %k0|%k0, %2}";
6317           else
6318             return "sub{b}\t{%2, %0|%0, %2}";
6319         }
6320       if (widen)
6321         return "add{l}\t{%k2, %k0|%k0, %k2}";
6322       else
6323         return "add{b}\t{%2, %0|%0, %2}";
6324     }
6325 }
6326   [(set (attr "type")
6327      (if_then_else (eq_attr "alternative" "3")
6328         (const_string "lea")
6329         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6330            (const_string "incdec")
6331            (const_string "alu"))))
6332    (set_attr "mode" "QI,QI,SI,SI")])
6333
6334 (define_insn "*addqi_1"
6335   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6336         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6337                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6338    (clobber (reg:CC FLAGS_REG))]
6339   "TARGET_PARTIAL_REG_STALL
6340    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6341 {
6342   int widen = (which_alternative == 2);
6343   switch (get_attr_type (insn))
6344     {
6345     case TYPE_INCDEC:
6346       if (operands[2] == const1_rtx)
6347         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6348       else
6349         {
6350           gcc_assert (operands[2] == constm1_rtx);
6351           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6352         }
6353
6354     default:
6355       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6356          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6357       if (CONST_INT_P (operands[2])
6358           && (INTVAL (operands[2]) == 128
6359               || (INTVAL (operands[2]) < 0
6360                   && INTVAL (operands[2]) != -128)))
6361         {
6362           operands[2] = GEN_INT (-INTVAL (operands[2]));
6363           if (widen)
6364             return "sub{l}\t{%2, %k0|%k0, %2}";
6365           else
6366             return "sub{b}\t{%2, %0|%0, %2}";
6367         }
6368       if (widen)
6369         return "add{l}\t{%k2, %k0|%k0, %k2}";
6370       else
6371         return "add{b}\t{%2, %0|%0, %2}";
6372     }
6373 }
6374   [(set (attr "type")
6375      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6376         (const_string "incdec")
6377         (const_string "alu")))
6378    (set_attr "mode" "QI,QI,SI")])
6379
6380 (define_insn "*addqi_1_slp"
6381   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6382         (plus:QI (match_dup 0)
6383                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6384    (clobber (reg:CC FLAGS_REG))]
6385   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6386    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6387 {
6388   switch (get_attr_type (insn))
6389     {
6390     case TYPE_INCDEC:
6391       if (operands[1] == const1_rtx)
6392         return "inc{b}\t%0";
6393       else
6394         {
6395           gcc_assert (operands[1] == constm1_rtx);
6396           return "dec{b}\t%0";
6397         }
6398
6399     default:
6400       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6401       if (CONST_INT_P (operands[1])
6402           && INTVAL (operands[1]) < 0)
6403         {
6404           operands[1] = GEN_INT (-INTVAL (operands[1]));
6405           return "sub{b}\t{%1, %0|%0, %1}";
6406         }
6407       return "add{b}\t{%1, %0|%0, %1}";
6408     }
6409 }
6410   [(set (attr "type")
6411      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6412         (const_string "incdec")
6413         (const_string "alu1")))
6414    (set (attr "memory")
6415      (if_then_else (match_operand 1 "memory_operand" "")
6416         (const_string "load")
6417         (const_string "none")))
6418    (set_attr "mode" "QI")])
6419
6420 (define_insn "*addqi_2"
6421   [(set (reg FLAGS_REG)
6422         (compare
6423           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6424                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6425           (const_int 0)))
6426    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6427         (plus:QI (match_dup 1) (match_dup 2)))]
6428   "ix86_match_ccmode (insn, CCGOCmode)
6429    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6430 {
6431   switch (get_attr_type (insn))
6432     {
6433     case TYPE_INCDEC:
6434       if (operands[2] == const1_rtx)
6435         return "inc{b}\t%0";
6436       else
6437         {
6438           gcc_assert (operands[2] == constm1_rtx
6439                       || (CONST_INT_P (operands[2])
6440                           && INTVAL (operands[2]) == 255));
6441           return "dec{b}\t%0";
6442         }
6443
6444     default:
6445       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6446       if (CONST_INT_P (operands[2])
6447           && INTVAL (operands[2]) < 0)
6448         {
6449           operands[2] = GEN_INT (-INTVAL (operands[2]));
6450           return "sub{b}\t{%2, %0|%0, %2}";
6451         }
6452       return "add{b}\t{%2, %0|%0, %2}";
6453     }
6454 }
6455   [(set (attr "type")
6456      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6457         (const_string "incdec")
6458         (const_string "alu")))
6459    (set_attr "mode" "QI")])
6460
6461 (define_insn "*addqi_3"
6462   [(set (reg FLAGS_REG)
6463         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6464                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6465    (clobber (match_scratch:QI 0 "=q"))]
6466   "ix86_match_ccmode (insn, CCZmode)
6467    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6468 {
6469   switch (get_attr_type (insn))
6470     {
6471     case TYPE_INCDEC:
6472       if (operands[2] == const1_rtx)
6473         return "inc{b}\t%0";
6474       else
6475         {
6476           gcc_assert (operands[2] == constm1_rtx
6477                       || (CONST_INT_P (operands[2])
6478                           && INTVAL (operands[2]) == 255));
6479           return "dec{b}\t%0";
6480         }
6481
6482     default:
6483       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6484       if (CONST_INT_P (operands[2])
6485           && INTVAL (operands[2]) < 0)
6486         {
6487           operands[2] = GEN_INT (-INTVAL (operands[2]));
6488           return "sub{b}\t{%2, %0|%0, %2}";
6489         }
6490       return "add{b}\t{%2, %0|%0, %2}";
6491     }
6492 }
6493   [(set (attr "type")
6494      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6495         (const_string "incdec")
6496         (const_string "alu")))
6497    (set_attr "mode" "QI")])
6498
6499 ; See comments above addsi_4 for details.
6500 (define_insn "*addqi_4"
6501   [(set (reg FLAGS_REG)
6502         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6503                  (match_operand:QI 2 "const_int_operand" "n")))
6504    (clobber (match_scratch:QI 0 "=qm"))]
6505   "ix86_match_ccmode (insn, CCGCmode)
6506    && (INTVAL (operands[2]) & 0xff) != 0x80"
6507 {
6508   switch (get_attr_type (insn))
6509     {
6510     case TYPE_INCDEC:
6511       if (operands[2] == constm1_rtx
6512           || (CONST_INT_P (operands[2])
6513               && INTVAL (operands[2]) == 255))
6514         return "inc{b}\t%0";
6515       else
6516         {
6517           gcc_assert (operands[2] == const1_rtx);
6518           return "dec{b}\t%0";
6519         }
6520
6521     default:
6522       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6523       if (INTVAL (operands[2]) < 0)
6524         {
6525           operands[2] = GEN_INT (-INTVAL (operands[2]));
6526           return "add{b}\t{%2, %0|%0, %2}";
6527         }
6528       return "sub{b}\t{%2, %0|%0, %2}";
6529     }
6530 }
6531   [(set (attr "type")
6532      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6533         (const_string "incdec")
6534         (const_string "alu")))
6535    (set_attr "mode" "QI")])
6536
6537
6538 (define_insn "*addqi_5"
6539   [(set (reg FLAGS_REG)
6540         (compare
6541           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6542                    (match_operand:QI 2 "general_operand" "qmni"))
6543           (const_int 0)))
6544    (clobber (match_scratch:QI 0 "=q"))]
6545   "ix86_match_ccmode (insn, CCGOCmode)
6546    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6547 {
6548   switch (get_attr_type (insn))
6549     {
6550     case TYPE_INCDEC:
6551       if (operands[2] == const1_rtx)
6552         return "inc{b}\t%0";
6553       else
6554         {
6555           gcc_assert (operands[2] == constm1_rtx
6556                       || (CONST_INT_P (operands[2])
6557                           && INTVAL (operands[2]) == 255));
6558           return "dec{b}\t%0";
6559         }
6560
6561     default:
6562       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6563       if (CONST_INT_P (operands[2])
6564           && INTVAL (operands[2]) < 0)
6565         {
6566           operands[2] = GEN_INT (-INTVAL (operands[2]));
6567           return "sub{b}\t{%2, %0|%0, %2}";
6568         }
6569       return "add{b}\t{%2, %0|%0, %2}";
6570     }
6571 }
6572   [(set (attr "type")
6573      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6574         (const_string "incdec")
6575         (const_string "alu")))
6576    (set_attr "mode" "QI")])
6577
6578
6579 (define_insn "addqi_ext_1"
6580   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6581                          (const_int 8)
6582                          (const_int 8))
6583         (plus:SI
6584           (zero_extract:SI
6585             (match_operand 1 "ext_register_operand" "0")
6586             (const_int 8)
6587             (const_int 8))
6588           (match_operand:QI 2 "general_operand" "Qmn")))
6589    (clobber (reg:CC FLAGS_REG))]
6590   "!TARGET_64BIT"
6591 {
6592   switch (get_attr_type (insn))
6593     {
6594     case TYPE_INCDEC:
6595       if (operands[2] == const1_rtx)
6596         return "inc{b}\t%h0";
6597       else
6598         {
6599           gcc_assert (operands[2] == constm1_rtx
6600                       || (CONST_INT_P (operands[2])
6601                           && INTVAL (operands[2]) == 255));
6602           return "dec{b}\t%h0";
6603         }
6604
6605     default:
6606       return "add{b}\t{%2, %h0|%h0, %2}";
6607     }
6608 }
6609   [(set (attr "type")
6610      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6611         (const_string "incdec")
6612         (const_string "alu")))
6613    (set_attr "mode" "QI")])
6614
6615 (define_insn "*addqi_ext_1_rex64"
6616   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6617                          (const_int 8)
6618                          (const_int 8))
6619         (plus:SI
6620           (zero_extract:SI
6621             (match_operand 1 "ext_register_operand" "0")
6622             (const_int 8)
6623             (const_int 8))
6624           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6625    (clobber (reg:CC FLAGS_REG))]
6626   "TARGET_64BIT"
6627 {
6628   switch (get_attr_type (insn))
6629     {
6630     case TYPE_INCDEC:
6631       if (operands[2] == const1_rtx)
6632         return "inc{b}\t%h0";
6633       else
6634         {
6635           gcc_assert (operands[2] == constm1_rtx
6636                       || (CONST_INT_P (operands[2])
6637                           && INTVAL (operands[2]) == 255));
6638           return "dec{b}\t%h0";
6639         }
6640
6641     default:
6642       return "add{b}\t{%2, %h0|%h0, %2}";
6643     }
6644 }
6645   [(set (attr "type")
6646      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6647         (const_string "incdec")
6648         (const_string "alu")))
6649    (set_attr "mode" "QI")])
6650
6651 (define_insn "*addqi_ext_2"
6652   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6653                          (const_int 8)
6654                          (const_int 8))
6655         (plus:SI
6656           (zero_extract:SI
6657             (match_operand 1 "ext_register_operand" "%0")
6658             (const_int 8)
6659             (const_int 8))
6660           (zero_extract:SI
6661             (match_operand 2 "ext_register_operand" "Q")
6662             (const_int 8)
6663             (const_int 8))))
6664    (clobber (reg:CC FLAGS_REG))]
6665   ""
6666   "add{b}\t{%h2, %h0|%h0, %h2}"
6667   [(set_attr "type" "alu")
6668    (set_attr "mode" "QI")])
6669
6670 ;; The patterns that match these are at the end of this file.
6671
6672 (define_expand "addxf3"
6673   [(set (match_operand:XF 0 "register_operand" "")
6674         (plus:XF (match_operand:XF 1 "register_operand" "")
6675                  (match_operand:XF 2 "register_operand" "")))]
6676   "TARGET_80387"
6677   "")
6678
6679 (define_expand "adddf3"
6680   [(set (match_operand:DF 0 "register_operand" "")
6681         (plus:DF (match_operand:DF 1 "register_operand" "")
6682                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6683   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6684   "")
6685
6686 (define_expand "addsf3"
6687   [(set (match_operand:SF 0 "register_operand" "")
6688         (plus:SF (match_operand:SF 1 "register_operand" "")
6689                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6690   "TARGET_80387 || TARGET_SSE_MATH"
6691   "")
6692 \f
6693 ;; Subtract instructions
6694
6695 ;; %%% splits for subditi3
6696
6697 (define_expand "subti3"
6698   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6699                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6700                              (match_operand:TI 2 "x86_64_general_operand" "")))
6701               (clobber (reg:CC FLAGS_REG))])]
6702   "TARGET_64BIT"
6703   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6704
6705 (define_insn "*subti3_1"
6706   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6707         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6708                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6709    (clobber (reg:CC FLAGS_REG))]
6710   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6711   "#")
6712
6713 (define_split
6714   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6715         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6716                   (match_operand:TI 2 "x86_64_general_operand" "")))
6717    (clobber (reg:CC FLAGS_REG))]
6718   "TARGET_64BIT && reload_completed"
6719   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6720               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6721    (parallel [(set (match_dup 3)
6722                    (minus:DI (match_dup 4)
6723                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6724                                       (match_dup 5))))
6725               (clobber (reg:CC FLAGS_REG))])]
6726   "split_ti (operands+0, 1, operands+0, operands+3);
6727    split_ti (operands+1, 1, operands+1, operands+4);
6728    split_ti (operands+2, 1, operands+2, operands+5);")
6729
6730 ;; %%% splits for subsidi3
6731
6732 (define_expand "subdi3"
6733   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6734                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6735                              (match_operand:DI 2 "x86_64_general_operand" "")))
6736               (clobber (reg:CC FLAGS_REG))])]
6737   ""
6738   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6739
6740 (define_insn "*subdi3_1"
6741   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6742         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6743                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6744    (clobber (reg:CC FLAGS_REG))]
6745   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6746   "#")
6747
6748 (define_split
6749   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6750         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6751                   (match_operand:DI 2 "general_operand" "")))
6752    (clobber (reg:CC FLAGS_REG))]
6753   "!TARGET_64BIT && reload_completed"
6754   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6755               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6756    (parallel [(set (match_dup 3)
6757                    (minus:SI (match_dup 4)
6758                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6759                                       (match_dup 5))))
6760               (clobber (reg:CC FLAGS_REG))])]
6761   "split_di (operands+0, 1, operands+0, operands+3);
6762    split_di (operands+1, 1, operands+1, operands+4);
6763    split_di (operands+2, 1, operands+2, operands+5);")
6764
6765 (define_insn "subdi3_carry_rex64"
6766   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6767           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6768             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6769                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6770    (clobber (reg:CC FLAGS_REG))]
6771   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6772   "sbb{q}\t{%2, %0|%0, %2}"
6773   [(set_attr "type" "alu")
6774    (set_attr "pent_pair" "pu")
6775    (set_attr "mode" "DI")])
6776
6777 (define_insn "*subdi_1_rex64"
6778   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6779         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6780                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6781    (clobber (reg:CC FLAGS_REG))]
6782   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6783   "sub{q}\t{%2, %0|%0, %2}"
6784   [(set_attr "type" "alu")
6785    (set_attr "mode" "DI")])
6786
6787 (define_insn "*subdi_2_rex64"
6788   [(set (reg FLAGS_REG)
6789         (compare
6790           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6791                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6792           (const_int 0)))
6793    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6794         (minus:DI (match_dup 1) (match_dup 2)))]
6795   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6796    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6797   "sub{q}\t{%2, %0|%0, %2}"
6798   [(set_attr "type" "alu")
6799    (set_attr "mode" "DI")])
6800
6801 (define_insn "*subdi_3_rex63"
6802   [(set (reg FLAGS_REG)
6803         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6804                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6805    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6806         (minus:DI (match_dup 1) (match_dup 2)))]
6807   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6808    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6809   "sub{q}\t{%2, %0|%0, %2}"
6810   [(set_attr "type" "alu")
6811    (set_attr "mode" "DI")])
6812
6813 (define_insn "subqi3_carry"
6814   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6815           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6816             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6817                (match_operand:QI 2 "general_operand" "qi,qm"))))
6818    (clobber (reg:CC FLAGS_REG))]
6819   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6820   "sbb{b}\t{%2, %0|%0, %2}"
6821   [(set_attr "type" "alu")
6822    (set_attr "pent_pair" "pu")
6823    (set_attr "mode" "QI")])
6824
6825 (define_insn "subhi3_carry"
6826   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6827           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6828             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6829                (match_operand:HI 2 "general_operand" "ri,rm"))))
6830    (clobber (reg:CC FLAGS_REG))]
6831   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6832   "sbb{w}\t{%2, %0|%0, %2}"
6833   [(set_attr "type" "alu")
6834    (set_attr "pent_pair" "pu")
6835    (set_attr "mode" "HI")])
6836
6837 (define_insn "subsi3_carry"
6838   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6839           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6840             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6841                (match_operand:SI 2 "general_operand" "ri,rm"))))
6842    (clobber (reg:CC FLAGS_REG))]
6843   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6844   "sbb{l}\t{%2, %0|%0, %2}"
6845   [(set_attr "type" "alu")
6846    (set_attr "pent_pair" "pu")
6847    (set_attr "mode" "SI")])
6848
6849 (define_insn "subsi3_carry_zext"
6850   [(set (match_operand:DI 0 "register_operand" "=r")
6851           (zero_extend:DI
6852             (minus:SI (match_operand:SI 1 "register_operand" "0")
6853               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6854                  (match_operand:SI 2 "general_operand" "g")))))
6855    (clobber (reg:CC FLAGS_REG))]
6856   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6857   "sbb{l}\t{%2, %k0|%k0, %2}"
6858   [(set_attr "type" "alu")
6859    (set_attr "pent_pair" "pu")
6860    (set_attr "mode" "SI")])
6861
6862 (define_expand "subsi3"
6863   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6864                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6865                              (match_operand:SI 2 "general_operand" "")))
6866               (clobber (reg:CC FLAGS_REG))])]
6867   ""
6868   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6869
6870 (define_insn "*subsi_1"
6871   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6872         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6873                   (match_operand:SI 2 "general_operand" "ri,rm")))
6874    (clobber (reg:CC FLAGS_REG))]
6875   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6876   "sub{l}\t{%2, %0|%0, %2}"
6877   [(set_attr "type" "alu")
6878    (set_attr "mode" "SI")])
6879
6880 (define_insn "*subsi_1_zext"
6881   [(set (match_operand:DI 0 "register_operand" "=r")
6882         (zero_extend:DI
6883           (minus:SI (match_operand:SI 1 "register_operand" "0")
6884                     (match_operand:SI 2 "general_operand" "g"))))
6885    (clobber (reg:CC FLAGS_REG))]
6886   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6887   "sub{l}\t{%2, %k0|%k0, %2}"
6888   [(set_attr "type" "alu")
6889    (set_attr "mode" "SI")])
6890
6891 (define_insn "*subsi_2"
6892   [(set (reg FLAGS_REG)
6893         (compare
6894           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6895                     (match_operand:SI 2 "general_operand" "ri,rm"))
6896           (const_int 0)))
6897    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6898         (minus:SI (match_dup 1) (match_dup 2)))]
6899   "ix86_match_ccmode (insn, CCGOCmode)
6900    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6901   "sub{l}\t{%2, %0|%0, %2}"
6902   [(set_attr "type" "alu")
6903    (set_attr "mode" "SI")])
6904
6905 (define_insn "*subsi_2_zext"
6906   [(set (reg FLAGS_REG)
6907         (compare
6908           (minus:SI (match_operand:SI 1 "register_operand" "0")
6909                     (match_operand:SI 2 "general_operand" "g"))
6910           (const_int 0)))
6911    (set (match_operand:DI 0 "register_operand" "=r")
6912         (zero_extend:DI
6913           (minus:SI (match_dup 1)
6914                     (match_dup 2))))]
6915   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6916    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6917   "sub{l}\t{%2, %k0|%k0, %2}"
6918   [(set_attr "type" "alu")
6919    (set_attr "mode" "SI")])
6920
6921 (define_insn "*subsi_3"
6922   [(set (reg FLAGS_REG)
6923         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6924                  (match_operand:SI 2 "general_operand" "ri,rm")))
6925    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6926         (minus:SI (match_dup 1) (match_dup 2)))]
6927   "ix86_match_ccmode (insn, CCmode)
6928    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6929   "sub{l}\t{%2, %0|%0, %2}"
6930   [(set_attr "type" "alu")
6931    (set_attr "mode" "SI")])
6932
6933 (define_insn "*subsi_3_zext"
6934   [(set (reg FLAGS_REG)
6935         (compare (match_operand:SI 1 "register_operand" "0")
6936                  (match_operand:SI 2 "general_operand" "g")))
6937    (set (match_operand:DI 0 "register_operand" "=r")
6938         (zero_extend:DI
6939           (minus:SI (match_dup 1)
6940                     (match_dup 2))))]
6941   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6942    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6943   "sub{l}\t{%2, %1|%1, %2}"
6944   [(set_attr "type" "alu")
6945    (set_attr "mode" "DI")])
6946
6947 (define_expand "subhi3"
6948   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6949                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6950                              (match_operand:HI 2 "general_operand" "")))
6951               (clobber (reg:CC FLAGS_REG))])]
6952   "TARGET_HIMODE_MATH"
6953   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6954
6955 (define_insn "*subhi_1"
6956   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6957         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6958                   (match_operand:HI 2 "general_operand" "ri,rm")))
6959    (clobber (reg:CC FLAGS_REG))]
6960   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6961   "sub{w}\t{%2, %0|%0, %2}"
6962   [(set_attr "type" "alu")
6963    (set_attr "mode" "HI")])
6964
6965 (define_insn "*subhi_2"
6966   [(set (reg FLAGS_REG)
6967         (compare
6968           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6969                     (match_operand:HI 2 "general_operand" "ri,rm"))
6970           (const_int 0)))
6971    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6972         (minus:HI (match_dup 1) (match_dup 2)))]
6973   "ix86_match_ccmode (insn, CCGOCmode)
6974    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6975   "sub{w}\t{%2, %0|%0, %2}"
6976   [(set_attr "type" "alu")
6977    (set_attr "mode" "HI")])
6978
6979 (define_insn "*subhi_3"
6980   [(set (reg FLAGS_REG)
6981         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6982                  (match_operand:HI 2 "general_operand" "ri,rm")))
6983    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6984         (minus:HI (match_dup 1) (match_dup 2)))]
6985   "ix86_match_ccmode (insn, CCmode)
6986    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6987   "sub{w}\t{%2, %0|%0, %2}"
6988   [(set_attr "type" "alu")
6989    (set_attr "mode" "HI")])
6990
6991 (define_expand "subqi3"
6992   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6993                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6994                              (match_operand:QI 2 "general_operand" "")))
6995               (clobber (reg:CC FLAGS_REG))])]
6996   "TARGET_QIMODE_MATH"
6997   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6998
6999 (define_insn "*subqi_1"
7000   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7001         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7002                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7003    (clobber (reg:CC FLAGS_REG))]
7004   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7005   "sub{b}\t{%2, %0|%0, %2}"
7006   [(set_attr "type" "alu")
7007    (set_attr "mode" "QI")])
7008
7009 (define_insn "*subqi_1_slp"
7010   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7011         (minus:QI (match_dup 0)
7012                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7013    (clobber (reg:CC FLAGS_REG))]
7014   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7015    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7016   "sub{b}\t{%1, %0|%0, %1}"
7017   [(set_attr "type" "alu1")
7018    (set_attr "mode" "QI")])
7019
7020 (define_insn "*subqi_2"
7021   [(set (reg FLAGS_REG)
7022         (compare
7023           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7024                     (match_operand:QI 2 "general_operand" "qi,qm"))
7025           (const_int 0)))
7026    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7027         (minus:HI (match_dup 1) (match_dup 2)))]
7028   "ix86_match_ccmode (insn, CCGOCmode)
7029    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7030   "sub{b}\t{%2, %0|%0, %2}"
7031   [(set_attr "type" "alu")
7032    (set_attr "mode" "QI")])
7033
7034 (define_insn "*subqi_3"
7035   [(set (reg FLAGS_REG)
7036         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7037                  (match_operand:QI 2 "general_operand" "qi,qm")))
7038    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7039         (minus:HI (match_dup 1) (match_dup 2)))]
7040   "ix86_match_ccmode (insn, CCmode)
7041    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7042   "sub{b}\t{%2, %0|%0, %2}"
7043   [(set_attr "type" "alu")
7044    (set_attr "mode" "QI")])
7045
7046 ;; The patterns that match these are at the end of this file.
7047
7048 (define_expand "subxf3"
7049   [(set (match_operand:XF 0 "register_operand" "")
7050         (minus:XF (match_operand:XF 1 "register_operand" "")
7051                   (match_operand:XF 2 "register_operand" "")))]
7052   "TARGET_80387"
7053   "")
7054
7055 (define_expand "subdf3"
7056   [(set (match_operand:DF 0 "register_operand" "")
7057         (minus:DF (match_operand:DF 1 "register_operand" "")
7058                   (match_operand:DF 2 "nonimmediate_operand" "")))]
7059   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7060   "")
7061
7062 (define_expand "subsf3"
7063   [(set (match_operand:SF 0 "register_operand" "")
7064         (minus:SF (match_operand:SF 1 "register_operand" "")
7065                   (match_operand:SF 2 "nonimmediate_operand" "")))]
7066   "TARGET_80387 || TARGET_SSE_MATH"
7067   "")
7068 \f
7069 ;; Multiply instructions
7070
7071 (define_expand "muldi3"
7072   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7073                    (mult:DI (match_operand:DI 1 "register_operand" "")
7074                             (match_operand:DI 2 "x86_64_general_operand" "")))
7075               (clobber (reg:CC FLAGS_REG))])]
7076   "TARGET_64BIT"
7077   "")
7078
7079 ;; On AMDFAM10 
7080 ;; IMUL reg64, reg64, imm8      Direct
7081 ;; IMUL reg64, mem64, imm8      VectorPath
7082 ;; IMUL reg64, reg64, imm32     Direct
7083 ;; IMUL reg64, mem64, imm32     VectorPath 
7084 ;; IMUL reg64, reg64            Direct
7085 ;; IMUL reg64, mem64            Direct
7086
7087 (define_insn "*muldi3_1_rex64"
7088   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7089         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7090                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7091    (clobber (reg:CC FLAGS_REG))]
7092   "TARGET_64BIT
7093    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7094   "@
7095    imul{q}\t{%2, %1, %0|%0, %1, %2}
7096    imul{q}\t{%2, %1, %0|%0, %1, %2}
7097    imul{q}\t{%2, %0|%0, %2}"
7098   [(set_attr "type" "imul")
7099    (set_attr "prefix_0f" "0,0,1")
7100    (set (attr "athlon_decode")
7101         (cond [(eq_attr "cpu" "athlon")
7102                   (const_string "vector")
7103                (eq_attr "alternative" "1")
7104                   (const_string "vector")
7105                (and (eq_attr "alternative" "2")
7106                     (match_operand 1 "memory_operand" ""))
7107                   (const_string "vector")]
7108               (const_string "direct")))
7109    (set (attr "amdfam10_decode")
7110         (cond [(and (eq_attr "alternative" "0,1")
7111                     (match_operand 1 "memory_operand" ""))
7112                   (const_string "vector")]
7113               (const_string "direct")))       
7114    (set_attr "mode" "DI")])
7115
7116 (define_expand "mulsi3"
7117   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7118                    (mult:SI (match_operand:SI 1 "register_operand" "")
7119                             (match_operand:SI 2 "general_operand" "")))
7120               (clobber (reg:CC FLAGS_REG))])]
7121   ""
7122   "")
7123
7124 ;; On AMDFAM10 
7125 ;; IMUL reg32, reg32, imm8      Direct
7126 ;; IMUL reg32, mem32, imm8      VectorPath
7127 ;; IMUL reg32, reg32, imm32     Direct
7128 ;; IMUL reg32, mem32, imm32     VectorPath
7129 ;; IMUL reg32, reg32            Direct
7130 ;; IMUL reg32, mem32            Direct
7131
7132 (define_insn "*mulsi3_1"
7133   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7134         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7135                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7136    (clobber (reg:CC FLAGS_REG))]
7137   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7138   "@
7139    imul{l}\t{%2, %1, %0|%0, %1, %2}
7140    imul{l}\t{%2, %1, %0|%0, %1, %2}
7141    imul{l}\t{%2, %0|%0, %2}"
7142   [(set_attr "type" "imul")
7143    (set_attr "prefix_0f" "0,0,1")
7144    (set (attr "athlon_decode")
7145         (cond [(eq_attr "cpu" "athlon")
7146                   (const_string "vector")
7147                (eq_attr "alternative" "1")
7148                   (const_string "vector")
7149                (and (eq_attr "alternative" "2")
7150                     (match_operand 1 "memory_operand" ""))
7151                   (const_string "vector")]
7152               (const_string "direct")))
7153    (set (attr "amdfam10_decode")
7154         (cond [(and (eq_attr "alternative" "0,1")
7155                     (match_operand 1 "memory_operand" ""))
7156                   (const_string "vector")]
7157               (const_string "direct")))       
7158    (set_attr "mode" "SI")])
7159
7160 (define_insn "*mulsi3_1_zext"
7161   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7162         (zero_extend:DI
7163           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7164                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7165    (clobber (reg:CC FLAGS_REG))]
7166   "TARGET_64BIT
7167    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7168   "@
7169    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7170    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7171    imul{l}\t{%2, %k0|%k0, %2}"
7172   [(set_attr "type" "imul")
7173    (set_attr "prefix_0f" "0,0,1")
7174    (set (attr "athlon_decode")
7175         (cond [(eq_attr "cpu" "athlon")
7176                   (const_string "vector")
7177                (eq_attr "alternative" "1")
7178                   (const_string "vector")
7179                (and (eq_attr "alternative" "2")
7180                     (match_operand 1 "memory_operand" ""))
7181                   (const_string "vector")]
7182               (const_string "direct")))
7183    (set (attr "amdfam10_decode")
7184         (cond [(and (eq_attr "alternative" "0,1")
7185                     (match_operand 1 "memory_operand" ""))
7186                   (const_string "vector")]
7187               (const_string "direct")))       
7188    (set_attr "mode" "SI")])
7189
7190 (define_expand "mulhi3"
7191   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7192                    (mult:HI (match_operand:HI 1 "register_operand" "")
7193                             (match_operand:HI 2 "general_operand" "")))
7194               (clobber (reg:CC FLAGS_REG))])]
7195   "TARGET_HIMODE_MATH"
7196   "")
7197
7198 ;; On AMDFAM10
7199 ;; IMUL reg16, reg16, imm8      VectorPath
7200 ;; IMUL reg16, mem16, imm8      VectorPath
7201 ;; IMUL reg16, reg16, imm16     VectorPath
7202 ;; IMUL reg16, mem16, imm16     VectorPath
7203 ;; IMUL reg16, reg16            Direct
7204 ;; IMUL reg16, mem16            Direct
7205 (define_insn "*mulhi3_1"
7206   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7207         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7208                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7209    (clobber (reg:CC FLAGS_REG))]
7210   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7211   "@
7212    imul{w}\t{%2, %1, %0|%0, %1, %2}
7213    imul{w}\t{%2, %1, %0|%0, %1, %2}
7214    imul{w}\t{%2, %0|%0, %2}"
7215   [(set_attr "type" "imul")
7216    (set_attr "prefix_0f" "0,0,1")
7217    (set (attr "athlon_decode")
7218         (cond [(eq_attr "cpu" "athlon")
7219                   (const_string "vector")
7220                (eq_attr "alternative" "1,2")
7221                   (const_string "vector")]
7222               (const_string "direct")))
7223    (set (attr "amdfam10_decode")
7224         (cond [(eq_attr "alternative" "0,1")
7225                   (const_string "vector")]
7226               (const_string "direct")))
7227    (set_attr "mode" "HI")])
7228
7229 (define_expand "mulqi3"
7230   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7231                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7232                             (match_operand:QI 2 "register_operand" "")))
7233               (clobber (reg:CC FLAGS_REG))])]
7234   "TARGET_QIMODE_MATH"
7235   "")
7236
7237 ;;On AMDFAM10
7238 ;; MUL reg8     Direct
7239 ;; MUL mem8     Direct
7240
7241 (define_insn "*mulqi3_1"
7242   [(set (match_operand:QI 0 "register_operand" "=a")
7243         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7244                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7245    (clobber (reg:CC FLAGS_REG))]
7246   "TARGET_QIMODE_MATH
7247    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7248   "mul{b}\t%2"
7249   [(set_attr "type" "imul")
7250    (set_attr "length_immediate" "0")
7251    (set (attr "athlon_decode")
7252      (if_then_else (eq_attr "cpu" "athlon")
7253         (const_string "vector")
7254         (const_string "direct")))
7255    (set_attr "amdfam10_decode" "direct")        
7256    (set_attr "mode" "QI")])
7257
7258 (define_expand "umulqihi3"
7259   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7260                    (mult:HI (zero_extend:HI
7261                               (match_operand:QI 1 "nonimmediate_operand" ""))
7262                             (zero_extend:HI
7263                               (match_operand:QI 2 "register_operand" ""))))
7264               (clobber (reg:CC FLAGS_REG))])]
7265   "TARGET_QIMODE_MATH"
7266   "")
7267
7268 (define_insn "*umulqihi3_1"
7269   [(set (match_operand:HI 0 "register_operand" "=a")
7270         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7271                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7272    (clobber (reg:CC FLAGS_REG))]
7273   "TARGET_QIMODE_MATH
7274    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7275   "mul{b}\t%2"
7276   [(set_attr "type" "imul")
7277    (set_attr "length_immediate" "0")
7278    (set (attr "athlon_decode")
7279      (if_then_else (eq_attr "cpu" "athlon")
7280         (const_string "vector")
7281         (const_string "direct")))
7282    (set_attr "amdfam10_decode" "direct")        
7283    (set_attr "mode" "QI")])
7284
7285 (define_expand "mulqihi3"
7286   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7287                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7288                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7289               (clobber (reg:CC FLAGS_REG))])]
7290   "TARGET_QIMODE_MATH"
7291   "")
7292
7293 (define_insn "*mulqihi3_insn"
7294   [(set (match_operand:HI 0 "register_operand" "=a")
7295         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7296                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7297    (clobber (reg:CC FLAGS_REG))]
7298   "TARGET_QIMODE_MATH
7299    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7300   "imul{b}\t%2"
7301   [(set_attr "type" "imul")
7302    (set_attr "length_immediate" "0")
7303    (set (attr "athlon_decode")
7304      (if_then_else (eq_attr "cpu" "athlon")
7305         (const_string "vector")
7306         (const_string "direct")))
7307    (set_attr "amdfam10_decode" "direct")        
7308    (set_attr "mode" "QI")])
7309
7310 (define_expand "umulditi3"
7311   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7312                    (mult:TI (zero_extend:TI
7313                               (match_operand:DI 1 "nonimmediate_operand" ""))
7314                             (zero_extend:TI
7315                               (match_operand:DI 2 "register_operand" ""))))
7316               (clobber (reg:CC FLAGS_REG))])]
7317   "TARGET_64BIT"
7318   "")
7319
7320 (define_insn "*umulditi3_insn"
7321   [(set (match_operand:TI 0 "register_operand" "=A")
7322         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7323                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7324    (clobber (reg:CC FLAGS_REG))]
7325   "TARGET_64BIT
7326    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7327   "mul{q}\t%2"
7328   [(set_attr "type" "imul")
7329    (set_attr "length_immediate" "0")
7330    (set (attr "athlon_decode")
7331      (if_then_else (eq_attr "cpu" "athlon")
7332         (const_string "vector")
7333         (const_string "double")))
7334    (set_attr "amdfam10_decode" "double")        
7335    (set_attr "mode" "DI")])
7336
7337 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7338 (define_expand "umulsidi3"
7339   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7340                    (mult:DI (zero_extend:DI
7341                               (match_operand:SI 1 "nonimmediate_operand" ""))
7342                             (zero_extend:DI
7343                               (match_operand:SI 2 "register_operand" ""))))
7344               (clobber (reg:CC FLAGS_REG))])]
7345   "!TARGET_64BIT"
7346   "")
7347
7348 (define_insn "*umulsidi3_insn"
7349   [(set (match_operand:DI 0 "register_operand" "=A")
7350         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7351                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7352    (clobber (reg:CC FLAGS_REG))]
7353   "!TARGET_64BIT
7354    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7355   "mul{l}\t%2"
7356   [(set_attr "type" "imul")
7357    (set_attr "length_immediate" "0")
7358    (set (attr "athlon_decode")
7359      (if_then_else (eq_attr "cpu" "athlon")
7360         (const_string "vector")
7361         (const_string "double")))
7362    (set_attr "amdfam10_decode" "double")        
7363    (set_attr "mode" "SI")])
7364
7365 (define_expand "mulditi3"
7366   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7367                    (mult:TI (sign_extend:TI
7368                               (match_operand:DI 1 "nonimmediate_operand" ""))
7369                             (sign_extend:TI
7370                               (match_operand:DI 2 "register_operand" ""))))
7371               (clobber (reg:CC FLAGS_REG))])]
7372   "TARGET_64BIT"
7373   "")
7374
7375 (define_insn "*mulditi3_insn"
7376   [(set (match_operand:TI 0 "register_operand" "=A")
7377         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7378                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7379    (clobber (reg:CC FLAGS_REG))]
7380   "TARGET_64BIT
7381    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7382   "imul{q}\t%2"
7383   [(set_attr "type" "imul")
7384    (set_attr "length_immediate" "0")
7385    (set (attr "athlon_decode")
7386      (if_then_else (eq_attr "cpu" "athlon")
7387         (const_string "vector")
7388         (const_string "double")))
7389    (set_attr "amdfam10_decode" "double")
7390    (set_attr "mode" "DI")])
7391
7392 (define_expand "mulsidi3"
7393   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7394                    (mult:DI (sign_extend:DI
7395                               (match_operand:SI 1 "nonimmediate_operand" ""))
7396                             (sign_extend:DI
7397                               (match_operand:SI 2 "register_operand" ""))))
7398               (clobber (reg:CC FLAGS_REG))])]
7399   "!TARGET_64BIT"
7400   "")
7401
7402 (define_insn "*mulsidi3_insn"
7403   [(set (match_operand:DI 0 "register_operand" "=A")
7404         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7405                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7406    (clobber (reg:CC FLAGS_REG))]
7407   "!TARGET_64BIT
7408    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7409   "imul{l}\t%2"
7410   [(set_attr "type" "imul")
7411    (set_attr "length_immediate" "0")
7412    (set (attr "athlon_decode")
7413      (if_then_else (eq_attr "cpu" "athlon")
7414         (const_string "vector")
7415         (const_string "double")))
7416    (set_attr "amdfam10_decode" "double")        
7417    (set_attr "mode" "SI")])
7418
7419 (define_expand "umuldi3_highpart"
7420   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7421                    (truncate:DI
7422                      (lshiftrt:TI
7423                        (mult:TI (zero_extend:TI
7424                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7425                                 (zero_extend:TI
7426                                   (match_operand:DI 2 "register_operand" "")))
7427                        (const_int 64))))
7428               (clobber (match_scratch:DI 3 ""))
7429               (clobber (reg:CC FLAGS_REG))])]
7430   "TARGET_64BIT"
7431   "")
7432
7433 (define_insn "*umuldi3_highpart_rex64"
7434   [(set (match_operand:DI 0 "register_operand" "=d")
7435         (truncate:DI
7436           (lshiftrt:TI
7437             (mult:TI (zero_extend:TI
7438                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7439                      (zero_extend:TI
7440                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7441             (const_int 64))))
7442    (clobber (match_scratch:DI 3 "=1"))
7443    (clobber (reg:CC FLAGS_REG))]
7444   "TARGET_64BIT
7445    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7446   "mul{q}\t%2"
7447   [(set_attr "type" "imul")
7448    (set_attr "length_immediate" "0")
7449    (set (attr "athlon_decode")
7450      (if_then_else (eq_attr "cpu" "athlon")
7451         (const_string "vector")
7452         (const_string "double")))
7453    (set_attr "amdfam10_decode" "double")        
7454    (set_attr "mode" "DI")])
7455
7456 (define_expand "umulsi3_highpart"
7457   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7458                    (truncate:SI
7459                      (lshiftrt:DI
7460                        (mult:DI (zero_extend:DI
7461                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7462                                 (zero_extend:DI
7463                                   (match_operand:SI 2 "register_operand" "")))
7464                        (const_int 32))))
7465               (clobber (match_scratch:SI 3 ""))
7466               (clobber (reg:CC FLAGS_REG))])]
7467   ""
7468   "")
7469
7470 (define_insn "*umulsi3_highpart_insn"
7471   [(set (match_operand:SI 0 "register_operand" "=d")
7472         (truncate:SI
7473           (lshiftrt:DI
7474             (mult:DI (zero_extend:DI
7475                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7476                      (zero_extend:DI
7477                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7478             (const_int 32))))
7479    (clobber (match_scratch:SI 3 "=1"))
7480    (clobber (reg:CC FLAGS_REG))]
7481   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7482   "mul{l}\t%2"
7483   [(set_attr "type" "imul")
7484    (set_attr "length_immediate" "0")
7485    (set (attr "athlon_decode")
7486      (if_then_else (eq_attr "cpu" "athlon")
7487         (const_string "vector")
7488         (const_string "double")))
7489    (set_attr "amdfam10_decode" "double")
7490    (set_attr "mode" "SI")])
7491
7492 (define_insn "*umulsi3_highpart_zext"
7493   [(set (match_operand:DI 0 "register_operand" "=d")
7494         (zero_extend:DI (truncate:SI
7495           (lshiftrt:DI
7496             (mult:DI (zero_extend:DI
7497                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7498                      (zero_extend:DI
7499                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7500             (const_int 32)))))
7501    (clobber (match_scratch:SI 3 "=1"))
7502    (clobber (reg:CC FLAGS_REG))]
7503   "TARGET_64BIT
7504    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7505   "mul{l}\t%2"
7506   [(set_attr "type" "imul")
7507    (set_attr "length_immediate" "0")
7508    (set (attr "athlon_decode")
7509      (if_then_else (eq_attr "cpu" "athlon")
7510         (const_string "vector")
7511         (const_string "double")))
7512    (set_attr "amdfam10_decode" "double")
7513    (set_attr "mode" "SI")])
7514
7515 (define_expand "smuldi3_highpart"
7516   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7517                    (truncate:DI
7518                      (lshiftrt:TI
7519                        (mult:TI (sign_extend:TI
7520                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7521                                 (sign_extend:TI
7522                                   (match_operand:DI 2 "register_operand" "")))
7523                        (const_int 64))))
7524               (clobber (match_scratch:DI 3 ""))
7525               (clobber (reg:CC FLAGS_REG))])]
7526   "TARGET_64BIT"
7527   "")
7528
7529 (define_insn "*smuldi3_highpart_rex64"
7530   [(set (match_operand:DI 0 "register_operand" "=d")
7531         (truncate:DI
7532           (lshiftrt:TI
7533             (mult:TI (sign_extend:TI
7534                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7535                      (sign_extend:TI
7536                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7537             (const_int 64))))
7538    (clobber (match_scratch:DI 3 "=1"))
7539    (clobber (reg:CC FLAGS_REG))]
7540   "TARGET_64BIT
7541    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7542   "imul{q}\t%2"
7543   [(set_attr "type" "imul")
7544    (set (attr "athlon_decode")
7545      (if_then_else (eq_attr "cpu" "athlon")
7546         (const_string "vector")
7547         (const_string "double")))
7548    (set_attr "amdfam10_decode" "double")
7549    (set_attr "mode" "DI")])
7550
7551 (define_expand "smulsi3_highpart"
7552   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7553                    (truncate:SI
7554                      (lshiftrt:DI
7555                        (mult:DI (sign_extend:DI
7556                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7557                                 (sign_extend:DI
7558                                   (match_operand:SI 2 "register_operand" "")))
7559                        (const_int 32))))
7560               (clobber (match_scratch:SI 3 ""))
7561               (clobber (reg:CC FLAGS_REG))])]
7562   ""
7563   "")
7564
7565 (define_insn "*smulsi3_highpart_insn"
7566   [(set (match_operand:SI 0 "register_operand" "=d")
7567         (truncate:SI
7568           (lshiftrt:DI
7569             (mult:DI (sign_extend:DI
7570                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7571                      (sign_extend:DI
7572                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7573             (const_int 32))))
7574    (clobber (match_scratch:SI 3 "=1"))
7575    (clobber (reg:CC FLAGS_REG))]
7576   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7577   "imul{l}\t%2"
7578   [(set_attr "type" "imul")
7579    (set (attr "athlon_decode")
7580      (if_then_else (eq_attr "cpu" "athlon")
7581         (const_string "vector")
7582         (const_string "double")))
7583    (set_attr "amdfam10_decode" "double")
7584    (set_attr "mode" "SI")])
7585
7586 (define_insn "*smulsi3_highpart_zext"
7587   [(set (match_operand:DI 0 "register_operand" "=d")
7588         (zero_extend:DI (truncate:SI
7589           (lshiftrt:DI
7590             (mult:DI (sign_extend:DI
7591                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7592                      (sign_extend:DI
7593                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7594             (const_int 32)))))
7595    (clobber (match_scratch:SI 3 "=1"))
7596    (clobber (reg:CC FLAGS_REG))]
7597   "TARGET_64BIT
7598    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7599   "imul{l}\t%2"
7600   [(set_attr "type" "imul")
7601    (set (attr "athlon_decode")
7602      (if_then_else (eq_attr "cpu" "athlon")
7603         (const_string "vector")
7604         (const_string "double")))
7605    (set_attr "amdfam10_decode" "double")
7606    (set_attr "mode" "SI")])
7607
7608 ;; The patterns that match these are at the end of this file.
7609
7610 (define_expand "mulxf3"
7611   [(set (match_operand:XF 0 "register_operand" "")
7612         (mult:XF (match_operand:XF 1 "register_operand" "")
7613                  (match_operand:XF 2 "register_operand" "")))]
7614   "TARGET_80387"
7615   "")
7616
7617 (define_expand "muldf3"
7618   [(set (match_operand:DF 0 "register_operand" "")
7619         (mult:DF (match_operand:DF 1 "register_operand" "")
7620                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7621   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7622   "")
7623
7624 (define_expand "mulsf3"
7625   [(set (match_operand:SF 0 "register_operand" "")
7626         (mult:SF (match_operand:SF 1 "register_operand" "")
7627                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7628   "TARGET_80387 || TARGET_SSE_MATH"
7629   "")
7630 \f
7631 ;; Divide instructions
7632
7633 (define_insn "divqi3"
7634   [(set (match_operand:QI 0 "register_operand" "=a")
7635         (div:QI (match_operand:HI 1 "register_operand" "0")
7636                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7637    (clobber (reg:CC FLAGS_REG))]
7638   "TARGET_QIMODE_MATH"
7639   "idiv{b}\t%2"
7640   [(set_attr "type" "idiv")
7641    (set_attr "mode" "QI")])
7642
7643 (define_insn "udivqi3"
7644   [(set (match_operand:QI 0 "register_operand" "=a")
7645         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7646                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7647    (clobber (reg:CC FLAGS_REG))]
7648   "TARGET_QIMODE_MATH"
7649   "div{b}\t%2"
7650   [(set_attr "type" "idiv")
7651    (set_attr "mode" "QI")])
7652
7653 ;; The patterns that match these are at the end of this file.
7654
7655 (define_expand "divxf3"
7656   [(set (match_operand:XF 0 "register_operand" "")
7657         (div:XF (match_operand:XF 1 "register_operand" "")
7658                 (match_operand:XF 2 "register_operand" "")))]
7659   "TARGET_80387"
7660   "")
7661
7662 (define_expand "divdf3"
7663   [(set (match_operand:DF 0 "register_operand" "")
7664         (div:DF (match_operand:DF 1 "register_operand" "")
7665                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7666    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7667    "")
7668
7669 (define_expand "divsf3"
7670   [(set (match_operand:SF 0 "register_operand" "")
7671         (div:SF (match_operand:SF 1 "register_operand" "")
7672                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7673   "TARGET_80387 || TARGET_SSE_MATH"
7674 {
7675   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
7676       && flag_finite_math_only && !flag_trapping_math
7677       && flag_unsafe_math_optimizations)
7678     {
7679       ix86_emit_swdivsf (operands[0], operands[1],
7680                          operands[2], SFmode);
7681       DONE;
7682     }
7683 })
7684 \f
7685 ;; Remainder instructions.
7686
7687 (define_expand "divmoddi4"
7688   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7689                    (div:DI (match_operand:DI 1 "register_operand" "")
7690                            (match_operand:DI 2 "nonimmediate_operand" "")))
7691               (set (match_operand:DI 3 "register_operand" "")
7692                    (mod:DI (match_dup 1) (match_dup 2)))
7693               (clobber (reg:CC FLAGS_REG))])]
7694   "TARGET_64BIT"
7695   "")
7696
7697 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7698 ;; Penalize eax case slightly because it results in worse scheduling
7699 ;; of code.
7700 (define_insn "*divmoddi4_nocltd_rex64"
7701   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7702         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7703                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7704    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7705         (mod:DI (match_dup 2) (match_dup 3)))
7706    (clobber (reg:CC FLAGS_REG))]
7707   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7708   "#"
7709   [(set_attr "type" "multi")])
7710
7711 (define_insn "*divmoddi4_cltd_rex64"
7712   [(set (match_operand:DI 0 "register_operand" "=a")
7713         (div:DI (match_operand:DI 2 "register_operand" "a")
7714                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7715    (set (match_operand:DI 1 "register_operand" "=&d")
7716         (mod:DI (match_dup 2) (match_dup 3)))
7717    (clobber (reg:CC FLAGS_REG))]
7718   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7719   "#"
7720   [(set_attr "type" "multi")])
7721
7722 (define_insn "*divmoddi_noext_rex64"
7723   [(set (match_operand:DI 0 "register_operand" "=a")
7724         (div:DI (match_operand:DI 1 "register_operand" "0")
7725                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7726    (set (match_operand:DI 3 "register_operand" "=d")
7727         (mod:DI (match_dup 1) (match_dup 2)))
7728    (use (match_operand:DI 4 "register_operand" "3"))
7729    (clobber (reg:CC FLAGS_REG))]
7730   "TARGET_64BIT"
7731   "idiv{q}\t%2"
7732   [(set_attr "type" "idiv")
7733    (set_attr "mode" "DI")])
7734
7735 (define_split
7736   [(set (match_operand:DI 0 "register_operand" "")
7737         (div:DI (match_operand:DI 1 "register_operand" "")
7738                 (match_operand:DI 2 "nonimmediate_operand" "")))
7739    (set (match_operand:DI 3 "register_operand" "")
7740         (mod:DI (match_dup 1) (match_dup 2)))
7741    (clobber (reg:CC FLAGS_REG))]
7742   "TARGET_64BIT && reload_completed"
7743   [(parallel [(set (match_dup 3)
7744                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7745               (clobber (reg:CC FLAGS_REG))])
7746    (parallel [(set (match_dup 0)
7747                    (div:DI (reg:DI 0) (match_dup 2)))
7748               (set (match_dup 3)
7749                    (mod:DI (reg:DI 0) (match_dup 2)))
7750               (use (match_dup 3))
7751               (clobber (reg:CC FLAGS_REG))])]
7752 {
7753   /* Avoid use of cltd in favor of a mov+shift.  */
7754   if (!TARGET_USE_CLTD && !optimize_size)
7755     {
7756       if (true_regnum (operands[1]))
7757         emit_move_insn (operands[0], operands[1]);
7758       else
7759         emit_move_insn (operands[3], operands[1]);
7760       operands[4] = operands[3];
7761     }
7762   else
7763     {
7764       gcc_assert (!true_regnum (operands[1]));
7765       operands[4] = operands[1];
7766     }
7767 })
7768
7769
7770 (define_expand "divmodsi4"
7771   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7772                    (div:SI (match_operand:SI 1 "register_operand" "")
7773                            (match_operand:SI 2 "nonimmediate_operand" "")))
7774               (set (match_operand:SI 3 "register_operand" "")
7775                    (mod:SI (match_dup 1) (match_dup 2)))
7776               (clobber (reg:CC FLAGS_REG))])]
7777   ""
7778   "")
7779
7780 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7781 ;; Penalize eax case slightly because it results in worse scheduling
7782 ;; of code.
7783 (define_insn "*divmodsi4_nocltd"
7784   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7785         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7786                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7787    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7788         (mod:SI (match_dup 2) (match_dup 3)))
7789    (clobber (reg:CC FLAGS_REG))]
7790   "!optimize_size && !TARGET_USE_CLTD"
7791   "#"
7792   [(set_attr "type" "multi")])
7793
7794 (define_insn "*divmodsi4_cltd"
7795   [(set (match_operand:SI 0 "register_operand" "=a")
7796         (div:SI (match_operand:SI 2 "register_operand" "a")
7797                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7798    (set (match_operand:SI 1 "register_operand" "=&d")
7799         (mod:SI (match_dup 2) (match_dup 3)))
7800    (clobber (reg:CC FLAGS_REG))]
7801   "optimize_size || TARGET_USE_CLTD"
7802   "#"
7803   [(set_attr "type" "multi")])
7804
7805 (define_insn "*divmodsi_noext"
7806   [(set (match_operand:SI 0 "register_operand" "=a")
7807         (div:SI (match_operand:SI 1 "register_operand" "0")
7808                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7809    (set (match_operand:SI 3 "register_operand" "=d")
7810         (mod:SI (match_dup 1) (match_dup 2)))
7811    (use (match_operand:SI 4 "register_operand" "3"))
7812    (clobber (reg:CC FLAGS_REG))]
7813   ""
7814   "idiv{l}\t%2"
7815   [(set_attr "type" "idiv")
7816    (set_attr "mode" "SI")])
7817
7818 (define_split
7819   [(set (match_operand:SI 0 "register_operand" "")
7820         (div:SI (match_operand:SI 1 "register_operand" "")
7821                 (match_operand:SI 2 "nonimmediate_operand" "")))
7822    (set (match_operand:SI 3 "register_operand" "")
7823         (mod:SI (match_dup 1) (match_dup 2)))
7824    (clobber (reg:CC FLAGS_REG))]
7825   "reload_completed"
7826   [(parallel [(set (match_dup 3)
7827                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7828               (clobber (reg:CC FLAGS_REG))])
7829    (parallel [(set (match_dup 0)
7830                    (div:SI (reg:SI 0) (match_dup 2)))
7831               (set (match_dup 3)
7832                    (mod:SI (reg:SI 0) (match_dup 2)))
7833               (use (match_dup 3))
7834               (clobber (reg:CC FLAGS_REG))])]
7835 {
7836   /* Avoid use of cltd in favor of a mov+shift.  */
7837   if (!TARGET_USE_CLTD && !optimize_size)
7838     {
7839       if (true_regnum (operands[1]))
7840         emit_move_insn (operands[0], operands[1]);
7841       else
7842         emit_move_insn (operands[3], operands[1]);
7843       operands[4] = operands[3];
7844     }
7845   else
7846     {
7847       gcc_assert (!true_regnum (operands[1]));
7848       operands[4] = operands[1];
7849     }
7850 })
7851 ;; %%% Split me.
7852 (define_insn "divmodhi4"
7853   [(set (match_operand:HI 0 "register_operand" "=a")
7854         (div:HI (match_operand:HI 1 "register_operand" "0")
7855                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7856    (set (match_operand:HI 3 "register_operand" "=&d")
7857         (mod:HI (match_dup 1) (match_dup 2)))
7858    (clobber (reg:CC FLAGS_REG))]
7859   "TARGET_HIMODE_MATH"
7860   "cwtd\;idiv{w}\t%2"
7861   [(set_attr "type" "multi")
7862    (set_attr "length_immediate" "0")
7863    (set_attr "mode" "SI")])
7864
7865 (define_insn "udivmoddi4"
7866   [(set (match_operand:DI 0 "register_operand" "=a")
7867         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7868                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7869    (set (match_operand:DI 3 "register_operand" "=&d")
7870         (umod:DI (match_dup 1) (match_dup 2)))
7871    (clobber (reg:CC FLAGS_REG))]
7872   "TARGET_64BIT"
7873   "xor{q}\t%3, %3\;div{q}\t%2"
7874   [(set_attr "type" "multi")
7875    (set_attr "length_immediate" "0")
7876    (set_attr "mode" "DI")])
7877
7878 (define_insn "*udivmoddi4_noext"
7879   [(set (match_operand:DI 0 "register_operand" "=a")
7880         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7881                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7882    (set (match_operand:DI 3 "register_operand" "=d")
7883         (umod:DI (match_dup 1) (match_dup 2)))
7884    (use (match_dup 3))
7885    (clobber (reg:CC FLAGS_REG))]
7886   "TARGET_64BIT"
7887   "div{q}\t%2"
7888   [(set_attr "type" "idiv")
7889    (set_attr "mode" "DI")])
7890
7891 (define_split
7892   [(set (match_operand:DI 0 "register_operand" "")
7893         (udiv:DI (match_operand:DI 1 "register_operand" "")
7894                  (match_operand:DI 2 "nonimmediate_operand" "")))
7895    (set (match_operand:DI 3 "register_operand" "")
7896         (umod:DI (match_dup 1) (match_dup 2)))
7897    (clobber (reg:CC FLAGS_REG))]
7898   "TARGET_64BIT && reload_completed"
7899   [(set (match_dup 3) (const_int 0))
7900    (parallel [(set (match_dup 0)
7901                    (udiv:DI (match_dup 1) (match_dup 2)))
7902               (set (match_dup 3)
7903                    (umod:DI (match_dup 1) (match_dup 2)))
7904               (use (match_dup 3))
7905               (clobber (reg:CC FLAGS_REG))])]
7906   "")
7907
7908 (define_insn "udivmodsi4"
7909   [(set (match_operand:SI 0 "register_operand" "=a")
7910         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7911                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7912    (set (match_operand:SI 3 "register_operand" "=&d")
7913         (umod:SI (match_dup 1) (match_dup 2)))
7914    (clobber (reg:CC FLAGS_REG))]
7915   ""
7916   "xor{l}\t%3, %3\;div{l}\t%2"
7917   [(set_attr "type" "multi")
7918    (set_attr "length_immediate" "0")
7919    (set_attr "mode" "SI")])
7920
7921 (define_insn "*udivmodsi4_noext"
7922   [(set (match_operand:SI 0 "register_operand" "=a")
7923         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7924                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7925    (set (match_operand:SI 3 "register_operand" "=d")
7926         (umod:SI (match_dup 1) (match_dup 2)))
7927    (use (match_dup 3))
7928    (clobber (reg:CC FLAGS_REG))]
7929   ""
7930   "div{l}\t%2"
7931   [(set_attr "type" "idiv")
7932    (set_attr "mode" "SI")])
7933
7934 (define_split
7935   [(set (match_operand:SI 0 "register_operand" "")
7936         (udiv:SI (match_operand:SI 1 "register_operand" "")
7937                  (match_operand:SI 2 "nonimmediate_operand" "")))
7938    (set (match_operand:SI 3 "register_operand" "")
7939         (umod:SI (match_dup 1) (match_dup 2)))
7940    (clobber (reg:CC FLAGS_REG))]
7941   "reload_completed"
7942   [(set (match_dup 3) (const_int 0))
7943    (parallel [(set (match_dup 0)
7944                    (udiv:SI (match_dup 1) (match_dup 2)))
7945               (set (match_dup 3)
7946                    (umod:SI (match_dup 1) (match_dup 2)))
7947               (use (match_dup 3))
7948               (clobber (reg:CC FLAGS_REG))])]
7949   "")
7950
7951 (define_expand "udivmodhi4"
7952   [(set (match_dup 4) (const_int 0))
7953    (parallel [(set (match_operand:HI 0 "register_operand" "")
7954                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7955                             (match_operand:HI 2 "nonimmediate_operand" "")))
7956               (set (match_operand:HI 3 "register_operand" "")
7957                    (umod:HI (match_dup 1) (match_dup 2)))
7958               (use (match_dup 4))
7959               (clobber (reg:CC FLAGS_REG))])]
7960   "TARGET_HIMODE_MATH"
7961   "operands[4] = gen_reg_rtx (HImode);")
7962
7963 (define_insn "*udivmodhi_noext"
7964   [(set (match_operand:HI 0 "register_operand" "=a")
7965         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7966                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7967    (set (match_operand:HI 3 "register_operand" "=d")
7968         (umod:HI (match_dup 1) (match_dup 2)))
7969    (use (match_operand:HI 4 "register_operand" "3"))
7970    (clobber (reg:CC FLAGS_REG))]
7971   ""
7972   "div{w}\t%2"
7973   [(set_attr "type" "idiv")
7974    (set_attr "mode" "HI")])
7975
7976 ;; We cannot use div/idiv for double division, because it causes
7977 ;; "division by zero" on the overflow and that's not what we expect
7978 ;; from truncate.  Because true (non truncating) double division is
7979 ;; never generated, we can't create this insn anyway.
7980 ;
7981 ;(define_insn ""
7982 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7983 ;       (truncate:SI
7984 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7985 ;                  (zero_extend:DI
7986 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7987 ;   (set (match_operand:SI 3 "register_operand" "=d")
7988 ;       (truncate:SI
7989 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7990 ;   (clobber (reg:CC FLAGS_REG))]
7991 ;  ""
7992 ;  "div{l}\t{%2, %0|%0, %2}"
7993 ;  [(set_attr "type" "idiv")])
7994 \f
7995 ;;- Logical AND instructions
7996
7997 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7998 ;; Note that this excludes ah.
7999
8000 (define_insn "*testdi_1_rex64"
8001   [(set (reg FLAGS_REG)
8002         (compare
8003           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8004                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8005           (const_int 0)))]
8006   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8007    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8008   "@
8009    test{l}\t{%k1, %k0|%k0, %k1}
8010    test{l}\t{%k1, %k0|%k0, %k1}
8011    test{q}\t{%1, %0|%0, %1}
8012    test{q}\t{%1, %0|%0, %1}
8013    test{q}\t{%1, %0|%0, %1}"
8014   [(set_attr "type" "test")
8015    (set_attr "modrm" "0,1,0,1,1")
8016    (set_attr "mode" "SI,SI,DI,DI,DI")
8017    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8018
8019 (define_insn "testsi_1"
8020   [(set (reg FLAGS_REG)
8021         (compare
8022           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8023                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8024           (const_int 0)))]
8025   "ix86_match_ccmode (insn, CCNOmode)
8026    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8027   "test{l}\t{%1, %0|%0, %1}"
8028   [(set_attr "type" "test")
8029    (set_attr "modrm" "0,1,1")
8030    (set_attr "mode" "SI")
8031    (set_attr "pent_pair" "uv,np,uv")])
8032
8033 (define_expand "testsi_ccno_1"
8034   [(set (reg:CCNO FLAGS_REG)
8035         (compare:CCNO
8036           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8037                   (match_operand:SI 1 "nonmemory_operand" ""))
8038           (const_int 0)))]
8039   ""
8040   "")
8041
8042 (define_insn "*testhi_1"
8043   [(set (reg FLAGS_REG)
8044         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8045                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8046                  (const_int 0)))]
8047   "ix86_match_ccmode (insn, CCNOmode)
8048    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8049   "test{w}\t{%1, %0|%0, %1}"
8050   [(set_attr "type" "test")
8051    (set_attr "modrm" "0,1,1")
8052    (set_attr "mode" "HI")
8053    (set_attr "pent_pair" "uv,np,uv")])
8054
8055 (define_expand "testqi_ccz_1"
8056   [(set (reg:CCZ FLAGS_REG)
8057         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8058                              (match_operand:QI 1 "nonmemory_operand" ""))
8059                  (const_int 0)))]
8060   ""
8061   "")
8062
8063 (define_insn "*testqi_1_maybe_si"
8064   [(set (reg FLAGS_REG)
8065         (compare
8066           (and:QI
8067             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8068             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8069           (const_int 0)))]
8070    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8071     && ix86_match_ccmode (insn,
8072                          CONST_INT_P (operands[1])
8073                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8074 {
8075   if (which_alternative == 3)
8076     {
8077       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8078         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8079       return "test{l}\t{%1, %k0|%k0, %1}";
8080     }
8081   return "test{b}\t{%1, %0|%0, %1}";
8082 }
8083   [(set_attr "type" "test")
8084    (set_attr "modrm" "0,1,1,1")
8085    (set_attr "mode" "QI,QI,QI,SI")
8086    (set_attr "pent_pair" "uv,np,uv,np")])
8087
8088 (define_insn "*testqi_1"
8089   [(set (reg FLAGS_REG)
8090         (compare
8091           (and:QI
8092             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8093             (match_operand:QI 1 "general_operand" "n,n,qn"))
8094           (const_int 0)))]
8095   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8096    && ix86_match_ccmode (insn, CCNOmode)"
8097   "test{b}\t{%1, %0|%0, %1}"
8098   [(set_attr "type" "test")
8099    (set_attr "modrm" "0,1,1")
8100    (set_attr "mode" "QI")
8101    (set_attr "pent_pair" "uv,np,uv")])
8102
8103 (define_expand "testqi_ext_ccno_0"
8104   [(set (reg:CCNO FLAGS_REG)
8105         (compare:CCNO
8106           (and:SI
8107             (zero_extract:SI
8108               (match_operand 0 "ext_register_operand" "")
8109               (const_int 8)
8110               (const_int 8))
8111             (match_operand 1 "const_int_operand" ""))
8112           (const_int 0)))]
8113   ""
8114   "")
8115
8116 (define_insn "*testqi_ext_0"
8117   [(set (reg FLAGS_REG)
8118         (compare
8119           (and:SI
8120             (zero_extract:SI
8121               (match_operand 0 "ext_register_operand" "Q")
8122               (const_int 8)
8123               (const_int 8))
8124             (match_operand 1 "const_int_operand" "n"))
8125           (const_int 0)))]
8126   "ix86_match_ccmode (insn, CCNOmode)"
8127   "test{b}\t{%1, %h0|%h0, %1}"
8128   [(set_attr "type" "test")
8129    (set_attr "mode" "QI")
8130    (set_attr "length_immediate" "1")
8131    (set_attr "pent_pair" "np")])
8132
8133 (define_insn "*testqi_ext_1"
8134   [(set (reg FLAGS_REG)
8135         (compare
8136           (and:SI
8137             (zero_extract:SI
8138               (match_operand 0 "ext_register_operand" "Q")
8139               (const_int 8)
8140               (const_int 8))
8141             (zero_extend:SI
8142               (match_operand:QI 1 "general_operand" "Qm")))
8143           (const_int 0)))]
8144   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8145    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8146   "test{b}\t{%1, %h0|%h0, %1}"
8147   [(set_attr "type" "test")
8148    (set_attr "mode" "QI")])
8149
8150 (define_insn "*testqi_ext_1_rex64"
8151   [(set (reg FLAGS_REG)
8152         (compare
8153           (and:SI
8154             (zero_extract:SI
8155               (match_operand 0 "ext_register_operand" "Q")
8156               (const_int 8)
8157               (const_int 8))
8158             (zero_extend:SI
8159               (match_operand:QI 1 "register_operand" "Q")))
8160           (const_int 0)))]
8161   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8162   "test{b}\t{%1, %h0|%h0, %1}"
8163   [(set_attr "type" "test")
8164    (set_attr "mode" "QI")])
8165
8166 (define_insn "*testqi_ext_2"
8167   [(set (reg FLAGS_REG)
8168         (compare
8169           (and:SI
8170             (zero_extract:SI
8171               (match_operand 0 "ext_register_operand" "Q")
8172               (const_int 8)
8173               (const_int 8))
8174             (zero_extract:SI
8175               (match_operand 1 "ext_register_operand" "Q")
8176               (const_int 8)
8177               (const_int 8)))
8178           (const_int 0)))]
8179   "ix86_match_ccmode (insn, CCNOmode)"
8180   "test{b}\t{%h1, %h0|%h0, %h1}"
8181   [(set_attr "type" "test")
8182    (set_attr "mode" "QI")])
8183
8184 ;; Combine likes to form bit extractions for some tests.  Humor it.
8185 (define_insn "*testqi_ext_3"
8186   [(set (reg FLAGS_REG)
8187         (compare (zero_extract:SI
8188                    (match_operand 0 "nonimmediate_operand" "rm")
8189                    (match_operand:SI 1 "const_int_operand" "")
8190                    (match_operand:SI 2 "const_int_operand" ""))
8191                  (const_int 0)))]
8192   "ix86_match_ccmode (insn, CCNOmode)
8193    && INTVAL (operands[1]) > 0
8194    && INTVAL (operands[2]) >= 0
8195    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8196    && (GET_MODE (operands[0]) == SImode
8197        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8198        || GET_MODE (operands[0]) == HImode
8199        || GET_MODE (operands[0]) == QImode)"
8200   "#")
8201
8202 (define_insn "*testqi_ext_3_rex64"
8203   [(set (reg FLAGS_REG)
8204         (compare (zero_extract:DI
8205                    (match_operand 0 "nonimmediate_operand" "rm")
8206                    (match_operand:DI 1 "const_int_operand" "")
8207                    (match_operand:DI 2 "const_int_operand" ""))
8208                  (const_int 0)))]
8209   "TARGET_64BIT
8210    && ix86_match_ccmode (insn, CCNOmode)
8211    && INTVAL (operands[1]) > 0
8212    && INTVAL (operands[2]) >= 0
8213    /* Ensure that resulting mask is zero or sign extended operand.  */
8214    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8215        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8216            && INTVAL (operands[1]) > 32))
8217    && (GET_MODE (operands[0]) == SImode
8218        || GET_MODE (operands[0]) == DImode
8219        || GET_MODE (operands[0]) == HImode
8220        || GET_MODE (operands[0]) == QImode)"
8221   "#")
8222
8223 (define_split
8224   [(set (match_operand 0 "flags_reg_operand" "")
8225         (match_operator 1 "compare_operator"
8226           [(zero_extract
8227              (match_operand 2 "nonimmediate_operand" "")
8228              (match_operand 3 "const_int_operand" "")
8229              (match_operand 4 "const_int_operand" ""))
8230            (const_int 0)]))]
8231   "ix86_match_ccmode (insn, CCNOmode)"
8232   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8233 {
8234   rtx val = operands[2];
8235   HOST_WIDE_INT len = INTVAL (operands[3]);
8236   HOST_WIDE_INT pos = INTVAL (operands[4]);
8237   HOST_WIDE_INT mask;
8238   enum machine_mode mode, submode;
8239
8240   mode = GET_MODE (val);
8241   if (MEM_P (val))
8242     {
8243       /* ??? Combine likes to put non-volatile mem extractions in QImode
8244          no matter the size of the test.  So find a mode that works.  */
8245       if (! MEM_VOLATILE_P (val))
8246         {
8247           mode = smallest_mode_for_size (pos + len, MODE_INT);
8248           val = adjust_address (val, mode, 0);
8249         }
8250     }
8251   else if (GET_CODE (val) == SUBREG
8252            && (submode = GET_MODE (SUBREG_REG (val)),
8253                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8254            && pos + len <= GET_MODE_BITSIZE (submode))
8255     {
8256       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8257       mode = submode;
8258       val = SUBREG_REG (val);
8259     }
8260   else if (mode == HImode && pos + len <= 8)
8261     {
8262       /* Small HImode tests can be converted to QImode.  */
8263       mode = QImode;
8264       val = gen_lowpart (QImode, val);
8265     }
8266
8267   if (len == HOST_BITS_PER_WIDE_INT)
8268     mask = -1;
8269   else
8270     mask = ((HOST_WIDE_INT)1 << len) - 1;
8271   mask <<= pos;
8272
8273   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8274 })
8275
8276 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8277 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8278 ;; this is relatively important trick.
8279 ;; Do the conversion only post-reload to avoid limiting of the register class
8280 ;; to QI regs.
8281 (define_split
8282   [(set (match_operand 0 "flags_reg_operand" "")
8283         (match_operator 1 "compare_operator"
8284           [(and (match_operand 2 "register_operand" "")
8285                 (match_operand 3 "const_int_operand" ""))
8286            (const_int 0)]))]
8287    "reload_completed
8288     && QI_REG_P (operands[2])
8289     && GET_MODE (operands[2]) != QImode
8290     && ((ix86_match_ccmode (insn, CCZmode)
8291          && !(INTVAL (operands[3]) & ~(255 << 8)))
8292         || (ix86_match_ccmode (insn, CCNOmode)
8293             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8294   [(set (match_dup 0)
8295         (match_op_dup 1
8296           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8297                    (match_dup 3))
8298            (const_int 0)]))]
8299   "operands[2] = gen_lowpart (SImode, operands[2]);
8300    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8301
8302 (define_split
8303   [(set (match_operand 0 "flags_reg_operand" "")
8304         (match_operator 1 "compare_operator"
8305           [(and (match_operand 2 "nonimmediate_operand" "")
8306                 (match_operand 3 "const_int_operand" ""))
8307            (const_int 0)]))]
8308    "reload_completed
8309     && GET_MODE (operands[2]) != QImode
8310     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8311     && ((ix86_match_ccmode (insn, CCZmode)
8312          && !(INTVAL (operands[3]) & ~255))
8313         || (ix86_match_ccmode (insn, CCNOmode)
8314             && !(INTVAL (operands[3]) & ~127)))"
8315   [(set (match_dup 0)
8316         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8317                          (const_int 0)]))]
8318   "operands[2] = gen_lowpart (QImode, operands[2]);
8319    operands[3] = gen_lowpart (QImode, operands[3]);")
8320
8321
8322 ;; %%% This used to optimize known byte-wide and operations to memory,
8323 ;; and sometimes to QImode registers.  If this is considered useful,
8324 ;; it should be done with splitters.
8325
8326 (define_expand "anddi3"
8327   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8328         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8329                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8330    (clobber (reg:CC FLAGS_REG))]
8331   "TARGET_64BIT"
8332   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8333
8334 (define_insn "*anddi_1_rex64"
8335   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8336         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8337                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8338    (clobber (reg:CC FLAGS_REG))]
8339   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8340 {
8341   switch (get_attr_type (insn))
8342     {
8343     case TYPE_IMOVX:
8344       {
8345         enum machine_mode mode;
8346
8347         gcc_assert (CONST_INT_P (operands[2]));
8348         if (INTVAL (operands[2]) == 0xff)
8349           mode = QImode;
8350         else
8351           {
8352             gcc_assert (INTVAL (operands[2]) == 0xffff);
8353             mode = HImode;
8354           }
8355
8356         operands[1] = gen_lowpart (mode, operands[1]);
8357         if (mode == QImode)
8358           return "movz{bq|x}\t{%1,%0|%0, %1}";
8359         else
8360           return "movz{wq|x}\t{%1,%0|%0, %1}";
8361       }
8362
8363     default:
8364       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8365       if (get_attr_mode (insn) == MODE_SI)
8366         return "and{l}\t{%k2, %k0|%k0, %k2}";
8367       else
8368         return "and{q}\t{%2, %0|%0, %2}";
8369     }
8370 }
8371   [(set_attr "type" "alu,alu,alu,imovx")
8372    (set_attr "length_immediate" "*,*,*,0")
8373    (set_attr "mode" "SI,DI,DI,DI")])
8374
8375 (define_insn "*anddi_2"
8376   [(set (reg FLAGS_REG)
8377         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8378                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8379                  (const_int 0)))
8380    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8381         (and:DI (match_dup 1) (match_dup 2)))]
8382   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8383    && ix86_binary_operator_ok (AND, DImode, operands)"
8384   "@
8385    and{l}\t{%k2, %k0|%k0, %k2}
8386    and{q}\t{%2, %0|%0, %2}
8387    and{q}\t{%2, %0|%0, %2}"
8388   [(set_attr "type" "alu")
8389    (set_attr "mode" "SI,DI,DI")])
8390
8391 (define_expand "andsi3"
8392   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8393         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8394                 (match_operand:SI 2 "general_operand" "")))
8395    (clobber (reg:CC FLAGS_REG))]
8396   ""
8397   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8398
8399 (define_insn "*andsi_1"
8400   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8401         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8402                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8403    (clobber (reg:CC FLAGS_REG))]
8404   "ix86_binary_operator_ok (AND, SImode, operands)"
8405 {
8406   switch (get_attr_type (insn))
8407     {
8408     case TYPE_IMOVX:
8409       {
8410         enum machine_mode mode;
8411
8412         gcc_assert (CONST_INT_P (operands[2]));
8413         if (INTVAL (operands[2]) == 0xff)
8414           mode = QImode;
8415         else
8416           {
8417             gcc_assert (INTVAL (operands[2]) == 0xffff);
8418             mode = HImode;
8419           }
8420
8421         operands[1] = gen_lowpart (mode, operands[1]);
8422         if (mode == QImode)
8423           return "movz{bl|x}\t{%1,%0|%0, %1}";
8424         else
8425           return "movz{wl|x}\t{%1,%0|%0, %1}";
8426       }
8427
8428     default:
8429       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8430       return "and{l}\t{%2, %0|%0, %2}";
8431     }
8432 }
8433   [(set_attr "type" "alu,alu,imovx")
8434    (set_attr "length_immediate" "*,*,0")
8435    (set_attr "mode" "SI")])
8436
8437 (define_split
8438   [(set (match_operand 0 "register_operand" "")
8439         (and (match_dup 0)
8440              (const_int -65536)))
8441    (clobber (reg:CC FLAGS_REG))]
8442   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8443   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8444   "operands[1] = gen_lowpart (HImode, operands[0]);")
8445
8446 (define_split
8447   [(set (match_operand 0 "ext_register_operand" "")
8448         (and (match_dup 0)
8449              (const_int -256)))
8450    (clobber (reg:CC FLAGS_REG))]
8451   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8452   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8453   "operands[1] = gen_lowpart (QImode, operands[0]);")
8454
8455 (define_split
8456   [(set (match_operand 0 "ext_register_operand" "")
8457         (and (match_dup 0)
8458              (const_int -65281)))
8459    (clobber (reg:CC FLAGS_REG))]
8460   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8461   [(parallel [(set (zero_extract:SI (match_dup 0)
8462                                     (const_int 8)
8463                                     (const_int 8))
8464                    (xor:SI
8465                      (zero_extract:SI (match_dup 0)
8466                                       (const_int 8)
8467                                       (const_int 8))
8468                      (zero_extract:SI (match_dup 0)
8469                                       (const_int 8)
8470                                       (const_int 8))))
8471               (clobber (reg:CC FLAGS_REG))])]
8472   "operands[0] = gen_lowpart (SImode, operands[0]);")
8473
8474 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8475 (define_insn "*andsi_1_zext"
8476   [(set (match_operand:DI 0 "register_operand" "=r")
8477         (zero_extend:DI
8478           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8479                   (match_operand:SI 2 "general_operand" "g"))))
8480    (clobber (reg:CC FLAGS_REG))]
8481   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8482   "and{l}\t{%2, %k0|%k0, %2}"
8483   [(set_attr "type" "alu")
8484    (set_attr "mode" "SI")])
8485
8486 (define_insn "*andsi_2"
8487   [(set (reg FLAGS_REG)
8488         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8489                          (match_operand:SI 2 "general_operand" "g,ri"))
8490                  (const_int 0)))
8491    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8492         (and:SI (match_dup 1) (match_dup 2)))]
8493   "ix86_match_ccmode (insn, CCNOmode)
8494    && ix86_binary_operator_ok (AND, SImode, operands)"
8495   "and{l}\t{%2, %0|%0, %2}"
8496   [(set_attr "type" "alu")
8497    (set_attr "mode" "SI")])
8498
8499 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8500 (define_insn "*andsi_2_zext"
8501   [(set (reg FLAGS_REG)
8502         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8503                          (match_operand:SI 2 "general_operand" "g"))
8504                  (const_int 0)))
8505    (set (match_operand:DI 0 "register_operand" "=r")
8506         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8507   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8508    && ix86_binary_operator_ok (AND, SImode, operands)"
8509   "and{l}\t{%2, %k0|%k0, %2}"
8510   [(set_attr "type" "alu")
8511    (set_attr "mode" "SI")])
8512
8513 (define_expand "andhi3"
8514   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8515         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8516                 (match_operand:HI 2 "general_operand" "")))
8517    (clobber (reg:CC FLAGS_REG))]
8518   "TARGET_HIMODE_MATH"
8519   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8520
8521 (define_insn "*andhi_1"
8522   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8523         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8524                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8525    (clobber (reg:CC FLAGS_REG))]
8526   "ix86_binary_operator_ok (AND, HImode, operands)"
8527 {
8528   switch (get_attr_type (insn))
8529     {
8530     case TYPE_IMOVX:
8531       gcc_assert (CONST_INT_P (operands[2]));
8532       gcc_assert (INTVAL (operands[2]) == 0xff);
8533       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8534
8535     default:
8536       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8537
8538       return "and{w}\t{%2, %0|%0, %2}";
8539     }
8540 }
8541   [(set_attr "type" "alu,alu,imovx")
8542    (set_attr "length_immediate" "*,*,0")
8543    (set_attr "mode" "HI,HI,SI")])
8544
8545 (define_insn "*andhi_2"
8546   [(set (reg FLAGS_REG)
8547         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8548                          (match_operand:HI 2 "general_operand" "g,ri"))
8549                  (const_int 0)))
8550    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8551         (and:HI (match_dup 1) (match_dup 2)))]
8552   "ix86_match_ccmode (insn, CCNOmode)
8553    && ix86_binary_operator_ok (AND, HImode, operands)"
8554   "and{w}\t{%2, %0|%0, %2}"
8555   [(set_attr "type" "alu")
8556    (set_attr "mode" "HI")])
8557
8558 (define_expand "andqi3"
8559   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8560         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8561                 (match_operand:QI 2 "general_operand" "")))
8562    (clobber (reg:CC FLAGS_REG))]
8563   "TARGET_QIMODE_MATH"
8564   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8565
8566 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8567 (define_insn "*andqi_1"
8568   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8569         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8570                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8571    (clobber (reg:CC FLAGS_REG))]
8572   "ix86_binary_operator_ok (AND, QImode, operands)"
8573   "@
8574    and{b}\t{%2, %0|%0, %2}
8575    and{b}\t{%2, %0|%0, %2}
8576    and{l}\t{%k2, %k0|%k0, %k2}"
8577   [(set_attr "type" "alu")
8578    (set_attr "mode" "QI,QI,SI")])
8579
8580 (define_insn "*andqi_1_slp"
8581   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8582         (and:QI (match_dup 0)
8583                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8584    (clobber (reg:CC FLAGS_REG))]
8585   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8586    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8587   "and{b}\t{%1, %0|%0, %1}"
8588   [(set_attr "type" "alu1")
8589    (set_attr "mode" "QI")])
8590
8591 (define_insn "*andqi_2_maybe_si"
8592   [(set (reg FLAGS_REG)
8593         (compare (and:QI
8594                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8595                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8596                  (const_int 0)))
8597    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8598         (and:QI (match_dup 1) (match_dup 2)))]
8599   "ix86_binary_operator_ok (AND, QImode, operands)
8600    && ix86_match_ccmode (insn,
8601                          CONST_INT_P (operands[2])
8602                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8603 {
8604   if (which_alternative == 2)
8605     {
8606       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8607         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8608       return "and{l}\t{%2, %k0|%k0, %2}";
8609     }
8610   return "and{b}\t{%2, %0|%0, %2}";
8611 }
8612   [(set_attr "type" "alu")
8613    (set_attr "mode" "QI,QI,SI")])
8614
8615 (define_insn "*andqi_2"
8616   [(set (reg FLAGS_REG)
8617         (compare (and:QI
8618                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8619                    (match_operand:QI 2 "general_operand" "qim,qi"))
8620                  (const_int 0)))
8621    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8622         (and:QI (match_dup 1) (match_dup 2)))]
8623   "ix86_match_ccmode (insn, CCNOmode)
8624    && ix86_binary_operator_ok (AND, QImode, operands)"
8625   "and{b}\t{%2, %0|%0, %2}"
8626   [(set_attr "type" "alu")
8627    (set_attr "mode" "QI")])
8628
8629 (define_insn "*andqi_2_slp"
8630   [(set (reg FLAGS_REG)
8631         (compare (and:QI
8632                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8633                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8634                  (const_int 0)))
8635    (set (strict_low_part (match_dup 0))
8636         (and:QI (match_dup 0) (match_dup 1)))]
8637   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8638    && ix86_match_ccmode (insn, CCNOmode)
8639    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8640   "and{b}\t{%1, %0|%0, %1}"
8641   [(set_attr "type" "alu1")
8642    (set_attr "mode" "QI")])
8643
8644 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8645 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8646 ;; for a QImode operand, which of course failed.
8647
8648 (define_insn "andqi_ext_0"
8649   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8650                          (const_int 8)
8651                          (const_int 8))
8652         (and:SI
8653           (zero_extract:SI
8654             (match_operand 1 "ext_register_operand" "0")
8655             (const_int 8)
8656             (const_int 8))
8657           (match_operand 2 "const_int_operand" "n")))
8658    (clobber (reg:CC FLAGS_REG))]
8659   ""
8660   "and{b}\t{%2, %h0|%h0, %2}"
8661   [(set_attr "type" "alu")
8662    (set_attr "length_immediate" "1")
8663    (set_attr "mode" "QI")])
8664
8665 ;; Generated by peephole translating test to and.  This shows up
8666 ;; often in fp comparisons.
8667
8668 (define_insn "*andqi_ext_0_cc"
8669   [(set (reg FLAGS_REG)
8670         (compare
8671           (and:SI
8672             (zero_extract:SI
8673               (match_operand 1 "ext_register_operand" "0")
8674               (const_int 8)
8675               (const_int 8))
8676             (match_operand 2 "const_int_operand" "n"))
8677           (const_int 0)))
8678    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8679                          (const_int 8)
8680                          (const_int 8))
8681         (and:SI
8682           (zero_extract:SI
8683             (match_dup 1)
8684             (const_int 8)
8685             (const_int 8))
8686           (match_dup 2)))]
8687   "ix86_match_ccmode (insn, CCNOmode)"
8688   "and{b}\t{%2, %h0|%h0, %2}"
8689   [(set_attr "type" "alu")
8690    (set_attr "length_immediate" "1")
8691    (set_attr "mode" "QI")])
8692
8693 (define_insn "*andqi_ext_1"
8694   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8695                          (const_int 8)
8696                          (const_int 8))
8697         (and:SI
8698           (zero_extract:SI
8699             (match_operand 1 "ext_register_operand" "0")
8700             (const_int 8)
8701             (const_int 8))
8702           (zero_extend:SI
8703             (match_operand:QI 2 "general_operand" "Qm"))))
8704    (clobber (reg:CC FLAGS_REG))]
8705   "!TARGET_64BIT"
8706   "and{b}\t{%2, %h0|%h0, %2}"
8707   [(set_attr "type" "alu")
8708    (set_attr "length_immediate" "0")
8709    (set_attr "mode" "QI")])
8710
8711 (define_insn "*andqi_ext_1_rex64"
8712   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8713                          (const_int 8)
8714                          (const_int 8))
8715         (and:SI
8716           (zero_extract:SI
8717             (match_operand 1 "ext_register_operand" "0")
8718             (const_int 8)
8719             (const_int 8))
8720           (zero_extend:SI
8721             (match_operand 2 "ext_register_operand" "Q"))))
8722    (clobber (reg:CC FLAGS_REG))]
8723   "TARGET_64BIT"
8724   "and{b}\t{%2, %h0|%h0, %2}"
8725   [(set_attr "type" "alu")
8726    (set_attr "length_immediate" "0")
8727    (set_attr "mode" "QI")])
8728
8729 (define_insn "*andqi_ext_2"
8730   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8731                          (const_int 8)
8732                          (const_int 8))
8733         (and:SI
8734           (zero_extract:SI
8735             (match_operand 1 "ext_register_operand" "%0")
8736             (const_int 8)
8737             (const_int 8))
8738           (zero_extract:SI
8739             (match_operand 2 "ext_register_operand" "Q")
8740             (const_int 8)
8741             (const_int 8))))
8742    (clobber (reg:CC FLAGS_REG))]
8743   ""
8744   "and{b}\t{%h2, %h0|%h0, %h2}"
8745   [(set_attr "type" "alu")
8746    (set_attr "length_immediate" "0")
8747    (set_attr "mode" "QI")])
8748
8749 ;; Convert wide AND instructions with immediate operand to shorter QImode
8750 ;; equivalents when possible.
8751 ;; Don't do the splitting with memory operands, since it introduces risk
8752 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8753 ;; for size, but that can (should?) be handled by generic code instead.
8754 (define_split
8755   [(set (match_operand 0 "register_operand" "")
8756         (and (match_operand 1 "register_operand" "")
8757              (match_operand 2 "const_int_operand" "")))
8758    (clobber (reg:CC FLAGS_REG))]
8759    "reload_completed
8760     && QI_REG_P (operands[0])
8761     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8762     && !(~INTVAL (operands[2]) & ~(255 << 8))
8763     && GET_MODE (operands[0]) != QImode"
8764   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8765                    (and:SI (zero_extract:SI (match_dup 1)
8766                                             (const_int 8) (const_int 8))
8767                            (match_dup 2)))
8768               (clobber (reg:CC FLAGS_REG))])]
8769   "operands[0] = gen_lowpart (SImode, operands[0]);
8770    operands[1] = gen_lowpart (SImode, operands[1]);
8771    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8772
8773 ;; Since AND can be encoded with sign extended immediate, this is only
8774 ;; profitable when 7th bit is not set.
8775 (define_split
8776   [(set (match_operand 0 "register_operand" "")
8777         (and (match_operand 1 "general_operand" "")
8778              (match_operand 2 "const_int_operand" "")))
8779    (clobber (reg:CC FLAGS_REG))]
8780    "reload_completed
8781     && ANY_QI_REG_P (operands[0])
8782     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8783     && !(~INTVAL (operands[2]) & ~255)
8784     && !(INTVAL (operands[2]) & 128)
8785     && GET_MODE (operands[0]) != QImode"
8786   [(parallel [(set (strict_low_part (match_dup 0))
8787                    (and:QI (match_dup 1)
8788                            (match_dup 2)))
8789               (clobber (reg:CC FLAGS_REG))])]
8790   "operands[0] = gen_lowpart (QImode, operands[0]);
8791    operands[1] = gen_lowpart (QImode, operands[1]);
8792    operands[2] = gen_lowpart (QImode, operands[2]);")
8793 \f
8794 ;; Logical inclusive OR instructions
8795
8796 ;; %%% This used to optimize known byte-wide and operations to memory.
8797 ;; If this is considered useful, it should be done with splitters.
8798
8799 (define_expand "iordi3"
8800   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8801         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8802                 (match_operand:DI 2 "x86_64_general_operand" "")))
8803    (clobber (reg:CC FLAGS_REG))]
8804   "TARGET_64BIT"
8805   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8806
8807 (define_insn "*iordi_1_rex64"
8808   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8809         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8810                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8811    (clobber (reg:CC FLAGS_REG))]
8812   "TARGET_64BIT
8813    && ix86_binary_operator_ok (IOR, DImode, operands)"
8814   "or{q}\t{%2, %0|%0, %2}"
8815   [(set_attr "type" "alu")
8816    (set_attr "mode" "DI")])
8817
8818 (define_insn "*iordi_2_rex64"
8819   [(set (reg FLAGS_REG)
8820         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8821                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8822                  (const_int 0)))
8823    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8824         (ior:DI (match_dup 1) (match_dup 2)))]
8825   "TARGET_64BIT
8826    && ix86_match_ccmode (insn, CCNOmode)
8827    && ix86_binary_operator_ok (IOR, DImode, operands)"
8828   "or{q}\t{%2, %0|%0, %2}"
8829   [(set_attr "type" "alu")
8830    (set_attr "mode" "DI")])
8831
8832 (define_insn "*iordi_3_rex64"
8833   [(set (reg FLAGS_REG)
8834         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8835                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8836                  (const_int 0)))
8837    (clobber (match_scratch:DI 0 "=r"))]
8838   "TARGET_64BIT
8839    && ix86_match_ccmode (insn, CCNOmode)
8840    && ix86_binary_operator_ok (IOR, DImode, operands)"
8841   "or{q}\t{%2, %0|%0, %2}"
8842   [(set_attr "type" "alu")
8843    (set_attr "mode" "DI")])
8844
8845
8846 (define_expand "iorsi3"
8847   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8848         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8849                 (match_operand:SI 2 "general_operand" "")))
8850    (clobber (reg:CC FLAGS_REG))]
8851   ""
8852   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8853
8854 (define_insn "*iorsi_1"
8855   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8856         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8857                 (match_operand:SI 2 "general_operand" "ri,g")))
8858    (clobber (reg:CC FLAGS_REG))]
8859   "ix86_binary_operator_ok (IOR, SImode, operands)"
8860   "or{l}\t{%2, %0|%0, %2}"
8861   [(set_attr "type" "alu")
8862    (set_attr "mode" "SI")])
8863
8864 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8865 (define_insn "*iorsi_1_zext"
8866   [(set (match_operand:DI 0 "register_operand" "=r")
8867         (zero_extend:DI
8868           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8869                   (match_operand:SI 2 "general_operand" "g"))))
8870    (clobber (reg:CC FLAGS_REG))]
8871   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8872   "or{l}\t{%2, %k0|%k0, %2}"
8873   [(set_attr "type" "alu")
8874    (set_attr "mode" "SI")])
8875
8876 (define_insn "*iorsi_1_zext_imm"
8877   [(set (match_operand:DI 0 "register_operand" "=r")
8878         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8879                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8880    (clobber (reg:CC FLAGS_REG))]
8881   "TARGET_64BIT"
8882   "or{l}\t{%2, %k0|%k0, %2}"
8883   [(set_attr "type" "alu")
8884    (set_attr "mode" "SI")])
8885
8886 (define_insn "*iorsi_2"
8887   [(set (reg FLAGS_REG)
8888         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8889                          (match_operand:SI 2 "general_operand" "g,ri"))
8890                  (const_int 0)))
8891    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8892         (ior:SI (match_dup 1) (match_dup 2)))]
8893   "ix86_match_ccmode (insn, CCNOmode)
8894    && ix86_binary_operator_ok (IOR, SImode, operands)"
8895   "or{l}\t{%2, %0|%0, %2}"
8896   [(set_attr "type" "alu")
8897    (set_attr "mode" "SI")])
8898
8899 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8900 ;; ??? Special case for immediate operand is missing - it is tricky.
8901 (define_insn "*iorsi_2_zext"
8902   [(set (reg FLAGS_REG)
8903         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8904                          (match_operand:SI 2 "general_operand" "g"))
8905                  (const_int 0)))
8906    (set (match_operand:DI 0 "register_operand" "=r")
8907         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8908   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8909    && ix86_binary_operator_ok (IOR, SImode, operands)"
8910   "or{l}\t{%2, %k0|%k0, %2}"
8911   [(set_attr "type" "alu")
8912    (set_attr "mode" "SI")])
8913
8914 (define_insn "*iorsi_2_zext_imm"
8915   [(set (reg FLAGS_REG)
8916         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8917                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8918                  (const_int 0)))
8919    (set (match_operand:DI 0 "register_operand" "=r")
8920         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8921   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8922    && ix86_binary_operator_ok (IOR, SImode, operands)"
8923   "or{l}\t{%2, %k0|%k0, %2}"
8924   [(set_attr "type" "alu")
8925    (set_attr "mode" "SI")])
8926
8927 (define_insn "*iorsi_3"
8928   [(set (reg FLAGS_REG)
8929         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8930                          (match_operand:SI 2 "general_operand" "g"))
8931                  (const_int 0)))
8932    (clobber (match_scratch:SI 0 "=r"))]
8933   "ix86_match_ccmode (insn, CCNOmode)
8934    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8935   "or{l}\t{%2, %0|%0, %2}"
8936   [(set_attr "type" "alu")
8937    (set_attr "mode" "SI")])
8938
8939 (define_expand "iorhi3"
8940   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8941         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8942                 (match_operand:HI 2 "general_operand" "")))
8943    (clobber (reg:CC FLAGS_REG))]
8944   "TARGET_HIMODE_MATH"
8945   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8946
8947 (define_insn "*iorhi_1"
8948   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8949         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8950                 (match_operand:HI 2 "general_operand" "g,ri")))
8951    (clobber (reg:CC FLAGS_REG))]
8952   "ix86_binary_operator_ok (IOR, HImode, operands)"
8953   "or{w}\t{%2, %0|%0, %2}"
8954   [(set_attr "type" "alu")
8955    (set_attr "mode" "HI")])
8956
8957 (define_insn "*iorhi_2"
8958   [(set (reg FLAGS_REG)
8959         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8960                          (match_operand:HI 2 "general_operand" "g,ri"))
8961                  (const_int 0)))
8962    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8963         (ior:HI (match_dup 1) (match_dup 2)))]
8964   "ix86_match_ccmode (insn, CCNOmode)
8965    && ix86_binary_operator_ok (IOR, HImode, operands)"
8966   "or{w}\t{%2, %0|%0, %2}"
8967   [(set_attr "type" "alu")
8968    (set_attr "mode" "HI")])
8969
8970 (define_insn "*iorhi_3"
8971   [(set (reg FLAGS_REG)
8972         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8973                          (match_operand:HI 2 "general_operand" "g"))
8974                  (const_int 0)))
8975    (clobber (match_scratch:HI 0 "=r"))]
8976   "ix86_match_ccmode (insn, CCNOmode)
8977    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8978   "or{w}\t{%2, %0|%0, %2}"
8979   [(set_attr "type" "alu")
8980    (set_attr "mode" "HI")])
8981
8982 (define_expand "iorqi3"
8983   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8984         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8985                 (match_operand:QI 2 "general_operand" "")))
8986    (clobber (reg:CC FLAGS_REG))]
8987   "TARGET_QIMODE_MATH"
8988   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8989
8990 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8991 (define_insn "*iorqi_1"
8992   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8993         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8994                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8995    (clobber (reg:CC FLAGS_REG))]
8996   "ix86_binary_operator_ok (IOR, QImode, operands)"
8997   "@
8998    or{b}\t{%2, %0|%0, %2}
8999    or{b}\t{%2, %0|%0, %2}
9000    or{l}\t{%k2, %k0|%k0, %k2}"
9001   [(set_attr "type" "alu")
9002    (set_attr "mode" "QI,QI,SI")])
9003
9004 (define_insn "*iorqi_1_slp"
9005   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9006         (ior:QI (match_dup 0)
9007                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9008    (clobber (reg:CC FLAGS_REG))]
9009   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9010    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9011   "or{b}\t{%1, %0|%0, %1}"
9012   [(set_attr "type" "alu1")
9013    (set_attr "mode" "QI")])
9014
9015 (define_insn "*iorqi_2"
9016   [(set (reg FLAGS_REG)
9017         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9018                          (match_operand:QI 2 "general_operand" "qim,qi"))
9019                  (const_int 0)))
9020    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9021         (ior:QI (match_dup 1) (match_dup 2)))]
9022   "ix86_match_ccmode (insn, CCNOmode)
9023    && ix86_binary_operator_ok (IOR, QImode, operands)"
9024   "or{b}\t{%2, %0|%0, %2}"
9025   [(set_attr "type" "alu")
9026    (set_attr "mode" "QI")])
9027
9028 (define_insn "*iorqi_2_slp"
9029   [(set (reg FLAGS_REG)
9030         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9031                          (match_operand:QI 1 "general_operand" "qim,qi"))
9032                  (const_int 0)))
9033    (set (strict_low_part (match_dup 0))
9034         (ior:QI (match_dup 0) (match_dup 1)))]
9035   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9036    && ix86_match_ccmode (insn, CCNOmode)
9037    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9038   "or{b}\t{%1, %0|%0, %1}"
9039   [(set_attr "type" "alu1")
9040    (set_attr "mode" "QI")])
9041
9042 (define_insn "*iorqi_3"
9043   [(set (reg FLAGS_REG)
9044         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9045                          (match_operand:QI 2 "general_operand" "qim"))
9046                  (const_int 0)))
9047    (clobber (match_scratch:QI 0 "=q"))]
9048   "ix86_match_ccmode (insn, CCNOmode)
9049    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9050   "or{b}\t{%2, %0|%0, %2}"
9051   [(set_attr "type" "alu")
9052    (set_attr "mode" "QI")])
9053
9054 (define_insn "iorqi_ext_0"
9055   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9056                          (const_int 8)
9057                          (const_int 8))
9058         (ior:SI
9059           (zero_extract:SI
9060             (match_operand 1 "ext_register_operand" "0")
9061             (const_int 8)
9062             (const_int 8))
9063           (match_operand 2 "const_int_operand" "n")))
9064    (clobber (reg:CC FLAGS_REG))]
9065   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9066   "or{b}\t{%2, %h0|%h0, %2}"
9067   [(set_attr "type" "alu")
9068    (set_attr "length_immediate" "1")
9069    (set_attr "mode" "QI")])
9070
9071 (define_insn "*iorqi_ext_1"
9072   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9073                          (const_int 8)
9074                          (const_int 8))
9075         (ior:SI
9076           (zero_extract:SI
9077             (match_operand 1 "ext_register_operand" "0")
9078             (const_int 8)
9079             (const_int 8))
9080           (zero_extend:SI
9081             (match_operand:QI 2 "general_operand" "Qm"))))
9082    (clobber (reg:CC FLAGS_REG))]
9083   "!TARGET_64BIT
9084    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9085   "or{b}\t{%2, %h0|%h0, %2}"
9086   [(set_attr "type" "alu")
9087    (set_attr "length_immediate" "0")
9088    (set_attr "mode" "QI")])
9089
9090 (define_insn "*iorqi_ext_1_rex64"
9091   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9092                          (const_int 8)
9093                          (const_int 8))
9094         (ior:SI
9095           (zero_extract:SI
9096             (match_operand 1 "ext_register_operand" "0")
9097             (const_int 8)
9098             (const_int 8))
9099           (zero_extend:SI
9100             (match_operand 2 "ext_register_operand" "Q"))))
9101    (clobber (reg:CC FLAGS_REG))]
9102   "TARGET_64BIT
9103    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9104   "or{b}\t{%2, %h0|%h0, %2}"
9105   [(set_attr "type" "alu")
9106    (set_attr "length_immediate" "0")
9107    (set_attr "mode" "QI")])
9108
9109 (define_insn "*iorqi_ext_2"
9110   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9111                          (const_int 8)
9112                          (const_int 8))
9113         (ior:SI
9114           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9115                            (const_int 8)
9116                            (const_int 8))
9117           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9118                            (const_int 8)
9119                            (const_int 8))))
9120    (clobber (reg:CC FLAGS_REG))]
9121   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9122   "ior{b}\t{%h2, %h0|%h0, %h2}"
9123   [(set_attr "type" "alu")
9124    (set_attr "length_immediate" "0")
9125    (set_attr "mode" "QI")])
9126
9127 (define_split
9128   [(set (match_operand 0 "register_operand" "")
9129         (ior (match_operand 1 "register_operand" "")
9130              (match_operand 2 "const_int_operand" "")))
9131    (clobber (reg:CC FLAGS_REG))]
9132    "reload_completed
9133     && QI_REG_P (operands[0])
9134     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9135     && !(INTVAL (operands[2]) & ~(255 << 8))
9136     && GET_MODE (operands[0]) != QImode"
9137   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9138                    (ior:SI (zero_extract:SI (match_dup 1)
9139                                             (const_int 8) (const_int 8))
9140                            (match_dup 2)))
9141               (clobber (reg:CC FLAGS_REG))])]
9142   "operands[0] = gen_lowpart (SImode, operands[0]);
9143    operands[1] = gen_lowpart (SImode, operands[1]);
9144    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9145
9146 ;; Since OR can be encoded with sign extended immediate, this is only
9147 ;; profitable when 7th bit is set.
9148 (define_split
9149   [(set (match_operand 0 "register_operand" "")
9150         (ior (match_operand 1 "general_operand" "")
9151              (match_operand 2 "const_int_operand" "")))
9152    (clobber (reg:CC FLAGS_REG))]
9153    "reload_completed
9154     && ANY_QI_REG_P (operands[0])
9155     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9156     && !(INTVAL (operands[2]) & ~255)
9157     && (INTVAL (operands[2]) & 128)
9158     && GET_MODE (operands[0]) != QImode"
9159   [(parallel [(set (strict_low_part (match_dup 0))
9160                    (ior:QI (match_dup 1)
9161                            (match_dup 2)))
9162               (clobber (reg:CC FLAGS_REG))])]
9163   "operands[0] = gen_lowpart (QImode, operands[0]);
9164    operands[1] = gen_lowpart (QImode, operands[1]);
9165    operands[2] = gen_lowpart (QImode, operands[2]);")
9166 \f
9167 ;; Logical XOR instructions
9168
9169 ;; %%% This used to optimize known byte-wide and operations to memory.
9170 ;; If this is considered useful, it should be done with splitters.
9171
9172 (define_expand "xordi3"
9173   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9174         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9175                 (match_operand:DI 2 "x86_64_general_operand" "")))
9176    (clobber (reg:CC FLAGS_REG))]
9177   "TARGET_64BIT"
9178   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9179
9180 (define_insn "*xordi_1_rex64"
9181   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9182         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9183                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9184    (clobber (reg:CC FLAGS_REG))]
9185   "TARGET_64BIT
9186    && ix86_binary_operator_ok (XOR, DImode, operands)"
9187   "@
9188    xor{q}\t{%2, %0|%0, %2}
9189    xor{q}\t{%2, %0|%0, %2}"
9190   [(set_attr "type" "alu")
9191    (set_attr "mode" "DI,DI")])
9192
9193 (define_insn "*xordi_2_rex64"
9194   [(set (reg FLAGS_REG)
9195         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9196                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9197                  (const_int 0)))
9198    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9199         (xor:DI (match_dup 1) (match_dup 2)))]
9200   "TARGET_64BIT
9201    && ix86_match_ccmode (insn, CCNOmode)
9202    && ix86_binary_operator_ok (XOR, DImode, operands)"
9203   "@
9204    xor{q}\t{%2, %0|%0, %2}
9205    xor{q}\t{%2, %0|%0, %2}"
9206   [(set_attr "type" "alu")
9207    (set_attr "mode" "DI,DI")])
9208
9209 (define_insn "*xordi_3_rex64"
9210   [(set (reg FLAGS_REG)
9211         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9212                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9213                  (const_int 0)))
9214    (clobber (match_scratch:DI 0 "=r"))]
9215   "TARGET_64BIT
9216    && ix86_match_ccmode (insn, CCNOmode)
9217    && ix86_binary_operator_ok (XOR, DImode, operands)"
9218   "xor{q}\t{%2, %0|%0, %2}"
9219   [(set_attr "type" "alu")
9220    (set_attr "mode" "DI")])
9221
9222 (define_expand "xorsi3"
9223   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9224         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9225                 (match_operand:SI 2 "general_operand" "")))
9226    (clobber (reg:CC FLAGS_REG))]
9227   ""
9228   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9229
9230 (define_insn "*xorsi_1"
9231   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9232         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9233                 (match_operand:SI 2 "general_operand" "ri,rm")))
9234    (clobber (reg:CC FLAGS_REG))]
9235   "ix86_binary_operator_ok (XOR, SImode, operands)"
9236   "xor{l}\t{%2, %0|%0, %2}"
9237   [(set_attr "type" "alu")
9238    (set_attr "mode" "SI")])
9239
9240 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9241 ;; Add speccase for immediates
9242 (define_insn "*xorsi_1_zext"
9243   [(set (match_operand:DI 0 "register_operand" "=r")
9244         (zero_extend:DI
9245           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9246                   (match_operand:SI 2 "general_operand" "g"))))
9247    (clobber (reg:CC FLAGS_REG))]
9248   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9249   "xor{l}\t{%2, %k0|%k0, %2}"
9250   [(set_attr "type" "alu")
9251    (set_attr "mode" "SI")])
9252
9253 (define_insn "*xorsi_1_zext_imm"
9254   [(set (match_operand:DI 0 "register_operand" "=r")
9255         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9256                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9257    (clobber (reg:CC FLAGS_REG))]
9258   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9259   "xor{l}\t{%2, %k0|%k0, %2}"
9260   [(set_attr "type" "alu")
9261    (set_attr "mode" "SI")])
9262
9263 (define_insn "*xorsi_2"
9264   [(set (reg FLAGS_REG)
9265         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9266                          (match_operand:SI 2 "general_operand" "g,ri"))
9267                  (const_int 0)))
9268    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9269         (xor:SI (match_dup 1) (match_dup 2)))]
9270   "ix86_match_ccmode (insn, CCNOmode)
9271    && ix86_binary_operator_ok (XOR, SImode, operands)"
9272   "xor{l}\t{%2, %0|%0, %2}"
9273   [(set_attr "type" "alu")
9274    (set_attr "mode" "SI")])
9275
9276 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9277 ;; ??? Special case for immediate operand is missing - it is tricky.
9278 (define_insn "*xorsi_2_zext"
9279   [(set (reg FLAGS_REG)
9280         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9281                          (match_operand:SI 2 "general_operand" "g"))
9282                  (const_int 0)))
9283    (set (match_operand:DI 0 "register_operand" "=r")
9284         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9285   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9286    && ix86_binary_operator_ok (XOR, SImode, operands)"
9287   "xor{l}\t{%2, %k0|%k0, %2}"
9288   [(set_attr "type" "alu")
9289    (set_attr "mode" "SI")])
9290
9291 (define_insn "*xorsi_2_zext_imm"
9292   [(set (reg FLAGS_REG)
9293         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9294                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9295                  (const_int 0)))
9296    (set (match_operand:DI 0 "register_operand" "=r")
9297         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9298   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9299    && ix86_binary_operator_ok (XOR, SImode, operands)"
9300   "xor{l}\t{%2, %k0|%k0, %2}"
9301   [(set_attr "type" "alu")
9302    (set_attr "mode" "SI")])
9303
9304 (define_insn "*xorsi_3"
9305   [(set (reg FLAGS_REG)
9306         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9307                          (match_operand:SI 2 "general_operand" "g"))
9308                  (const_int 0)))
9309    (clobber (match_scratch:SI 0 "=r"))]
9310   "ix86_match_ccmode (insn, CCNOmode)
9311    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9312   "xor{l}\t{%2, %0|%0, %2}"
9313   [(set_attr "type" "alu")
9314    (set_attr "mode" "SI")])
9315
9316 (define_expand "xorhi3"
9317   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9318         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9319                 (match_operand:HI 2 "general_operand" "")))
9320    (clobber (reg:CC FLAGS_REG))]
9321   "TARGET_HIMODE_MATH"
9322   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9323
9324 (define_insn "*xorhi_1"
9325   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9326         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9327                 (match_operand:HI 2 "general_operand" "g,ri")))
9328    (clobber (reg:CC FLAGS_REG))]
9329   "ix86_binary_operator_ok (XOR, HImode, operands)"
9330   "xor{w}\t{%2, %0|%0, %2}"
9331   [(set_attr "type" "alu")
9332    (set_attr "mode" "HI")])
9333
9334 (define_insn "*xorhi_2"
9335   [(set (reg FLAGS_REG)
9336         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9337                          (match_operand:HI 2 "general_operand" "g,ri"))
9338                  (const_int 0)))
9339    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9340         (xor:HI (match_dup 1) (match_dup 2)))]
9341   "ix86_match_ccmode (insn, CCNOmode)
9342    && ix86_binary_operator_ok (XOR, HImode, operands)"
9343   "xor{w}\t{%2, %0|%0, %2}"
9344   [(set_attr "type" "alu")
9345    (set_attr "mode" "HI")])
9346
9347 (define_insn "*xorhi_3"
9348   [(set (reg FLAGS_REG)
9349         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9350                          (match_operand:HI 2 "general_operand" "g"))
9351                  (const_int 0)))
9352    (clobber (match_scratch:HI 0 "=r"))]
9353   "ix86_match_ccmode (insn, CCNOmode)
9354    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9355   "xor{w}\t{%2, %0|%0, %2}"
9356   [(set_attr "type" "alu")
9357    (set_attr "mode" "HI")])
9358
9359 (define_expand "xorqi3"
9360   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9361         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9362                 (match_operand:QI 2 "general_operand" "")))
9363    (clobber (reg:CC FLAGS_REG))]
9364   "TARGET_QIMODE_MATH"
9365   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9366
9367 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9368 (define_insn "*xorqi_1"
9369   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9370         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9371                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9372    (clobber (reg:CC FLAGS_REG))]
9373   "ix86_binary_operator_ok (XOR, QImode, operands)"
9374   "@
9375    xor{b}\t{%2, %0|%0, %2}
9376    xor{b}\t{%2, %0|%0, %2}
9377    xor{l}\t{%k2, %k0|%k0, %k2}"
9378   [(set_attr "type" "alu")
9379    (set_attr "mode" "QI,QI,SI")])
9380
9381 (define_insn "*xorqi_1_slp"
9382   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9383         (xor:QI (match_dup 0)
9384                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9385    (clobber (reg:CC FLAGS_REG))]
9386   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9387    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9388   "xor{b}\t{%1, %0|%0, %1}"
9389   [(set_attr "type" "alu1")
9390    (set_attr "mode" "QI")])
9391
9392 (define_insn "xorqi_ext_0"
9393   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9394                          (const_int 8)
9395                          (const_int 8))
9396         (xor:SI
9397           (zero_extract:SI
9398             (match_operand 1 "ext_register_operand" "0")
9399             (const_int 8)
9400             (const_int 8))
9401           (match_operand 2 "const_int_operand" "n")))
9402    (clobber (reg:CC FLAGS_REG))]
9403   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9404   "xor{b}\t{%2, %h0|%h0, %2}"
9405   [(set_attr "type" "alu")
9406    (set_attr "length_immediate" "1")
9407    (set_attr "mode" "QI")])
9408
9409 (define_insn "*xorqi_ext_1"
9410   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9411                          (const_int 8)
9412                          (const_int 8))
9413         (xor:SI
9414           (zero_extract:SI
9415             (match_operand 1 "ext_register_operand" "0")
9416             (const_int 8)
9417             (const_int 8))
9418           (zero_extend:SI
9419             (match_operand:QI 2 "general_operand" "Qm"))))
9420    (clobber (reg:CC FLAGS_REG))]
9421   "!TARGET_64BIT
9422    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9423   "xor{b}\t{%2, %h0|%h0, %2}"
9424   [(set_attr "type" "alu")
9425    (set_attr "length_immediate" "0")
9426    (set_attr "mode" "QI")])
9427
9428 (define_insn "*xorqi_ext_1_rex64"
9429   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9430                          (const_int 8)
9431                          (const_int 8))
9432         (xor:SI
9433           (zero_extract:SI
9434             (match_operand 1 "ext_register_operand" "0")
9435             (const_int 8)
9436             (const_int 8))
9437           (zero_extend:SI
9438             (match_operand 2 "ext_register_operand" "Q"))))
9439    (clobber (reg:CC FLAGS_REG))]
9440   "TARGET_64BIT
9441    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9442   "xor{b}\t{%2, %h0|%h0, %2}"
9443   [(set_attr "type" "alu")
9444    (set_attr "length_immediate" "0")
9445    (set_attr "mode" "QI")])
9446
9447 (define_insn "*xorqi_ext_2"
9448   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9449                          (const_int 8)
9450                          (const_int 8))
9451         (xor:SI
9452           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9453                            (const_int 8)
9454                            (const_int 8))
9455           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9456                            (const_int 8)
9457                            (const_int 8))))
9458    (clobber (reg:CC FLAGS_REG))]
9459   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9460   "xor{b}\t{%h2, %h0|%h0, %h2}"
9461   [(set_attr "type" "alu")
9462    (set_attr "length_immediate" "0")
9463    (set_attr "mode" "QI")])
9464
9465 (define_insn "*xorqi_cc_1"
9466   [(set (reg FLAGS_REG)
9467         (compare
9468           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9469                   (match_operand:QI 2 "general_operand" "qim,qi"))
9470           (const_int 0)))
9471    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9472         (xor:QI (match_dup 1) (match_dup 2)))]
9473   "ix86_match_ccmode (insn, CCNOmode)
9474    && ix86_binary_operator_ok (XOR, QImode, operands)"
9475   "xor{b}\t{%2, %0|%0, %2}"
9476   [(set_attr "type" "alu")
9477    (set_attr "mode" "QI")])
9478
9479 (define_insn "*xorqi_2_slp"
9480   [(set (reg FLAGS_REG)
9481         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9482                          (match_operand:QI 1 "general_operand" "qim,qi"))
9483                  (const_int 0)))
9484    (set (strict_low_part (match_dup 0))
9485         (xor:QI (match_dup 0) (match_dup 1)))]
9486   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9487    && ix86_match_ccmode (insn, CCNOmode)
9488    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9489   "xor{b}\t{%1, %0|%0, %1}"
9490   [(set_attr "type" "alu1")
9491    (set_attr "mode" "QI")])
9492
9493 (define_insn "*xorqi_cc_2"
9494   [(set (reg FLAGS_REG)
9495         (compare
9496           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9497                   (match_operand:QI 2 "general_operand" "qim"))
9498           (const_int 0)))
9499    (clobber (match_scratch:QI 0 "=q"))]
9500   "ix86_match_ccmode (insn, CCNOmode)
9501    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9502   "xor{b}\t{%2, %0|%0, %2}"
9503   [(set_attr "type" "alu")
9504    (set_attr "mode" "QI")])
9505
9506 (define_insn "*xorqi_cc_ext_1"
9507   [(set (reg FLAGS_REG)
9508         (compare
9509           (xor:SI
9510             (zero_extract:SI
9511               (match_operand 1 "ext_register_operand" "0")
9512               (const_int 8)
9513               (const_int 8))
9514             (match_operand:QI 2 "general_operand" "qmn"))
9515           (const_int 0)))
9516    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9517                          (const_int 8)
9518                          (const_int 8))
9519         (xor:SI
9520           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9521           (match_dup 2)))]
9522   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9523   "xor{b}\t{%2, %h0|%h0, %2}"
9524   [(set_attr "type" "alu")
9525    (set_attr "mode" "QI")])
9526
9527 (define_insn "*xorqi_cc_ext_1_rex64"
9528   [(set (reg FLAGS_REG)
9529         (compare
9530           (xor:SI
9531             (zero_extract:SI
9532               (match_operand 1 "ext_register_operand" "0")
9533               (const_int 8)
9534               (const_int 8))
9535             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9536           (const_int 0)))
9537    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9538                          (const_int 8)
9539                          (const_int 8))
9540         (xor:SI
9541           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9542           (match_dup 2)))]
9543   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9544   "xor{b}\t{%2, %h0|%h0, %2}"
9545   [(set_attr "type" "alu")
9546    (set_attr "mode" "QI")])
9547
9548 (define_expand "xorqi_cc_ext_1"
9549   [(parallel [
9550      (set (reg:CCNO FLAGS_REG)
9551           (compare:CCNO
9552             (xor:SI
9553               (zero_extract:SI
9554                 (match_operand 1 "ext_register_operand" "")
9555                 (const_int 8)
9556                 (const_int 8))
9557               (match_operand:QI 2 "general_operand" ""))
9558             (const_int 0)))
9559      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9560                            (const_int 8)
9561                            (const_int 8))
9562           (xor:SI
9563             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9564             (match_dup 2)))])]
9565   ""
9566   "")
9567
9568 (define_split
9569   [(set (match_operand 0 "register_operand" "")
9570         (xor (match_operand 1 "register_operand" "")
9571              (match_operand 2 "const_int_operand" "")))
9572    (clobber (reg:CC FLAGS_REG))]
9573    "reload_completed
9574     && QI_REG_P (operands[0])
9575     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9576     && !(INTVAL (operands[2]) & ~(255 << 8))
9577     && GET_MODE (operands[0]) != QImode"
9578   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9579                    (xor:SI (zero_extract:SI (match_dup 1)
9580                                             (const_int 8) (const_int 8))
9581                            (match_dup 2)))
9582               (clobber (reg:CC FLAGS_REG))])]
9583   "operands[0] = gen_lowpart (SImode, operands[0]);
9584    operands[1] = gen_lowpart (SImode, operands[1]);
9585    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9586
9587 ;; Since XOR can be encoded with sign extended immediate, this is only
9588 ;; profitable when 7th bit is set.
9589 (define_split
9590   [(set (match_operand 0 "register_operand" "")
9591         (xor (match_operand 1 "general_operand" "")
9592              (match_operand 2 "const_int_operand" "")))
9593    (clobber (reg:CC FLAGS_REG))]
9594    "reload_completed
9595     && ANY_QI_REG_P (operands[0])
9596     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9597     && !(INTVAL (operands[2]) & ~255)
9598     && (INTVAL (operands[2]) & 128)
9599     && GET_MODE (operands[0]) != QImode"
9600   [(parallel [(set (strict_low_part (match_dup 0))
9601                    (xor:QI (match_dup 1)
9602                            (match_dup 2)))
9603               (clobber (reg:CC FLAGS_REG))])]
9604   "operands[0] = gen_lowpart (QImode, operands[0]);
9605    operands[1] = gen_lowpart (QImode, operands[1]);
9606    operands[2] = gen_lowpart (QImode, operands[2]);")
9607 \f
9608 ;; Negation instructions
9609
9610 (define_expand "negti2"
9611   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9612                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9613               (clobber (reg:CC FLAGS_REG))])]
9614   "TARGET_64BIT"
9615   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9616
9617 (define_insn "*negti2_1"
9618   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9619         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9620    (clobber (reg:CC FLAGS_REG))]
9621   "TARGET_64BIT
9622    && ix86_unary_operator_ok (NEG, TImode, operands)"
9623   "#")
9624
9625 (define_split
9626   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9627         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9628    (clobber (reg:CC FLAGS_REG))]
9629   "TARGET_64BIT && reload_completed"
9630   [(parallel
9631     [(set (reg:CCZ FLAGS_REG)
9632           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9633      (set (match_dup 0) (neg:DI (match_dup 2)))])
9634    (parallel
9635     [(set (match_dup 1)
9636           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9637                             (match_dup 3))
9638                    (const_int 0)))
9639      (clobber (reg:CC FLAGS_REG))])
9640    (parallel
9641     [(set (match_dup 1)
9642           (neg:DI (match_dup 1)))
9643      (clobber (reg:CC FLAGS_REG))])]
9644   "split_ti (operands+1, 1, operands+2, operands+3);
9645    split_ti (operands+0, 1, operands+0, operands+1);")
9646
9647 (define_expand "negdi2"
9648   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9649                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9650               (clobber (reg:CC FLAGS_REG))])]
9651   ""
9652   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9653
9654 (define_insn "*negdi2_1"
9655   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9656         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9657    (clobber (reg:CC FLAGS_REG))]
9658   "!TARGET_64BIT
9659    && ix86_unary_operator_ok (NEG, DImode, operands)"
9660   "#")
9661
9662 (define_split
9663   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9664         (neg:DI (match_operand:DI 1 "general_operand" "")))
9665    (clobber (reg:CC FLAGS_REG))]
9666   "!TARGET_64BIT && reload_completed"
9667   [(parallel
9668     [(set (reg:CCZ FLAGS_REG)
9669           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9670      (set (match_dup 0) (neg:SI (match_dup 2)))])
9671    (parallel
9672     [(set (match_dup 1)
9673           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9674                             (match_dup 3))
9675                    (const_int 0)))
9676      (clobber (reg:CC FLAGS_REG))])
9677    (parallel
9678     [(set (match_dup 1)
9679           (neg:SI (match_dup 1)))
9680      (clobber (reg:CC FLAGS_REG))])]
9681   "split_di (operands+1, 1, operands+2, operands+3);
9682    split_di (operands+0, 1, operands+0, operands+1);")
9683
9684 (define_insn "*negdi2_1_rex64"
9685   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9686         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9687    (clobber (reg:CC FLAGS_REG))]
9688   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9689   "neg{q}\t%0"
9690   [(set_attr "type" "negnot")
9691    (set_attr "mode" "DI")])
9692
9693 ;; The problem with neg is that it does not perform (compare x 0),
9694 ;; it really performs (compare 0 x), which leaves us with the zero
9695 ;; flag being the only useful item.
9696
9697 (define_insn "*negdi2_cmpz_rex64"
9698   [(set (reg:CCZ FLAGS_REG)
9699         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9700                      (const_int 0)))
9701    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9702         (neg:DI (match_dup 1)))]
9703   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9704   "neg{q}\t%0"
9705   [(set_attr "type" "negnot")
9706    (set_attr "mode" "DI")])
9707
9708
9709 (define_expand "negsi2"
9710   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9711                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9712               (clobber (reg:CC FLAGS_REG))])]
9713   ""
9714   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9715
9716 (define_insn "*negsi2_1"
9717   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9718         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9719    (clobber (reg:CC FLAGS_REG))]
9720   "ix86_unary_operator_ok (NEG, SImode, operands)"
9721   "neg{l}\t%0"
9722   [(set_attr "type" "negnot")
9723    (set_attr "mode" "SI")])
9724
9725 ;; Combine is quite creative about this pattern.
9726 (define_insn "*negsi2_1_zext"
9727   [(set (match_operand:DI 0 "register_operand" "=r")
9728         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9729                                         (const_int 32)))
9730                      (const_int 32)))
9731    (clobber (reg:CC FLAGS_REG))]
9732   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9733   "neg{l}\t%k0"
9734   [(set_attr "type" "negnot")
9735    (set_attr "mode" "SI")])
9736
9737 ;; The problem with neg is that it does not perform (compare x 0),
9738 ;; it really performs (compare 0 x), which leaves us with the zero
9739 ;; flag being the only useful item.
9740
9741 (define_insn "*negsi2_cmpz"
9742   [(set (reg:CCZ FLAGS_REG)
9743         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9744                      (const_int 0)))
9745    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9746         (neg:SI (match_dup 1)))]
9747   "ix86_unary_operator_ok (NEG, SImode, operands)"
9748   "neg{l}\t%0"
9749   [(set_attr "type" "negnot")
9750    (set_attr "mode" "SI")])
9751
9752 (define_insn "*negsi2_cmpz_zext"
9753   [(set (reg:CCZ FLAGS_REG)
9754         (compare:CCZ (lshiftrt:DI
9755                        (neg:DI (ashift:DI
9756                                  (match_operand:DI 1 "register_operand" "0")
9757                                  (const_int 32)))
9758                        (const_int 32))
9759                      (const_int 0)))
9760    (set (match_operand:DI 0 "register_operand" "=r")
9761         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9762                                         (const_int 32)))
9763                      (const_int 32)))]
9764   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9765   "neg{l}\t%k0"
9766   [(set_attr "type" "negnot")
9767    (set_attr "mode" "SI")])
9768
9769 (define_expand "neghi2"
9770   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9771                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9772               (clobber (reg:CC FLAGS_REG))])]
9773   "TARGET_HIMODE_MATH"
9774   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9775
9776 (define_insn "*neghi2_1"
9777   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9778         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9779    (clobber (reg:CC FLAGS_REG))]
9780   "ix86_unary_operator_ok (NEG, HImode, operands)"
9781   "neg{w}\t%0"
9782   [(set_attr "type" "negnot")
9783    (set_attr "mode" "HI")])
9784
9785 (define_insn "*neghi2_cmpz"
9786   [(set (reg:CCZ FLAGS_REG)
9787         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9788                      (const_int 0)))
9789    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9790         (neg:HI (match_dup 1)))]
9791   "ix86_unary_operator_ok (NEG, HImode, operands)"
9792   "neg{w}\t%0"
9793   [(set_attr "type" "negnot")
9794    (set_attr "mode" "HI")])
9795
9796 (define_expand "negqi2"
9797   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9798                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9799               (clobber (reg:CC FLAGS_REG))])]
9800   "TARGET_QIMODE_MATH"
9801   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9802
9803 (define_insn "*negqi2_1"
9804   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9805         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9806    (clobber (reg:CC FLAGS_REG))]
9807   "ix86_unary_operator_ok (NEG, QImode, operands)"
9808   "neg{b}\t%0"
9809   [(set_attr "type" "negnot")
9810    (set_attr "mode" "QI")])
9811
9812 (define_insn "*negqi2_cmpz"
9813   [(set (reg:CCZ FLAGS_REG)
9814         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9815                      (const_int 0)))
9816    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9817         (neg:QI (match_dup 1)))]
9818   "ix86_unary_operator_ok (NEG, QImode, operands)"
9819   "neg{b}\t%0"
9820   [(set_attr "type" "negnot")
9821    (set_attr "mode" "QI")])
9822
9823 ;; Changing of sign for FP values is doable using integer unit too.
9824
9825 (define_expand "negsf2"
9826   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9827         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9828   "TARGET_80387 || TARGET_SSE_MATH"
9829   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9830
9831 (define_expand "abssf2"
9832   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9833         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9834   "TARGET_80387 || TARGET_SSE_MATH"
9835   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9836
9837 (define_insn "*absnegsf2_mixed"
9838   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9839         (match_operator:SF 3 "absneg_operator"
9840           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9841    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9842    (clobber (reg:CC FLAGS_REG))]
9843   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9844    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9845   "#")
9846
9847 (define_insn "*absnegsf2_sse"
9848   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9849         (match_operator:SF 3 "absneg_operator"
9850           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9851    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9852    (clobber (reg:CC FLAGS_REG))]
9853   "TARGET_SSE_MATH
9854    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9855   "#")
9856
9857 (define_insn "*absnegsf2_i387"
9858   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9859         (match_operator:SF 3 "absneg_operator"
9860           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9861    (use (match_operand 2 "" ""))
9862    (clobber (reg:CC FLAGS_REG))]
9863   "TARGET_80387 && !TARGET_SSE_MATH
9864    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9865   "#")
9866
9867 (define_expand "negdf2"
9868   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9869         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9870   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9871   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9872
9873 (define_expand "absdf2"
9874   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9875         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9876   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9877   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9878
9879 (define_insn "*absnegdf2_mixed"
9880   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
9881         (match_operator:DF 3 "absneg_operator"
9882           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9883    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
9884    (clobber (reg:CC FLAGS_REG))]
9885   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9886    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9887   "#")
9888
9889 (define_insn "*absnegdf2_sse"
9890   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
9891         (match_operator:DF 3 "absneg_operator"
9892           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
9893    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
9894    (clobber (reg:CC FLAGS_REG))]
9895   "TARGET_SSE2 && TARGET_SSE_MATH
9896    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9897   "#")
9898
9899 (define_insn "*absnegdf2_i387"
9900   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9901         (match_operator:DF 3 "absneg_operator"
9902           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9903    (use (match_operand 2 "" ""))
9904    (clobber (reg:CC FLAGS_REG))]
9905   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9906    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9907   "#")
9908
9909 (define_expand "negxf2"
9910   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9911         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9912   "TARGET_80387"
9913   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9914
9915 (define_expand "absxf2"
9916   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9917         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9918   "TARGET_80387"
9919   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9920
9921 (define_insn "*absnegxf2_i387"
9922   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9923         (match_operator:XF 3 "absneg_operator"
9924           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9925    (use (match_operand 2 "" ""))
9926    (clobber (reg:CC FLAGS_REG))]
9927   "TARGET_80387
9928    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9929   "#")
9930
9931 (define_expand "negtf2"
9932   [(set (match_operand:TF 0 "nonimmediate_operand" "")
9933         (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
9934   "TARGET_64BIT"
9935   "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
9936
9937 (define_expand "abstf2"
9938   [(set (match_operand:TF 0 "nonimmediate_operand" "")
9939         (abs:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
9940   "TARGET_64BIT"
9941   "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
9942
9943 (define_insn "*absnegtf2_sse"
9944   [(set (match_operand:TF 0 "nonimmediate_operand"    "=x,x,m")
9945         (match_operator:TF 3 "absneg_operator"
9946           [(match_operand:TF 1 "nonimmediate_operand" "0, x,0")]))
9947    (use (match_operand:TF 2 "nonimmediate_operand"    "xm,0,X"))
9948    (clobber (reg:CC FLAGS_REG))]
9949   "TARGET_64BIT
9950    && ix86_unary_operator_ok (GET_CODE (operands[3]), TFmode, operands)"
9951   "#")
9952
9953 ;; Splitters for fp abs and neg.
9954
9955 (define_split
9956   [(set (match_operand 0 "fp_register_operand" "")
9957         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9958    (use (match_operand 2 "" ""))
9959    (clobber (reg:CC FLAGS_REG))]
9960   "reload_completed"
9961   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9962
9963 (define_split
9964   [(set (match_operand 0 "register_operand" "")
9965         (match_operator 3 "absneg_operator"
9966           [(match_operand 1 "register_operand" "")]))
9967    (use (match_operand 2 "nonimmediate_operand" ""))
9968    (clobber (reg:CC FLAGS_REG))]
9969   "reload_completed && SSE_REG_P (operands[0])"
9970   [(set (match_dup 0) (match_dup 3))]
9971 {
9972   enum machine_mode mode = GET_MODE (operands[0]);
9973   enum machine_mode vmode = GET_MODE (operands[2]);
9974   rtx tmp;
9975
9976   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9977   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9978   if (operands_match_p (operands[0], operands[2]))
9979     {
9980       tmp = operands[1];
9981       operands[1] = operands[2];
9982       operands[2] = tmp;
9983     }
9984   if (GET_CODE (operands[3]) == ABS)
9985     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9986   else
9987     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9988   operands[3] = tmp;
9989 })
9990
9991 (define_split
9992   [(set (match_operand:SF 0 "register_operand" "")
9993         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9994    (use (match_operand:V4SF 2 "" ""))
9995    (clobber (reg:CC FLAGS_REG))]
9996   "reload_completed"
9997   [(parallel [(set (match_dup 0) (match_dup 1))
9998               (clobber (reg:CC FLAGS_REG))])]
9999 {
10000   rtx tmp;
10001   operands[0] = gen_lowpart (SImode, operands[0]);
10002   if (GET_CODE (operands[1]) == ABS)
10003     {
10004       tmp = gen_int_mode (0x7fffffff, SImode);
10005       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10006     }
10007   else
10008     {
10009       tmp = gen_int_mode (0x80000000, SImode);
10010       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10011     }
10012   operands[1] = tmp;
10013 })
10014
10015 (define_split
10016   [(set (match_operand:DF 0 "register_operand" "")
10017         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10018    (use (match_operand 2 "" ""))
10019    (clobber (reg:CC FLAGS_REG))]
10020   "reload_completed"
10021   [(parallel [(set (match_dup 0) (match_dup 1))
10022               (clobber (reg:CC FLAGS_REG))])]
10023 {
10024   rtx tmp;
10025   if (TARGET_64BIT)
10026     {
10027       tmp = gen_lowpart (DImode, operands[0]);
10028       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10029       operands[0] = tmp;
10030
10031       if (GET_CODE (operands[1]) == ABS)
10032         tmp = const0_rtx;
10033       else
10034         tmp = gen_rtx_NOT (DImode, tmp);
10035     }
10036   else
10037     {
10038       operands[0] = gen_highpart (SImode, operands[0]);
10039       if (GET_CODE (operands[1]) == ABS)
10040         {
10041           tmp = gen_int_mode (0x7fffffff, SImode);
10042           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10043         }
10044       else
10045         {
10046           tmp = gen_int_mode (0x80000000, SImode);
10047           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10048         }
10049     }
10050   operands[1] = tmp;
10051 })
10052
10053 (define_split
10054   [(set (match_operand:XF 0 "register_operand" "")
10055         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10056    (use (match_operand 2 "" ""))
10057    (clobber (reg:CC FLAGS_REG))]
10058   "reload_completed"
10059   [(parallel [(set (match_dup 0) (match_dup 1))
10060               (clobber (reg:CC FLAGS_REG))])]
10061 {
10062   rtx tmp;
10063   operands[0] = gen_rtx_REG (SImode,
10064                              true_regnum (operands[0])
10065                              + (TARGET_64BIT ? 1 : 2));
10066   if (GET_CODE (operands[1]) == ABS)
10067     {
10068       tmp = GEN_INT (0x7fff);
10069       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10070     }
10071   else
10072     {
10073       tmp = GEN_INT (0x8000);
10074       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10075     }
10076   operands[1] = tmp;
10077 })
10078
10079 (define_split
10080   [(set (match_operand 0 "memory_operand" "")
10081         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10082    (use (match_operand 2 "" ""))
10083    (clobber (reg:CC FLAGS_REG))]
10084   "reload_completed"
10085   [(parallel [(set (match_dup 0) (match_dup 1))
10086               (clobber (reg:CC FLAGS_REG))])]
10087 {
10088   enum machine_mode mode = GET_MODE (operands[0]);
10089   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10090   rtx tmp;
10091
10092   operands[0] = adjust_address (operands[0], QImode, size - 1);
10093   if (GET_CODE (operands[1]) == ABS)
10094     {
10095       tmp = gen_int_mode (0x7f, QImode);
10096       tmp = gen_rtx_AND (QImode, operands[0], tmp);
10097     }
10098   else
10099     {
10100       tmp = gen_int_mode (0x80, QImode);
10101       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10102     }
10103   operands[1] = tmp;
10104 })
10105
10106 ;; Conditionalize these after reload. If they match before reload, we
10107 ;; lose the clobber and ability to use integer instructions.
10108
10109 (define_insn "*negsf2_1"
10110   [(set (match_operand:SF 0 "register_operand" "=f")
10111         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10112   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10113   "fchs"
10114   [(set_attr "type" "fsgn")
10115    (set_attr "mode" "SF")])
10116
10117 (define_insn "*negdf2_1"
10118   [(set (match_operand:DF 0 "register_operand" "=f")
10119         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10120   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10121   "fchs"
10122   [(set_attr "type" "fsgn")
10123    (set_attr "mode" "DF")])
10124
10125 (define_insn "*negxf2_1"
10126   [(set (match_operand:XF 0 "register_operand" "=f")
10127         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10128   "TARGET_80387"
10129   "fchs"
10130   [(set_attr "type" "fsgn")
10131    (set_attr "mode" "XF")])
10132
10133 (define_insn "*abssf2_1"
10134   [(set (match_operand:SF 0 "register_operand" "=f")
10135         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10136   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10137   "fabs"
10138   [(set_attr "type" "fsgn")
10139    (set_attr "mode" "SF")])
10140
10141 (define_insn "*absdf2_1"
10142   [(set (match_operand:DF 0 "register_operand" "=f")
10143         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10144   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10145   "fabs"
10146   [(set_attr "type" "fsgn")
10147    (set_attr "mode" "DF")])
10148
10149 (define_insn "*absxf2_1"
10150   [(set (match_operand:XF 0 "register_operand" "=f")
10151         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10152   "TARGET_80387"
10153   "fabs"
10154   [(set_attr "type" "fsgn")
10155    (set_attr "mode" "DF")])
10156
10157 (define_insn "*negextendsfdf2"
10158   [(set (match_operand:DF 0 "register_operand" "=f")
10159         (neg:DF (float_extend:DF
10160                   (match_operand:SF 1 "register_operand" "0"))))]
10161   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10162   "fchs"
10163   [(set_attr "type" "fsgn")
10164    (set_attr "mode" "DF")])
10165
10166 (define_insn "*negextenddfxf2"
10167   [(set (match_operand:XF 0 "register_operand" "=f")
10168         (neg:XF (float_extend:XF
10169                   (match_operand:DF 1 "register_operand" "0"))))]
10170   "TARGET_80387"
10171   "fchs"
10172   [(set_attr "type" "fsgn")
10173    (set_attr "mode" "XF")])
10174
10175 (define_insn "*negextendsfxf2"
10176   [(set (match_operand:XF 0 "register_operand" "=f")
10177         (neg:XF (float_extend:XF
10178                   (match_operand:SF 1 "register_operand" "0"))))]
10179   "TARGET_80387"
10180   "fchs"
10181   [(set_attr "type" "fsgn")
10182    (set_attr "mode" "XF")])
10183
10184 (define_insn "*absextendsfdf2"
10185   [(set (match_operand:DF 0 "register_operand" "=f")
10186         (abs:DF (float_extend:DF
10187                   (match_operand:SF 1 "register_operand" "0"))))]
10188   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10189   "fabs"
10190   [(set_attr "type" "fsgn")
10191    (set_attr "mode" "DF")])
10192
10193 (define_insn "*absextenddfxf2"
10194   [(set (match_operand:XF 0 "register_operand" "=f")
10195         (abs:XF (float_extend:XF
10196           (match_operand:DF 1 "register_operand" "0"))))]
10197   "TARGET_80387"
10198   "fabs"
10199   [(set_attr "type" "fsgn")
10200    (set_attr "mode" "XF")])
10201
10202 (define_insn "*absextendsfxf2"
10203   [(set (match_operand:XF 0 "register_operand" "=f")
10204         (abs:XF (float_extend:XF
10205           (match_operand:SF 1 "register_operand" "0"))))]
10206   "TARGET_80387"
10207   "fabs"
10208   [(set_attr "type" "fsgn")
10209    (set_attr "mode" "XF")])
10210
10211 ;; Copysign instructions
10212
10213 (define_mode_iterator CSGNMODE [SF DF TF])
10214 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10215
10216 (define_expand "copysign<mode>3"
10217   [(match_operand:CSGNMODE 0 "register_operand" "")
10218    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10219    (match_operand:CSGNMODE 2 "register_operand" "")]
10220   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10221    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10222 {
10223   ix86_expand_copysign (operands);
10224   DONE;
10225 })
10226
10227 (define_insn_and_split "copysign<mode>3_const"
10228   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10229         (unspec:CSGNMODE
10230           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10231            (match_operand:CSGNMODE 2 "register_operand" "0")
10232            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10233           UNSPEC_COPYSIGN))]
10234   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10235    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10236   "#"
10237   "&& reload_completed"
10238   [(const_int 0)]
10239 {
10240   ix86_split_copysign_const (operands);
10241   DONE;
10242 })
10243
10244 (define_insn "copysign<mode>3_var"
10245   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10246         (unspec:CSGNMODE
10247           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10248            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10249            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10250            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10251           UNSPEC_COPYSIGN))
10252    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10253   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10254    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10255   "#")
10256
10257 (define_split
10258   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10259         (unspec:CSGNMODE
10260           [(match_operand:CSGNMODE 2 "register_operand" "")
10261            (match_operand:CSGNMODE 3 "register_operand" "")
10262            (match_operand:<CSGNVMODE> 4 "" "")
10263            (match_operand:<CSGNVMODE> 5 "" "")]
10264           UNSPEC_COPYSIGN))
10265    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10266   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10267     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10268    && reload_completed"
10269   [(const_int 0)]
10270 {
10271   ix86_split_copysign_var (operands);
10272   DONE;
10273 })
10274 \f
10275 ;; One complement instructions
10276
10277 (define_expand "one_cmpldi2"
10278   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10279         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10280   "TARGET_64BIT"
10281   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10282
10283 (define_insn "*one_cmpldi2_1_rex64"
10284   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10285         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10286   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10287   "not{q}\t%0"
10288   [(set_attr "type" "negnot")
10289    (set_attr "mode" "DI")])
10290
10291 (define_insn "*one_cmpldi2_2_rex64"
10292   [(set (reg FLAGS_REG)
10293         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10294                  (const_int 0)))
10295    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10296         (not:DI (match_dup 1)))]
10297   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10298    && ix86_unary_operator_ok (NOT, DImode, operands)"
10299   "#"
10300   [(set_attr "type" "alu1")
10301    (set_attr "mode" "DI")])
10302
10303 (define_split
10304   [(set (match_operand 0 "flags_reg_operand" "")
10305         (match_operator 2 "compare_operator"
10306           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10307            (const_int 0)]))
10308    (set (match_operand:DI 1 "nonimmediate_operand" "")
10309         (not:DI (match_dup 3)))]
10310   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10311   [(parallel [(set (match_dup 0)
10312                    (match_op_dup 2
10313                      [(xor:DI (match_dup 3) (const_int -1))
10314                       (const_int 0)]))
10315               (set (match_dup 1)
10316                    (xor:DI (match_dup 3) (const_int -1)))])]
10317   "")
10318
10319 (define_expand "one_cmplsi2"
10320   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10321         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10322   ""
10323   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10324
10325 (define_insn "*one_cmplsi2_1"
10326   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10327         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10328   "ix86_unary_operator_ok (NOT, SImode, operands)"
10329   "not{l}\t%0"
10330   [(set_attr "type" "negnot")
10331    (set_attr "mode" "SI")])
10332
10333 ;; ??? Currently never generated - xor is used instead.
10334 (define_insn "*one_cmplsi2_1_zext"
10335   [(set (match_operand:DI 0 "register_operand" "=r")
10336         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10337   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10338   "not{l}\t%k0"
10339   [(set_attr "type" "negnot")
10340    (set_attr "mode" "SI")])
10341
10342 (define_insn "*one_cmplsi2_2"
10343   [(set (reg FLAGS_REG)
10344         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10345                  (const_int 0)))
10346    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10347         (not:SI (match_dup 1)))]
10348   "ix86_match_ccmode (insn, CCNOmode)
10349    && ix86_unary_operator_ok (NOT, SImode, operands)"
10350   "#"
10351   [(set_attr "type" "alu1")
10352    (set_attr "mode" "SI")])
10353
10354 (define_split
10355   [(set (match_operand 0 "flags_reg_operand" "")
10356         (match_operator 2 "compare_operator"
10357           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10358            (const_int 0)]))
10359    (set (match_operand:SI 1 "nonimmediate_operand" "")
10360         (not:SI (match_dup 3)))]
10361   "ix86_match_ccmode (insn, CCNOmode)"
10362   [(parallel [(set (match_dup 0)
10363                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10364                                     (const_int 0)]))
10365               (set (match_dup 1)
10366                    (xor:SI (match_dup 3) (const_int -1)))])]
10367   "")
10368
10369 ;; ??? Currently never generated - xor is used instead.
10370 (define_insn "*one_cmplsi2_2_zext"
10371   [(set (reg FLAGS_REG)
10372         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10373                  (const_int 0)))
10374    (set (match_operand:DI 0 "register_operand" "=r")
10375         (zero_extend:DI (not:SI (match_dup 1))))]
10376   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10377    && ix86_unary_operator_ok (NOT, SImode, operands)"
10378   "#"
10379   [(set_attr "type" "alu1")
10380    (set_attr "mode" "SI")])
10381
10382 (define_split
10383   [(set (match_operand 0 "flags_reg_operand" "")
10384         (match_operator 2 "compare_operator"
10385           [(not:SI (match_operand:SI 3 "register_operand" ""))
10386            (const_int 0)]))
10387    (set (match_operand:DI 1 "register_operand" "")
10388         (zero_extend:DI (not:SI (match_dup 3))))]
10389   "ix86_match_ccmode (insn, CCNOmode)"
10390   [(parallel [(set (match_dup 0)
10391                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10392                                     (const_int 0)]))
10393               (set (match_dup 1)
10394                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10395   "")
10396
10397 (define_expand "one_cmplhi2"
10398   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10399         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10400   "TARGET_HIMODE_MATH"
10401   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10402
10403 (define_insn "*one_cmplhi2_1"
10404   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10405         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10406   "ix86_unary_operator_ok (NOT, HImode, operands)"
10407   "not{w}\t%0"
10408   [(set_attr "type" "negnot")
10409    (set_attr "mode" "HI")])
10410
10411 (define_insn "*one_cmplhi2_2"
10412   [(set (reg FLAGS_REG)
10413         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10414                  (const_int 0)))
10415    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10416         (not:HI (match_dup 1)))]
10417   "ix86_match_ccmode (insn, CCNOmode)
10418    && ix86_unary_operator_ok (NEG, HImode, operands)"
10419   "#"
10420   [(set_attr "type" "alu1")
10421    (set_attr "mode" "HI")])
10422
10423 (define_split
10424   [(set (match_operand 0 "flags_reg_operand" "")
10425         (match_operator 2 "compare_operator"
10426           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10427            (const_int 0)]))
10428    (set (match_operand:HI 1 "nonimmediate_operand" "")
10429         (not:HI (match_dup 3)))]
10430   "ix86_match_ccmode (insn, CCNOmode)"
10431   [(parallel [(set (match_dup 0)
10432                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10433                                     (const_int 0)]))
10434               (set (match_dup 1)
10435                    (xor:HI (match_dup 3) (const_int -1)))])]
10436   "")
10437
10438 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10439 (define_expand "one_cmplqi2"
10440   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10441         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10442   "TARGET_QIMODE_MATH"
10443   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10444
10445 (define_insn "*one_cmplqi2_1"
10446   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10447         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10448   "ix86_unary_operator_ok (NOT, QImode, operands)"
10449   "@
10450    not{b}\t%0
10451    not{l}\t%k0"
10452   [(set_attr "type" "negnot")
10453    (set_attr "mode" "QI,SI")])
10454
10455 (define_insn "*one_cmplqi2_2"
10456   [(set (reg FLAGS_REG)
10457         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10458                  (const_int 0)))
10459    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10460         (not:QI (match_dup 1)))]
10461   "ix86_match_ccmode (insn, CCNOmode)
10462    && ix86_unary_operator_ok (NOT, QImode, operands)"
10463   "#"
10464   [(set_attr "type" "alu1")
10465    (set_attr "mode" "QI")])
10466
10467 (define_split
10468   [(set (match_operand 0 "flags_reg_operand" "")
10469         (match_operator 2 "compare_operator"
10470           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10471            (const_int 0)]))
10472    (set (match_operand:QI 1 "nonimmediate_operand" "")
10473         (not:QI (match_dup 3)))]
10474   "ix86_match_ccmode (insn, CCNOmode)"
10475   [(parallel [(set (match_dup 0)
10476                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10477                                     (const_int 0)]))
10478               (set (match_dup 1)
10479                    (xor:QI (match_dup 3) (const_int -1)))])]
10480   "")
10481 \f
10482 ;; Arithmetic shift instructions
10483
10484 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10485 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10486 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10487 ;; from the assembler input.
10488 ;;
10489 ;; This instruction shifts the target reg/mem as usual, but instead of
10490 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10491 ;; is a left shift double, bits are taken from the high order bits of
10492 ;; reg, else if the insn is a shift right double, bits are taken from the
10493 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10494 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10495 ;;
10496 ;; Since sh[lr]d does not change the `reg' operand, that is done
10497 ;; separately, making all shifts emit pairs of shift double and normal
10498 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10499 ;; support a 63 bit shift, each shift where the count is in a reg expands
10500 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10501 ;;
10502 ;; If the shift count is a constant, we need never emit more than one
10503 ;; shift pair, instead using moves and sign extension for counts greater
10504 ;; than 31.
10505
10506 (define_expand "ashlti3"
10507   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10508                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10509                               (match_operand:QI 2 "nonmemory_operand" "")))
10510               (clobber (reg:CC FLAGS_REG))])]
10511   "TARGET_64BIT"
10512 {
10513   if (! immediate_operand (operands[2], QImode))
10514     {
10515       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10516       DONE;
10517     }
10518   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10519   DONE;
10520 })
10521
10522 (define_insn "ashlti3_1"
10523   [(set (match_operand:TI 0 "register_operand" "=r")
10524         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10525                    (match_operand:QI 2 "register_operand" "c")))
10526    (clobber (match_scratch:DI 3 "=&r"))
10527    (clobber (reg:CC FLAGS_REG))]
10528   "TARGET_64BIT"
10529   "#"
10530   [(set_attr "type" "multi")])
10531
10532 ;; This pattern must be defined before *ashlti3_2 to prevent
10533 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10534
10535 (define_insn "sse2_ashlti3"
10536   [(set (match_operand:TI 0 "register_operand" "=x")
10537         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10538                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10539   "TARGET_SSE2"
10540 {
10541   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10542   return "pslldq\t{%2, %0|%0, %2}";
10543 }
10544   [(set_attr "type" "sseishft")
10545    (set_attr "prefix_data16" "1")
10546    (set_attr "mode" "TI")])
10547
10548 (define_insn "*ashlti3_2"
10549   [(set (match_operand:TI 0 "register_operand" "=r")
10550         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10551                    (match_operand:QI 2 "immediate_operand" "O")))
10552    (clobber (reg:CC FLAGS_REG))]
10553   "TARGET_64BIT"
10554   "#"
10555   [(set_attr "type" "multi")])
10556
10557 (define_split
10558   [(set (match_operand:TI 0 "register_operand" "")
10559         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10560                    (match_operand:QI 2 "register_operand" "")))
10561    (clobber (match_scratch:DI 3 ""))
10562    (clobber (reg:CC FLAGS_REG))]
10563   "TARGET_64BIT && reload_completed"
10564   [(const_int 0)]
10565   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10566
10567 (define_split
10568   [(set (match_operand:TI 0 "register_operand" "")
10569         (ashift:TI (match_operand:TI 1 "register_operand" "")
10570                    (match_operand:QI 2 "immediate_operand" "")))
10571    (clobber (reg:CC FLAGS_REG))]
10572   "TARGET_64BIT && reload_completed"
10573   [(const_int 0)]
10574   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10575
10576 (define_insn "x86_64_shld"
10577   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10578         (ior:DI (ashift:DI (match_dup 0)
10579                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10580                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10581                   (minus:QI (const_int 64) (match_dup 2)))))
10582    (clobber (reg:CC FLAGS_REG))]
10583   "TARGET_64BIT"
10584   "@
10585    shld{q}\t{%2, %1, %0|%0, %1, %2}
10586    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10587   [(set_attr "type" "ishift")
10588    (set_attr "prefix_0f" "1")
10589    (set_attr "mode" "DI")
10590    (set_attr "athlon_decode" "vector")
10591    (set_attr "amdfam10_decode" "vector")])   
10592
10593 (define_expand "x86_64_shift_adj"
10594   [(set (reg:CCZ FLAGS_REG)
10595         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10596                              (const_int 64))
10597                      (const_int 0)))
10598    (set (match_operand:DI 0 "register_operand" "")
10599         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10600                          (match_operand:DI 1 "register_operand" "")
10601                          (match_dup 0)))
10602    (set (match_dup 1)
10603         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10604                          (match_operand:DI 3 "register_operand" "r")
10605                          (match_dup 1)))]
10606   "TARGET_64BIT"
10607   "")
10608
10609 (define_expand "ashldi3"
10610   [(set (match_operand:DI 0 "shiftdi_operand" "")
10611         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10612                    (match_operand:QI 2 "nonmemory_operand" "")))]
10613   ""
10614   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10615
10616 (define_insn "*ashldi3_1_rex64"
10617   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10618         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10619                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10620    (clobber (reg:CC FLAGS_REG))]
10621   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10622 {
10623   switch (get_attr_type (insn))
10624     {
10625     case TYPE_ALU:
10626       gcc_assert (operands[2] == const1_rtx);
10627       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10628       return "add{q}\t%0, %0";
10629
10630     case TYPE_LEA:
10631       gcc_assert (CONST_INT_P (operands[2]));
10632       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10633       operands[1] = gen_rtx_MULT (DImode, operands[1],
10634                                   GEN_INT (1 << INTVAL (operands[2])));
10635       return "lea{q}\t{%a1, %0|%0, %a1}";
10636
10637     default:
10638       if (REG_P (operands[2]))
10639         return "sal{q}\t{%b2, %0|%0, %b2}";
10640       else if (operands[2] == const1_rtx
10641                && (TARGET_SHIFT1 || optimize_size))
10642         return "sal{q}\t%0";
10643       else
10644         return "sal{q}\t{%2, %0|%0, %2}";
10645     }
10646 }
10647   [(set (attr "type")
10648      (cond [(eq_attr "alternative" "1")
10649               (const_string "lea")
10650             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10651                           (const_int 0))
10652                       (match_operand 0 "register_operand" ""))
10653                  (match_operand 2 "const1_operand" ""))
10654               (const_string "alu")
10655            ]
10656            (const_string "ishift")))
10657    (set_attr "mode" "DI")])
10658
10659 ;; Convert lea to the lea pattern to avoid flags dependency.
10660 (define_split
10661   [(set (match_operand:DI 0 "register_operand" "")
10662         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10663                    (match_operand:QI 2 "immediate_operand" "")))
10664    (clobber (reg:CC FLAGS_REG))]
10665   "TARGET_64BIT && reload_completed
10666    && true_regnum (operands[0]) != true_regnum (operands[1])"
10667   [(set (match_dup 0)
10668         (mult:DI (match_dup 1)
10669                  (match_dup 2)))]
10670   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10671
10672 ;; This pattern can't accept a variable shift count, since shifts by
10673 ;; zero don't affect the flags.  We assume that shifts by constant
10674 ;; zero are optimized away.
10675 (define_insn "*ashldi3_cmp_rex64"
10676   [(set (reg FLAGS_REG)
10677         (compare
10678           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10679                      (match_operand:QI 2 "immediate_operand" "e"))
10680           (const_int 0)))
10681    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10682         (ashift:DI (match_dup 1) (match_dup 2)))]
10683   "TARGET_64BIT
10684    && (optimize_size
10685        || !TARGET_PARTIAL_FLAG_REG_STALL
10686        || (operands[2] == const1_rtx
10687            && (TARGET_SHIFT1
10688                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10689    && ix86_match_ccmode (insn, CCGOCmode)
10690    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10691 {
10692   switch (get_attr_type (insn))
10693     {
10694     case TYPE_ALU:
10695       gcc_assert (operands[2] == const1_rtx);
10696       return "add{q}\t%0, %0";
10697
10698     default:
10699       if (REG_P (operands[2]))
10700         return "sal{q}\t{%b2, %0|%0, %b2}";
10701       else if (operands[2] == const1_rtx
10702                && (TARGET_SHIFT1 || optimize_size))
10703         return "sal{q}\t%0";
10704       else
10705         return "sal{q}\t{%2, %0|%0, %2}";
10706     }
10707 }
10708   [(set (attr "type")
10709      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10710                           (const_int 0))
10711                       (match_operand 0 "register_operand" ""))
10712                  (match_operand 2 "const1_operand" ""))
10713               (const_string "alu")
10714            ]
10715            (const_string "ishift")))
10716    (set_attr "mode" "DI")])
10717
10718 (define_insn "*ashldi3_cconly_rex64"
10719   [(set (reg FLAGS_REG)
10720         (compare
10721           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10722                      (match_operand:QI 2 "immediate_operand" "e"))
10723           (const_int 0)))
10724    (clobber (match_scratch:DI 0 "=r"))]
10725   "TARGET_64BIT
10726    && (optimize_size
10727        || !TARGET_PARTIAL_FLAG_REG_STALL
10728        || (operands[2] == const1_rtx
10729            && (TARGET_SHIFT1
10730                || TARGET_DOUBLE_WITH_ADD)))
10731    && ix86_match_ccmode (insn, CCGOCmode)
10732    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10733 {
10734   switch (get_attr_type (insn))
10735     {
10736     case TYPE_ALU:
10737       gcc_assert (operands[2] == const1_rtx);
10738       return "add{q}\t%0, %0";
10739
10740     default:
10741       if (REG_P (operands[2]))
10742         return "sal{q}\t{%b2, %0|%0, %b2}";
10743       else if (operands[2] == const1_rtx
10744                && (TARGET_SHIFT1 || optimize_size))
10745         return "sal{q}\t%0";
10746       else
10747         return "sal{q}\t{%2, %0|%0, %2}";
10748     }
10749 }
10750   [(set (attr "type")
10751      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10752                           (const_int 0))
10753                       (match_operand 0 "register_operand" ""))
10754                  (match_operand 2 "const1_operand" ""))
10755               (const_string "alu")
10756            ]
10757            (const_string "ishift")))
10758    (set_attr "mode" "DI")])
10759
10760 (define_insn "*ashldi3_1"
10761   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10762         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10763                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10764    (clobber (reg:CC FLAGS_REG))]
10765   "!TARGET_64BIT"
10766   "#"
10767   [(set_attr "type" "multi")])
10768
10769 ;; By default we don't ask for a scratch register, because when DImode
10770 ;; values are manipulated, registers are already at a premium.  But if
10771 ;; we have one handy, we won't turn it away.
10772 (define_peephole2
10773   [(match_scratch:SI 3 "r")
10774    (parallel [(set (match_operand:DI 0 "register_operand" "")
10775                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10776                               (match_operand:QI 2 "nonmemory_operand" "")))
10777               (clobber (reg:CC FLAGS_REG))])
10778    (match_dup 3)]
10779   "!TARGET_64BIT && TARGET_CMOVE"
10780   [(const_int 0)]
10781   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10782
10783 (define_split
10784   [(set (match_operand:DI 0 "register_operand" "")
10785         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10786                    (match_operand:QI 2 "nonmemory_operand" "")))
10787    (clobber (reg:CC FLAGS_REG))]
10788   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10789                      ? epilogue_completed : reload_completed)"
10790   [(const_int 0)]
10791   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10792
10793 (define_insn "x86_shld_1"
10794   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10795         (ior:SI (ashift:SI (match_dup 0)
10796                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10797                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10798                   (minus:QI (const_int 32) (match_dup 2)))))
10799    (clobber (reg:CC FLAGS_REG))]
10800   ""
10801   "@
10802    shld{l}\t{%2, %1, %0|%0, %1, %2}
10803    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10804   [(set_attr "type" "ishift")
10805    (set_attr "prefix_0f" "1")
10806    (set_attr "mode" "SI")
10807    (set_attr "pent_pair" "np")
10808    (set_attr "athlon_decode" "vector")
10809    (set_attr "amdfam10_decode" "vector")])   
10810
10811 (define_expand "x86_shift_adj_1"
10812   [(set (reg:CCZ FLAGS_REG)
10813         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10814                              (const_int 32))
10815                      (const_int 0)))
10816    (set (match_operand:SI 0 "register_operand" "")
10817         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10818                          (match_operand:SI 1 "register_operand" "")
10819                          (match_dup 0)))
10820    (set (match_dup 1)
10821         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10822                          (match_operand:SI 3 "register_operand" "r")
10823                          (match_dup 1)))]
10824   "TARGET_CMOVE"
10825   "")
10826
10827 (define_expand "x86_shift_adj_2"
10828   [(use (match_operand:SI 0 "register_operand" ""))
10829    (use (match_operand:SI 1 "register_operand" ""))
10830    (use (match_operand:QI 2 "register_operand" ""))]
10831   ""
10832 {
10833   rtx label = gen_label_rtx ();
10834   rtx tmp;
10835
10836   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10837
10838   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10839   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10840   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10841                               gen_rtx_LABEL_REF (VOIDmode, label),
10842                               pc_rtx);
10843   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10844   JUMP_LABEL (tmp) = label;
10845
10846   emit_move_insn (operands[0], operands[1]);
10847   ix86_expand_clear (operands[1]);
10848
10849   emit_label (label);
10850   LABEL_NUSES (label) = 1;
10851
10852   DONE;
10853 })
10854
10855 (define_expand "ashlsi3"
10856   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10857         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10858                    (match_operand:QI 2 "nonmemory_operand" "")))
10859    (clobber (reg:CC FLAGS_REG))]
10860   ""
10861   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10862
10863 (define_insn "*ashlsi3_1"
10864   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10865         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10866                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10867    (clobber (reg:CC FLAGS_REG))]
10868   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10869 {
10870   switch (get_attr_type (insn))
10871     {
10872     case TYPE_ALU:
10873       gcc_assert (operands[2] == const1_rtx);
10874       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10875       return "add{l}\t%0, %0";
10876
10877     case TYPE_LEA:
10878       return "#";
10879
10880     default:
10881       if (REG_P (operands[2]))
10882         return "sal{l}\t{%b2, %0|%0, %b2}";
10883       else if (operands[2] == const1_rtx
10884                && (TARGET_SHIFT1 || optimize_size))
10885         return "sal{l}\t%0";
10886       else
10887         return "sal{l}\t{%2, %0|%0, %2}";
10888     }
10889 }
10890   [(set (attr "type")
10891      (cond [(eq_attr "alternative" "1")
10892               (const_string "lea")
10893             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10894                           (const_int 0))
10895                       (match_operand 0 "register_operand" ""))
10896                  (match_operand 2 "const1_operand" ""))
10897               (const_string "alu")
10898            ]
10899            (const_string "ishift")))
10900    (set_attr "mode" "SI")])
10901
10902 ;; Convert lea to the lea pattern to avoid flags dependency.
10903 (define_split
10904   [(set (match_operand 0 "register_operand" "")
10905         (ashift (match_operand 1 "index_register_operand" "")
10906                 (match_operand:QI 2 "const_int_operand" "")))
10907    (clobber (reg:CC FLAGS_REG))]
10908   "reload_completed
10909    && true_regnum (operands[0]) != true_regnum (operands[1])
10910    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10911   [(const_int 0)]
10912 {
10913   rtx pat;
10914   enum machine_mode mode = GET_MODE (operands[0]);
10915
10916   if (GET_MODE_SIZE (mode) < 4)
10917     operands[0] = gen_lowpart (SImode, operands[0]);
10918   if (mode != Pmode)
10919     operands[1] = gen_lowpart (Pmode, operands[1]);
10920   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10921
10922   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10923   if (Pmode != SImode)
10924     pat = gen_rtx_SUBREG (SImode, pat, 0);
10925   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10926   DONE;
10927 })
10928
10929 ;; Rare case of shifting RSP is handled by generating move and shift
10930 (define_split
10931   [(set (match_operand 0 "register_operand" "")
10932         (ashift (match_operand 1 "register_operand" "")
10933                 (match_operand:QI 2 "const_int_operand" "")))
10934    (clobber (reg:CC FLAGS_REG))]
10935   "reload_completed
10936    && true_regnum (operands[0]) != true_regnum (operands[1])"
10937   [(const_int 0)]
10938 {
10939   rtx pat, clob;
10940   emit_move_insn (operands[0], operands[1]);
10941   pat = gen_rtx_SET (VOIDmode, operands[0],
10942                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10943                                      operands[0], operands[2]));
10944   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10945   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10946   DONE;
10947 })
10948
10949 (define_insn "*ashlsi3_1_zext"
10950   [(set (match_operand:DI 0 "register_operand" "=r,r")
10951         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10952                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10953    (clobber (reg:CC FLAGS_REG))]
10954   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10955 {
10956   switch (get_attr_type (insn))
10957     {
10958     case TYPE_ALU:
10959       gcc_assert (operands[2] == const1_rtx);
10960       return "add{l}\t%k0, %k0";
10961
10962     case TYPE_LEA:
10963       return "#";
10964
10965     default:
10966       if (REG_P (operands[2]))
10967         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10968       else if (operands[2] == const1_rtx
10969                && (TARGET_SHIFT1 || optimize_size))
10970         return "sal{l}\t%k0";
10971       else
10972         return "sal{l}\t{%2, %k0|%k0, %2}";
10973     }
10974 }
10975   [(set (attr "type")
10976      (cond [(eq_attr "alternative" "1")
10977               (const_string "lea")
10978             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10979                      (const_int 0))
10980                  (match_operand 2 "const1_operand" ""))
10981               (const_string "alu")
10982            ]
10983            (const_string "ishift")))
10984    (set_attr "mode" "SI")])
10985
10986 ;; Convert lea to the lea pattern to avoid flags dependency.
10987 (define_split
10988   [(set (match_operand:DI 0 "register_operand" "")
10989         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10990                                 (match_operand:QI 2 "const_int_operand" ""))))
10991    (clobber (reg:CC FLAGS_REG))]
10992   "TARGET_64BIT && reload_completed
10993    && true_regnum (operands[0]) != true_regnum (operands[1])"
10994   [(set (match_dup 0) (zero_extend:DI
10995                         (subreg:SI (mult:SI (match_dup 1)
10996                                             (match_dup 2)) 0)))]
10997 {
10998   operands[1] = gen_lowpart (Pmode, operands[1]);
10999   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11000 })
11001
11002 ;; This pattern can't accept a variable shift count, since shifts by
11003 ;; zero don't affect the flags.  We assume that shifts by constant
11004 ;; zero are optimized away.
11005 (define_insn "*ashlsi3_cmp"
11006   [(set (reg FLAGS_REG)
11007         (compare
11008           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11009                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11010           (const_int 0)))
11011    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11012         (ashift:SI (match_dup 1) (match_dup 2)))]
11013    "(optimize_size
11014      || !TARGET_PARTIAL_FLAG_REG_STALL
11015      || (operands[2] == const1_rtx
11016          && (TARGET_SHIFT1
11017              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11018    && ix86_match_ccmode (insn, CCGOCmode)
11019    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11020 {
11021   switch (get_attr_type (insn))
11022     {
11023     case TYPE_ALU:
11024       gcc_assert (operands[2] == const1_rtx);
11025       return "add{l}\t%0, %0";
11026
11027     default:
11028       if (REG_P (operands[2]))
11029         return "sal{l}\t{%b2, %0|%0, %b2}";
11030       else if (operands[2] == const1_rtx
11031                && (TARGET_SHIFT1 || optimize_size))
11032         return "sal{l}\t%0";
11033       else
11034         return "sal{l}\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" "SI")])
11046
11047 (define_insn "*ashlsi3_cconly"
11048   [(set (reg FLAGS_REG)
11049         (compare
11050           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11051                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11052           (const_int 0)))
11053    (clobber (match_scratch:SI 0 "=r"))]
11054   "(optimize_size
11055     || !TARGET_PARTIAL_FLAG_REG_STALL
11056     || (operands[2] == const1_rtx
11057         && (TARGET_SHIFT1
11058             || TARGET_DOUBLE_WITH_ADD)))
11059    && ix86_match_ccmode (insn, CCGOCmode)
11060    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11061 {
11062   switch (get_attr_type (insn))
11063     {
11064     case TYPE_ALU:
11065       gcc_assert (operands[2] == const1_rtx);
11066       return "add{l}\t%0, %0";
11067
11068     default:
11069       if (REG_P (operands[2]))
11070         return "sal{l}\t{%b2, %0|%0, %b2}";
11071       else if (operands[2] == const1_rtx
11072                && (TARGET_SHIFT1 || optimize_size))
11073         return "sal{l}\t%0";
11074       else
11075         return "sal{l}\t{%2, %0|%0, %2}";
11076     }
11077 }
11078   [(set (attr "type")
11079      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11080                           (const_int 0))
11081                       (match_operand 0 "register_operand" ""))
11082                  (match_operand 2 "const1_operand" ""))
11083               (const_string "alu")
11084            ]
11085            (const_string "ishift")))
11086    (set_attr "mode" "SI")])
11087
11088 (define_insn "*ashlsi3_cmp_zext"
11089   [(set (reg FLAGS_REG)
11090         (compare
11091           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11092                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11093           (const_int 0)))
11094    (set (match_operand:DI 0 "register_operand" "=r")
11095         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11096   "TARGET_64BIT
11097    && (optimize_size
11098        || !TARGET_PARTIAL_FLAG_REG_STALL
11099        || (operands[2] == const1_rtx
11100            && (TARGET_SHIFT1
11101                || TARGET_DOUBLE_WITH_ADD)))
11102    && ix86_match_ccmode (insn, CCGOCmode)
11103    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11104 {
11105   switch (get_attr_type (insn))
11106     {
11107     case TYPE_ALU:
11108       gcc_assert (operands[2] == const1_rtx);
11109       return "add{l}\t%k0, %k0";
11110
11111     default:
11112       if (REG_P (operands[2]))
11113         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11114       else if (operands[2] == const1_rtx
11115                && (TARGET_SHIFT1 || optimize_size))
11116         return "sal{l}\t%k0";
11117       else
11118         return "sal{l}\t{%2, %k0|%k0, %2}";
11119     }
11120 }
11121   [(set (attr "type")
11122      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11123                      (const_int 0))
11124                  (match_operand 2 "const1_operand" ""))
11125               (const_string "alu")
11126            ]
11127            (const_string "ishift")))
11128    (set_attr "mode" "SI")])
11129
11130 (define_expand "ashlhi3"
11131   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11132         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11133                    (match_operand:QI 2 "nonmemory_operand" "")))
11134    (clobber (reg:CC FLAGS_REG))]
11135   "TARGET_HIMODE_MATH"
11136   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11137
11138 (define_insn "*ashlhi3_1_lea"
11139   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11140         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11141                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11142    (clobber (reg:CC FLAGS_REG))]
11143   "!TARGET_PARTIAL_REG_STALL
11144    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11145 {
11146   switch (get_attr_type (insn))
11147     {
11148     case TYPE_LEA:
11149       return "#";
11150     case TYPE_ALU:
11151       gcc_assert (operands[2] == const1_rtx);
11152       return "add{w}\t%0, %0";
11153
11154     default:
11155       if (REG_P (operands[2]))
11156         return "sal{w}\t{%b2, %0|%0, %b2}";
11157       else if (operands[2] == const1_rtx
11158                && (TARGET_SHIFT1 || optimize_size))
11159         return "sal{w}\t%0";
11160       else
11161         return "sal{w}\t{%2, %0|%0, %2}";
11162     }
11163 }
11164   [(set (attr "type")
11165      (cond [(eq_attr "alternative" "1")
11166               (const_string "lea")
11167             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11168                           (const_int 0))
11169                       (match_operand 0 "register_operand" ""))
11170                  (match_operand 2 "const1_operand" ""))
11171               (const_string "alu")
11172            ]
11173            (const_string "ishift")))
11174    (set_attr "mode" "HI,SI")])
11175
11176 (define_insn "*ashlhi3_1"
11177   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11178         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11179                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11180    (clobber (reg:CC FLAGS_REG))]
11181   "TARGET_PARTIAL_REG_STALL
11182    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11183 {
11184   switch (get_attr_type (insn))
11185     {
11186     case TYPE_ALU:
11187       gcc_assert (operands[2] == const1_rtx);
11188       return "add{w}\t%0, %0";
11189
11190     default:
11191       if (REG_P (operands[2]))
11192         return "sal{w}\t{%b2, %0|%0, %b2}";
11193       else if (operands[2] == const1_rtx
11194                && (TARGET_SHIFT1 || optimize_size))
11195         return "sal{w}\t%0";
11196       else
11197         return "sal{w}\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" "HI")])
11209
11210 ;; This pattern can't accept a variable shift count, since shifts by
11211 ;; zero don't affect the flags.  We assume that shifts by constant
11212 ;; zero are optimized away.
11213 (define_insn "*ashlhi3_cmp"
11214   [(set (reg FLAGS_REG)
11215         (compare
11216           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11217                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11218           (const_int 0)))
11219    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11220         (ashift:HI (match_dup 1) (match_dup 2)))]
11221   "(optimize_size
11222     || !TARGET_PARTIAL_FLAG_REG_STALL
11223     || (operands[2] == const1_rtx
11224         && (TARGET_SHIFT1
11225             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11226    && ix86_match_ccmode (insn, CCGOCmode)
11227    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11228 {
11229   switch (get_attr_type (insn))
11230     {
11231     case TYPE_ALU:
11232       gcc_assert (operands[2] == const1_rtx);
11233       return "add{w}\t%0, %0";
11234
11235     default:
11236       if (REG_P (operands[2]))
11237         return "sal{w}\t{%b2, %0|%0, %b2}";
11238       else if (operands[2] == const1_rtx
11239                && (TARGET_SHIFT1 || optimize_size))
11240         return "sal{w}\t%0";
11241       else
11242         return "sal{w}\t{%2, %0|%0, %2}";
11243     }
11244 }
11245   [(set (attr "type")
11246      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11247                           (const_int 0))
11248                       (match_operand 0 "register_operand" ""))
11249                  (match_operand 2 "const1_operand" ""))
11250               (const_string "alu")
11251            ]
11252            (const_string "ishift")))
11253    (set_attr "mode" "HI")])
11254
11255 (define_insn "*ashlhi3_cconly"
11256   [(set (reg FLAGS_REG)
11257         (compare
11258           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11259                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11260           (const_int 0)))
11261    (clobber (match_scratch:HI 0 "=r"))]
11262   "(optimize_size
11263     || !TARGET_PARTIAL_FLAG_REG_STALL
11264     || (operands[2] == const1_rtx
11265         && (TARGET_SHIFT1
11266             || TARGET_DOUBLE_WITH_ADD)))
11267    && ix86_match_ccmode (insn, CCGOCmode)
11268    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11269 {
11270   switch (get_attr_type (insn))
11271     {
11272     case TYPE_ALU:
11273       gcc_assert (operands[2] == const1_rtx);
11274       return "add{w}\t%0, %0";
11275
11276     default:
11277       if (REG_P (operands[2]))
11278         return "sal{w}\t{%b2, %0|%0, %b2}";
11279       else if (operands[2] == const1_rtx
11280                && (TARGET_SHIFT1 || optimize_size))
11281         return "sal{w}\t%0";
11282       else
11283         return "sal{w}\t{%2, %0|%0, %2}";
11284     }
11285 }
11286   [(set (attr "type")
11287      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11288                           (const_int 0))
11289                       (match_operand 0 "register_operand" ""))
11290                  (match_operand 2 "const1_operand" ""))
11291               (const_string "alu")
11292            ]
11293            (const_string "ishift")))
11294    (set_attr "mode" "HI")])
11295
11296 (define_expand "ashlqi3"
11297   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11298         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11299                    (match_operand:QI 2 "nonmemory_operand" "")))
11300    (clobber (reg:CC FLAGS_REG))]
11301   "TARGET_QIMODE_MATH"
11302   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11303
11304 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11305
11306 (define_insn "*ashlqi3_1_lea"
11307   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11308         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11309                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11310    (clobber (reg:CC FLAGS_REG))]
11311   "!TARGET_PARTIAL_REG_STALL
11312    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11313 {
11314   switch (get_attr_type (insn))
11315     {
11316     case TYPE_LEA:
11317       return "#";
11318     case TYPE_ALU:
11319       gcc_assert (operands[2] == const1_rtx);
11320       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11321         return "add{l}\t%k0, %k0";
11322       else
11323         return "add{b}\t%0, %0";
11324
11325     default:
11326       if (REG_P (operands[2]))
11327         {
11328           if (get_attr_mode (insn) == MODE_SI)
11329             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11330           else
11331             return "sal{b}\t{%b2, %0|%0, %b2}";
11332         }
11333       else if (operands[2] == const1_rtx
11334                && (TARGET_SHIFT1 || optimize_size))
11335         {
11336           if (get_attr_mode (insn) == MODE_SI)
11337             return "sal{l}\t%0";
11338           else
11339             return "sal{b}\t%0";
11340         }
11341       else
11342         {
11343           if (get_attr_mode (insn) == MODE_SI)
11344             return "sal{l}\t{%2, %k0|%k0, %2}";
11345           else
11346             return "sal{b}\t{%2, %0|%0, %2}";
11347         }
11348     }
11349 }
11350   [(set (attr "type")
11351      (cond [(eq_attr "alternative" "2")
11352               (const_string "lea")
11353             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11354                           (const_int 0))
11355                       (match_operand 0 "register_operand" ""))
11356                  (match_operand 2 "const1_operand" ""))
11357               (const_string "alu")
11358            ]
11359            (const_string "ishift")))
11360    (set_attr "mode" "QI,SI,SI")])
11361
11362 (define_insn "*ashlqi3_1"
11363   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11364         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11365                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11366    (clobber (reg:CC FLAGS_REG))]
11367   "TARGET_PARTIAL_REG_STALL
11368    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11369 {
11370   switch (get_attr_type (insn))
11371     {
11372     case TYPE_ALU:
11373       gcc_assert (operands[2] == const1_rtx);
11374       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11375         return "add{l}\t%k0, %k0";
11376       else
11377         return "add{b}\t%0, %0";
11378
11379     default:
11380       if (REG_P (operands[2]))
11381         {
11382           if (get_attr_mode (insn) == MODE_SI)
11383             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11384           else
11385             return "sal{b}\t{%b2, %0|%0, %b2}";
11386         }
11387       else if (operands[2] == const1_rtx
11388                && (TARGET_SHIFT1 || optimize_size))
11389         {
11390           if (get_attr_mode (insn) == MODE_SI)
11391             return "sal{l}\t%0";
11392           else
11393             return "sal{b}\t%0";
11394         }
11395       else
11396         {
11397           if (get_attr_mode (insn) == MODE_SI)
11398             return "sal{l}\t{%2, %k0|%k0, %2}";
11399           else
11400             return "sal{b}\t{%2, %0|%0, %2}";
11401         }
11402     }
11403 }
11404   [(set (attr "type")
11405      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11406                           (const_int 0))
11407                       (match_operand 0 "register_operand" ""))
11408                  (match_operand 2 "const1_operand" ""))
11409               (const_string "alu")
11410            ]
11411            (const_string "ishift")))
11412    (set_attr "mode" "QI,SI")])
11413
11414 ;; This pattern can't accept a variable shift count, since shifts by
11415 ;; zero don't affect the flags.  We assume that shifts by constant
11416 ;; zero are optimized away.
11417 (define_insn "*ashlqi3_cmp"
11418   [(set (reg FLAGS_REG)
11419         (compare
11420           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11421                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11422           (const_int 0)))
11423    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11424         (ashift:QI (match_dup 1) (match_dup 2)))]
11425   "(optimize_size
11426     || !TARGET_PARTIAL_FLAG_REG_STALL
11427     || (operands[2] == const1_rtx
11428         && (TARGET_SHIFT1
11429             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11430    && ix86_match_ccmode (insn, CCGOCmode)
11431    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11432 {
11433   switch (get_attr_type (insn))
11434     {
11435     case TYPE_ALU:
11436       gcc_assert (operands[2] == const1_rtx);
11437       return "add{b}\t%0, %0";
11438
11439     default:
11440       if (REG_P (operands[2]))
11441         return "sal{b}\t{%b2, %0|%0, %b2}";
11442       else if (operands[2] == const1_rtx
11443                && (TARGET_SHIFT1 || optimize_size))
11444         return "sal{b}\t%0";
11445       else
11446         return "sal{b}\t{%2, %0|%0, %2}";
11447     }
11448 }
11449   [(set (attr "type")
11450      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11451                           (const_int 0))
11452                       (match_operand 0 "register_operand" ""))
11453                  (match_operand 2 "const1_operand" ""))
11454               (const_string "alu")
11455            ]
11456            (const_string "ishift")))
11457    (set_attr "mode" "QI")])
11458
11459 (define_insn "*ashlqi3_cconly"
11460   [(set (reg FLAGS_REG)
11461         (compare
11462           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11463                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11464           (const_int 0)))
11465    (clobber (match_scratch:QI 0 "=q"))]
11466   "(optimize_size
11467     || !TARGET_PARTIAL_FLAG_REG_STALL
11468     || (operands[2] == const1_rtx
11469         && (TARGET_SHIFT1
11470             || TARGET_DOUBLE_WITH_ADD)))
11471    && ix86_match_ccmode (insn, CCGOCmode)
11472    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11473 {
11474   switch (get_attr_type (insn))
11475     {
11476     case TYPE_ALU:
11477       gcc_assert (operands[2] == const1_rtx);
11478       return "add{b}\t%0, %0";
11479
11480     default:
11481       if (REG_P (operands[2]))
11482         return "sal{b}\t{%b2, %0|%0, %b2}";
11483       else if (operands[2] == const1_rtx
11484                && (TARGET_SHIFT1 || optimize_size))
11485         return "sal{b}\t%0";
11486       else
11487         return "sal{b}\t{%2, %0|%0, %2}";
11488     }
11489 }
11490   [(set (attr "type")
11491      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11492                           (const_int 0))
11493                       (match_operand 0 "register_operand" ""))
11494                  (match_operand 2 "const1_operand" ""))
11495               (const_string "alu")
11496            ]
11497            (const_string "ishift")))
11498    (set_attr "mode" "QI")])
11499
11500 ;; See comment above `ashldi3' about how this works.
11501
11502 (define_expand "ashrti3"
11503   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11504                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11505                                 (match_operand:QI 2 "nonmemory_operand" "")))
11506               (clobber (reg:CC FLAGS_REG))])]
11507   "TARGET_64BIT"
11508 {
11509   if (! immediate_operand (operands[2], QImode))
11510     {
11511       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11512       DONE;
11513     }
11514   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11515   DONE;
11516 })
11517
11518 (define_insn "ashrti3_1"
11519   [(set (match_operand:TI 0 "register_operand" "=r")
11520         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11521                      (match_operand:QI 2 "register_operand" "c")))
11522    (clobber (match_scratch:DI 3 "=&r"))
11523    (clobber (reg:CC FLAGS_REG))]
11524   "TARGET_64BIT"
11525   "#"
11526   [(set_attr "type" "multi")])
11527
11528 (define_insn "*ashrti3_2"
11529   [(set (match_operand:TI 0 "register_operand" "=r")
11530         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11531                      (match_operand:QI 2 "immediate_operand" "O")))
11532    (clobber (reg:CC FLAGS_REG))]
11533   "TARGET_64BIT"
11534   "#"
11535   [(set_attr "type" "multi")])
11536
11537 (define_split
11538   [(set (match_operand:TI 0 "register_operand" "")
11539         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11540                      (match_operand:QI 2 "register_operand" "")))
11541    (clobber (match_scratch:DI 3 ""))
11542    (clobber (reg:CC FLAGS_REG))]
11543   "TARGET_64BIT && reload_completed"
11544   [(const_int 0)]
11545   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11546
11547 (define_split
11548   [(set (match_operand:TI 0 "register_operand" "")
11549         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11550                      (match_operand:QI 2 "immediate_operand" "")))
11551    (clobber (reg:CC FLAGS_REG))]
11552   "TARGET_64BIT && reload_completed"
11553   [(const_int 0)]
11554   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11555
11556 (define_insn "x86_64_shrd"
11557   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11558         (ior:DI (ashiftrt:DI (match_dup 0)
11559                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11560                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11561                   (minus:QI (const_int 64) (match_dup 2)))))
11562    (clobber (reg:CC FLAGS_REG))]
11563   "TARGET_64BIT"
11564   "@
11565    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11566    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11567   [(set_attr "type" "ishift")
11568    (set_attr "prefix_0f" "1")
11569    (set_attr "mode" "DI")
11570    (set_attr "athlon_decode" "vector")
11571    (set_attr "amdfam10_decode" "vector")])   
11572
11573 (define_expand "ashrdi3"
11574   [(set (match_operand:DI 0 "shiftdi_operand" "")
11575         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11576                      (match_operand:QI 2 "nonmemory_operand" "")))]
11577   ""
11578   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11579
11580 (define_insn "*ashrdi3_63_rex64"
11581   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11582         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11583                      (match_operand:DI 2 "const_int_operand" "i,i")))
11584    (clobber (reg:CC FLAGS_REG))]
11585   "TARGET_64BIT && INTVAL (operands[2]) == 63
11586    && (TARGET_USE_CLTD || optimize_size)
11587    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11588   "@
11589    {cqto|cqo}
11590    sar{q}\t{%2, %0|%0, %2}"
11591   [(set_attr "type" "imovx,ishift")
11592    (set_attr "prefix_0f" "0,*")
11593    (set_attr "length_immediate" "0,*")
11594    (set_attr "modrm" "0,1")
11595    (set_attr "mode" "DI")])
11596
11597 (define_insn "*ashrdi3_1_one_bit_rex64"
11598   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11599         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11600                      (match_operand:QI 2 "const1_operand" "")))
11601    (clobber (reg:CC FLAGS_REG))]
11602   "TARGET_64BIT
11603    && (TARGET_SHIFT1 || optimize_size)
11604    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11605   "sar{q}\t%0"
11606   [(set_attr "type" "ishift")
11607    (set (attr "length")
11608      (if_then_else (match_operand:DI 0 "register_operand" "")
11609         (const_string "2")
11610         (const_string "*")))])
11611
11612 (define_insn "*ashrdi3_1_rex64"
11613   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11614         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11615                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11616    (clobber (reg:CC FLAGS_REG))]
11617   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11618   "@
11619    sar{q}\t{%2, %0|%0, %2}
11620    sar{q}\t{%b2, %0|%0, %b2}"
11621   [(set_attr "type" "ishift")
11622    (set_attr "mode" "DI")])
11623
11624 ;; This pattern can't accept a variable shift count, since shifts by
11625 ;; zero don't affect the flags.  We assume that shifts by constant
11626 ;; zero are optimized away.
11627 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11628   [(set (reg FLAGS_REG)
11629         (compare
11630           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11631                        (match_operand:QI 2 "const1_operand" ""))
11632           (const_int 0)))
11633    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11634         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11635   "TARGET_64BIT
11636    && (TARGET_SHIFT1 || optimize_size)
11637    && ix86_match_ccmode (insn, CCGOCmode)
11638    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11639   "sar{q}\t%0"
11640   [(set_attr "type" "ishift")
11641    (set (attr "length")
11642      (if_then_else (match_operand:DI 0 "register_operand" "")
11643         (const_string "2")
11644         (const_string "*")))])
11645
11646 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11647   [(set (reg FLAGS_REG)
11648         (compare
11649           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11650                        (match_operand:QI 2 "const1_operand" ""))
11651           (const_int 0)))
11652    (clobber (match_scratch:DI 0 "=r"))]
11653   "TARGET_64BIT
11654    && (TARGET_SHIFT1 || optimize_size)
11655    && ix86_match_ccmode (insn, CCGOCmode)
11656    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11657   "sar{q}\t%0"
11658   [(set_attr "type" "ishift")
11659    (set_attr "length" "2")])
11660
11661 ;; This pattern can't accept a variable shift count, since shifts by
11662 ;; zero don't affect the flags.  We assume that shifts by constant
11663 ;; zero are optimized away.
11664 (define_insn "*ashrdi3_cmp_rex64"
11665   [(set (reg FLAGS_REG)
11666         (compare
11667           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11668                        (match_operand:QI 2 "const_int_operand" "n"))
11669           (const_int 0)))
11670    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11671         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11672   "TARGET_64BIT
11673    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11674    && ix86_match_ccmode (insn, CCGOCmode)
11675    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11676   "sar{q}\t{%2, %0|%0, %2}"
11677   [(set_attr "type" "ishift")
11678    (set_attr "mode" "DI")])
11679
11680 (define_insn "*ashrdi3_cconly_rex64"
11681   [(set (reg FLAGS_REG)
11682         (compare
11683           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11684                        (match_operand:QI 2 "const_int_operand" "n"))
11685           (const_int 0)))
11686    (clobber (match_scratch:DI 0 "=r"))]
11687   "TARGET_64BIT
11688    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11689    && ix86_match_ccmode (insn, CCGOCmode)
11690    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11691   "sar{q}\t{%2, %0|%0, %2}"
11692   [(set_attr "type" "ishift")
11693    (set_attr "mode" "DI")])
11694
11695 (define_insn "*ashrdi3_1"
11696   [(set (match_operand:DI 0 "register_operand" "=r")
11697         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11698                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11699    (clobber (reg:CC FLAGS_REG))]
11700   "!TARGET_64BIT"
11701   "#"
11702   [(set_attr "type" "multi")])
11703
11704 ;; By default we don't ask for a scratch register, because when DImode
11705 ;; values are manipulated, registers are already at a premium.  But if
11706 ;; we have one handy, we won't turn it away.
11707 (define_peephole2
11708   [(match_scratch:SI 3 "r")
11709    (parallel [(set (match_operand:DI 0 "register_operand" "")
11710                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11711                                 (match_operand:QI 2 "nonmemory_operand" "")))
11712               (clobber (reg:CC FLAGS_REG))])
11713    (match_dup 3)]
11714   "!TARGET_64BIT && TARGET_CMOVE"
11715   [(const_int 0)]
11716   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11717
11718 (define_split
11719   [(set (match_operand:DI 0 "register_operand" "")
11720         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11721                      (match_operand:QI 2 "nonmemory_operand" "")))
11722    (clobber (reg:CC FLAGS_REG))]
11723   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11724                      ? epilogue_completed : reload_completed)"
11725   [(const_int 0)]
11726   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11727
11728 (define_insn "x86_shrd_1"
11729   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11730         (ior:SI (ashiftrt:SI (match_dup 0)
11731                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11732                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11733                   (minus:QI (const_int 32) (match_dup 2)))))
11734    (clobber (reg:CC FLAGS_REG))]
11735   ""
11736   "@
11737    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11738    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11739   [(set_attr "type" "ishift")
11740    (set_attr "prefix_0f" "1")
11741    (set_attr "pent_pair" "np")
11742    (set_attr "mode" "SI")])
11743
11744 (define_expand "x86_shift_adj_3"
11745   [(use (match_operand:SI 0 "register_operand" ""))
11746    (use (match_operand:SI 1 "register_operand" ""))
11747    (use (match_operand:QI 2 "register_operand" ""))]
11748   ""
11749 {
11750   rtx label = gen_label_rtx ();
11751   rtx tmp;
11752
11753   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11754
11755   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11756   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11757   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11758                               gen_rtx_LABEL_REF (VOIDmode, label),
11759                               pc_rtx);
11760   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11761   JUMP_LABEL (tmp) = label;
11762
11763   emit_move_insn (operands[0], operands[1]);
11764   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11765
11766   emit_label (label);
11767   LABEL_NUSES (label) = 1;
11768
11769   DONE;
11770 })
11771
11772 (define_insn "ashrsi3_31"
11773   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11774         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11775                      (match_operand:SI 2 "const_int_operand" "i,i")))
11776    (clobber (reg:CC FLAGS_REG))]
11777   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11778    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11779   "@
11780    {cltd|cdq}
11781    sar{l}\t{%2, %0|%0, %2}"
11782   [(set_attr "type" "imovx,ishift")
11783    (set_attr "prefix_0f" "0,*")
11784    (set_attr "length_immediate" "0,*")
11785    (set_attr "modrm" "0,1")
11786    (set_attr "mode" "SI")])
11787
11788 (define_insn "*ashrsi3_31_zext"
11789   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11790         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11791                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11792    (clobber (reg:CC FLAGS_REG))]
11793   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11794    && INTVAL (operands[2]) == 31
11795    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11796   "@
11797    {cltd|cdq}
11798    sar{l}\t{%2, %k0|%k0, %2}"
11799   [(set_attr "type" "imovx,ishift")
11800    (set_attr "prefix_0f" "0,*")
11801    (set_attr "length_immediate" "0,*")
11802    (set_attr "modrm" "0,1")
11803    (set_attr "mode" "SI")])
11804
11805 (define_expand "ashrsi3"
11806   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11807         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11808                      (match_operand:QI 2 "nonmemory_operand" "")))
11809    (clobber (reg:CC FLAGS_REG))]
11810   ""
11811   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11812
11813 (define_insn "*ashrsi3_1_one_bit"
11814   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11815         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11816                      (match_operand:QI 2 "const1_operand" "")))
11817    (clobber (reg:CC FLAGS_REG))]
11818   "(TARGET_SHIFT1 || optimize_size)
11819    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11820   "sar{l}\t%0"
11821   [(set_attr "type" "ishift")
11822    (set (attr "length")
11823      (if_then_else (match_operand:SI 0 "register_operand" "")
11824         (const_string "2")
11825         (const_string "*")))])
11826
11827 (define_insn "*ashrsi3_1_one_bit_zext"
11828   [(set (match_operand:DI 0 "register_operand" "=r")
11829         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11830                                      (match_operand:QI 2 "const1_operand" ""))))
11831    (clobber (reg:CC FLAGS_REG))]
11832   "TARGET_64BIT
11833    && (TARGET_SHIFT1 || optimize_size)
11834    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11835   "sar{l}\t%k0"
11836   [(set_attr "type" "ishift")
11837    (set_attr "length" "2")])
11838
11839 (define_insn "*ashrsi3_1"
11840   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11841         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11842                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11843    (clobber (reg:CC FLAGS_REG))]
11844   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11845   "@
11846    sar{l}\t{%2, %0|%0, %2}
11847    sar{l}\t{%b2, %0|%0, %b2}"
11848   [(set_attr "type" "ishift")
11849    (set_attr "mode" "SI")])
11850
11851 (define_insn "*ashrsi3_1_zext"
11852   [(set (match_operand:DI 0 "register_operand" "=r,r")
11853         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11854                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11855    (clobber (reg:CC FLAGS_REG))]
11856   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11857   "@
11858    sar{l}\t{%2, %k0|%k0, %2}
11859    sar{l}\t{%b2, %k0|%k0, %b2}"
11860   [(set_attr "type" "ishift")
11861    (set_attr "mode" "SI")])
11862
11863 ;; This pattern can't accept a variable shift count, since shifts by
11864 ;; zero don't affect the flags.  We assume that shifts by constant
11865 ;; zero are optimized away.
11866 (define_insn "*ashrsi3_one_bit_cmp"
11867   [(set (reg FLAGS_REG)
11868         (compare
11869           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11870                        (match_operand:QI 2 "const1_operand" ""))
11871           (const_int 0)))
11872    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11873         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11874   "(TARGET_SHIFT1 || optimize_size)
11875    && ix86_match_ccmode (insn, CCGOCmode)
11876    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11877   "sar{l}\t%0"
11878   [(set_attr "type" "ishift")
11879    (set (attr "length")
11880      (if_then_else (match_operand:SI 0 "register_operand" "")
11881         (const_string "2")
11882         (const_string "*")))])
11883
11884 (define_insn "*ashrsi3_one_bit_cconly"
11885   [(set (reg FLAGS_REG)
11886         (compare
11887           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11888                        (match_operand:QI 2 "const1_operand" ""))
11889           (const_int 0)))
11890    (clobber (match_scratch:SI 0 "=r"))]
11891   "(TARGET_SHIFT1 || optimize_size)
11892    && ix86_match_ccmode (insn, CCGOCmode)
11893    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11894   "sar{l}\t%0"
11895   [(set_attr "type" "ishift")
11896    (set_attr "length" "2")])
11897
11898 (define_insn "*ashrsi3_one_bit_cmp_zext"
11899   [(set (reg FLAGS_REG)
11900         (compare
11901           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11902                        (match_operand:QI 2 "const1_operand" ""))
11903           (const_int 0)))
11904    (set (match_operand:DI 0 "register_operand" "=r")
11905         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11906   "TARGET_64BIT
11907    && (TARGET_SHIFT1 || optimize_size)
11908    && ix86_match_ccmode (insn, CCmode)
11909    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11910   "sar{l}\t%k0"
11911   [(set_attr "type" "ishift")
11912    (set_attr "length" "2")])
11913
11914 ;; This pattern can't accept a variable shift count, since shifts by
11915 ;; zero don't affect the flags.  We assume that shifts by constant
11916 ;; zero are optimized away.
11917 (define_insn "*ashrsi3_cmp"
11918   [(set (reg FLAGS_REG)
11919         (compare
11920           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11921                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11922           (const_int 0)))
11923    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11924         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11925   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11926    && ix86_match_ccmode (insn, CCGOCmode)
11927    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11928   "sar{l}\t{%2, %0|%0, %2}"
11929   [(set_attr "type" "ishift")
11930    (set_attr "mode" "SI")])
11931
11932 (define_insn "*ashrsi3_cconly"
11933   [(set (reg FLAGS_REG)
11934         (compare
11935           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11936                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11937           (const_int 0)))
11938    (clobber (match_scratch:SI 0 "=r"))]
11939   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11940    && ix86_match_ccmode (insn, CCGOCmode)
11941    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11942   "sar{l}\t{%2, %0|%0, %2}"
11943   [(set_attr "type" "ishift")
11944    (set_attr "mode" "SI")])
11945
11946 (define_insn "*ashrsi3_cmp_zext"
11947   [(set (reg FLAGS_REG)
11948         (compare
11949           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11950                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11951           (const_int 0)))
11952    (set (match_operand:DI 0 "register_operand" "=r")
11953         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11954   "TARGET_64BIT
11955    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11956    && ix86_match_ccmode (insn, CCGOCmode)
11957    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11958   "sar{l}\t{%2, %k0|%k0, %2}"
11959   [(set_attr "type" "ishift")
11960    (set_attr "mode" "SI")])
11961
11962 (define_expand "ashrhi3"
11963   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11964         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11965                      (match_operand:QI 2 "nonmemory_operand" "")))
11966    (clobber (reg:CC FLAGS_REG))]
11967   "TARGET_HIMODE_MATH"
11968   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11969
11970 (define_insn "*ashrhi3_1_one_bit"
11971   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11972         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11973                      (match_operand:QI 2 "const1_operand" "")))
11974    (clobber (reg:CC FLAGS_REG))]
11975   "(TARGET_SHIFT1 || optimize_size)
11976    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11977   "sar{w}\t%0"
11978   [(set_attr "type" "ishift")
11979    (set (attr "length")
11980      (if_then_else (match_operand 0 "register_operand" "")
11981         (const_string "2")
11982         (const_string "*")))])
11983
11984 (define_insn "*ashrhi3_1"
11985   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11986         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11987                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11988    (clobber (reg:CC FLAGS_REG))]
11989   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11990   "@
11991    sar{w}\t{%2, %0|%0, %2}
11992    sar{w}\t{%b2, %0|%0, %b2}"
11993   [(set_attr "type" "ishift")
11994    (set_attr "mode" "HI")])
11995
11996 ;; This pattern can't accept a variable shift count, since shifts by
11997 ;; zero don't affect the flags.  We assume that shifts by constant
11998 ;; zero are optimized away.
11999 (define_insn "*ashrhi3_one_bit_cmp"
12000   [(set (reg FLAGS_REG)
12001         (compare
12002           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12003                        (match_operand:QI 2 "const1_operand" ""))
12004           (const_int 0)))
12005    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12006         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12007   "(TARGET_SHIFT1 || optimize_size)
12008    && ix86_match_ccmode (insn, CCGOCmode)
12009    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12010   "sar{w}\t%0"
12011   [(set_attr "type" "ishift")
12012    (set (attr "length")
12013      (if_then_else (match_operand 0 "register_operand" "")
12014         (const_string "2")
12015         (const_string "*")))])
12016
12017 (define_insn "*ashrhi3_one_bit_cconly"
12018   [(set (reg FLAGS_REG)
12019         (compare
12020           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12021                        (match_operand:QI 2 "const1_operand" ""))
12022           (const_int 0)))
12023    (clobber (match_scratch:HI 0 "=r"))]
12024   "(TARGET_SHIFT1 || optimize_size)
12025    && ix86_match_ccmode (insn, CCGOCmode)
12026    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12027   "sar{w}\t%0"
12028   [(set_attr "type" "ishift")
12029    (set_attr "length" "2")])
12030
12031 ;; This pattern can't accept a variable shift count, since shifts by
12032 ;; zero don't affect the flags.  We assume that shifts by constant
12033 ;; zero are optimized away.
12034 (define_insn "*ashrhi3_cmp"
12035   [(set (reg FLAGS_REG)
12036         (compare
12037           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12038                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12039           (const_int 0)))
12040    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12041         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12042   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12043    && ix86_match_ccmode (insn, CCGOCmode)
12044    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12045   "sar{w}\t{%2, %0|%0, %2}"
12046   [(set_attr "type" "ishift")
12047    (set_attr "mode" "HI")])
12048
12049 (define_insn "*ashrhi3_cconly"
12050   [(set (reg FLAGS_REG)
12051         (compare
12052           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12053                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12054           (const_int 0)))
12055    (clobber (match_scratch:HI 0 "=r"))]
12056   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12057    && ix86_match_ccmode (insn, CCGOCmode)
12058    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12059   "sar{w}\t{%2, %0|%0, %2}"
12060   [(set_attr "type" "ishift")
12061    (set_attr "mode" "HI")])
12062
12063 (define_expand "ashrqi3"
12064   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12065         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12066                      (match_operand:QI 2 "nonmemory_operand" "")))
12067    (clobber (reg:CC FLAGS_REG))]
12068   "TARGET_QIMODE_MATH"
12069   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12070
12071 (define_insn "*ashrqi3_1_one_bit"
12072   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12073         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12074                      (match_operand:QI 2 "const1_operand" "")))
12075    (clobber (reg:CC FLAGS_REG))]
12076   "(TARGET_SHIFT1 || optimize_size)
12077    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12078   "sar{b}\t%0"
12079   [(set_attr "type" "ishift")
12080    (set (attr "length")
12081      (if_then_else (match_operand 0 "register_operand" "")
12082         (const_string "2")
12083         (const_string "*")))])
12084
12085 (define_insn "*ashrqi3_1_one_bit_slp"
12086   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12087         (ashiftrt:QI (match_dup 0)
12088                      (match_operand:QI 1 "const1_operand" "")))
12089    (clobber (reg:CC FLAGS_REG))]
12090   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12091    && (TARGET_SHIFT1 || optimize_size)
12092    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12093   "sar{b}\t%0"
12094   [(set_attr "type" "ishift1")
12095    (set (attr "length")
12096      (if_then_else (match_operand 0 "register_operand" "")
12097         (const_string "2")
12098         (const_string "*")))])
12099
12100 (define_insn "*ashrqi3_1"
12101   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12102         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12103                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12104    (clobber (reg:CC FLAGS_REG))]
12105   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12106   "@
12107    sar{b}\t{%2, %0|%0, %2}
12108    sar{b}\t{%b2, %0|%0, %b2}"
12109   [(set_attr "type" "ishift")
12110    (set_attr "mode" "QI")])
12111
12112 (define_insn "*ashrqi3_1_slp"
12113   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12114         (ashiftrt:QI (match_dup 0)
12115                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12116    (clobber (reg:CC FLAGS_REG))]
12117   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12118    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12119   "@
12120    sar{b}\t{%1, %0|%0, %1}
12121    sar{b}\t{%b1, %0|%0, %b1}"
12122   [(set_attr "type" "ishift1")
12123    (set_attr "mode" "QI")])
12124
12125 ;; This pattern can't accept a variable shift count, since shifts by
12126 ;; zero don't affect the flags.  We assume that shifts by constant
12127 ;; zero are optimized away.
12128 (define_insn "*ashrqi3_one_bit_cmp"
12129   [(set (reg FLAGS_REG)
12130         (compare
12131           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12132                        (match_operand:QI 2 "const1_operand" "I"))
12133           (const_int 0)))
12134    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12135         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12136   "(TARGET_SHIFT1 || optimize_size)
12137    && ix86_match_ccmode (insn, CCGOCmode)
12138    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12139   "sar{b}\t%0"
12140   [(set_attr "type" "ishift")
12141    (set (attr "length")
12142      (if_then_else (match_operand 0 "register_operand" "")
12143         (const_string "2")
12144         (const_string "*")))])
12145
12146 (define_insn "*ashrqi3_one_bit_cconly"
12147   [(set (reg FLAGS_REG)
12148         (compare
12149           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12150                        (match_operand:QI 2 "const1_operand" "I"))
12151           (const_int 0)))
12152    (clobber (match_scratch:QI 0 "=q"))]
12153   "(TARGET_SHIFT1 || optimize_size)
12154    && ix86_match_ccmode (insn, CCGOCmode)
12155    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12156   "sar{b}\t%0"
12157   [(set_attr "type" "ishift")
12158    (set_attr "length" "2")])
12159
12160 ;; This pattern can't accept a variable shift count, since shifts by
12161 ;; zero don't affect the flags.  We assume that shifts by constant
12162 ;; zero are optimized away.
12163 (define_insn "*ashrqi3_cmp"
12164   [(set (reg FLAGS_REG)
12165         (compare
12166           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12167                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12168           (const_int 0)))
12169    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12170         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12171   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12172    && ix86_match_ccmode (insn, CCGOCmode)
12173    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12174   "sar{b}\t{%2, %0|%0, %2}"
12175   [(set_attr "type" "ishift")
12176    (set_attr "mode" "QI")])
12177
12178 (define_insn "*ashrqi3_cconly"
12179   [(set (reg FLAGS_REG)
12180         (compare
12181           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12182                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12183           (const_int 0)))
12184    (clobber (match_scratch:QI 0 "=q"))]
12185   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12186    && ix86_match_ccmode (insn, CCGOCmode)
12187    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12188   "sar{b}\t{%2, %0|%0, %2}"
12189   [(set_attr "type" "ishift")
12190    (set_attr "mode" "QI")])
12191
12192 \f
12193 ;; Logical shift instructions
12194
12195 ;; See comment above `ashldi3' about how this works.
12196
12197 (define_expand "lshrti3"
12198   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12199                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12200                                 (match_operand:QI 2 "nonmemory_operand" "")))
12201               (clobber (reg:CC FLAGS_REG))])]
12202   "TARGET_64BIT"
12203 {
12204   if (! immediate_operand (operands[2], QImode))
12205     {
12206       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12207       DONE;
12208     }
12209   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12210   DONE;
12211 })
12212
12213 (define_insn "lshrti3_1"
12214   [(set (match_operand:TI 0 "register_operand" "=r")
12215         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12216                      (match_operand:QI 2 "register_operand" "c")))
12217    (clobber (match_scratch:DI 3 "=&r"))
12218    (clobber (reg:CC FLAGS_REG))]
12219   "TARGET_64BIT"
12220   "#"
12221   [(set_attr "type" "multi")])
12222
12223 ;; This pattern must be defined before *lshrti3_2 to prevent
12224 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12225
12226 (define_insn "sse2_lshrti3"
12227   [(set (match_operand:TI 0 "register_operand" "=x")
12228         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12229                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12230   "TARGET_SSE2"
12231 {
12232   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12233   return "psrldq\t{%2, %0|%0, %2}";
12234 }
12235   [(set_attr "type" "sseishft")
12236    (set_attr "prefix_data16" "1")
12237    (set_attr "mode" "TI")])
12238
12239 (define_insn "*lshrti3_2"
12240   [(set (match_operand:TI 0 "register_operand" "=r")
12241         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12242                      (match_operand:QI 2 "immediate_operand" "O")))
12243    (clobber (reg:CC FLAGS_REG))]
12244   "TARGET_64BIT"
12245   "#"
12246   [(set_attr "type" "multi")])
12247
12248 (define_split
12249   [(set (match_operand:TI 0 "register_operand" "")
12250         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12251                      (match_operand:QI 2 "register_operand" "")))
12252    (clobber (match_scratch:DI 3 ""))
12253    (clobber (reg:CC FLAGS_REG))]
12254   "TARGET_64BIT && reload_completed"
12255   [(const_int 0)]
12256   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12257
12258 (define_split
12259   [(set (match_operand:TI 0 "register_operand" "")
12260         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12261                      (match_operand:QI 2 "immediate_operand" "")))
12262    (clobber (reg:CC FLAGS_REG))]
12263   "TARGET_64BIT && reload_completed"
12264   [(const_int 0)]
12265   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12266
12267 (define_expand "lshrdi3"
12268   [(set (match_operand:DI 0 "shiftdi_operand" "")
12269         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12270                      (match_operand:QI 2 "nonmemory_operand" "")))]
12271   ""
12272   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12273
12274 (define_insn "*lshrdi3_1_one_bit_rex64"
12275   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12276         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12277                      (match_operand:QI 2 "const1_operand" "")))
12278    (clobber (reg:CC FLAGS_REG))]
12279   "TARGET_64BIT
12280    && (TARGET_SHIFT1 || optimize_size)
12281    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12282   "shr{q}\t%0"
12283   [(set_attr "type" "ishift")
12284    (set (attr "length")
12285      (if_then_else (match_operand:DI 0 "register_operand" "")
12286         (const_string "2")
12287         (const_string "*")))])
12288
12289 (define_insn "*lshrdi3_1_rex64"
12290   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12291         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12292                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12293    (clobber (reg:CC FLAGS_REG))]
12294   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12295   "@
12296    shr{q}\t{%2, %0|%0, %2}
12297    shr{q}\t{%b2, %0|%0, %b2}"
12298   [(set_attr "type" "ishift")
12299    (set_attr "mode" "DI")])
12300
12301 ;; This pattern can't accept a variable shift count, since shifts by
12302 ;; zero don't affect the flags.  We assume that shifts by constant
12303 ;; zero are optimized away.
12304 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12305   [(set (reg FLAGS_REG)
12306         (compare
12307           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12308                        (match_operand:QI 2 "const1_operand" ""))
12309           (const_int 0)))
12310    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12311         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12312   "TARGET_64BIT
12313    && (TARGET_SHIFT1 || optimize_size)
12314    && ix86_match_ccmode (insn, CCGOCmode)
12315    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12316   "shr{q}\t%0"
12317   [(set_attr "type" "ishift")
12318    (set (attr "length")
12319      (if_then_else (match_operand:DI 0 "register_operand" "")
12320         (const_string "2")
12321         (const_string "*")))])
12322
12323 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12324   [(set (reg FLAGS_REG)
12325         (compare
12326           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12327                        (match_operand:QI 2 "const1_operand" ""))
12328           (const_int 0)))
12329    (clobber (match_scratch:DI 0 "=r"))]
12330   "TARGET_64BIT
12331    && (TARGET_SHIFT1 || optimize_size)
12332    && ix86_match_ccmode (insn, CCGOCmode)
12333    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12334   "shr{q}\t%0"
12335   [(set_attr "type" "ishift")
12336    (set_attr "length" "2")])
12337
12338 ;; This pattern can't accept a variable shift count, since shifts by
12339 ;; zero don't affect the flags.  We assume that shifts by constant
12340 ;; zero are optimized away.
12341 (define_insn "*lshrdi3_cmp_rex64"
12342   [(set (reg FLAGS_REG)
12343         (compare
12344           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12345                        (match_operand:QI 2 "const_int_operand" "e"))
12346           (const_int 0)))
12347    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12348         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12349   "TARGET_64BIT
12350    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12351    && ix86_match_ccmode (insn, CCGOCmode)
12352    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12353   "shr{q}\t{%2, %0|%0, %2}"
12354   [(set_attr "type" "ishift")
12355    (set_attr "mode" "DI")])
12356
12357 (define_insn "*lshrdi3_cconly_rex64"
12358   [(set (reg FLAGS_REG)
12359         (compare
12360           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12361                        (match_operand:QI 2 "const_int_operand" "e"))
12362           (const_int 0)))
12363    (clobber (match_scratch:DI 0 "=r"))]
12364   "TARGET_64BIT
12365    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12366    && ix86_match_ccmode (insn, CCGOCmode)
12367    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12368   "shr{q}\t{%2, %0|%0, %2}"
12369   [(set_attr "type" "ishift")
12370    (set_attr "mode" "DI")])
12371
12372 (define_insn "*lshrdi3_1"
12373   [(set (match_operand:DI 0 "register_operand" "=r")
12374         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12375                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12376    (clobber (reg:CC FLAGS_REG))]
12377   "!TARGET_64BIT"
12378   "#"
12379   [(set_attr "type" "multi")])
12380
12381 ;; By default we don't ask for a scratch register, because when DImode
12382 ;; values are manipulated, registers are already at a premium.  But if
12383 ;; we have one handy, we won't turn it away.
12384 (define_peephole2
12385   [(match_scratch:SI 3 "r")
12386    (parallel [(set (match_operand:DI 0 "register_operand" "")
12387                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12388                                 (match_operand:QI 2 "nonmemory_operand" "")))
12389               (clobber (reg:CC FLAGS_REG))])
12390    (match_dup 3)]
12391   "!TARGET_64BIT && TARGET_CMOVE"
12392   [(const_int 0)]
12393   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12394
12395 (define_split
12396   [(set (match_operand:DI 0 "register_operand" "")
12397         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12398                      (match_operand:QI 2 "nonmemory_operand" "")))
12399    (clobber (reg:CC FLAGS_REG))]
12400   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12401                      ? epilogue_completed : reload_completed)"
12402   [(const_int 0)]
12403   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12404
12405 (define_expand "lshrsi3"
12406   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12407         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12408                      (match_operand:QI 2 "nonmemory_operand" "")))
12409    (clobber (reg:CC FLAGS_REG))]
12410   ""
12411   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12412
12413 (define_insn "*lshrsi3_1_one_bit"
12414   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12415         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12416                      (match_operand:QI 2 "const1_operand" "")))
12417    (clobber (reg:CC FLAGS_REG))]
12418   "(TARGET_SHIFT1 || optimize_size)
12419    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12420   "shr{l}\t%0"
12421   [(set_attr "type" "ishift")
12422    (set (attr "length")
12423      (if_then_else (match_operand:SI 0 "register_operand" "")
12424         (const_string "2")
12425         (const_string "*")))])
12426
12427 (define_insn "*lshrsi3_1_one_bit_zext"
12428   [(set (match_operand:DI 0 "register_operand" "=r")
12429         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12430                      (match_operand:QI 2 "const1_operand" "")))
12431    (clobber (reg:CC FLAGS_REG))]
12432   "TARGET_64BIT
12433    && (TARGET_SHIFT1 || optimize_size)
12434    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12435   "shr{l}\t%k0"
12436   [(set_attr "type" "ishift")
12437    (set_attr "length" "2")])
12438
12439 (define_insn "*lshrsi3_1"
12440   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12441         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12442                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12443    (clobber (reg:CC FLAGS_REG))]
12444   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12445   "@
12446    shr{l}\t{%2, %0|%0, %2}
12447    shr{l}\t{%b2, %0|%0, %b2}"
12448   [(set_attr "type" "ishift")
12449    (set_attr "mode" "SI")])
12450
12451 (define_insn "*lshrsi3_1_zext"
12452   [(set (match_operand:DI 0 "register_operand" "=r,r")
12453         (zero_extend:DI
12454           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12455                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12456    (clobber (reg:CC FLAGS_REG))]
12457   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12458   "@
12459    shr{l}\t{%2, %k0|%k0, %2}
12460    shr{l}\t{%b2, %k0|%k0, %b2}"
12461   [(set_attr "type" "ishift")
12462    (set_attr "mode" "SI")])
12463
12464 ;; This pattern can't accept a variable shift count, since shifts by
12465 ;; zero don't affect the flags.  We assume that shifts by constant
12466 ;; zero are optimized away.
12467 (define_insn "*lshrsi3_one_bit_cmp"
12468   [(set (reg FLAGS_REG)
12469         (compare
12470           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12471                        (match_operand:QI 2 "const1_operand" ""))
12472           (const_int 0)))
12473    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12474         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12475   "(TARGET_SHIFT1 || optimize_size)
12476    && ix86_match_ccmode (insn, CCGOCmode)
12477    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12478   "shr{l}\t%0"
12479   [(set_attr "type" "ishift")
12480    (set (attr "length")
12481      (if_then_else (match_operand:SI 0 "register_operand" "")
12482         (const_string "2")
12483         (const_string "*")))])
12484
12485 (define_insn "*lshrsi3_one_bit_cconly"
12486   [(set (reg FLAGS_REG)
12487         (compare
12488           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12489                        (match_operand:QI 2 "const1_operand" ""))
12490           (const_int 0)))
12491    (clobber (match_scratch:SI 0 "=r"))]
12492   "(TARGET_SHIFT1 || optimize_size)
12493    && ix86_match_ccmode (insn, CCGOCmode)
12494    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12495   "shr{l}\t%0"
12496   [(set_attr "type" "ishift")
12497    (set_attr "length" "2")])
12498
12499 (define_insn "*lshrsi3_cmp_one_bit_zext"
12500   [(set (reg FLAGS_REG)
12501         (compare
12502           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12503                        (match_operand:QI 2 "const1_operand" ""))
12504           (const_int 0)))
12505    (set (match_operand:DI 0 "register_operand" "=r")
12506         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12507   "TARGET_64BIT
12508    && (TARGET_SHIFT1 || optimize_size)
12509    && ix86_match_ccmode (insn, CCGOCmode)
12510    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12511   "shr{l}\t%k0"
12512   [(set_attr "type" "ishift")
12513    (set_attr "length" "2")])
12514
12515 ;; This pattern can't accept a variable shift count, since shifts by
12516 ;; zero don't affect the flags.  We assume that shifts by constant
12517 ;; zero are optimized away.
12518 (define_insn "*lshrsi3_cmp"
12519   [(set (reg FLAGS_REG)
12520         (compare
12521           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12522                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12523           (const_int 0)))
12524    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12525         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12526   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12527    && ix86_match_ccmode (insn, CCGOCmode)
12528    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12529   "shr{l}\t{%2, %0|%0, %2}"
12530   [(set_attr "type" "ishift")
12531    (set_attr "mode" "SI")])
12532
12533 (define_insn "*lshrsi3_cconly"
12534   [(set (reg FLAGS_REG)
12535       (compare
12536         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12537                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12538         (const_int 0)))
12539    (clobber (match_scratch:SI 0 "=r"))]
12540   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12541    && ix86_match_ccmode (insn, CCGOCmode)
12542    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12543   "shr{l}\t{%2, %0|%0, %2}"
12544   [(set_attr "type" "ishift")
12545    (set_attr "mode" "SI")])
12546
12547 (define_insn "*lshrsi3_cmp_zext"
12548   [(set (reg FLAGS_REG)
12549         (compare
12550           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12551                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12552           (const_int 0)))
12553    (set (match_operand:DI 0 "register_operand" "=r")
12554         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12555   "TARGET_64BIT
12556    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12557    && ix86_match_ccmode (insn, CCGOCmode)
12558    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12559   "shr{l}\t{%2, %k0|%k0, %2}"
12560   [(set_attr "type" "ishift")
12561    (set_attr "mode" "SI")])
12562
12563 (define_expand "lshrhi3"
12564   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12565         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12566                      (match_operand:QI 2 "nonmemory_operand" "")))
12567    (clobber (reg:CC FLAGS_REG))]
12568   "TARGET_HIMODE_MATH"
12569   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12570
12571 (define_insn "*lshrhi3_1_one_bit"
12572   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12573         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12574                      (match_operand:QI 2 "const1_operand" "")))
12575    (clobber (reg:CC FLAGS_REG))]
12576   "(TARGET_SHIFT1 || optimize_size)
12577    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12578   "shr{w}\t%0"
12579   [(set_attr "type" "ishift")
12580    (set (attr "length")
12581      (if_then_else (match_operand 0 "register_operand" "")
12582         (const_string "2")
12583         (const_string "*")))])
12584
12585 (define_insn "*lshrhi3_1"
12586   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12587         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12588                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12589    (clobber (reg:CC FLAGS_REG))]
12590   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12591   "@
12592    shr{w}\t{%2, %0|%0, %2}
12593    shr{w}\t{%b2, %0|%0, %b2}"
12594   [(set_attr "type" "ishift")
12595    (set_attr "mode" "HI")])
12596
12597 ;; This pattern can't accept a variable shift count, since shifts by
12598 ;; zero don't affect the flags.  We assume that shifts by constant
12599 ;; zero are optimized away.
12600 (define_insn "*lshrhi3_one_bit_cmp"
12601   [(set (reg FLAGS_REG)
12602         (compare
12603           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12604                        (match_operand:QI 2 "const1_operand" ""))
12605           (const_int 0)))
12606    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12607         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12608   "(TARGET_SHIFT1 || optimize_size)
12609    && ix86_match_ccmode (insn, CCGOCmode)
12610    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12611   "shr{w}\t%0"
12612   [(set_attr "type" "ishift")
12613    (set (attr "length")
12614      (if_then_else (match_operand:SI 0 "register_operand" "")
12615         (const_string "2")
12616         (const_string "*")))])
12617
12618 (define_insn "*lshrhi3_one_bit_cconly"
12619   [(set (reg FLAGS_REG)
12620         (compare
12621           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12622                        (match_operand:QI 2 "const1_operand" ""))
12623           (const_int 0)))
12624    (clobber (match_scratch:HI 0 "=r"))]
12625   "(TARGET_SHIFT1 || optimize_size)
12626    && ix86_match_ccmode (insn, CCGOCmode)
12627    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12628   "shr{w}\t%0"
12629   [(set_attr "type" "ishift")
12630    (set_attr "length" "2")])
12631
12632 ;; This pattern can't accept a variable shift count, since shifts by
12633 ;; zero don't affect the flags.  We assume that shifts by constant
12634 ;; zero are optimized away.
12635 (define_insn "*lshrhi3_cmp"
12636   [(set (reg FLAGS_REG)
12637         (compare
12638           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12639                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12640           (const_int 0)))
12641    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12642         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12643   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12644    && ix86_match_ccmode (insn, CCGOCmode)
12645    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12646   "shr{w}\t{%2, %0|%0, %2}"
12647   [(set_attr "type" "ishift")
12648    (set_attr "mode" "HI")])
12649
12650 (define_insn "*lshrhi3_cconly"
12651   [(set (reg FLAGS_REG)
12652         (compare
12653           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12654                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12655           (const_int 0)))
12656    (clobber (match_scratch:HI 0 "=r"))]
12657   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12658    && ix86_match_ccmode (insn, CCGOCmode)
12659    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12660   "shr{w}\t{%2, %0|%0, %2}"
12661   [(set_attr "type" "ishift")
12662    (set_attr "mode" "HI")])
12663
12664 (define_expand "lshrqi3"
12665   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12666         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12667                      (match_operand:QI 2 "nonmemory_operand" "")))
12668    (clobber (reg:CC FLAGS_REG))]
12669   "TARGET_QIMODE_MATH"
12670   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12671
12672 (define_insn "*lshrqi3_1_one_bit"
12673   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12674         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12675                      (match_operand:QI 2 "const1_operand" "")))
12676    (clobber (reg:CC FLAGS_REG))]
12677   "(TARGET_SHIFT1 || optimize_size)
12678    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12679   "shr{b}\t%0"
12680   [(set_attr "type" "ishift")
12681    (set (attr "length")
12682      (if_then_else (match_operand 0 "register_operand" "")
12683         (const_string "2")
12684         (const_string "*")))])
12685
12686 (define_insn "*lshrqi3_1_one_bit_slp"
12687   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12688         (lshiftrt:QI (match_dup 0)
12689                      (match_operand:QI 1 "const1_operand" "")))
12690    (clobber (reg:CC FLAGS_REG))]
12691   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12692    && (TARGET_SHIFT1 || optimize_size)"
12693   "shr{b}\t%0"
12694   [(set_attr "type" "ishift1")
12695    (set (attr "length")
12696      (if_then_else (match_operand 0 "register_operand" "")
12697         (const_string "2")
12698         (const_string "*")))])
12699
12700 (define_insn "*lshrqi3_1"
12701   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12702         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12703                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12704    (clobber (reg:CC FLAGS_REG))]
12705   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12706   "@
12707    shr{b}\t{%2, %0|%0, %2}
12708    shr{b}\t{%b2, %0|%0, %b2}"
12709   [(set_attr "type" "ishift")
12710    (set_attr "mode" "QI")])
12711
12712 (define_insn "*lshrqi3_1_slp"
12713   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12714         (lshiftrt:QI (match_dup 0)
12715                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12716    (clobber (reg:CC FLAGS_REG))]
12717   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12718    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12719   "@
12720    shr{b}\t{%1, %0|%0, %1}
12721    shr{b}\t{%b1, %0|%0, %b1}"
12722   [(set_attr "type" "ishift1")
12723    (set_attr "mode" "QI")])
12724
12725 ;; This pattern can't accept a variable shift count, since shifts by
12726 ;; zero don't affect the flags.  We assume that shifts by constant
12727 ;; zero are optimized away.
12728 (define_insn "*lshrqi2_one_bit_cmp"
12729   [(set (reg FLAGS_REG)
12730         (compare
12731           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12732                        (match_operand:QI 2 "const1_operand" ""))
12733           (const_int 0)))
12734    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12735         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12736   "(TARGET_SHIFT1 || optimize_size)
12737    && ix86_match_ccmode (insn, CCGOCmode)
12738    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12739   "shr{b}\t%0"
12740   [(set_attr "type" "ishift")
12741    (set (attr "length")
12742      (if_then_else (match_operand:SI 0 "register_operand" "")
12743         (const_string "2")
12744         (const_string "*")))])
12745
12746 (define_insn "*lshrqi2_one_bit_cconly"
12747   [(set (reg FLAGS_REG)
12748         (compare
12749           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12750                        (match_operand:QI 2 "const1_operand" ""))
12751           (const_int 0)))
12752    (clobber (match_scratch:QI 0 "=q"))]
12753   "(TARGET_SHIFT1 || optimize_size)
12754    && ix86_match_ccmode (insn, CCGOCmode)
12755    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12756   "shr{b}\t%0"
12757   [(set_attr "type" "ishift")
12758    (set_attr "length" "2")])
12759
12760 ;; This pattern can't accept a variable shift count, since shifts by
12761 ;; zero don't affect the flags.  We assume that shifts by constant
12762 ;; zero are optimized away.
12763 (define_insn "*lshrqi2_cmp"
12764   [(set (reg FLAGS_REG)
12765         (compare
12766           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12767                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12768           (const_int 0)))
12769    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12770         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12771   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12772    && ix86_match_ccmode (insn, CCGOCmode)
12773    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12774   "shr{b}\t{%2, %0|%0, %2}"
12775   [(set_attr "type" "ishift")
12776    (set_attr "mode" "QI")])
12777
12778 (define_insn "*lshrqi2_cconly"
12779   [(set (reg FLAGS_REG)
12780         (compare
12781           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12782                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12783           (const_int 0)))
12784    (clobber (match_scratch:QI 0 "=q"))]
12785   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12786    && ix86_match_ccmode (insn, CCGOCmode)
12787    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12788   "shr{b}\t{%2, %0|%0, %2}"
12789   [(set_attr "type" "ishift")
12790    (set_attr "mode" "QI")])
12791 \f
12792 ;; Rotate instructions
12793
12794 (define_expand "rotldi3"
12795   [(set (match_operand:DI 0 "shiftdi_operand" "")
12796         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12797                    (match_operand:QI 2 "nonmemory_operand" "")))
12798    (clobber (reg:CC FLAGS_REG))]
12799  ""
12800 {
12801   if (TARGET_64BIT)
12802     {
12803       ix86_expand_binary_operator (ROTATE, DImode, operands);
12804       DONE;
12805     }
12806   if (!const_1_to_31_operand (operands[2], VOIDmode))
12807     FAIL;
12808   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12809   DONE;
12810 })
12811
12812 ;; Implement rotation using two double-precision shift instructions
12813 ;; and a scratch register.
12814 (define_insn_and_split "ix86_rotldi3"
12815  [(set (match_operand:DI 0 "register_operand" "=r")
12816        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12817                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12818   (clobber (reg:CC FLAGS_REG))
12819   (clobber (match_scratch:SI 3 "=&r"))]
12820  "!TARGET_64BIT"
12821  ""
12822  "&& reload_completed"
12823  [(set (match_dup 3) (match_dup 4))
12824   (parallel
12825    [(set (match_dup 4)
12826          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12827                  (lshiftrt:SI (match_dup 5)
12828                               (minus:QI (const_int 32) (match_dup 2)))))
12829     (clobber (reg:CC FLAGS_REG))])
12830   (parallel
12831    [(set (match_dup 5)
12832          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12833                  (lshiftrt:SI (match_dup 3)
12834                               (minus:QI (const_int 32) (match_dup 2)))))
12835     (clobber (reg:CC FLAGS_REG))])]
12836  "split_di (operands, 1, operands + 4, operands + 5);")
12837
12838 (define_insn "*rotlsi3_1_one_bit_rex64"
12839   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12840         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12841                    (match_operand:QI 2 "const1_operand" "")))
12842    (clobber (reg:CC FLAGS_REG))]
12843   "TARGET_64BIT
12844    && (TARGET_SHIFT1 || optimize_size)
12845    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12846   "rol{q}\t%0"
12847   [(set_attr "type" "rotate")
12848    (set (attr "length")
12849      (if_then_else (match_operand:DI 0 "register_operand" "")
12850         (const_string "2")
12851         (const_string "*")))])
12852
12853 (define_insn "*rotldi3_1_rex64"
12854   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12855         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12856                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12857    (clobber (reg:CC FLAGS_REG))]
12858   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12859   "@
12860    rol{q}\t{%2, %0|%0, %2}
12861    rol{q}\t{%b2, %0|%0, %b2}"
12862   [(set_attr "type" "rotate")
12863    (set_attr "mode" "DI")])
12864
12865 (define_expand "rotlsi3"
12866   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12867         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12868                    (match_operand:QI 2 "nonmemory_operand" "")))
12869    (clobber (reg:CC FLAGS_REG))]
12870   ""
12871   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12872
12873 (define_insn "*rotlsi3_1_one_bit"
12874   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12875         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12876                    (match_operand:QI 2 "const1_operand" "")))
12877    (clobber (reg:CC FLAGS_REG))]
12878   "(TARGET_SHIFT1 || optimize_size)
12879    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12880   "rol{l}\t%0"
12881   [(set_attr "type" "rotate")
12882    (set (attr "length")
12883      (if_then_else (match_operand:SI 0 "register_operand" "")
12884         (const_string "2")
12885         (const_string "*")))])
12886
12887 (define_insn "*rotlsi3_1_one_bit_zext"
12888   [(set (match_operand:DI 0 "register_operand" "=r")
12889         (zero_extend:DI
12890           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12891                      (match_operand:QI 2 "const1_operand" ""))))
12892    (clobber (reg:CC FLAGS_REG))]
12893   "TARGET_64BIT
12894    && (TARGET_SHIFT1 || optimize_size)
12895    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12896   "rol{l}\t%k0"
12897   [(set_attr "type" "rotate")
12898    (set_attr "length" "2")])
12899
12900 (define_insn "*rotlsi3_1"
12901   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12902         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12903                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12904    (clobber (reg:CC FLAGS_REG))]
12905   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12906   "@
12907    rol{l}\t{%2, %0|%0, %2}
12908    rol{l}\t{%b2, %0|%0, %b2}"
12909   [(set_attr "type" "rotate")
12910    (set_attr "mode" "SI")])
12911
12912 (define_insn "*rotlsi3_1_zext"
12913   [(set (match_operand:DI 0 "register_operand" "=r,r")
12914         (zero_extend:DI
12915           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12916                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12917    (clobber (reg:CC FLAGS_REG))]
12918   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12919   "@
12920    rol{l}\t{%2, %k0|%k0, %2}
12921    rol{l}\t{%b2, %k0|%k0, %b2}"
12922   [(set_attr "type" "rotate")
12923    (set_attr "mode" "SI")])
12924
12925 (define_expand "rotlhi3"
12926   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12927         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12928                    (match_operand:QI 2 "nonmemory_operand" "")))
12929    (clobber (reg:CC FLAGS_REG))]
12930   "TARGET_HIMODE_MATH"
12931   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12932
12933 (define_insn "*rotlhi3_1_one_bit"
12934   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12935         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12936                    (match_operand:QI 2 "const1_operand" "")))
12937    (clobber (reg:CC FLAGS_REG))]
12938   "(TARGET_SHIFT1 || optimize_size)
12939    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12940   "rol{w}\t%0"
12941   [(set_attr "type" "rotate")
12942    (set (attr "length")
12943      (if_then_else (match_operand 0 "register_operand" "")
12944         (const_string "2")
12945         (const_string "*")))])
12946
12947 (define_insn "*rotlhi3_1"
12948   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12949         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12950                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12951    (clobber (reg:CC FLAGS_REG))]
12952   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12953   "@
12954    rol{w}\t{%2, %0|%0, %2}
12955    rol{w}\t{%b2, %0|%0, %b2}"
12956   [(set_attr "type" "rotate")
12957    (set_attr "mode" "HI")])
12958
12959 (define_split
12960  [(set (match_operand:HI 0 "register_operand" "")
12961        (rotate:HI (match_dup 0) (const_int 8)))
12962   (clobber (reg:CC FLAGS_REG))]
12963  "reload_completed"
12964  [(parallel [(set (strict_low_part (match_dup 0))
12965                   (bswap:HI (match_dup 0)))
12966              (clobber (reg:CC FLAGS_REG))])]
12967  "")
12968
12969 (define_expand "rotlqi3"
12970   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12971         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12972                    (match_operand:QI 2 "nonmemory_operand" "")))
12973    (clobber (reg:CC FLAGS_REG))]
12974   "TARGET_QIMODE_MATH"
12975   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12976
12977 (define_insn "*rotlqi3_1_one_bit_slp"
12978   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12979         (rotate:QI (match_dup 0)
12980                    (match_operand:QI 1 "const1_operand" "")))
12981    (clobber (reg:CC FLAGS_REG))]
12982   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12983    && (TARGET_SHIFT1 || optimize_size)"
12984   "rol{b}\t%0"
12985   [(set_attr "type" "rotate1")
12986    (set (attr "length")
12987      (if_then_else (match_operand 0 "register_operand" "")
12988         (const_string "2")
12989         (const_string "*")))])
12990
12991 (define_insn "*rotlqi3_1_one_bit"
12992   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12993         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12994                    (match_operand:QI 2 "const1_operand" "")))
12995    (clobber (reg:CC FLAGS_REG))]
12996   "(TARGET_SHIFT1 || optimize_size)
12997    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12998   "rol{b}\t%0"
12999   [(set_attr "type" "rotate")
13000    (set (attr "length")
13001      (if_then_else (match_operand 0 "register_operand" "")
13002         (const_string "2")
13003         (const_string "*")))])
13004
13005 (define_insn "*rotlqi3_1_slp"
13006   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13007         (rotate:QI (match_dup 0)
13008                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13009    (clobber (reg:CC FLAGS_REG))]
13010   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13011    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13012   "@
13013    rol{b}\t{%1, %0|%0, %1}
13014    rol{b}\t{%b1, %0|%0, %b1}"
13015   [(set_attr "type" "rotate1")
13016    (set_attr "mode" "QI")])
13017
13018 (define_insn "*rotlqi3_1"
13019   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13020         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13021                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13022    (clobber (reg:CC FLAGS_REG))]
13023   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13024   "@
13025    rol{b}\t{%2, %0|%0, %2}
13026    rol{b}\t{%b2, %0|%0, %b2}"
13027   [(set_attr "type" "rotate")
13028    (set_attr "mode" "QI")])
13029
13030 (define_expand "rotrdi3"
13031   [(set (match_operand:DI 0 "shiftdi_operand" "")
13032         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13033                    (match_operand:QI 2 "nonmemory_operand" "")))
13034    (clobber (reg:CC FLAGS_REG))]
13035  ""
13036 {
13037   if (TARGET_64BIT)
13038     {
13039       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13040       DONE;
13041     }
13042   if (!const_1_to_31_operand (operands[2], VOIDmode))
13043     FAIL;
13044   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13045   DONE;
13046 })
13047
13048 ;; Implement rotation using two double-precision shift instructions
13049 ;; and a scratch register.
13050 (define_insn_and_split "ix86_rotrdi3"
13051  [(set (match_operand:DI 0 "register_operand" "=r")
13052        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13053                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13054   (clobber (reg:CC FLAGS_REG))
13055   (clobber (match_scratch:SI 3 "=&r"))]
13056  "!TARGET_64BIT"
13057  ""
13058  "&& reload_completed"
13059  [(set (match_dup 3) (match_dup 4))
13060   (parallel
13061    [(set (match_dup 4)
13062          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13063                  (ashift:SI (match_dup 5)
13064                             (minus:QI (const_int 32) (match_dup 2)))))
13065     (clobber (reg:CC FLAGS_REG))])
13066   (parallel
13067    [(set (match_dup 5)
13068          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13069                  (ashift:SI (match_dup 3)
13070                             (minus:QI (const_int 32) (match_dup 2)))))
13071     (clobber (reg:CC FLAGS_REG))])]
13072  "split_di (operands, 1, operands + 4, operands + 5);")
13073
13074 (define_insn "*rotrdi3_1_one_bit_rex64"
13075   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13076         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13077                      (match_operand:QI 2 "const1_operand" "")))
13078    (clobber (reg:CC FLAGS_REG))]
13079   "TARGET_64BIT
13080    && (TARGET_SHIFT1 || optimize_size)
13081    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13082   "ror{q}\t%0"
13083   [(set_attr "type" "rotate")
13084    (set (attr "length")
13085      (if_then_else (match_operand:DI 0 "register_operand" "")
13086         (const_string "2")
13087         (const_string "*")))])
13088
13089 (define_insn "*rotrdi3_1_rex64"
13090   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13091         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13092                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13093    (clobber (reg:CC FLAGS_REG))]
13094   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13095   "@
13096    ror{q}\t{%2, %0|%0, %2}
13097    ror{q}\t{%b2, %0|%0, %b2}"
13098   [(set_attr "type" "rotate")
13099    (set_attr "mode" "DI")])
13100
13101 (define_expand "rotrsi3"
13102   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13103         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13104                      (match_operand:QI 2 "nonmemory_operand" "")))
13105    (clobber (reg:CC FLAGS_REG))]
13106   ""
13107   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13108
13109 (define_insn "*rotrsi3_1_one_bit"
13110   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13111         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13112                      (match_operand:QI 2 "const1_operand" "")))
13113    (clobber (reg:CC FLAGS_REG))]
13114   "(TARGET_SHIFT1 || optimize_size)
13115    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13116   "ror{l}\t%0"
13117   [(set_attr "type" "rotate")
13118    (set (attr "length")
13119      (if_then_else (match_operand:SI 0 "register_operand" "")
13120         (const_string "2")
13121         (const_string "*")))])
13122
13123 (define_insn "*rotrsi3_1_one_bit_zext"
13124   [(set (match_operand:DI 0 "register_operand" "=r")
13125         (zero_extend:DI
13126           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13127                        (match_operand:QI 2 "const1_operand" ""))))
13128    (clobber (reg:CC FLAGS_REG))]
13129   "TARGET_64BIT
13130    && (TARGET_SHIFT1 || optimize_size)
13131    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13132   "ror{l}\t%k0"
13133   [(set_attr "type" "rotate")
13134    (set (attr "length")
13135      (if_then_else (match_operand:SI 0 "register_operand" "")
13136         (const_string "2")
13137         (const_string "*")))])
13138
13139 (define_insn "*rotrsi3_1"
13140   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13141         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13142                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13143    (clobber (reg:CC FLAGS_REG))]
13144   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13145   "@
13146    ror{l}\t{%2, %0|%0, %2}
13147    ror{l}\t{%b2, %0|%0, %b2}"
13148   [(set_attr "type" "rotate")
13149    (set_attr "mode" "SI")])
13150
13151 (define_insn "*rotrsi3_1_zext"
13152   [(set (match_operand:DI 0 "register_operand" "=r,r")
13153         (zero_extend:DI
13154           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13155                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13156    (clobber (reg:CC FLAGS_REG))]
13157   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13158   "@
13159    ror{l}\t{%2, %k0|%k0, %2}
13160    ror{l}\t{%b2, %k0|%k0, %b2}"
13161   [(set_attr "type" "rotate")
13162    (set_attr "mode" "SI")])
13163
13164 (define_expand "rotrhi3"
13165   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13166         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13167                      (match_operand:QI 2 "nonmemory_operand" "")))
13168    (clobber (reg:CC FLAGS_REG))]
13169   "TARGET_HIMODE_MATH"
13170   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13171
13172 (define_insn "*rotrhi3_one_bit"
13173   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13174         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13175                      (match_operand:QI 2 "const1_operand" "")))
13176    (clobber (reg:CC FLAGS_REG))]
13177   "(TARGET_SHIFT1 || optimize_size)
13178    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13179   "ror{w}\t%0"
13180   [(set_attr "type" "rotate")
13181    (set (attr "length")
13182      (if_then_else (match_operand 0 "register_operand" "")
13183         (const_string "2")
13184         (const_string "*")))])
13185
13186 (define_insn "*rotrhi3_1"
13187   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13188         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13189                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13190    (clobber (reg:CC FLAGS_REG))]
13191   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13192   "@
13193    ror{w}\t{%2, %0|%0, %2}
13194    ror{w}\t{%b2, %0|%0, %b2}"
13195   [(set_attr "type" "rotate")
13196    (set_attr "mode" "HI")])
13197
13198 (define_split
13199  [(set (match_operand:HI 0 "register_operand" "")
13200        (rotatert:HI (match_dup 0) (const_int 8)))
13201   (clobber (reg:CC FLAGS_REG))]
13202  "reload_completed"
13203  [(parallel [(set (strict_low_part (match_dup 0))
13204                   (bswap:HI (match_dup 0)))
13205              (clobber (reg:CC FLAGS_REG))])]
13206  "")
13207
13208 (define_expand "rotrqi3"
13209   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13210         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13211                      (match_operand:QI 2 "nonmemory_operand" "")))
13212    (clobber (reg:CC FLAGS_REG))]
13213   "TARGET_QIMODE_MATH"
13214   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13215
13216 (define_insn "*rotrqi3_1_one_bit"
13217   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13218         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13219                      (match_operand:QI 2 "const1_operand" "")))
13220    (clobber (reg:CC FLAGS_REG))]
13221   "(TARGET_SHIFT1 || optimize_size)
13222    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13223   "ror{b}\t%0"
13224   [(set_attr "type" "rotate")
13225    (set (attr "length")
13226      (if_then_else (match_operand 0 "register_operand" "")
13227         (const_string "2")
13228         (const_string "*")))])
13229
13230 (define_insn "*rotrqi3_1_one_bit_slp"
13231   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13232         (rotatert:QI (match_dup 0)
13233                      (match_operand:QI 1 "const1_operand" "")))
13234    (clobber (reg:CC FLAGS_REG))]
13235   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13236    && (TARGET_SHIFT1 || optimize_size)"
13237   "ror{b}\t%0"
13238   [(set_attr "type" "rotate1")
13239    (set (attr "length")
13240      (if_then_else (match_operand 0 "register_operand" "")
13241         (const_string "2")
13242         (const_string "*")))])
13243
13244 (define_insn "*rotrqi3_1"
13245   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13246         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13247                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13248    (clobber (reg:CC FLAGS_REG))]
13249   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13250   "@
13251    ror{b}\t{%2, %0|%0, %2}
13252    ror{b}\t{%b2, %0|%0, %b2}"
13253   [(set_attr "type" "rotate")
13254    (set_attr "mode" "QI")])
13255
13256 (define_insn "*rotrqi3_1_slp"
13257   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13258         (rotatert:QI (match_dup 0)
13259                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13260    (clobber (reg:CC FLAGS_REG))]
13261   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13262    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13263   "@
13264    ror{b}\t{%1, %0|%0, %1}
13265    ror{b}\t{%b1, %0|%0, %b1}"
13266   [(set_attr "type" "rotate1")
13267    (set_attr "mode" "QI")])
13268 \f
13269 ;; Bit set / bit test instructions
13270
13271 (define_expand "extv"
13272   [(set (match_operand:SI 0 "register_operand" "")
13273         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13274                          (match_operand:SI 2 "const8_operand" "")
13275                          (match_operand:SI 3 "const8_operand" "")))]
13276   ""
13277 {
13278   /* Handle extractions from %ah et al.  */
13279   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13280     FAIL;
13281
13282   /* From mips.md: extract_bit_field doesn't verify that our source
13283      matches the predicate, so check it again here.  */
13284   if (! ext_register_operand (operands[1], VOIDmode))
13285     FAIL;
13286 })
13287
13288 (define_expand "extzv"
13289   [(set (match_operand:SI 0 "register_operand" "")
13290         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13291                          (match_operand:SI 2 "const8_operand" "")
13292                          (match_operand:SI 3 "const8_operand" "")))]
13293   ""
13294 {
13295   /* Handle extractions from %ah et al.  */
13296   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13297     FAIL;
13298
13299   /* From mips.md: extract_bit_field doesn't verify that our source
13300      matches the predicate, so check it again here.  */
13301   if (! ext_register_operand (operands[1], VOIDmode))
13302     FAIL;
13303 })
13304
13305 (define_expand "insv"
13306   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13307                       (match_operand 1 "const8_operand" "")
13308                       (match_operand 2 "const8_operand" ""))
13309         (match_operand 3 "register_operand" ""))]
13310   ""
13311 {
13312   /* Handle insertions to %ah et al.  */
13313   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13314     FAIL;
13315
13316   /* From mips.md: insert_bit_field doesn't verify that our source
13317      matches the predicate, so check it again here.  */
13318   if (! ext_register_operand (operands[0], VOIDmode))
13319     FAIL;
13320
13321   if (TARGET_64BIT)
13322     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13323   else
13324     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13325
13326   DONE;
13327 })
13328
13329 ;; %%% bts, btr, btc, bt.
13330 ;; In general these instructions are *slow* when applied to memory,
13331 ;; since they enforce atomic operation.  When applied to registers,
13332 ;; it depends on the cpu implementation.  They're never faster than
13333 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13334 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13335 ;; within the instruction itself, so operating on bits in the high
13336 ;; 32-bits of a register becomes easier.
13337 ;;
13338 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13339 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13340 ;; negdf respectively, so they can never be disabled entirely.
13341
13342 (define_insn "*btsq"
13343   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13344                          (const_int 1)
13345                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13346         (const_int 1))
13347    (clobber (reg:CC FLAGS_REG))]
13348   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13349   "bts{q} %1,%0"
13350   [(set_attr "type" "alu1")])
13351
13352 (define_insn "*btrq"
13353   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13354                          (const_int 1)
13355                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13356         (const_int 0))
13357    (clobber (reg:CC FLAGS_REG))]
13358   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13359   "btr{q} %1,%0"
13360   [(set_attr "type" "alu1")])
13361
13362 (define_insn "*btcq"
13363   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13364                          (const_int 1)
13365                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13366         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13367    (clobber (reg:CC FLAGS_REG))]
13368   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13369   "btc{q} %1,%0"
13370   [(set_attr "type" "alu1")])
13371
13372 ;; Allow Nocona to avoid these instructions if a register is available.
13373
13374 (define_peephole2
13375   [(match_scratch:DI 2 "r")
13376    (parallel [(set (zero_extract:DI
13377                      (match_operand:DI 0 "register_operand" "")
13378                      (const_int 1)
13379                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13380                    (const_int 1))
13381               (clobber (reg:CC FLAGS_REG))])]
13382   "TARGET_64BIT && !TARGET_USE_BT"
13383   [(const_int 0)]
13384 {
13385   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13386   rtx op1;
13387
13388   if (HOST_BITS_PER_WIDE_INT >= 64)
13389     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13390   else if (i < HOST_BITS_PER_WIDE_INT)
13391     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13392   else
13393     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13394
13395   op1 = immed_double_const (lo, hi, DImode);
13396   if (i >= 31)
13397     {
13398       emit_move_insn (operands[2], op1);
13399       op1 = operands[2];
13400     }
13401
13402   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13403   DONE;
13404 })
13405
13406 (define_peephole2
13407   [(match_scratch:DI 2 "r")
13408    (parallel [(set (zero_extract:DI
13409                      (match_operand:DI 0 "register_operand" "")
13410                      (const_int 1)
13411                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13412                    (const_int 0))
13413               (clobber (reg:CC FLAGS_REG))])]
13414   "TARGET_64BIT && !TARGET_USE_BT"
13415   [(const_int 0)]
13416 {
13417   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13418   rtx op1;
13419
13420   if (HOST_BITS_PER_WIDE_INT >= 64)
13421     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13422   else if (i < HOST_BITS_PER_WIDE_INT)
13423     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13424   else
13425     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13426
13427   op1 = immed_double_const (~lo, ~hi, DImode);
13428   if (i >= 32)
13429     {
13430       emit_move_insn (operands[2], op1);
13431       op1 = operands[2];
13432     }
13433
13434   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13435   DONE;
13436 })
13437
13438 (define_peephole2
13439   [(match_scratch:DI 2 "r")
13440    (parallel [(set (zero_extract:DI
13441                      (match_operand:DI 0 "register_operand" "")
13442                      (const_int 1)
13443                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13444               (not:DI (zero_extract:DI
13445                         (match_dup 0) (const_int 1) (match_dup 1))))
13446               (clobber (reg:CC FLAGS_REG))])]
13447   "TARGET_64BIT && !TARGET_USE_BT"
13448   [(const_int 0)]
13449 {
13450   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13451   rtx op1;
13452
13453   if (HOST_BITS_PER_WIDE_INT >= 64)
13454     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13455   else if (i < HOST_BITS_PER_WIDE_INT)
13456     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13457   else
13458     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13459
13460   op1 = immed_double_const (lo, hi, DImode);
13461   if (i >= 31)
13462     {
13463       emit_move_insn (operands[2], op1);
13464       op1 = operands[2];
13465     }
13466
13467   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13468   DONE;
13469 })
13470 \f
13471 ;; Store-flag instructions.
13472
13473 ;; For all sCOND expanders, also expand the compare or test insn that
13474 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13475
13476 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13477 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13478 ;; way, which can later delete the movzx if only QImode is needed.
13479
13480 (define_expand "seq"
13481   [(set (match_operand:QI 0 "register_operand" "")
13482         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13483   ""
13484   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13485
13486 (define_expand "sne"
13487   [(set (match_operand:QI 0 "register_operand" "")
13488         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13489   ""
13490   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13491
13492 (define_expand "sgt"
13493   [(set (match_operand:QI 0 "register_operand" "")
13494         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13495   ""
13496   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13497
13498 (define_expand "sgtu"
13499   [(set (match_operand:QI 0 "register_operand" "")
13500         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13501   ""
13502   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13503
13504 (define_expand "slt"
13505   [(set (match_operand:QI 0 "register_operand" "")
13506         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13507   ""
13508   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13509
13510 (define_expand "sltu"
13511   [(set (match_operand:QI 0 "register_operand" "")
13512         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13513   ""
13514   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13515
13516 (define_expand "sge"
13517   [(set (match_operand:QI 0 "register_operand" "")
13518         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13519   ""
13520   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13521
13522 (define_expand "sgeu"
13523   [(set (match_operand:QI 0 "register_operand" "")
13524         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13525   ""
13526   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13527
13528 (define_expand "sle"
13529   [(set (match_operand:QI 0 "register_operand" "")
13530         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13531   ""
13532   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13533
13534 (define_expand "sleu"
13535   [(set (match_operand:QI 0 "register_operand" "")
13536         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13537   ""
13538   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13539
13540 (define_expand "sunordered"
13541   [(set (match_operand:QI 0 "register_operand" "")
13542         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13543   "TARGET_80387 || TARGET_SSE"
13544   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13545
13546 (define_expand "sordered"
13547   [(set (match_operand:QI 0 "register_operand" "")
13548         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13549   "TARGET_80387"
13550   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13551
13552 (define_expand "suneq"
13553   [(set (match_operand:QI 0 "register_operand" "")
13554         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13555   "TARGET_80387 || TARGET_SSE"
13556   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13557
13558 (define_expand "sunge"
13559   [(set (match_operand:QI 0 "register_operand" "")
13560         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13561   "TARGET_80387 || TARGET_SSE"
13562   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13563
13564 (define_expand "sungt"
13565   [(set (match_operand:QI 0 "register_operand" "")
13566         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13567   "TARGET_80387 || TARGET_SSE"
13568   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13569
13570 (define_expand "sunle"
13571   [(set (match_operand:QI 0 "register_operand" "")
13572         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13573   "TARGET_80387 || TARGET_SSE"
13574   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13575
13576 (define_expand "sunlt"
13577   [(set (match_operand:QI 0 "register_operand" "")
13578         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13579   "TARGET_80387 || TARGET_SSE"
13580   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13581
13582 (define_expand "sltgt"
13583   [(set (match_operand:QI 0 "register_operand" "")
13584         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13585   "TARGET_80387 || TARGET_SSE"
13586   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13587
13588 (define_insn "*setcc_1"
13589   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13590         (match_operator:QI 1 "ix86_comparison_operator"
13591           [(reg FLAGS_REG) (const_int 0)]))]
13592   ""
13593   "set%C1\t%0"
13594   [(set_attr "type" "setcc")
13595    (set_attr "mode" "QI")])
13596
13597 (define_insn "*setcc_2"
13598   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13599         (match_operator:QI 1 "ix86_comparison_operator"
13600           [(reg FLAGS_REG) (const_int 0)]))]
13601   ""
13602   "set%C1\t%0"
13603   [(set_attr "type" "setcc")
13604    (set_attr "mode" "QI")])
13605
13606 ;; In general it is not safe to assume too much about CCmode registers,
13607 ;; so simplify-rtx stops when it sees a second one.  Under certain
13608 ;; conditions this is safe on x86, so help combine not create
13609 ;;
13610 ;;      seta    %al
13611 ;;      testb   %al, %al
13612 ;;      sete    %al
13613
13614 (define_split
13615   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13616         (ne:QI (match_operator 1 "ix86_comparison_operator"
13617                  [(reg FLAGS_REG) (const_int 0)])
13618             (const_int 0)))]
13619   ""
13620   [(set (match_dup 0) (match_dup 1))]
13621 {
13622   PUT_MODE (operands[1], QImode);
13623 })
13624
13625 (define_split
13626   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13627         (ne:QI (match_operator 1 "ix86_comparison_operator"
13628                  [(reg FLAGS_REG) (const_int 0)])
13629             (const_int 0)))]
13630   ""
13631   [(set (match_dup 0) (match_dup 1))]
13632 {
13633   PUT_MODE (operands[1], QImode);
13634 })
13635
13636 (define_split
13637   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13638         (eq:QI (match_operator 1 "ix86_comparison_operator"
13639                  [(reg FLAGS_REG) (const_int 0)])
13640             (const_int 0)))]
13641   ""
13642   [(set (match_dup 0) (match_dup 1))]
13643 {
13644   rtx new_op1 = copy_rtx (operands[1]);
13645   operands[1] = new_op1;
13646   PUT_MODE (new_op1, QImode);
13647   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13648                                              GET_MODE (XEXP (new_op1, 0))));
13649
13650   /* Make sure that (a) the CCmode we have for the flags is strong
13651      enough for the reversed compare or (b) we have a valid FP compare.  */
13652   if (! ix86_comparison_operator (new_op1, VOIDmode))
13653     FAIL;
13654 })
13655
13656 (define_split
13657   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13658         (eq:QI (match_operator 1 "ix86_comparison_operator"
13659                  [(reg FLAGS_REG) (const_int 0)])
13660             (const_int 0)))]
13661   ""
13662   [(set (match_dup 0) (match_dup 1))]
13663 {
13664   rtx new_op1 = copy_rtx (operands[1]);
13665   operands[1] = new_op1;
13666   PUT_MODE (new_op1, QImode);
13667   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13668                                              GET_MODE (XEXP (new_op1, 0))));
13669
13670   /* Make sure that (a) the CCmode we have for the flags is strong
13671      enough for the reversed compare or (b) we have a valid FP compare.  */
13672   if (! ix86_comparison_operator (new_op1, VOIDmode))
13673     FAIL;
13674 })
13675
13676 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13677 ;; subsequent logical operations are used to imitate conditional moves.
13678 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13679 ;; it directly.
13680
13681 (define_insn "*sse_setccsf"
13682   [(set (match_operand:SF 0 "register_operand" "=x")
13683         (match_operator:SF 1 "sse_comparison_operator"
13684           [(match_operand:SF 2 "register_operand" "0")
13685            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13686   "TARGET_SSE"
13687   "cmp%D1ss\t{%3, %0|%0, %3}"
13688   [(set_attr "type" "ssecmp")
13689    (set_attr "mode" "SF")])
13690
13691 (define_insn "*sse_setccdf"
13692   [(set (match_operand:DF 0 "register_operand" "=x")
13693         (match_operator:DF 1 "sse_comparison_operator"
13694           [(match_operand:DF 2 "register_operand" "0")
13695            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13696   "TARGET_SSE2"
13697   "cmp%D1sd\t{%3, %0|%0, %3}"
13698   [(set_attr "type" "ssecmp")
13699    (set_attr "mode" "DF")])
13700 \f
13701 ;; Basic conditional jump instructions.
13702 ;; We ignore the overflow flag for signed branch instructions.
13703
13704 ;; For all bCOND expanders, also expand the compare or test insn that
13705 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13706
13707 (define_expand "beq"
13708   [(set (pc)
13709         (if_then_else (match_dup 1)
13710                       (label_ref (match_operand 0 "" ""))
13711                       (pc)))]
13712   ""
13713   "ix86_expand_branch (EQ, operands[0]); DONE;")
13714
13715 (define_expand "bne"
13716   [(set (pc)
13717         (if_then_else (match_dup 1)
13718                       (label_ref (match_operand 0 "" ""))
13719                       (pc)))]
13720   ""
13721   "ix86_expand_branch (NE, operands[0]); DONE;")
13722
13723 (define_expand "bgt"
13724   [(set (pc)
13725         (if_then_else (match_dup 1)
13726                       (label_ref (match_operand 0 "" ""))
13727                       (pc)))]
13728   ""
13729   "ix86_expand_branch (GT, operands[0]); DONE;")
13730
13731 (define_expand "bgtu"
13732   [(set (pc)
13733         (if_then_else (match_dup 1)
13734                       (label_ref (match_operand 0 "" ""))
13735                       (pc)))]
13736   ""
13737   "ix86_expand_branch (GTU, operands[0]); DONE;")
13738
13739 (define_expand "blt"
13740   [(set (pc)
13741         (if_then_else (match_dup 1)
13742                       (label_ref (match_operand 0 "" ""))
13743                       (pc)))]
13744   ""
13745   "ix86_expand_branch (LT, operands[0]); DONE;")
13746
13747 (define_expand "bltu"
13748   [(set (pc)
13749         (if_then_else (match_dup 1)
13750                       (label_ref (match_operand 0 "" ""))
13751                       (pc)))]
13752   ""
13753   "ix86_expand_branch (LTU, operands[0]); DONE;")
13754
13755 (define_expand "bge"
13756   [(set (pc)
13757         (if_then_else (match_dup 1)
13758                       (label_ref (match_operand 0 "" ""))
13759                       (pc)))]
13760   ""
13761   "ix86_expand_branch (GE, operands[0]); DONE;")
13762
13763 (define_expand "bgeu"
13764   [(set (pc)
13765         (if_then_else (match_dup 1)
13766                       (label_ref (match_operand 0 "" ""))
13767                       (pc)))]
13768   ""
13769   "ix86_expand_branch (GEU, operands[0]); DONE;")
13770
13771 (define_expand "ble"
13772   [(set (pc)
13773         (if_then_else (match_dup 1)
13774                       (label_ref (match_operand 0 "" ""))
13775                       (pc)))]
13776   ""
13777   "ix86_expand_branch (LE, operands[0]); DONE;")
13778
13779 (define_expand "bleu"
13780   [(set (pc)
13781         (if_then_else (match_dup 1)
13782                       (label_ref (match_operand 0 "" ""))
13783                       (pc)))]
13784   ""
13785   "ix86_expand_branch (LEU, operands[0]); DONE;")
13786
13787 (define_expand "bunordered"
13788   [(set (pc)
13789         (if_then_else (match_dup 1)
13790                       (label_ref (match_operand 0 "" ""))
13791                       (pc)))]
13792   "TARGET_80387 || TARGET_SSE_MATH"
13793   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13794
13795 (define_expand "bordered"
13796   [(set (pc)
13797         (if_then_else (match_dup 1)
13798                       (label_ref (match_operand 0 "" ""))
13799                       (pc)))]
13800   "TARGET_80387 || TARGET_SSE_MATH"
13801   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13802
13803 (define_expand "buneq"
13804   [(set (pc)
13805         (if_then_else (match_dup 1)
13806                       (label_ref (match_operand 0 "" ""))
13807                       (pc)))]
13808   "TARGET_80387 || TARGET_SSE_MATH"
13809   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13810
13811 (define_expand "bunge"
13812   [(set (pc)
13813         (if_then_else (match_dup 1)
13814                       (label_ref (match_operand 0 "" ""))
13815                       (pc)))]
13816   "TARGET_80387 || TARGET_SSE_MATH"
13817   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13818
13819 (define_expand "bungt"
13820   [(set (pc)
13821         (if_then_else (match_dup 1)
13822                       (label_ref (match_operand 0 "" ""))
13823                       (pc)))]
13824   "TARGET_80387 || TARGET_SSE_MATH"
13825   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13826
13827 (define_expand "bunle"
13828   [(set (pc)
13829         (if_then_else (match_dup 1)
13830                       (label_ref (match_operand 0 "" ""))
13831                       (pc)))]
13832   "TARGET_80387 || TARGET_SSE_MATH"
13833   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13834
13835 (define_expand "bunlt"
13836   [(set (pc)
13837         (if_then_else (match_dup 1)
13838                       (label_ref (match_operand 0 "" ""))
13839                       (pc)))]
13840   "TARGET_80387 || TARGET_SSE_MATH"
13841   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13842
13843 (define_expand "bltgt"
13844   [(set (pc)
13845         (if_then_else (match_dup 1)
13846                       (label_ref (match_operand 0 "" ""))
13847                       (pc)))]
13848   "TARGET_80387 || TARGET_SSE_MATH"
13849   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13850
13851 (define_insn "*jcc_1"
13852   [(set (pc)
13853         (if_then_else (match_operator 1 "ix86_comparison_operator"
13854                                       [(reg FLAGS_REG) (const_int 0)])
13855                       (label_ref (match_operand 0 "" ""))
13856                       (pc)))]
13857   ""
13858   "%+j%C1\t%l0"
13859   [(set_attr "type" "ibr")
13860    (set_attr "modrm" "0")
13861    (set (attr "length")
13862            (if_then_else (and (ge (minus (match_dup 0) (pc))
13863                                   (const_int -126))
13864                               (lt (minus (match_dup 0) (pc))
13865                                   (const_int 128)))
13866              (const_int 2)
13867              (const_int 6)))])
13868
13869 (define_insn "*jcc_2"
13870   [(set (pc)
13871         (if_then_else (match_operator 1 "ix86_comparison_operator"
13872                                       [(reg FLAGS_REG) (const_int 0)])
13873                       (pc)
13874                       (label_ref (match_operand 0 "" ""))))]
13875   ""
13876   "%+j%c1\t%l0"
13877   [(set_attr "type" "ibr")
13878    (set_attr "modrm" "0")
13879    (set (attr "length")
13880            (if_then_else (and (ge (minus (match_dup 0) (pc))
13881                                   (const_int -126))
13882                               (lt (minus (match_dup 0) (pc))
13883                                   (const_int 128)))
13884              (const_int 2)
13885              (const_int 6)))])
13886
13887 ;; In general it is not safe to assume too much about CCmode registers,
13888 ;; so simplify-rtx stops when it sees a second one.  Under certain
13889 ;; conditions this is safe on x86, so help combine not create
13890 ;;
13891 ;;      seta    %al
13892 ;;      testb   %al, %al
13893 ;;      je      Lfoo
13894
13895 (define_split
13896   [(set (pc)
13897         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13898                                       [(reg FLAGS_REG) (const_int 0)])
13899                           (const_int 0))
13900                       (label_ref (match_operand 1 "" ""))
13901                       (pc)))]
13902   ""
13903   [(set (pc)
13904         (if_then_else (match_dup 0)
13905                       (label_ref (match_dup 1))
13906                       (pc)))]
13907 {
13908   PUT_MODE (operands[0], VOIDmode);
13909 })
13910
13911 (define_split
13912   [(set (pc)
13913         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13914                                       [(reg FLAGS_REG) (const_int 0)])
13915                           (const_int 0))
13916                       (label_ref (match_operand 1 "" ""))
13917                       (pc)))]
13918   ""
13919   [(set (pc)
13920         (if_then_else (match_dup 0)
13921                       (label_ref (match_dup 1))
13922                       (pc)))]
13923 {
13924   rtx new_op0 = copy_rtx (operands[0]);
13925   operands[0] = new_op0;
13926   PUT_MODE (new_op0, VOIDmode);
13927   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13928                                              GET_MODE (XEXP (new_op0, 0))));
13929
13930   /* Make sure that (a) the CCmode we have for the flags is strong
13931      enough for the reversed compare or (b) we have a valid FP compare.  */
13932   if (! ix86_comparison_operator (new_op0, VOIDmode))
13933     FAIL;
13934 })
13935
13936 ;; Define combination compare-and-branch fp compare instructions to use
13937 ;; during early optimization.  Splitting the operation apart early makes
13938 ;; for bad code when we want to reverse the operation.
13939
13940 (define_insn "*fp_jcc_1_mixed"
13941   [(set (pc)
13942         (if_then_else (match_operator 0 "comparison_operator"
13943                         [(match_operand 1 "register_operand" "f,x")
13944                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13945           (label_ref (match_operand 3 "" ""))
13946           (pc)))
13947    (clobber (reg:CCFP FPSR_REG))
13948    (clobber (reg:CCFP FLAGS_REG))]
13949   "TARGET_MIX_SSE_I387
13950    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13951    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13952    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13953   "#")
13954
13955 (define_insn "*fp_jcc_1_sse"
13956   [(set (pc)
13957         (if_then_else (match_operator 0 "comparison_operator"
13958                         [(match_operand 1 "register_operand" "x")
13959                          (match_operand 2 "nonimmediate_operand" "xm")])
13960           (label_ref (match_operand 3 "" ""))
13961           (pc)))
13962    (clobber (reg:CCFP FPSR_REG))
13963    (clobber (reg:CCFP FLAGS_REG))]
13964   "TARGET_SSE_MATH
13965    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13966    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13967    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13968   "#")
13969
13970 (define_insn "*fp_jcc_1_387"
13971   [(set (pc)
13972         (if_then_else (match_operator 0 "comparison_operator"
13973                         [(match_operand 1 "register_operand" "f")
13974                          (match_operand 2 "register_operand" "f")])
13975           (label_ref (match_operand 3 "" ""))
13976           (pc)))
13977    (clobber (reg:CCFP FPSR_REG))
13978    (clobber (reg:CCFP FLAGS_REG))]
13979   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13980    && TARGET_CMOVE
13981    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13982    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13983   "#")
13984
13985 (define_insn "*fp_jcc_2_mixed"
13986   [(set (pc)
13987         (if_then_else (match_operator 0 "comparison_operator"
13988                         [(match_operand 1 "register_operand" "f,x")
13989                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13990           (pc)
13991           (label_ref (match_operand 3 "" ""))))
13992    (clobber (reg:CCFP FPSR_REG))
13993    (clobber (reg:CCFP FLAGS_REG))]
13994   "TARGET_MIX_SSE_I387
13995    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13996    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13997    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13998   "#")
13999
14000 (define_insn "*fp_jcc_2_sse"
14001   [(set (pc)
14002         (if_then_else (match_operator 0 "comparison_operator"
14003                         [(match_operand 1 "register_operand" "x")
14004                          (match_operand 2 "nonimmediate_operand" "xm")])
14005           (pc)
14006           (label_ref (match_operand 3 "" ""))))
14007    (clobber (reg:CCFP FPSR_REG))
14008    (clobber (reg:CCFP FLAGS_REG))]
14009   "TARGET_SSE_MATH
14010    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14011    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14012    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14013   "#")
14014
14015 (define_insn "*fp_jcc_2_387"
14016   [(set (pc)
14017         (if_then_else (match_operator 0 "comparison_operator"
14018                         [(match_operand 1 "register_operand" "f")
14019                          (match_operand 2 "register_operand" "f")])
14020           (pc)
14021           (label_ref (match_operand 3 "" ""))))
14022    (clobber (reg:CCFP FPSR_REG))
14023    (clobber (reg:CCFP FLAGS_REG))]
14024   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14025    && TARGET_CMOVE
14026    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14027    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14028   "#")
14029
14030 (define_insn "*fp_jcc_3_387"
14031   [(set (pc)
14032         (if_then_else (match_operator 0 "comparison_operator"
14033                         [(match_operand 1 "register_operand" "f")
14034                          (match_operand 2 "nonimmediate_operand" "fm")])
14035           (label_ref (match_operand 3 "" ""))
14036           (pc)))
14037    (clobber (reg:CCFP FPSR_REG))
14038    (clobber (reg:CCFP FLAGS_REG))
14039    (clobber (match_scratch:HI 4 "=a"))]
14040   "TARGET_80387
14041    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14042    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14043    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14044    && SELECT_CC_MODE (GET_CODE (operands[0]),
14045                       operands[1], operands[2]) == CCFPmode
14046    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14047   "#")
14048
14049 (define_insn "*fp_jcc_4_387"
14050   [(set (pc)
14051         (if_then_else (match_operator 0 "comparison_operator"
14052                         [(match_operand 1 "register_operand" "f")
14053                          (match_operand 2 "nonimmediate_operand" "fm")])
14054           (pc)
14055           (label_ref (match_operand 3 "" ""))))
14056    (clobber (reg:CCFP FPSR_REG))
14057    (clobber (reg:CCFP FLAGS_REG))
14058    (clobber (match_scratch:HI 4 "=a"))]
14059   "TARGET_80387
14060    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14061    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14062    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14063    && SELECT_CC_MODE (GET_CODE (operands[0]),
14064                       operands[1], operands[2]) == CCFPmode
14065    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14066   "#")
14067
14068 (define_insn "*fp_jcc_5_387"
14069   [(set (pc)
14070         (if_then_else (match_operator 0 "comparison_operator"
14071                         [(match_operand 1 "register_operand" "f")
14072                          (match_operand 2 "register_operand" "f")])
14073           (label_ref (match_operand 3 "" ""))
14074           (pc)))
14075    (clobber (reg:CCFP FPSR_REG))
14076    (clobber (reg:CCFP FLAGS_REG))
14077    (clobber (match_scratch:HI 4 "=a"))]
14078   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14079    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14080    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14081   "#")
14082
14083 (define_insn "*fp_jcc_6_387"
14084   [(set (pc)
14085         (if_then_else (match_operator 0 "comparison_operator"
14086                         [(match_operand 1 "register_operand" "f")
14087                          (match_operand 2 "register_operand" "f")])
14088           (pc)
14089           (label_ref (match_operand 3 "" ""))))
14090    (clobber (reg:CCFP FPSR_REG))
14091    (clobber (reg:CCFP FLAGS_REG))
14092    (clobber (match_scratch:HI 4 "=a"))]
14093   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14094    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14095    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14096   "#")
14097
14098 (define_insn "*fp_jcc_7_387"
14099   [(set (pc)
14100         (if_then_else (match_operator 0 "comparison_operator"
14101                         [(match_operand 1 "register_operand" "f")
14102                          (match_operand 2 "const0_operand" "X")])
14103           (label_ref (match_operand 3 "" ""))
14104           (pc)))
14105    (clobber (reg:CCFP FPSR_REG))
14106    (clobber (reg:CCFP FLAGS_REG))
14107    (clobber (match_scratch:HI 4 "=a"))]
14108   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14109    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14110    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14111    && SELECT_CC_MODE (GET_CODE (operands[0]),
14112                       operands[1], operands[2]) == CCFPmode
14113    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14114   "#")
14115
14116 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14117 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14118 ;; with a precedence over other operators and is always put in the first
14119 ;; place. Swap condition and operands to match ficom instruction.
14120
14121 (define_insn "*fp_jcc_8<mode>_387"
14122   [(set (pc)
14123         (if_then_else (match_operator 0 "comparison_operator"
14124                         [(match_operator 1 "float_operator"
14125                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14126                            (match_operand 3 "register_operand" "f,f")])
14127           (label_ref (match_operand 4 "" ""))
14128           (pc)))
14129    (clobber (reg:CCFP FPSR_REG))
14130    (clobber (reg:CCFP FLAGS_REG))
14131    (clobber (match_scratch:HI 5 "=a,a"))]
14132   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14133    && TARGET_USE_<MODE>MODE_FIOP
14134    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14135    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14136    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14137    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14138   "#")
14139
14140 (define_split
14141   [(set (pc)
14142         (if_then_else (match_operator 0 "comparison_operator"
14143                         [(match_operand 1 "register_operand" "")
14144                          (match_operand 2 "nonimmediate_operand" "")])
14145           (match_operand 3 "" "")
14146           (match_operand 4 "" "")))
14147    (clobber (reg:CCFP FPSR_REG))
14148    (clobber (reg:CCFP FLAGS_REG))]
14149   "reload_completed"
14150   [(const_int 0)]
14151 {
14152   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14153                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14154   DONE;
14155 })
14156
14157 (define_split
14158   [(set (pc)
14159         (if_then_else (match_operator 0 "comparison_operator"
14160                         [(match_operand 1 "register_operand" "")
14161                          (match_operand 2 "general_operand" "")])
14162           (match_operand 3 "" "")
14163           (match_operand 4 "" "")))
14164    (clobber (reg:CCFP FPSR_REG))
14165    (clobber (reg:CCFP FLAGS_REG))
14166    (clobber (match_scratch:HI 5 "=a"))]
14167   "reload_completed"
14168   [(const_int 0)]
14169 {
14170   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14171                         operands[3], operands[4], operands[5], NULL_RTX);
14172   DONE;
14173 })
14174
14175 (define_split
14176   [(set (pc)
14177         (if_then_else (match_operator 0 "comparison_operator"
14178                         [(match_operator 1 "float_operator"
14179                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14180                            (match_operand 3 "register_operand" "")])
14181           (match_operand 4 "" "")
14182           (match_operand 5 "" "")))
14183    (clobber (reg:CCFP FPSR_REG))
14184    (clobber (reg:CCFP FLAGS_REG))
14185    (clobber (match_scratch:HI 6 "=a"))]
14186   "reload_completed"
14187   [(const_int 0)]
14188 {
14189   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14190   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14191                         operands[3], operands[7],
14192                         operands[4], operands[5], operands[6], NULL_RTX);
14193   DONE;
14194 })
14195
14196 ;; %%% Kill this when reload knows how to do it.
14197 (define_split
14198   [(set (pc)
14199         (if_then_else (match_operator 0 "comparison_operator"
14200                         [(match_operator 1 "float_operator"
14201                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14202                            (match_operand 3 "register_operand" "")])
14203           (match_operand 4 "" "")
14204           (match_operand 5 "" "")))
14205    (clobber (reg:CCFP FPSR_REG))
14206    (clobber (reg:CCFP FLAGS_REG))
14207    (clobber (match_scratch:HI 6 "=a"))]
14208   "reload_completed"
14209   [(const_int 0)]
14210 {
14211   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14212   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14213   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14214                         operands[3], operands[7],
14215                         operands[4], operands[5], operands[6], operands[2]);
14216   DONE;
14217 })
14218 \f
14219 ;; Unconditional and other jump instructions
14220
14221 (define_insn "jump"
14222   [(set (pc)
14223         (label_ref (match_operand 0 "" "")))]
14224   ""
14225   "jmp\t%l0"
14226   [(set_attr "type" "ibr")
14227    (set (attr "length")
14228            (if_then_else (and (ge (minus (match_dup 0) (pc))
14229                                   (const_int -126))
14230                               (lt (minus (match_dup 0) (pc))
14231                                   (const_int 128)))
14232              (const_int 2)
14233              (const_int 5)))
14234    (set_attr "modrm" "0")])
14235
14236 (define_expand "indirect_jump"
14237   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14238   ""
14239   "")
14240
14241 (define_insn "*indirect_jump"
14242   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14243   "!TARGET_64BIT"
14244   "jmp\t%A0"
14245   [(set_attr "type" "ibr")
14246    (set_attr "length_immediate" "0")])
14247
14248 (define_insn "*indirect_jump_rtx64"
14249   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14250   "TARGET_64BIT"
14251   "jmp\t%A0"
14252   [(set_attr "type" "ibr")
14253    (set_attr "length_immediate" "0")])
14254
14255 (define_expand "tablejump"
14256   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14257               (use (label_ref (match_operand 1 "" "")))])]
14258   ""
14259 {
14260   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14261      relative.  Convert the relative address to an absolute address.  */
14262   if (flag_pic)
14263     {
14264       rtx op0, op1;
14265       enum rtx_code code;
14266
14267       /* We can't use @GOTOFF for text labels on VxWorks;
14268          see gotoff_operand.  */
14269       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14270         {
14271           code = PLUS;
14272           op0 = operands[0];
14273           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14274         }
14275       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14276         {
14277           code = PLUS;
14278           op0 = operands[0];
14279           op1 = pic_offset_table_rtx;
14280         }
14281       else
14282         {
14283           code = MINUS;
14284           op0 = pic_offset_table_rtx;
14285           op1 = operands[0];
14286         }
14287
14288       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14289                                          OPTAB_DIRECT);
14290     }
14291 })
14292
14293 (define_insn "*tablejump_1"
14294   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14295    (use (label_ref (match_operand 1 "" "")))]
14296   "!TARGET_64BIT"
14297   "jmp\t%A0"
14298   [(set_attr "type" "ibr")
14299    (set_attr "length_immediate" "0")])
14300
14301 (define_insn "*tablejump_1_rtx64"
14302   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14303    (use (label_ref (match_operand 1 "" "")))]
14304   "TARGET_64BIT"
14305   "jmp\t%A0"
14306   [(set_attr "type" "ibr")
14307    (set_attr "length_immediate" "0")])
14308 \f
14309 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14310
14311 (define_peephole2
14312   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14313    (set (match_operand:QI 1 "register_operand" "")
14314         (match_operator:QI 2 "ix86_comparison_operator"
14315           [(reg FLAGS_REG) (const_int 0)]))
14316    (set (match_operand 3 "q_regs_operand" "")
14317         (zero_extend (match_dup 1)))]
14318   "(peep2_reg_dead_p (3, operands[1])
14319     || operands_match_p (operands[1], operands[3]))
14320    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14321   [(set (match_dup 4) (match_dup 0))
14322    (set (strict_low_part (match_dup 5))
14323         (match_dup 2))]
14324 {
14325   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14326   operands[5] = gen_lowpart (QImode, operands[3]);
14327   ix86_expand_clear (operands[3]);
14328 })
14329
14330 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14331
14332 (define_peephole2
14333   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14334    (set (match_operand:QI 1 "register_operand" "")
14335         (match_operator:QI 2 "ix86_comparison_operator"
14336           [(reg FLAGS_REG) (const_int 0)]))
14337    (parallel [(set (match_operand 3 "q_regs_operand" "")
14338                    (zero_extend (match_dup 1)))
14339               (clobber (reg:CC FLAGS_REG))])]
14340   "(peep2_reg_dead_p (3, operands[1])
14341     || operands_match_p (operands[1], operands[3]))
14342    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14343   [(set (match_dup 4) (match_dup 0))
14344    (set (strict_low_part (match_dup 5))
14345         (match_dup 2))]
14346 {
14347   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14348   operands[5] = gen_lowpart (QImode, operands[3]);
14349   ix86_expand_clear (operands[3]);
14350 })
14351 \f
14352 ;; Call instructions.
14353
14354 ;; The predicates normally associated with named expanders are not properly
14355 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14356 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14357
14358 ;; Call subroutine returning no value.
14359
14360 (define_expand "call_pop"
14361   [(parallel [(call (match_operand:QI 0 "" "")
14362                     (match_operand:SI 1 "" ""))
14363               (set (reg:SI SP_REG)
14364                    (plus:SI (reg:SI SP_REG)
14365                             (match_operand:SI 3 "" "")))])]
14366   "!TARGET_64BIT"
14367 {
14368   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14369   DONE;
14370 })
14371
14372 (define_insn "*call_pop_0"
14373   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14374          (match_operand:SI 1 "" ""))
14375    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14376                             (match_operand:SI 2 "immediate_operand" "")))]
14377   "!TARGET_64BIT"
14378 {
14379   if (SIBLING_CALL_P (insn))
14380     return "jmp\t%P0";
14381   else
14382     return "call\t%P0";
14383 }
14384   [(set_attr "type" "call")])
14385
14386 (define_insn "*call_pop_1"
14387   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14388          (match_operand:SI 1 "" ""))
14389    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14390                             (match_operand:SI 2 "immediate_operand" "i")))]
14391   "!TARGET_64BIT"
14392 {
14393   if (constant_call_address_operand (operands[0], Pmode))
14394     {
14395       if (SIBLING_CALL_P (insn))
14396         return "jmp\t%P0";
14397       else
14398         return "call\t%P0";
14399     }
14400   if (SIBLING_CALL_P (insn))
14401     return "jmp\t%A0";
14402   else
14403     return "call\t%A0";
14404 }
14405   [(set_attr "type" "call")])
14406
14407 (define_expand "call"
14408   [(call (match_operand:QI 0 "" "")
14409          (match_operand 1 "" ""))
14410    (use (match_operand 2 "" ""))]
14411   ""
14412 {
14413   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14414   DONE;
14415 })
14416
14417 (define_expand "sibcall"
14418   [(call (match_operand:QI 0 "" "")
14419          (match_operand 1 "" ""))
14420    (use (match_operand 2 "" ""))]
14421   ""
14422 {
14423   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14424   DONE;
14425 })
14426
14427 (define_insn "*call_0"
14428   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14429          (match_operand 1 "" ""))]
14430   ""
14431 {
14432   if (SIBLING_CALL_P (insn))
14433     return "jmp\t%P0";
14434   else
14435     return "call\t%P0";
14436 }
14437   [(set_attr "type" "call")])
14438
14439 (define_insn "*call_1"
14440   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14441          (match_operand 1 "" ""))]
14442   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14443 {
14444   if (constant_call_address_operand (operands[0], Pmode))
14445     return "call\t%P0";
14446   return "call\t%A0";
14447 }
14448   [(set_attr "type" "call")])
14449
14450 (define_insn "*sibcall_1"
14451   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14452          (match_operand 1 "" ""))]
14453   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14454 {
14455   if (constant_call_address_operand (operands[0], Pmode))
14456     return "jmp\t%P0";
14457   return "jmp\t%A0";
14458 }
14459   [(set_attr "type" "call")])
14460
14461 (define_insn "*call_1_rex64"
14462   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14463          (match_operand 1 "" ""))]
14464   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14465    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14466 {
14467   if (constant_call_address_operand (operands[0], Pmode))
14468     return "call\t%P0";
14469   return "call\t%A0";
14470 }
14471   [(set_attr "type" "call")])
14472
14473 (define_insn "*call_1_rex64_large"
14474   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14475          (match_operand 1 "" ""))]
14476   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14477   "call\t%A0"
14478   [(set_attr "type" "call")])
14479
14480 (define_insn "*sibcall_1_rex64"
14481   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14482          (match_operand 1 "" ""))]
14483   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14484   "jmp\t%P0"
14485   [(set_attr "type" "call")])
14486
14487 (define_insn "*sibcall_1_rex64_v"
14488   [(call (mem:QI (reg:DI R11_REG))
14489          (match_operand 0 "" ""))]
14490   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14491   "jmp\t*%%r11"
14492   [(set_attr "type" "call")])
14493
14494
14495 ;; Call subroutine, returning value in operand 0
14496
14497 (define_expand "call_value_pop"
14498   [(parallel [(set (match_operand 0 "" "")
14499                    (call (match_operand:QI 1 "" "")
14500                          (match_operand:SI 2 "" "")))
14501               (set (reg:SI SP_REG)
14502                    (plus:SI (reg:SI SP_REG)
14503                             (match_operand:SI 4 "" "")))])]
14504   "!TARGET_64BIT"
14505 {
14506   ix86_expand_call (operands[0], operands[1], operands[2],
14507                     operands[3], operands[4], 0);
14508   DONE;
14509 })
14510
14511 (define_expand "call_value"
14512   [(set (match_operand 0 "" "")
14513         (call (match_operand:QI 1 "" "")
14514               (match_operand:SI 2 "" "")))
14515    (use (match_operand:SI 3 "" ""))]
14516   ;; Operand 2 not used on the i386.
14517   ""
14518 {
14519   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14520   DONE;
14521 })
14522
14523 (define_expand "sibcall_value"
14524   [(set (match_operand 0 "" "")
14525         (call (match_operand:QI 1 "" "")
14526               (match_operand:SI 2 "" "")))
14527    (use (match_operand:SI 3 "" ""))]
14528   ;; Operand 2 not used on the i386.
14529   ""
14530 {
14531   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14532   DONE;
14533 })
14534
14535 ;; Call subroutine returning any type.
14536
14537 (define_expand "untyped_call"
14538   [(parallel [(call (match_operand 0 "" "")
14539                     (const_int 0))
14540               (match_operand 1 "" "")
14541               (match_operand 2 "" "")])]
14542   ""
14543 {
14544   int i;
14545
14546   /* In order to give reg-stack an easier job in validating two
14547      coprocessor registers as containing a possible return value,
14548      simply pretend the untyped call returns a complex long double
14549      value.  */
14550
14551   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14552                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14553                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14554                     NULL, 0);
14555
14556   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14557     {
14558       rtx set = XVECEXP (operands[2], 0, i);
14559       emit_move_insn (SET_DEST (set), SET_SRC (set));
14560     }
14561
14562   /* The optimizer does not know that the call sets the function value
14563      registers we stored in the result block.  We avoid problems by
14564      claiming that all hard registers are used and clobbered at this
14565      point.  */
14566   emit_insn (gen_blockage ());
14567
14568   DONE;
14569 })
14570 \f
14571 ;; Prologue and epilogue instructions
14572
14573 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14574 ;; all of memory.  This blocks insns from being moved across this point.
14575
14576 (define_insn "blockage"
14577   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14578   ""
14579   ""
14580   [(set_attr "length" "0")])
14581
14582 ;; As USE insns aren't meaningful after reload, this is used instead
14583 ;; to prevent deleting instructions setting registers for PIC code
14584 (define_insn "prologue_use"
14585   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14586   ""
14587   ""
14588   [(set_attr "length" "0")])
14589
14590 ;; Insn emitted into the body of a function to return from a function.
14591 ;; This is only done if the function's epilogue is known to be simple.
14592 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14593
14594 (define_expand "return"
14595   [(return)]
14596   "ix86_can_use_return_insn_p ()"
14597 {
14598   if (current_function_pops_args)
14599     {
14600       rtx popc = GEN_INT (current_function_pops_args);
14601       emit_jump_insn (gen_return_pop_internal (popc));
14602       DONE;
14603     }
14604 })
14605
14606 (define_insn "return_internal"
14607   [(return)]
14608   "reload_completed"
14609   "ret"
14610   [(set_attr "length" "1")
14611    (set_attr "length_immediate" "0")
14612    (set_attr "modrm" "0")])
14613
14614 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14615 ;; instruction Athlon and K8 have.
14616
14617 (define_insn "return_internal_long"
14618   [(return)
14619    (unspec [(const_int 0)] UNSPEC_REP)]
14620   "reload_completed"
14621   "rep{\;| }ret"
14622   [(set_attr "length" "1")
14623    (set_attr "length_immediate" "0")
14624    (set_attr "prefix_rep" "1")
14625    (set_attr "modrm" "0")])
14626
14627 (define_insn "return_pop_internal"
14628   [(return)
14629    (use (match_operand:SI 0 "const_int_operand" ""))]
14630   "reload_completed"
14631   "ret\t%0"
14632   [(set_attr "length" "3")
14633    (set_attr "length_immediate" "2")
14634    (set_attr "modrm" "0")])
14635
14636 (define_insn "return_indirect_internal"
14637   [(return)
14638    (use (match_operand:SI 0 "register_operand" "r"))]
14639   "reload_completed"
14640   "jmp\t%A0"
14641   [(set_attr "type" "ibr")
14642    (set_attr "length_immediate" "0")])
14643
14644 (define_insn "nop"
14645   [(const_int 0)]
14646   ""
14647   "nop"
14648   [(set_attr "length" "1")
14649    (set_attr "length_immediate" "0")
14650    (set_attr "modrm" "0")])
14651
14652 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14653 ;; branch prediction penalty for the third jump in a 16-byte
14654 ;; block on K8.
14655
14656 (define_insn "align"
14657   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14658   ""
14659 {
14660 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14661   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14662 #else
14663   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14664      The align insn is used to avoid 3 jump instructions in the row to improve
14665      branch prediction and the benefits hardly outweigh the cost of extra 8
14666      nops on the average inserted by full alignment pseudo operation.  */
14667 #endif
14668   return "";
14669 }
14670   [(set_attr "length" "16")])
14671
14672 (define_expand "prologue"
14673   [(const_int 1)]
14674   ""
14675   "ix86_expand_prologue (); DONE;")
14676
14677 (define_insn "set_got"
14678   [(set (match_operand:SI 0 "register_operand" "=r")
14679         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14680    (clobber (reg:CC FLAGS_REG))]
14681   "!TARGET_64BIT"
14682   { return output_set_got (operands[0], NULL_RTX); }
14683   [(set_attr "type" "multi")
14684    (set_attr "length" "12")])
14685
14686 (define_insn "set_got_labelled"
14687   [(set (match_operand:SI 0 "register_operand" "=r")
14688         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14689          UNSPEC_SET_GOT))
14690    (clobber (reg:CC FLAGS_REG))]
14691   "!TARGET_64BIT"
14692   { return output_set_got (operands[0], operands[1]); }
14693   [(set_attr "type" "multi")
14694    (set_attr "length" "12")])
14695
14696 (define_insn "set_got_rex64"
14697   [(set (match_operand:DI 0 "register_operand" "=r")
14698         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14699   "TARGET_64BIT"
14700   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14701   [(set_attr "type" "lea")
14702    (set_attr "length" "6")])
14703
14704 (define_insn "set_rip_rex64"
14705   [(set (match_operand:DI 0 "register_operand" "=r")
14706         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14707   "TARGET_64BIT"
14708   "lea{q}\t%l1(%%rip), %0"
14709   [(set_attr "type" "lea")
14710    (set_attr "length" "6")])
14711
14712 (define_insn "set_got_offset_rex64"
14713   [(set (match_operand:DI 0 "register_operand" "=r")
14714         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14715   "TARGET_64BIT"
14716   "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
14717   [(set_attr "type" "imov")
14718    (set_attr "length" "11")])
14719
14720 (define_expand "epilogue"
14721   [(const_int 1)]
14722   ""
14723   "ix86_expand_epilogue (1); DONE;")
14724
14725 (define_expand "sibcall_epilogue"
14726   [(const_int 1)]
14727   ""
14728   "ix86_expand_epilogue (0); DONE;")
14729
14730 (define_expand "eh_return"
14731   [(use (match_operand 0 "register_operand" ""))]
14732   ""
14733 {
14734   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14735
14736   /* Tricky bit: we write the address of the handler to which we will
14737      be returning into someone else's stack frame, one word below the
14738      stack address we wish to restore.  */
14739   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14740   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14741   tmp = gen_rtx_MEM (Pmode, tmp);
14742   emit_move_insn (tmp, ra);
14743
14744   if (Pmode == SImode)
14745     emit_jump_insn (gen_eh_return_si (sa));
14746   else
14747     emit_jump_insn (gen_eh_return_di (sa));
14748   emit_barrier ();
14749   DONE;
14750 })
14751
14752 (define_insn_and_split "eh_return_si"
14753   [(set (pc)
14754         (unspec [(match_operand:SI 0 "register_operand" "c")]
14755                  UNSPEC_EH_RETURN))]
14756   "!TARGET_64BIT"
14757   "#"
14758   "reload_completed"
14759   [(const_int 1)]
14760   "ix86_expand_epilogue (2); DONE;")
14761
14762 (define_insn_and_split "eh_return_di"
14763   [(set (pc)
14764         (unspec [(match_operand:DI 0 "register_operand" "c")]
14765                  UNSPEC_EH_RETURN))]
14766   "TARGET_64BIT"
14767   "#"
14768   "reload_completed"
14769   [(const_int 1)]
14770   "ix86_expand_epilogue (2); DONE;")
14771
14772 (define_insn "leave"
14773   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14774    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14775    (clobber (mem:BLK (scratch)))]
14776   "!TARGET_64BIT"
14777   "leave"
14778   [(set_attr "type" "leave")])
14779
14780 (define_insn "leave_rex64"
14781   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14782    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14783    (clobber (mem:BLK (scratch)))]
14784   "TARGET_64BIT"
14785   "leave"
14786   [(set_attr "type" "leave")])
14787 \f
14788 (define_expand "ffssi2"
14789   [(parallel
14790      [(set (match_operand:SI 0 "register_operand" "")
14791            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14792       (clobber (match_scratch:SI 2 ""))
14793       (clobber (reg:CC FLAGS_REG))])]
14794   ""
14795 {
14796   if (TARGET_CMOVE)
14797     {
14798       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14799       DONE;
14800     }
14801 })
14802
14803 (define_expand "ffs_cmove"
14804   [(set (match_dup 2) (const_int -1))
14805    (parallel [(set (reg:CCZ FLAGS_REG)
14806                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
14807                                 (const_int 0)))
14808               (set (match_operand:SI 0 "nonimmediate_operand" "")
14809                    (ctz:SI (match_dup 1)))])
14810    (set (match_dup 0) (if_then_else:SI
14811                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14812                         (match_dup 2)
14813                         (match_dup 0)))
14814    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14815               (clobber (reg:CC FLAGS_REG))])]
14816   "TARGET_CMOVE"
14817   "operands[2] = gen_reg_rtx (SImode);")
14818
14819 (define_insn_and_split "*ffs_no_cmove"
14820   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14821         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14822    (clobber (match_scratch:SI 2 "=&q"))
14823    (clobber (reg:CC FLAGS_REG))]
14824   "!TARGET_CMOVE"
14825   "#"
14826   "&& reload_completed"
14827   [(parallel [(set (reg:CCZ FLAGS_REG)
14828                    (compare:CCZ (match_dup 1) (const_int 0)))
14829               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14830    (set (strict_low_part (match_dup 3))
14831         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14832    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14833               (clobber (reg:CC FLAGS_REG))])
14834    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14835               (clobber (reg:CC FLAGS_REG))])
14836    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14837               (clobber (reg:CC FLAGS_REG))])]
14838 {
14839   operands[3] = gen_lowpart (QImode, operands[2]);
14840   ix86_expand_clear (operands[2]);
14841 })
14842
14843 (define_insn "*ffssi_1"
14844   [(set (reg:CCZ FLAGS_REG)
14845         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14846                      (const_int 0)))
14847    (set (match_operand:SI 0 "register_operand" "=r")
14848         (ctz:SI (match_dup 1)))]
14849   ""
14850   "bsf{l}\t{%1, %0|%0, %1}"
14851   [(set_attr "prefix_0f" "1")])
14852
14853 (define_expand "ffsdi2"
14854   [(set (match_dup 2) (const_int -1))
14855    (parallel [(set (reg:CCZ FLAGS_REG)
14856                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
14857                                 (const_int 0)))
14858               (set (match_operand:DI 0 "nonimmediate_operand" "")
14859                    (ctz:DI (match_dup 1)))])
14860    (set (match_dup 0) (if_then_else:DI
14861                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14862                         (match_dup 2)
14863                         (match_dup 0)))
14864    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14865               (clobber (reg:CC FLAGS_REG))])]
14866   "TARGET_64BIT"
14867   "operands[2] = gen_reg_rtx (DImode);")
14868
14869 (define_insn "*ffsdi_1"
14870   [(set (reg:CCZ FLAGS_REG)
14871         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14872                      (const_int 0)))
14873    (set (match_operand:DI 0 "register_operand" "=r")
14874         (ctz:DI (match_dup 1)))]
14875   "TARGET_64BIT"
14876   "bsf{q}\t{%1, %0|%0, %1}"
14877   [(set_attr "prefix_0f" "1")])
14878
14879 (define_insn "ctzsi2"
14880   [(set (match_operand:SI 0 "register_operand" "=r")
14881         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14882    (clobber (reg:CC FLAGS_REG))]
14883   ""
14884   "bsf{l}\t{%1, %0|%0, %1}"
14885   [(set_attr "prefix_0f" "1")])
14886
14887 (define_insn "ctzdi2"
14888   [(set (match_operand:DI 0 "register_operand" "=r")
14889         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14890    (clobber (reg:CC FLAGS_REG))]
14891   "TARGET_64BIT"
14892   "bsf{q}\t{%1, %0|%0, %1}"
14893   [(set_attr "prefix_0f" "1")])
14894
14895 (define_expand "clzsi2"
14896   [(parallel
14897      [(set (match_operand:SI 0 "register_operand" "")
14898            (minus:SI (const_int 31)
14899                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14900       (clobber (reg:CC FLAGS_REG))])
14901    (parallel
14902      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14903       (clobber (reg:CC FLAGS_REG))])]
14904   ""
14905 {
14906   if (TARGET_ABM)
14907     {
14908       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14909       DONE;
14910     }
14911 })
14912
14913 (define_insn "clzsi2_abm"
14914   [(set (match_operand:SI 0 "register_operand" "=r")
14915         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14916    (clobber (reg:CC FLAGS_REG))]
14917   "TARGET_ABM"
14918   "lzcnt{l}\t{%1, %0|%0, %1}"
14919   [(set_attr "prefix_rep" "1")
14920    (set_attr "type" "bitmanip")
14921    (set_attr "mode" "SI")])
14922
14923 (define_insn "*bsr"
14924   [(set (match_operand:SI 0 "register_operand" "=r")
14925         (minus:SI (const_int 31)
14926                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14927    (clobber (reg:CC FLAGS_REG))]
14928   ""
14929   "bsr{l}\t{%1, %0|%0, %1}"
14930   [(set_attr "prefix_0f" "1")
14931    (set_attr "mode" "SI")])
14932
14933 (define_insn "popcountsi2"
14934   [(set (match_operand:SI 0 "register_operand" "=r")
14935         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14936    (clobber (reg:CC FLAGS_REG))]
14937   "TARGET_POPCNT"
14938   "popcnt{l}\t{%1, %0|%0, %1}"
14939   [(set_attr "prefix_rep" "1")
14940    (set_attr "type" "bitmanip")
14941    (set_attr "mode" "SI")])
14942
14943 (define_insn "*popcountsi2_cmp"
14944   [(set (reg FLAGS_REG)
14945         (compare
14946           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14947           (const_int 0)))
14948    (set (match_operand:SI 0 "register_operand" "=r")
14949         (popcount:SI (match_dup 1)))]
14950   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14951   "popcnt{l}\t{%1, %0|%0, %1}"
14952   [(set_attr "prefix_rep" "1")
14953    (set_attr "type" "bitmanip")
14954    (set_attr "mode" "SI")])
14955
14956 (define_insn "*popcountsi2_cmp_zext"
14957   [(set (reg FLAGS_REG)
14958         (compare
14959           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14960           (const_int 0)))
14961    (set (match_operand:DI 0 "register_operand" "=r")
14962         (zero_extend:DI(popcount:SI (match_dup 1))))]
14963   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14964   "popcnt{l}\t{%1, %0|%0, %1}"
14965   [(set_attr "prefix_rep" "1")
14966    (set_attr "type" "bitmanip")
14967    (set_attr "mode" "SI")])
14968
14969 (define_expand "bswapsi2"
14970   [(set (match_operand:SI 0 "register_operand" "")
14971         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14972   ""
14973 {
14974   if (!TARGET_BSWAP)
14975     {
14976       rtx x = operands[0];
14977
14978       emit_move_insn (x, operands[1]);
14979       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14980       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14981       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14982       DONE;
14983     }
14984 })
14985
14986 (define_insn "*bswapsi_1"
14987   [(set (match_operand:SI 0 "register_operand" "=r")
14988         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14989   "TARGET_BSWAP"
14990   "bswap\t%0"
14991   [(set_attr "prefix_0f" "1")
14992    (set_attr "length" "2")])
14993
14994 (define_insn "*bswaphi_lowpart_1"
14995   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14996         (bswap:HI (match_dup 0)))
14997    (clobber (reg:CC FLAGS_REG))]
14998   "TARGET_USE_XCHGB || optimize_size"
14999   "@
15000     xchg{b}\t{%h0, %b0|%b0, %h0}
15001     rol{w}\t{$8, %0|%0, 8}"
15002   [(set_attr "length" "2,4")
15003    (set_attr "mode" "QI,HI")])
15004
15005 (define_insn "bswaphi_lowpart"
15006   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15007         (bswap:HI (match_dup 0)))
15008    (clobber (reg:CC FLAGS_REG))]
15009   ""
15010   "rol{w}\t{$8, %0|%0, 8}"
15011   [(set_attr "length" "4")
15012    (set_attr "mode" "HI")])
15013
15014 (define_insn "bswapdi2"
15015   [(set (match_operand:DI 0 "register_operand" "=r")
15016         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15017   "TARGET_64BIT"
15018   "bswap\t%0"
15019   [(set_attr "prefix_0f" "1")
15020    (set_attr "length" "3")])
15021
15022 (define_expand "clzdi2"
15023   [(parallel
15024      [(set (match_operand:DI 0 "register_operand" "")
15025            (minus:DI (const_int 63)
15026                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15027       (clobber (reg:CC FLAGS_REG))])
15028    (parallel
15029      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15030       (clobber (reg:CC FLAGS_REG))])]
15031   "TARGET_64BIT"
15032 {
15033   if (TARGET_ABM)
15034     {
15035       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15036       DONE;
15037     }
15038 })
15039
15040 (define_insn "clzdi2_abm"
15041   [(set (match_operand:DI 0 "register_operand" "=r")
15042         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15043    (clobber (reg:CC FLAGS_REG))]
15044   "TARGET_64BIT && TARGET_ABM"
15045   "lzcnt{q}\t{%1, %0|%0, %1}"
15046   [(set_attr "prefix_rep" "1")
15047    (set_attr "type" "bitmanip")
15048    (set_attr "mode" "DI")])
15049
15050 (define_insn "*bsr_rex64"
15051   [(set (match_operand:DI 0 "register_operand" "=r")
15052         (minus:DI (const_int 63)
15053                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15054    (clobber (reg:CC FLAGS_REG))]
15055   "TARGET_64BIT"
15056   "bsr{q}\t{%1, %0|%0, %1}"
15057   [(set_attr "prefix_0f" "1")
15058    (set_attr "mode" "DI")])
15059
15060 (define_insn "popcountdi2"
15061   [(set (match_operand:DI 0 "register_operand" "=r")
15062         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15063    (clobber (reg:CC FLAGS_REG))]
15064   "TARGET_64BIT && TARGET_POPCNT"
15065   "popcnt{q}\t{%1, %0|%0, %1}"
15066   [(set_attr "prefix_rep" "1")
15067    (set_attr "type" "bitmanip")
15068    (set_attr "mode" "DI")])
15069
15070 (define_insn "*popcountdi2_cmp"
15071   [(set (reg FLAGS_REG)
15072         (compare
15073           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15074           (const_int 0)))
15075    (set (match_operand:DI 0 "register_operand" "=r")
15076         (popcount:DI (match_dup 1)))]
15077   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15078   "popcnt{q}\t{%1, %0|%0, %1}"
15079   [(set_attr "prefix_rep" "1")
15080    (set_attr "type" "bitmanip")
15081    (set_attr "mode" "DI")])
15082
15083 (define_expand "clzhi2"
15084   [(parallel
15085      [(set (match_operand:HI 0 "register_operand" "")
15086            (minus:HI (const_int 15)
15087                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15088       (clobber (reg:CC FLAGS_REG))])
15089    (parallel
15090      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15091       (clobber (reg:CC FLAGS_REG))])]
15092   ""
15093 {
15094   if (TARGET_ABM)
15095     {
15096       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15097       DONE;
15098     }
15099 })
15100
15101 (define_insn "clzhi2_abm"
15102   [(set (match_operand:HI 0 "register_operand" "=r")
15103         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15104    (clobber (reg:CC FLAGS_REG))]
15105   "TARGET_ABM"
15106   "lzcnt{w}\t{%1, %0|%0, %1}"
15107   [(set_attr "prefix_rep" "1")
15108    (set_attr "type" "bitmanip")
15109    (set_attr "mode" "HI")])
15110
15111 (define_insn "*bsrhi"
15112   [(set (match_operand:HI 0 "register_operand" "=r")
15113         (minus:HI (const_int 15)
15114                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15115    (clobber (reg:CC FLAGS_REG))]
15116   ""
15117   "bsr{w}\t{%1, %0|%0, %1}"
15118   [(set_attr "prefix_0f" "1")
15119    (set_attr "mode" "HI")])
15120
15121 (define_insn "popcounthi2"
15122   [(set (match_operand:HI 0 "register_operand" "=r")
15123         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15124    (clobber (reg:CC FLAGS_REG))]
15125   "TARGET_POPCNT"
15126   "popcnt{w}\t{%1, %0|%0, %1}"
15127   [(set_attr "prefix_rep" "1")
15128    (set_attr "type" "bitmanip")
15129    (set_attr "mode" "HI")])
15130
15131 (define_insn "*popcounthi2_cmp"
15132   [(set (reg FLAGS_REG)
15133         (compare
15134           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15135           (const_int 0)))
15136    (set (match_operand:HI 0 "register_operand" "=r")
15137         (popcount:HI (match_dup 1)))]
15138   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15139   "popcnt{w}\t{%1, %0|%0, %1}"
15140   [(set_attr "prefix_rep" "1")
15141    (set_attr "type" "bitmanip")
15142    (set_attr "mode" "HI")])
15143
15144 (define_expand "paritydi2"
15145   [(set (match_operand:DI 0 "register_operand" "")
15146         (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15147   "! TARGET_POPCNT"
15148 {
15149   rtx scratch = gen_reg_rtx (QImode);
15150   rtx cond;
15151
15152   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15153                                 NULL_RTX, operands[1]));
15154
15155   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15156                          gen_rtx_REG (CCmode, FLAGS_REG),
15157                          const0_rtx);
15158   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15159
15160   if (TARGET_64BIT)
15161     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15162   else
15163     {
15164       rtx tmp = gen_reg_rtx (SImode);
15165
15166       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15167       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15168     }
15169   DONE;
15170 })
15171
15172 (define_insn_and_split "paritydi2_cmp"
15173   [(set (reg:CC FLAGS_REG)
15174         (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15175    (clobber (match_scratch:DI 0 "=r,X"))
15176    (clobber (match_scratch:SI 1 "=r,r"))
15177    (clobber (match_scratch:HI 2 "=Q,Q"))]
15178   "! TARGET_POPCNT"
15179   "#"
15180   "&& reload_completed"
15181   [(parallel
15182      [(set (match_dup 1)
15183            (xor:SI (match_dup 1) (match_dup 4)))
15184       (clobber (reg:CC FLAGS_REG))])
15185    (parallel
15186      [(set (reg:CC FLAGS_REG)
15187            (parity:CC (match_dup 1)))
15188       (clobber (match_dup 1))
15189       (clobber (match_dup 2))])]
15190 {
15191   operands[4] = gen_lowpart (SImode, operands[3]);
15192
15193   if (MEM_P (operands[3]))
15194     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15195   else if (! TARGET_64BIT)
15196     operands[1] = gen_highpart (SImode, operands[3]);
15197   else
15198     {
15199       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15200       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15201     }
15202 })
15203
15204 (define_expand "paritysi2"
15205   [(set (match_operand:SI 0 "register_operand" "")
15206         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15207   "! TARGET_POPCNT"
15208 {
15209   rtx scratch = gen_reg_rtx (QImode);
15210   rtx cond;
15211
15212   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15213
15214   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15215                          gen_rtx_REG (CCmode, FLAGS_REG),
15216                          const0_rtx);
15217   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15218
15219   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15220   DONE;
15221 })
15222
15223 (define_insn_and_split "paritysi2_cmp"
15224   [(set (reg:CC FLAGS_REG)
15225         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15226    (clobber (match_scratch:SI 0 "=r,X"))
15227    (clobber (match_scratch:HI 1 "=Q,Q"))]
15228   "! TARGET_POPCNT"
15229   "#"
15230   "&& reload_completed"
15231   [(parallel
15232      [(set (match_dup 1)
15233            (xor:HI (match_dup 1) (match_dup 3)))
15234       (clobber (reg:CC FLAGS_REG))])
15235    (parallel
15236      [(set (reg:CC FLAGS_REG)
15237            (parity:CC (match_dup 1)))
15238       (clobber (match_dup 1))])]
15239 {
15240   operands[3] = gen_lowpart (HImode, operands[2]);
15241
15242   if (MEM_P (operands[2]))
15243     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15244   else
15245     {
15246       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15247       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15248     }
15249 })
15250
15251 (define_insn "*parityhi2_cmp"
15252   [(set (reg:CC FLAGS_REG)
15253         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15254    (clobber (match_scratch:HI 0 "=Q"))]
15255   "! TARGET_POPCNT"
15256   "xor{b}\t{%h0, %b0|%b0, %h0}"
15257   [(set_attr "length" "2")
15258    (set_attr "mode" "HI")])
15259
15260 (define_insn "*parityqi2_cmp"
15261   [(set (reg:CC FLAGS_REG)
15262         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15263   "! TARGET_POPCNT"
15264   "test{b}\t%0, %0"
15265   [(set_attr "length" "2")
15266    (set_attr "mode" "QI")])
15267 \f
15268 ;; Thread-local storage patterns for ELF.
15269 ;;
15270 ;; Note that these code sequences must appear exactly as shown
15271 ;; in order to allow linker relaxation.
15272
15273 (define_insn "*tls_global_dynamic_32_gnu"
15274   [(set (match_operand:SI 0 "register_operand" "=a")
15275         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15276                     (match_operand:SI 2 "tls_symbolic_operand" "")
15277                     (match_operand:SI 3 "call_insn_operand" "")]
15278                     UNSPEC_TLS_GD))
15279    (clobber (match_scratch:SI 4 "=d"))
15280    (clobber (match_scratch:SI 5 "=c"))
15281    (clobber (reg:CC FLAGS_REG))]
15282   "!TARGET_64BIT && TARGET_GNU_TLS"
15283   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15284   [(set_attr "type" "multi")
15285    (set_attr "length" "12")])
15286
15287 (define_insn "*tls_global_dynamic_32_sun"
15288   [(set (match_operand:SI 0 "register_operand" "=a")
15289         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15290                     (match_operand:SI 2 "tls_symbolic_operand" "")
15291                     (match_operand:SI 3 "call_insn_operand" "")]
15292                     UNSPEC_TLS_GD))
15293    (clobber (match_scratch:SI 4 "=d"))
15294    (clobber (match_scratch:SI 5 "=c"))
15295    (clobber (reg:CC FLAGS_REG))]
15296   "!TARGET_64BIT && TARGET_SUN_TLS"
15297   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15298         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15299   [(set_attr "type" "multi")
15300    (set_attr "length" "14")])
15301
15302 (define_expand "tls_global_dynamic_32"
15303   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15304                    (unspec:SI
15305                     [(match_dup 2)
15306                      (match_operand:SI 1 "tls_symbolic_operand" "")
15307                      (match_dup 3)]
15308                     UNSPEC_TLS_GD))
15309               (clobber (match_scratch:SI 4 ""))
15310               (clobber (match_scratch:SI 5 ""))
15311               (clobber (reg:CC FLAGS_REG))])]
15312   ""
15313 {
15314   if (flag_pic)
15315     operands[2] = pic_offset_table_rtx;
15316   else
15317     {
15318       operands[2] = gen_reg_rtx (Pmode);
15319       emit_insn (gen_set_got (operands[2]));
15320     }
15321   if (TARGET_GNU2_TLS)
15322     {
15323        emit_insn (gen_tls_dynamic_gnu2_32
15324                   (operands[0], operands[1], operands[2]));
15325        DONE;
15326     }
15327   operands[3] = ix86_tls_get_addr ();
15328 })
15329
15330 (define_insn "*tls_global_dynamic_64"
15331   [(set (match_operand:DI 0 "register_operand" "=a")
15332         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15333                  (match_operand:DI 3 "" "")))
15334    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15335               UNSPEC_TLS_GD)]
15336   "TARGET_64BIT"
15337   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15338   [(set_attr "type" "multi")
15339    (set_attr "length" "16")])
15340
15341 (define_expand "tls_global_dynamic_64"
15342   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15343                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15344               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15345                          UNSPEC_TLS_GD)])]
15346   ""
15347 {
15348   if (TARGET_GNU2_TLS)
15349     {
15350        emit_insn (gen_tls_dynamic_gnu2_64
15351                   (operands[0], operands[1]));
15352        DONE;
15353     }
15354   operands[2] = ix86_tls_get_addr ();
15355 })
15356
15357 (define_insn "*tls_local_dynamic_base_32_gnu"
15358   [(set (match_operand:SI 0 "register_operand" "=a")
15359         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15360                     (match_operand:SI 2 "call_insn_operand" "")]
15361                    UNSPEC_TLS_LD_BASE))
15362    (clobber (match_scratch:SI 3 "=d"))
15363    (clobber (match_scratch:SI 4 "=c"))
15364    (clobber (reg:CC FLAGS_REG))]
15365   "!TARGET_64BIT && TARGET_GNU_TLS"
15366   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15367   [(set_attr "type" "multi")
15368    (set_attr "length" "11")])
15369
15370 (define_insn "*tls_local_dynamic_base_32_sun"
15371   [(set (match_operand:SI 0 "register_operand" "=a")
15372         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15373                     (match_operand:SI 2 "call_insn_operand" "")]
15374                    UNSPEC_TLS_LD_BASE))
15375    (clobber (match_scratch:SI 3 "=d"))
15376    (clobber (match_scratch:SI 4 "=c"))
15377    (clobber (reg:CC FLAGS_REG))]
15378   "!TARGET_64BIT && TARGET_SUN_TLS"
15379   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15380         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15381   [(set_attr "type" "multi")
15382    (set_attr "length" "13")])
15383
15384 (define_expand "tls_local_dynamic_base_32"
15385   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15386                    (unspec:SI [(match_dup 1) (match_dup 2)]
15387                               UNSPEC_TLS_LD_BASE))
15388               (clobber (match_scratch:SI 3 ""))
15389               (clobber (match_scratch:SI 4 ""))
15390               (clobber (reg:CC FLAGS_REG))])]
15391   ""
15392 {
15393   if (flag_pic)
15394     operands[1] = pic_offset_table_rtx;
15395   else
15396     {
15397       operands[1] = gen_reg_rtx (Pmode);
15398       emit_insn (gen_set_got (operands[1]));
15399     }
15400   if (TARGET_GNU2_TLS)
15401     {
15402        emit_insn (gen_tls_dynamic_gnu2_32
15403                   (operands[0], ix86_tls_module_base (), operands[1]));
15404        DONE;
15405     }
15406   operands[2] = ix86_tls_get_addr ();
15407 })
15408
15409 (define_insn "*tls_local_dynamic_base_64"
15410   [(set (match_operand:DI 0 "register_operand" "=a")
15411         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15412                  (match_operand:DI 2 "" "")))
15413    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15414   "TARGET_64BIT"
15415   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15416   [(set_attr "type" "multi")
15417    (set_attr "length" "12")])
15418
15419 (define_expand "tls_local_dynamic_base_64"
15420   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15421                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15422               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15423   ""
15424 {
15425   if (TARGET_GNU2_TLS)
15426     {
15427        emit_insn (gen_tls_dynamic_gnu2_64
15428                   (operands[0], ix86_tls_module_base ()));
15429        DONE;
15430     }
15431   operands[1] = ix86_tls_get_addr ();
15432 })
15433
15434 ;; Local dynamic of a single variable is a lose.  Show combine how
15435 ;; to convert that back to global dynamic.
15436
15437 (define_insn_and_split "*tls_local_dynamic_32_once"
15438   [(set (match_operand:SI 0 "register_operand" "=a")
15439         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15440                              (match_operand:SI 2 "call_insn_operand" "")]
15441                             UNSPEC_TLS_LD_BASE)
15442                  (const:SI (unspec:SI
15443                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15444                             UNSPEC_DTPOFF))))
15445    (clobber (match_scratch:SI 4 "=d"))
15446    (clobber (match_scratch:SI 5 "=c"))
15447    (clobber (reg:CC FLAGS_REG))]
15448   ""
15449   "#"
15450   ""
15451   [(parallel [(set (match_dup 0)
15452                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15453                               UNSPEC_TLS_GD))
15454               (clobber (match_dup 4))
15455               (clobber (match_dup 5))
15456               (clobber (reg:CC FLAGS_REG))])]
15457   "")
15458
15459 ;; Load and add the thread base pointer from %gs:0.
15460
15461 (define_insn "*load_tp_si"
15462   [(set (match_operand:SI 0 "register_operand" "=r")
15463         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15464   "!TARGET_64BIT"
15465   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15466   [(set_attr "type" "imov")
15467    (set_attr "modrm" "0")
15468    (set_attr "length" "7")
15469    (set_attr "memory" "load")
15470    (set_attr "imm_disp" "false")])
15471
15472 (define_insn "*add_tp_si"
15473   [(set (match_operand:SI 0 "register_operand" "=r")
15474         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15475                  (match_operand:SI 1 "register_operand" "0")))
15476    (clobber (reg:CC FLAGS_REG))]
15477   "!TARGET_64BIT"
15478   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15479   [(set_attr "type" "alu")
15480    (set_attr "modrm" "0")
15481    (set_attr "length" "7")
15482    (set_attr "memory" "load")
15483    (set_attr "imm_disp" "false")])
15484
15485 (define_insn "*load_tp_di"
15486   [(set (match_operand:DI 0 "register_operand" "=r")
15487         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15488   "TARGET_64BIT"
15489   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15490   [(set_attr "type" "imov")
15491    (set_attr "modrm" "0")
15492    (set_attr "length" "7")
15493    (set_attr "memory" "load")
15494    (set_attr "imm_disp" "false")])
15495
15496 (define_insn "*add_tp_di"
15497   [(set (match_operand:DI 0 "register_operand" "=r")
15498         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15499                  (match_operand:DI 1 "register_operand" "0")))
15500    (clobber (reg:CC FLAGS_REG))]
15501   "TARGET_64BIT"
15502   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15503   [(set_attr "type" "alu")
15504    (set_attr "modrm" "0")
15505    (set_attr "length" "7")
15506    (set_attr "memory" "load")
15507    (set_attr "imm_disp" "false")])
15508
15509 ;; GNU2 TLS patterns can be split.
15510
15511 (define_expand "tls_dynamic_gnu2_32"
15512   [(set (match_dup 3)
15513         (plus:SI (match_operand:SI 2 "register_operand" "")
15514                  (const:SI
15515                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15516                              UNSPEC_TLSDESC))))
15517    (parallel
15518     [(set (match_operand:SI 0 "register_operand" "")
15519           (unspec:SI [(match_dup 1) (match_dup 3)
15520                       (match_dup 2) (reg:SI SP_REG)]
15521                       UNSPEC_TLSDESC))
15522      (clobber (reg:CC FLAGS_REG))])]
15523   "!TARGET_64BIT && TARGET_GNU2_TLS"
15524 {
15525   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15526   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15527 })
15528
15529 (define_insn "*tls_dynamic_lea_32"
15530   [(set (match_operand:SI 0 "register_operand" "=r")
15531         (plus:SI (match_operand:SI 1 "register_operand" "b")
15532                  (const:SI
15533                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15534                               UNSPEC_TLSDESC))))]
15535   "!TARGET_64BIT && TARGET_GNU2_TLS"
15536   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15537   [(set_attr "type" "lea")
15538    (set_attr "mode" "SI")
15539    (set_attr "length" "6")
15540    (set_attr "length_address" "4")])
15541
15542 (define_insn "*tls_dynamic_call_32"
15543   [(set (match_operand:SI 0 "register_operand" "=a")
15544         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15545                     (match_operand:SI 2 "register_operand" "0")
15546                     ;; we have to make sure %ebx still points to the GOT
15547                     (match_operand:SI 3 "register_operand" "b")
15548                     (reg:SI SP_REG)]
15549                    UNSPEC_TLSDESC))
15550    (clobber (reg:CC FLAGS_REG))]
15551   "!TARGET_64BIT && TARGET_GNU2_TLS"
15552   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15553   [(set_attr "type" "call")
15554    (set_attr "length" "2")
15555    (set_attr "length_address" "0")])
15556
15557 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15558   [(set (match_operand:SI 0 "register_operand" "=&a")
15559         (plus:SI
15560          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15561                      (match_operand:SI 4 "" "")
15562                      (match_operand:SI 2 "register_operand" "b")
15563                      (reg:SI SP_REG)]
15564                     UNSPEC_TLSDESC)
15565          (const:SI (unspec:SI
15566                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15567                     UNSPEC_DTPOFF))))
15568    (clobber (reg:CC FLAGS_REG))]
15569   "!TARGET_64BIT && TARGET_GNU2_TLS"
15570   "#"
15571   ""
15572   [(set (match_dup 0) (match_dup 5))]
15573 {
15574   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15575   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15576 })
15577
15578 (define_expand "tls_dynamic_gnu2_64"
15579   [(set (match_dup 2)
15580         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15581                    UNSPEC_TLSDESC))
15582    (parallel
15583     [(set (match_operand:DI 0 "register_operand" "")
15584           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15585                      UNSPEC_TLSDESC))
15586      (clobber (reg:CC FLAGS_REG))])]
15587   "TARGET_64BIT && TARGET_GNU2_TLS"
15588 {
15589   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15590   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15591 })
15592
15593 (define_insn "*tls_dynamic_lea_64"
15594   [(set (match_operand:DI 0 "register_operand" "=r")
15595         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15596                    UNSPEC_TLSDESC))]
15597   "TARGET_64BIT && TARGET_GNU2_TLS"
15598   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15599   [(set_attr "type" "lea")
15600    (set_attr "mode" "DI")
15601    (set_attr "length" "7")
15602    (set_attr "length_address" "4")])
15603
15604 (define_insn "*tls_dynamic_call_64"
15605   [(set (match_operand:DI 0 "register_operand" "=a")
15606         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15607                     (match_operand:DI 2 "register_operand" "0")
15608                     (reg:DI SP_REG)]
15609                    UNSPEC_TLSDESC))
15610    (clobber (reg:CC FLAGS_REG))]
15611   "TARGET_64BIT && TARGET_GNU2_TLS"
15612   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15613   [(set_attr "type" "call")
15614    (set_attr "length" "2")
15615    (set_attr "length_address" "0")])
15616
15617 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15618   [(set (match_operand:DI 0 "register_operand" "=&a")
15619         (plus:DI
15620          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15621                      (match_operand:DI 3 "" "")
15622                      (reg:DI SP_REG)]
15623                     UNSPEC_TLSDESC)
15624          (const:DI (unspec:DI
15625                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15626                     UNSPEC_DTPOFF))))
15627    (clobber (reg:CC FLAGS_REG))]
15628   "TARGET_64BIT && TARGET_GNU2_TLS"
15629   "#"
15630   ""
15631   [(set (match_dup 0) (match_dup 4))]
15632 {
15633   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15634   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15635 })
15636
15637 ;;
15638 \f
15639 ;; These patterns match the binary 387 instructions for addM3, subM3,
15640 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15641 ;; SFmode.  The first is the normal insn, the second the same insn but
15642 ;; with one operand a conversion, and the third the same insn but with
15643 ;; the other operand a conversion.  The conversion may be SFmode or
15644 ;; SImode if the target mode DFmode, but only SImode if the target mode
15645 ;; is SFmode.
15646
15647 ;; Gcc is slightly more smart about handling normal two address instructions
15648 ;; so use special patterns for add and mull.
15649
15650 (define_insn "*fop_sf_comm_mixed"
15651   [(set (match_operand:SF 0 "register_operand" "=f,x")
15652         (match_operator:SF 3 "binary_fp_operator"
15653                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15654                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15655   "TARGET_MIX_SSE_I387
15656    && COMMUTATIVE_ARITH_P (operands[3])
15657    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15658   "* return output_387_binary_op (insn, operands);"
15659   [(set (attr "type")
15660         (if_then_else (eq_attr "alternative" "1")
15661            (if_then_else (match_operand:SF 3 "mult_operator" "")
15662               (const_string "ssemul")
15663               (const_string "sseadd"))
15664            (if_then_else (match_operand:SF 3 "mult_operator" "")
15665               (const_string "fmul")
15666               (const_string "fop"))))
15667    (set_attr "mode" "SF")])
15668
15669 (define_insn "*fop_sf_comm_sse"
15670   [(set (match_operand:SF 0 "register_operand" "=x")
15671         (match_operator:SF 3 "binary_fp_operator"
15672                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15673                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15674   "TARGET_SSE_MATH
15675    && COMMUTATIVE_ARITH_P (operands[3])
15676    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15677   "* return output_387_binary_op (insn, operands);"
15678   [(set (attr "type")
15679         (if_then_else (match_operand:SF 3 "mult_operator" "")
15680            (const_string "ssemul")
15681            (const_string "sseadd")))
15682    (set_attr "mode" "SF")])
15683
15684 (define_insn "*fop_sf_comm_i387"
15685   [(set (match_operand:SF 0 "register_operand" "=f")
15686         (match_operator:SF 3 "binary_fp_operator"
15687                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15688                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15689   "TARGET_80387
15690    && COMMUTATIVE_ARITH_P (operands[3])
15691    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15692   "* return output_387_binary_op (insn, operands);"
15693   [(set (attr "type")
15694         (if_then_else (match_operand:SF 3 "mult_operator" "")
15695            (const_string "fmul")
15696            (const_string "fop")))
15697    (set_attr "mode" "SF")])
15698
15699 (define_insn "*fop_sf_1_mixed"
15700   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15701         (match_operator:SF 3 "binary_fp_operator"
15702                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15703                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15704   "TARGET_MIX_SSE_I387
15705    && !COMMUTATIVE_ARITH_P (operands[3])
15706    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15707   "* return output_387_binary_op (insn, operands);"
15708   [(set (attr "type")
15709         (cond [(and (eq_attr "alternative" "2")
15710                     (match_operand:SF 3 "mult_operator" ""))
15711                  (const_string "ssemul")
15712                (and (eq_attr "alternative" "2")
15713                     (match_operand:SF 3 "div_operator" ""))
15714                  (const_string "ssediv")
15715                (eq_attr "alternative" "2")
15716                  (const_string "sseadd")
15717                (match_operand:SF 3 "mult_operator" "")
15718                  (const_string "fmul")
15719                (match_operand:SF 3 "div_operator" "")
15720                  (const_string "fdiv")
15721               ]
15722               (const_string "fop")))
15723    (set_attr "mode" "SF")])
15724
15725 (define_insn "*rcpsf2_sse"
15726   [(set (match_operand:SF 0 "register_operand" "=x")
15727         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15728                    UNSPEC_RCP))]
15729   "TARGET_SSE_MATH"
15730   "rcpss\t{%1, %0|%0, %1}"
15731   [(set_attr "type" "sse")
15732    (set_attr "mode" "SF")])
15733
15734 (define_insn "*fop_sf_1_sse"
15735   [(set (match_operand:SF 0 "register_operand" "=x")
15736         (match_operator:SF 3 "binary_fp_operator"
15737                         [(match_operand:SF 1 "register_operand" "0")
15738                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15739   "TARGET_SSE_MATH
15740    && !COMMUTATIVE_ARITH_P (operands[3])"
15741   "* return output_387_binary_op (insn, operands);"
15742   [(set (attr "type")
15743         (cond [(match_operand:SF 3 "mult_operator" "")
15744                  (const_string "ssemul")
15745                (match_operand:SF 3 "div_operator" "")
15746                  (const_string "ssediv")
15747               ]
15748               (const_string "sseadd")))
15749    (set_attr "mode" "SF")])
15750
15751 ;; This pattern is not fully shadowed by the pattern above.
15752 (define_insn "*fop_sf_1_i387"
15753   [(set (match_operand:SF 0 "register_operand" "=f,f")
15754         (match_operator:SF 3 "binary_fp_operator"
15755                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15756                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15757   "TARGET_80387 && !TARGET_SSE_MATH
15758    && !COMMUTATIVE_ARITH_P (operands[3])
15759    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15760   "* return output_387_binary_op (insn, operands);"
15761   [(set (attr "type")
15762         (cond [(match_operand:SF 3 "mult_operator" "")
15763                  (const_string "fmul")
15764                (match_operand:SF 3 "div_operator" "")
15765                  (const_string "fdiv")
15766               ]
15767               (const_string "fop")))
15768    (set_attr "mode" "SF")])
15769
15770 ;; ??? Add SSE splitters for these!
15771 (define_insn "*fop_sf_2<mode>_i387"
15772   [(set (match_operand:SF 0 "register_operand" "=f,f")
15773         (match_operator:SF 3 "binary_fp_operator"
15774           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15775            (match_operand:SF 2 "register_operand" "0,0")]))]
15776   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15777   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15778   [(set (attr "type")
15779         (cond [(match_operand:SF 3 "mult_operator" "")
15780                  (const_string "fmul")
15781                (match_operand:SF 3 "div_operator" "")
15782                  (const_string "fdiv")
15783               ]
15784               (const_string "fop")))
15785    (set_attr "fp_int_src" "true")
15786    (set_attr "mode" "<MODE>")])
15787
15788 (define_insn "*fop_sf_3<mode>_i387"
15789   [(set (match_operand:SF 0 "register_operand" "=f,f")
15790         (match_operator:SF 3 "binary_fp_operator"
15791           [(match_operand:SF 1 "register_operand" "0,0")
15792            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15793   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15794   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15795   [(set (attr "type")
15796         (cond [(match_operand:SF 3 "mult_operator" "")
15797                  (const_string "fmul")
15798                (match_operand:SF 3 "div_operator" "")
15799                  (const_string "fdiv")
15800               ]
15801               (const_string "fop")))
15802    (set_attr "fp_int_src" "true")
15803    (set_attr "mode" "<MODE>")])
15804
15805 (define_insn "*fop_df_comm_mixed"
15806   [(set (match_operand:DF 0 "register_operand" "=f,x")
15807         (match_operator:DF 3 "binary_fp_operator"
15808           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15809            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15810   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15811    && COMMUTATIVE_ARITH_P (operands[3])
15812    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15813   "* return output_387_binary_op (insn, operands);"
15814   [(set (attr "type")
15815         (if_then_else (eq_attr "alternative" "1")
15816            (if_then_else (match_operand:DF 3 "mult_operator" "")
15817               (const_string "ssemul")
15818               (const_string "sseadd"))
15819            (if_then_else (match_operand:DF 3 "mult_operator" "")
15820               (const_string "fmul")
15821               (const_string "fop"))))
15822    (set_attr "mode" "DF")])
15823
15824 (define_insn "*fop_df_comm_sse"
15825   [(set (match_operand:DF 0 "register_operand" "=x")
15826         (match_operator:DF 3 "binary_fp_operator"
15827           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15828            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15829   "TARGET_SSE2 && TARGET_SSE_MATH
15830    && COMMUTATIVE_ARITH_P (operands[3])
15831    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15832   "* return output_387_binary_op (insn, operands);"
15833   [(set (attr "type")
15834         (if_then_else (match_operand:DF 3 "mult_operator" "")
15835            (const_string "ssemul")
15836            (const_string "sseadd")))
15837    (set_attr "mode" "DF")])
15838
15839 (define_insn "*fop_df_comm_i387"
15840   [(set (match_operand:DF 0 "register_operand" "=f")
15841         (match_operator:DF 3 "binary_fp_operator"
15842                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15843                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15844   "TARGET_80387
15845    && COMMUTATIVE_ARITH_P (operands[3])
15846    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15847   "* return output_387_binary_op (insn, operands);"
15848   [(set (attr "type")
15849         (if_then_else (match_operand:DF 3 "mult_operator" "")
15850            (const_string "fmul")
15851            (const_string "fop")))
15852    (set_attr "mode" "DF")])
15853
15854 (define_insn "*fop_df_1_mixed"
15855   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15856         (match_operator:DF 3 "binary_fp_operator"
15857           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15858            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15859   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15860    && !COMMUTATIVE_ARITH_P (operands[3])
15861    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15862   "* return output_387_binary_op (insn, operands);"
15863   [(set (attr "type")
15864         (cond [(and (eq_attr "alternative" "2")
15865                     (match_operand:DF 3 "mult_operator" ""))
15866                  (const_string "ssemul")
15867                (and (eq_attr "alternative" "2")
15868                     (match_operand:DF 3 "div_operator" ""))
15869                  (const_string "ssediv")
15870                (eq_attr "alternative" "2")
15871                  (const_string "sseadd")
15872                (match_operand:DF 3 "mult_operator" "")
15873                  (const_string "fmul")
15874                (match_operand:DF 3 "div_operator" "")
15875                  (const_string "fdiv")
15876               ]
15877               (const_string "fop")))
15878    (set_attr "mode" "DF")])
15879
15880 (define_insn "*fop_df_1_sse"
15881   [(set (match_operand:DF 0 "register_operand" "=x")
15882         (match_operator:DF 3 "binary_fp_operator"
15883           [(match_operand:DF 1 "register_operand" "0")
15884            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15885   "TARGET_SSE2 && TARGET_SSE_MATH
15886    && !COMMUTATIVE_ARITH_P (operands[3])"
15887   "* return output_387_binary_op (insn, operands);"
15888   [(set_attr "mode" "DF")
15889    (set (attr "type")
15890         (cond [(match_operand:DF 3 "mult_operator" "")
15891                  (const_string "ssemul")
15892                (match_operand:DF 3 "div_operator" "")
15893                  (const_string "ssediv")
15894               ]
15895               (const_string "sseadd")))])
15896
15897 ;; This pattern is not fully shadowed by the pattern above.
15898 (define_insn "*fop_df_1_i387"
15899   [(set (match_operand:DF 0 "register_operand" "=f,f")
15900         (match_operator:DF 3 "binary_fp_operator"
15901                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15902                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15903   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15904    && !COMMUTATIVE_ARITH_P (operands[3])
15905    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15906   "* return output_387_binary_op (insn, operands);"
15907   [(set (attr "type")
15908         (cond [(match_operand:DF 3 "mult_operator" "")
15909                  (const_string "fmul")
15910                (match_operand:DF 3 "div_operator" "")
15911                  (const_string "fdiv")
15912               ]
15913               (const_string "fop")))
15914    (set_attr "mode" "DF")])
15915
15916 ;; ??? Add SSE splitters for these!
15917 (define_insn "*fop_df_2<mode>_i387"
15918   [(set (match_operand:DF 0 "register_operand" "=f,f")
15919         (match_operator:DF 3 "binary_fp_operator"
15920            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15921             (match_operand:DF 2 "register_operand" "0,0")]))]
15922   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15923    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15924   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15925   [(set (attr "type")
15926         (cond [(match_operand:DF 3 "mult_operator" "")
15927                  (const_string "fmul")
15928                (match_operand:DF 3 "div_operator" "")
15929                  (const_string "fdiv")
15930               ]
15931               (const_string "fop")))
15932    (set_attr "fp_int_src" "true")
15933    (set_attr "mode" "<MODE>")])
15934
15935 (define_insn "*fop_df_3<mode>_i387"
15936   [(set (match_operand:DF 0 "register_operand" "=f,f")
15937         (match_operator:DF 3 "binary_fp_operator"
15938            [(match_operand:DF 1 "register_operand" "0,0")
15939             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15940   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15941    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15942   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15943   [(set (attr "type")
15944         (cond [(match_operand:DF 3 "mult_operator" "")
15945                  (const_string "fmul")
15946                (match_operand:DF 3 "div_operator" "")
15947                  (const_string "fdiv")
15948               ]
15949               (const_string "fop")))
15950    (set_attr "fp_int_src" "true")
15951    (set_attr "mode" "<MODE>")])
15952
15953 (define_insn "*fop_df_4_i387"
15954   [(set (match_operand:DF 0 "register_operand" "=f,f")
15955         (match_operator:DF 3 "binary_fp_operator"
15956            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15957             (match_operand:DF 2 "register_operand" "0,f")]))]
15958   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15959    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15960   "* return output_387_binary_op (insn, operands);"
15961   [(set (attr "type")
15962         (cond [(match_operand:DF 3 "mult_operator" "")
15963                  (const_string "fmul")
15964                (match_operand:DF 3 "div_operator" "")
15965                  (const_string "fdiv")
15966               ]
15967               (const_string "fop")))
15968    (set_attr "mode" "SF")])
15969
15970 (define_insn "*fop_df_5_i387"
15971   [(set (match_operand:DF 0 "register_operand" "=f,f")
15972         (match_operator:DF 3 "binary_fp_operator"
15973           [(match_operand:DF 1 "register_operand" "0,f")
15974            (float_extend:DF
15975             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15976   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15977   "* return output_387_binary_op (insn, operands);"
15978   [(set (attr "type")
15979         (cond [(match_operand:DF 3 "mult_operator" "")
15980                  (const_string "fmul")
15981                (match_operand:DF 3 "div_operator" "")
15982                  (const_string "fdiv")
15983               ]
15984               (const_string "fop")))
15985    (set_attr "mode" "SF")])
15986
15987 (define_insn "*fop_df_6_i387"
15988   [(set (match_operand:DF 0 "register_operand" "=f,f")
15989         (match_operator:DF 3 "binary_fp_operator"
15990           [(float_extend:DF
15991             (match_operand:SF 1 "register_operand" "0,f"))
15992            (float_extend:DF
15993             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15994   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15995   "* return output_387_binary_op (insn, operands);"
15996   [(set (attr "type")
15997         (cond [(match_operand:DF 3 "mult_operator" "")
15998                  (const_string "fmul")
15999                (match_operand:DF 3 "div_operator" "")
16000                  (const_string "fdiv")
16001               ]
16002               (const_string "fop")))
16003    (set_attr "mode" "SF")])
16004
16005 (define_insn "*fop_xf_comm_i387"
16006   [(set (match_operand:XF 0 "register_operand" "=f")
16007         (match_operator:XF 3 "binary_fp_operator"
16008                         [(match_operand:XF 1 "register_operand" "%0")
16009                          (match_operand:XF 2 "register_operand" "f")]))]
16010   "TARGET_80387
16011    && COMMUTATIVE_ARITH_P (operands[3])"
16012   "* return output_387_binary_op (insn, operands);"
16013   [(set (attr "type")
16014         (if_then_else (match_operand:XF 3 "mult_operator" "")
16015            (const_string "fmul")
16016            (const_string "fop")))
16017    (set_attr "mode" "XF")])
16018
16019 (define_insn "*fop_xf_1_i387"
16020   [(set (match_operand:XF 0 "register_operand" "=f,f")
16021         (match_operator:XF 3 "binary_fp_operator"
16022                         [(match_operand:XF 1 "register_operand" "0,f")
16023                          (match_operand:XF 2 "register_operand" "f,0")]))]
16024   "TARGET_80387
16025    && !COMMUTATIVE_ARITH_P (operands[3])"
16026   "* return output_387_binary_op (insn, operands);"
16027   [(set (attr "type")
16028         (cond [(match_operand:XF 3 "mult_operator" "")
16029                  (const_string "fmul")
16030                (match_operand:XF 3 "div_operator" "")
16031                  (const_string "fdiv")
16032               ]
16033               (const_string "fop")))
16034    (set_attr "mode" "XF")])
16035
16036 (define_insn "*fop_xf_2<mode>_i387"
16037   [(set (match_operand:XF 0 "register_operand" "=f,f")
16038         (match_operator:XF 3 "binary_fp_operator"
16039            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16040             (match_operand:XF 2 "register_operand" "0,0")]))]
16041   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16042   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16043   [(set (attr "type")
16044         (cond [(match_operand:XF 3 "mult_operator" "")
16045                  (const_string "fmul")
16046                (match_operand:XF 3 "div_operator" "")
16047                  (const_string "fdiv")
16048               ]
16049               (const_string "fop")))
16050    (set_attr "fp_int_src" "true")
16051    (set_attr "mode" "<MODE>")])
16052
16053 (define_insn "*fop_xf_3<mode>_i387"
16054   [(set (match_operand:XF 0 "register_operand" "=f,f")
16055         (match_operator:XF 3 "binary_fp_operator"
16056           [(match_operand:XF 1 "register_operand" "0,0")
16057            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16058   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16059   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16060   [(set (attr "type")
16061         (cond [(match_operand:XF 3 "mult_operator" "")
16062                  (const_string "fmul")
16063                (match_operand:XF 3 "div_operator" "")
16064                  (const_string "fdiv")
16065               ]
16066               (const_string "fop")))
16067    (set_attr "fp_int_src" "true")
16068    (set_attr "mode" "<MODE>")])
16069
16070 (define_insn "*fop_xf_4_i387"
16071   [(set (match_operand:XF 0 "register_operand" "=f,f")
16072         (match_operator:XF 3 "binary_fp_operator"
16073            [(float_extend:XF
16074               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
16075             (match_operand:XF 2 "register_operand" "0,f")]))]
16076   "TARGET_80387"
16077   "* return output_387_binary_op (insn, operands);"
16078   [(set (attr "type")
16079         (cond [(match_operand:XF 3 "mult_operator" "")
16080                  (const_string "fmul")
16081                (match_operand:XF 3 "div_operator" "")
16082                  (const_string "fdiv")
16083               ]
16084               (const_string "fop")))
16085    (set_attr "mode" "SF")])
16086
16087 (define_insn "*fop_xf_5_i387"
16088   [(set (match_operand:XF 0 "register_operand" "=f,f")
16089         (match_operator:XF 3 "binary_fp_operator"
16090           [(match_operand:XF 1 "register_operand" "0,f")
16091            (float_extend:XF
16092              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16093   "TARGET_80387"
16094   "* return output_387_binary_op (insn, operands);"
16095   [(set (attr "type")
16096         (cond [(match_operand:XF 3 "mult_operator" "")
16097                  (const_string "fmul")
16098                (match_operand:XF 3 "div_operator" "")
16099                  (const_string "fdiv")
16100               ]
16101               (const_string "fop")))
16102    (set_attr "mode" "SF")])
16103
16104 (define_insn "*fop_xf_6_i387"
16105   [(set (match_operand:XF 0 "register_operand" "=f,f")
16106         (match_operator:XF 3 "binary_fp_operator"
16107           [(float_extend:XF
16108              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
16109            (float_extend:XF
16110              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16111   "TARGET_80387"
16112   "* return output_387_binary_op (insn, operands);"
16113   [(set (attr "type")
16114         (cond [(match_operand:XF 3 "mult_operator" "")
16115                  (const_string "fmul")
16116                (match_operand:XF 3 "div_operator" "")
16117                  (const_string "fdiv")
16118               ]
16119               (const_string "fop")))
16120    (set_attr "mode" "SF")])
16121
16122 (define_split
16123   [(set (match_operand 0 "register_operand" "")
16124         (match_operator 3 "binary_fp_operator"
16125            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16126             (match_operand 2 "register_operand" "")]))]
16127   "reload_completed
16128    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16129   [(const_int 0)]
16130 {
16131   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16132   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16133   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16134                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16135                                           GET_MODE (operands[3]),
16136                                           operands[4],
16137                                           operands[2])));
16138   ix86_free_from_memory (GET_MODE (operands[1]));
16139   DONE;
16140 })
16141
16142 (define_split
16143   [(set (match_operand 0 "register_operand" "")
16144         (match_operator 3 "binary_fp_operator"
16145            [(match_operand 1 "register_operand" "")
16146             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16147   "reload_completed
16148    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16149   [(const_int 0)]
16150 {
16151   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16152   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16153   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16154                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16155                                           GET_MODE (operands[3]),
16156                                           operands[1],
16157                                           operands[4])));
16158   ix86_free_from_memory (GET_MODE (operands[2]));
16159   DONE;
16160 })
16161 \f
16162 ;; FPU special functions.
16163
16164 ;; This pattern implements a no-op XFmode truncation for
16165 ;; all fancy i386 XFmode math functions.
16166
16167 (define_insn "truncxf<mode>2_i387_noop_unspec"
16168   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16169         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16170         UNSPEC_TRUNC_NOOP))]
16171   "TARGET_USE_FANCY_MATH_387"
16172   "* return output_387_reg_move (insn, operands);"
16173   [(set_attr "type" "fmov")
16174    (set_attr "mode" "<MODE>")])
16175
16176 (define_insn "sqrtxf2"
16177   [(set (match_operand:XF 0 "register_operand" "=f")
16178         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16179   "TARGET_USE_FANCY_MATH_387"
16180   "fsqrt"
16181   [(set_attr "type" "fpspc")
16182    (set_attr "mode" "XF")
16183    (set_attr "athlon_decode" "direct")
16184    (set_attr "amdfam10_decode" "direct")])
16185
16186 (define_insn "sqrt_extend<mode>xf2_i387"
16187   [(set (match_operand:XF 0 "register_operand" "=f")
16188         (sqrt:XF
16189           (float_extend:XF
16190             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16191   "TARGET_USE_FANCY_MATH_387"
16192   "fsqrt"
16193   [(set_attr "type" "fpspc")
16194    (set_attr "mode" "XF")
16195    (set_attr "athlon_decode" "direct")   
16196    (set_attr "amdfam10_decode" "direct")])
16197
16198 (define_insn "*rsqrtsf2_sse"
16199   [(set (match_operand:SF 0 "register_operand" "=x")
16200         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16201                    UNSPEC_RSQRT))]
16202   "TARGET_SSE_MATH"
16203   "rsqrtss\t{%1, %0|%0, %1}"
16204   [(set_attr "type" "sse")
16205    (set_attr "mode" "SF")])
16206
16207 (define_expand "rsqrtsf2"
16208   [(set (match_operand:SF 0 "register_operand" "=x")
16209         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16210                    UNSPEC_RSQRT))]
16211   "TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16212    && flag_finite_math_only && !flag_trapping_math
16213    && flag_unsafe_math_optimizations"
16214 {
16215   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16216   DONE;
16217 })
16218
16219 (define_insn "*sqrt<mode>2_sse"
16220   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16221         (sqrt:SSEMODEF
16222           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16223   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16224   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16225   [(set_attr "type" "sse")
16226    (set_attr "mode" "<MODE>")
16227    (set_attr "athlon_decode" "*")
16228    (set_attr "amdfam10_decode" "*")])
16229
16230 (define_expand "sqrt<mode>2"
16231   [(set (match_operand:X87MODEF12 0 "register_operand" "")
16232         (sqrt:X87MODEF12
16233           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16234   "TARGET_USE_FANCY_MATH_387
16235    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16236 {
16237   if (<MODE>mode == SFmode
16238       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16239       && flag_finite_math_only && !flag_trapping_math
16240       && flag_unsafe_math_optimizations)
16241     {
16242       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16243       DONE;
16244     }
16245
16246   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16247     {
16248       rtx op0 = gen_reg_rtx (XFmode);
16249       rtx op1 = force_reg (<MODE>mode, operands[1]);
16250
16251       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16252       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16253       DONE;
16254    }
16255 })
16256
16257 (define_insn "fpremxf4_i387"
16258   [(set (match_operand:XF 0 "register_operand" "=f")
16259         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16260                     (match_operand:XF 3 "register_operand" "1")]
16261                    UNSPEC_FPREM_F))
16262    (set (match_operand:XF 1 "register_operand" "=u")
16263         (unspec:XF [(match_dup 2) (match_dup 3)]
16264                    UNSPEC_FPREM_U))
16265    (set (reg:CCFP FPSR_REG)
16266         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16267                      UNSPEC_C2_FLAG))]
16268   "TARGET_USE_FANCY_MATH_387"
16269   "fprem"
16270   [(set_attr "type" "fpspc")
16271    (set_attr "mode" "XF")])
16272
16273 (define_expand "fmodxf3"
16274   [(use (match_operand:XF 0 "register_operand" ""))
16275    (use (match_operand:XF 1 "register_operand" ""))
16276    (use (match_operand:XF 2 "register_operand" ""))]
16277   "TARGET_USE_FANCY_MATH_387"
16278 {
16279   rtx label = gen_label_rtx ();
16280
16281   emit_label (label);
16282
16283   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16284                                 operands[1], operands[2]));
16285   ix86_emit_fp_unordered_jump (label);
16286   LABEL_NUSES (label) = 1;
16287
16288   emit_move_insn (operands[0], operands[1]);
16289   DONE;
16290 })
16291
16292 (define_expand "fmod<mode>3"
16293   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16294    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16295    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16296   "TARGET_USE_FANCY_MATH_387"
16297 {
16298   rtx label = gen_label_rtx ();
16299
16300   rtx op1 = gen_reg_rtx (XFmode);
16301   rtx op2 = gen_reg_rtx (XFmode);
16302
16303   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16304   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16305
16306   emit_label (label);
16307   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16308   ix86_emit_fp_unordered_jump (label);
16309   LABEL_NUSES (label) = 1;
16310
16311   /* Truncate the result properly for strict SSE math.  */
16312   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16313       && !TARGET_MIX_SSE_I387)
16314     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16315   else
16316     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16317
16318   DONE;
16319 })
16320
16321 (define_insn "fprem1xf4_i387"
16322   [(set (match_operand:XF 0 "register_operand" "=f")
16323         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16324                     (match_operand:XF 3 "register_operand" "1")]
16325                    UNSPEC_FPREM1_F))
16326    (set (match_operand:XF 1 "register_operand" "=u")
16327         (unspec:XF [(match_dup 2) (match_dup 3)]
16328                    UNSPEC_FPREM1_U))
16329    (set (reg:CCFP FPSR_REG)
16330         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16331                      UNSPEC_C2_FLAG))]
16332   "TARGET_USE_FANCY_MATH_387"
16333   "fprem1"
16334   [(set_attr "type" "fpspc")
16335    (set_attr "mode" "XF")])
16336
16337 (define_expand "remainderxf3"
16338   [(use (match_operand:XF 0 "register_operand" ""))
16339    (use (match_operand:XF 1 "register_operand" ""))
16340    (use (match_operand:XF 2 "register_operand" ""))]
16341   "TARGET_USE_FANCY_MATH_387"
16342 {
16343   rtx label = gen_label_rtx ();
16344
16345   emit_label (label);
16346
16347   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16348                                  operands[1], operands[2]));
16349   ix86_emit_fp_unordered_jump (label);
16350   LABEL_NUSES (label) = 1;
16351
16352   emit_move_insn (operands[0], operands[1]);
16353   DONE;
16354 })
16355
16356 (define_expand "remainder<mode>3"
16357   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16358    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16359    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16360   "TARGET_USE_FANCY_MATH_387"
16361 {
16362   rtx label = gen_label_rtx ();
16363
16364   rtx op1 = gen_reg_rtx (XFmode);
16365   rtx op2 = gen_reg_rtx (XFmode);
16366
16367   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16368   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16369
16370   emit_label (label);
16371
16372   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16373   ix86_emit_fp_unordered_jump (label);
16374   LABEL_NUSES (label) = 1;
16375
16376   /* Truncate the result properly for strict SSE math.  */
16377   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16378       && !TARGET_MIX_SSE_I387)
16379     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16380   else
16381     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16382
16383   DONE;
16384 })
16385
16386 (define_insn "*sinxf2_i387"
16387   [(set (match_operand:XF 0 "register_operand" "=f")
16388         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16389   "TARGET_USE_FANCY_MATH_387
16390    && flag_unsafe_math_optimizations"
16391   "fsin"
16392   [(set_attr "type" "fpspc")
16393    (set_attr "mode" "XF")])
16394
16395 (define_insn "*sin_extend<mode>xf2_i387"
16396   [(set (match_operand:XF 0 "register_operand" "=f")
16397         (unspec:XF [(float_extend:XF
16398                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16399                    UNSPEC_SIN))]
16400   "TARGET_USE_FANCY_MATH_387
16401    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16402        || TARGET_MIX_SSE_I387)
16403    && flag_unsafe_math_optimizations"
16404   "fsin"
16405   [(set_attr "type" "fpspc")
16406    (set_attr "mode" "XF")])
16407
16408 (define_insn "*cosxf2_i387"
16409   [(set (match_operand:XF 0 "register_operand" "=f")
16410         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16411   "TARGET_USE_FANCY_MATH_387
16412    && flag_unsafe_math_optimizations"
16413   "fcos"
16414   [(set_attr "type" "fpspc")
16415    (set_attr "mode" "XF")])
16416
16417 (define_insn "*cos_extend<mode>xf2_i387"
16418   [(set (match_operand:XF 0 "register_operand" "=f")
16419         (unspec:XF [(float_extend:XF
16420                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16421                    UNSPEC_COS))]
16422   "TARGET_USE_FANCY_MATH_387
16423    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16424        || TARGET_MIX_SSE_I387)
16425    && flag_unsafe_math_optimizations"
16426   "fcos"
16427   [(set_attr "type" "fpspc")
16428    (set_attr "mode" "XF")])
16429
16430 ;; When sincos pattern is defined, sin and cos builtin functions will be
16431 ;; expanded to sincos pattern with one of its outputs left unused.
16432 ;; CSE pass will figure out if two sincos patterns can be combined,
16433 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16434 ;; depending on the unused output.
16435
16436 (define_insn "sincosxf3"
16437   [(set (match_operand:XF 0 "register_operand" "=f")
16438         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16439                    UNSPEC_SINCOS_COS))
16440    (set (match_operand:XF 1 "register_operand" "=u")
16441         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16442   "TARGET_USE_FANCY_MATH_387
16443    && flag_unsafe_math_optimizations"
16444   "fsincos"
16445   [(set_attr "type" "fpspc")
16446    (set_attr "mode" "XF")])
16447
16448 (define_split
16449   [(set (match_operand:XF 0 "register_operand" "")
16450         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16451                    UNSPEC_SINCOS_COS))
16452    (set (match_operand:XF 1 "register_operand" "")
16453         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16454   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16455    && !reload_completed && !reload_in_progress"
16456   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16457   "")
16458
16459 (define_split
16460   [(set (match_operand:XF 0 "register_operand" "")
16461         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16462                    UNSPEC_SINCOS_COS))
16463    (set (match_operand:XF 1 "register_operand" "")
16464         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16465   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16466    && !reload_completed && !reload_in_progress"
16467   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16468   "")
16469
16470 (define_insn "sincos_extend<mode>xf3_i387"
16471   [(set (match_operand:XF 0 "register_operand" "=f")
16472         (unspec:XF [(float_extend:XF
16473                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16474                    UNSPEC_SINCOS_COS))
16475    (set (match_operand:XF 1 "register_operand" "=u")
16476         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16477   "TARGET_USE_FANCY_MATH_387
16478    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16479        || TARGET_MIX_SSE_I387)
16480    && flag_unsafe_math_optimizations"
16481   "fsincos"
16482   [(set_attr "type" "fpspc")
16483    (set_attr "mode" "XF")])
16484
16485 (define_split
16486   [(set (match_operand:XF 0 "register_operand" "")
16487         (unspec:XF [(float_extend:XF
16488                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16489                    UNSPEC_SINCOS_COS))
16490    (set (match_operand:XF 1 "register_operand" "")
16491         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16492   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16493    && !reload_completed && !reload_in_progress"
16494   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16495   "")
16496
16497 (define_split
16498   [(set (match_operand:XF 0 "register_operand" "")
16499         (unspec:XF [(float_extend:XF
16500                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16501                    UNSPEC_SINCOS_COS))
16502    (set (match_operand:XF 1 "register_operand" "")
16503         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16504   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16505    && !reload_completed && !reload_in_progress"
16506   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16507   "")
16508
16509 (define_expand "sincos<mode>3"
16510   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16511    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16512    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16513   "TARGET_USE_FANCY_MATH_387
16514    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16515        || TARGET_MIX_SSE_I387)
16516    && flag_unsafe_math_optimizations"
16517 {
16518   rtx op0 = gen_reg_rtx (XFmode);
16519   rtx op1 = gen_reg_rtx (XFmode);
16520
16521   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16522   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16523   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16524   DONE;
16525 })
16526
16527 (define_insn "fptanxf4_i387"
16528   [(set (match_operand:XF 0 "register_operand" "=f")
16529         (match_operand:XF 3 "const_double_operand" "F"))
16530    (set (match_operand:XF 1 "register_operand" "=u")
16531         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16532                    UNSPEC_TAN))]
16533   "TARGET_USE_FANCY_MATH_387
16534    && flag_unsafe_math_optimizations
16535    && standard_80387_constant_p (operands[3]) == 2"
16536   "fptan"
16537   [(set_attr "type" "fpspc")
16538    (set_attr "mode" "XF")])
16539
16540 (define_insn "fptan_extend<mode>xf4_i387"
16541   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16542         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16543    (set (match_operand:XF 1 "register_operand" "=u")
16544         (unspec:XF [(float_extend:XF
16545                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16546                    UNSPEC_TAN))]
16547   "TARGET_USE_FANCY_MATH_387
16548    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16549        || TARGET_MIX_SSE_I387)
16550    && flag_unsafe_math_optimizations
16551    && standard_80387_constant_p (operands[3]) == 2"
16552   "fptan"
16553   [(set_attr "type" "fpspc")
16554    (set_attr "mode" "XF")])
16555
16556 (define_expand "tanxf2"
16557   [(use (match_operand:XF 0 "register_operand" ""))
16558    (use (match_operand:XF 1 "register_operand" ""))]
16559   "TARGET_USE_FANCY_MATH_387
16560    && flag_unsafe_math_optimizations"
16561 {
16562   rtx one = gen_reg_rtx (XFmode);
16563   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16564
16565   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16566   DONE;
16567 })
16568
16569 (define_expand "tan<mode>2"
16570   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16571    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16572   "TARGET_USE_FANCY_MATH_387
16573    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16574        || TARGET_MIX_SSE_I387)
16575    && flag_unsafe_math_optimizations"
16576 {
16577   rtx op0 = gen_reg_rtx (XFmode);
16578
16579   rtx one = gen_reg_rtx (<MODE>mode);
16580   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16581
16582   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16583                                              operands[1], op2));
16584   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16585   DONE;
16586 })
16587
16588 (define_insn "*fpatanxf3_i387"
16589   [(set (match_operand:XF 0 "register_operand" "=f")
16590         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16591                     (match_operand:XF 2 "register_operand" "u")]
16592                    UNSPEC_FPATAN))
16593    (clobber (match_scratch:XF 3 "=2"))]
16594   "TARGET_USE_FANCY_MATH_387
16595    && flag_unsafe_math_optimizations"
16596   "fpatan"
16597   [(set_attr "type" "fpspc")
16598    (set_attr "mode" "XF")])
16599
16600 (define_insn "fpatan_extend<mode>xf3_i387"
16601   [(set (match_operand:XF 0 "register_operand" "=f")
16602         (unspec:XF [(float_extend:XF
16603                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16604                     (float_extend:XF
16605                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
16606                    UNSPEC_FPATAN))
16607    (clobber (match_scratch:XF 3 "=2"))]
16608   "TARGET_USE_FANCY_MATH_387
16609    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16610        || TARGET_MIX_SSE_I387)
16611    && flag_unsafe_math_optimizations"
16612   "fpatan"
16613   [(set_attr "type" "fpspc")
16614    (set_attr "mode" "XF")])
16615
16616 (define_expand "atan2xf3"
16617   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16618                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16619                                (match_operand:XF 1 "register_operand" "")]
16620                               UNSPEC_FPATAN))
16621               (clobber (match_scratch:XF 3 ""))])]
16622   "TARGET_USE_FANCY_MATH_387
16623    && flag_unsafe_math_optimizations"
16624   "")
16625
16626 (define_expand "atan2<mode>3"
16627   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16628    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16629    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16630   "TARGET_USE_FANCY_MATH_387
16631    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16632        || TARGET_MIX_SSE_I387)
16633    && flag_unsafe_math_optimizations"
16634 {
16635   rtx op0 = gen_reg_rtx (XFmode);
16636
16637   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16638   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16639   DONE;
16640 })
16641
16642 (define_expand "atanxf2"
16643   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16644                    (unspec:XF [(match_dup 2)
16645                                (match_operand:XF 1 "register_operand" "")]
16646                               UNSPEC_FPATAN))
16647               (clobber (match_scratch:XF 3 ""))])]
16648   "TARGET_USE_FANCY_MATH_387
16649    && flag_unsafe_math_optimizations"
16650 {
16651   operands[2] = gen_reg_rtx (XFmode);
16652   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16653 })
16654
16655 (define_expand "atan<mode>2"
16656   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16657    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16658   "TARGET_USE_FANCY_MATH_387
16659    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16660        || TARGET_MIX_SSE_I387)
16661    && flag_unsafe_math_optimizations"
16662 {
16663   rtx op0 = gen_reg_rtx (XFmode);
16664
16665   rtx op2 = gen_reg_rtx (<MODE>mode);
16666   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16667
16668   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16669   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16670   DONE;
16671 })
16672
16673 (define_expand "asinxf2"
16674   [(set (match_dup 2)
16675         (mult:XF (match_operand:XF 1 "register_operand" "")
16676                  (match_dup 1)))
16677    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16678    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16679    (parallel [(set (match_operand:XF 0 "register_operand" "")
16680                    (unspec:XF [(match_dup 5) (match_dup 1)]
16681                               UNSPEC_FPATAN))
16682               (clobber (match_scratch:XF 6 ""))])]
16683   "TARGET_USE_FANCY_MATH_387
16684    && flag_unsafe_math_optimizations && !optimize_size"
16685 {
16686   int i;
16687
16688   for (i = 2; i < 6; i++)
16689     operands[i] = gen_reg_rtx (XFmode);
16690
16691   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16692 })
16693
16694 (define_expand "asin<mode>2"
16695   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16696    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16697  "TARGET_USE_FANCY_MATH_387
16698    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16699        || TARGET_MIX_SSE_I387)
16700    && flag_unsafe_math_optimizations && !optimize_size"
16701 {
16702   rtx op0 = gen_reg_rtx (XFmode);
16703   rtx op1 = gen_reg_rtx (XFmode);
16704
16705   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16706   emit_insn (gen_asinxf2 (op0, op1));
16707   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16708   DONE;
16709 })
16710
16711 (define_expand "acosxf2"
16712   [(set (match_dup 2)
16713         (mult:XF (match_operand:XF 1 "register_operand" "")
16714                  (match_dup 1)))
16715    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16716    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16717    (parallel [(set (match_operand:XF 0 "register_operand" "")
16718                    (unspec:XF [(match_dup 1) (match_dup 5)]
16719                               UNSPEC_FPATAN))
16720               (clobber (match_scratch:XF 6 ""))])]
16721   "TARGET_USE_FANCY_MATH_387
16722    && flag_unsafe_math_optimizations && !optimize_size"
16723 {
16724   int i;
16725
16726   for (i = 2; i < 6; i++)
16727     operands[i] = gen_reg_rtx (XFmode);
16728
16729   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16730 })
16731
16732 (define_expand "acos<mode>2"
16733   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16734    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16735  "TARGET_USE_FANCY_MATH_387
16736    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16737        || TARGET_MIX_SSE_I387)
16738    && flag_unsafe_math_optimizations && !optimize_size"
16739 {
16740   rtx op0 = gen_reg_rtx (XFmode);
16741   rtx op1 = gen_reg_rtx (XFmode);
16742
16743   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16744   emit_insn (gen_acosxf2 (op0, op1));
16745   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16746   DONE;
16747 })
16748
16749 (define_insn "fyl2xxf3_i387"
16750   [(set (match_operand:XF 0 "register_operand" "=f")
16751         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16752                     (match_operand:XF 2 "register_operand" "u")]
16753                    UNSPEC_FYL2X))
16754    (clobber (match_scratch:XF 3 "=2"))]
16755   "TARGET_USE_FANCY_MATH_387
16756    && flag_unsafe_math_optimizations"
16757   "fyl2x"
16758   [(set_attr "type" "fpspc")
16759    (set_attr "mode" "XF")])
16760
16761 (define_insn "fyl2x_extend<mode>xf3_i387"
16762   [(set (match_operand:XF 0 "register_operand" "=f")
16763         (unspec:XF [(float_extend:XF
16764                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16765                     (match_operand:XF 2 "register_operand" "u")]
16766                    UNSPEC_FYL2X))
16767    (clobber (match_scratch:XF 3 "=2"))]
16768   "TARGET_USE_FANCY_MATH_387
16769    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16770        || TARGET_MIX_SSE_I387)
16771    && flag_unsafe_math_optimizations"
16772   "fyl2x"
16773   [(set_attr "type" "fpspc")
16774    (set_attr "mode" "XF")])
16775
16776 (define_expand "logxf2"
16777   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16778                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16779                                (match_dup 2)] UNSPEC_FYL2X))
16780               (clobber (match_scratch:XF 3 ""))])]
16781   "TARGET_USE_FANCY_MATH_387
16782    && flag_unsafe_math_optimizations"
16783 {
16784   operands[2] = gen_reg_rtx (XFmode);
16785   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16786 })
16787
16788 (define_expand "log<mode>2"
16789   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16790    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16791   "TARGET_USE_FANCY_MATH_387
16792    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16793        || TARGET_MIX_SSE_I387)
16794    && flag_unsafe_math_optimizations"
16795 {
16796   rtx op0 = gen_reg_rtx (XFmode);
16797
16798   rtx op2 = gen_reg_rtx (XFmode);
16799   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16800
16801   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16802   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16803   DONE;
16804 })
16805
16806 (define_expand "log10xf2"
16807   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16808                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16809                                (match_dup 2)] UNSPEC_FYL2X))
16810               (clobber (match_scratch:XF 3 ""))])]
16811   "TARGET_USE_FANCY_MATH_387
16812    && flag_unsafe_math_optimizations"
16813 {
16814   operands[2] = gen_reg_rtx (XFmode);
16815   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16816 })
16817
16818 (define_expand "log10<mode>2"
16819   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16820    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16821   "TARGET_USE_FANCY_MATH_387
16822    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16823        || TARGET_MIX_SSE_I387)
16824    && flag_unsafe_math_optimizations"
16825 {
16826   rtx op0 = gen_reg_rtx (XFmode);
16827
16828   rtx op2 = gen_reg_rtx (XFmode);
16829   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16830
16831   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16832   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16833   DONE;
16834 })
16835
16836 (define_expand "log2xf2"
16837   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16838                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16839                                (match_dup 2)] UNSPEC_FYL2X))
16840               (clobber (match_scratch:XF 3 ""))])]
16841   "TARGET_USE_FANCY_MATH_387
16842    && flag_unsafe_math_optimizations"
16843 {
16844   operands[2] = gen_reg_rtx (XFmode);
16845   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16846 })
16847
16848 (define_expand "log2<mode>2"
16849   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16850    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16851   "TARGET_USE_FANCY_MATH_387
16852    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16853        || TARGET_MIX_SSE_I387)
16854    && flag_unsafe_math_optimizations"
16855 {
16856   rtx op0 = gen_reg_rtx (XFmode);
16857
16858   rtx op2 = gen_reg_rtx (XFmode);
16859   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16860
16861   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16862   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16863   DONE;
16864 })
16865
16866 (define_insn "fyl2xp1xf3_i387"
16867   [(set (match_operand:XF 0 "register_operand" "=f")
16868         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16869                     (match_operand:XF 2 "register_operand" "u")]
16870                    UNSPEC_FYL2XP1))
16871    (clobber (match_scratch:XF 3 "=2"))]
16872   "TARGET_USE_FANCY_MATH_387
16873    && flag_unsafe_math_optimizations"
16874   "fyl2xp1"
16875   [(set_attr "type" "fpspc")
16876    (set_attr "mode" "XF")])
16877
16878 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16879   [(set (match_operand:XF 0 "register_operand" "=f")
16880         (unspec:XF [(float_extend:XF
16881                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16882                     (match_operand:XF 2 "register_operand" "u")]
16883                    UNSPEC_FYL2XP1))
16884    (clobber (match_scratch:XF 3 "=2"))]
16885   "TARGET_USE_FANCY_MATH_387
16886    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16887        || TARGET_MIX_SSE_I387)
16888    && flag_unsafe_math_optimizations"
16889   "fyl2xp1"
16890   [(set_attr "type" "fpspc")
16891    (set_attr "mode" "XF")])
16892
16893 (define_expand "log1pxf2"
16894   [(use (match_operand:XF 0 "register_operand" ""))
16895    (use (match_operand:XF 1 "register_operand" ""))]
16896   "TARGET_USE_FANCY_MATH_387
16897    && flag_unsafe_math_optimizations && !optimize_size"
16898 {
16899   ix86_emit_i387_log1p (operands[0], operands[1]);
16900   DONE;
16901 })
16902
16903 (define_expand "log1p<mode>2"
16904   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16905    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16906   "TARGET_USE_FANCY_MATH_387
16907    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16908        || TARGET_MIX_SSE_I387)
16909    && flag_unsafe_math_optimizations && !optimize_size"
16910 {
16911   rtx op0 = gen_reg_rtx (XFmode);
16912
16913   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16914
16915   ix86_emit_i387_log1p (op0, operands[1]);
16916   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16917   DONE;
16918 })
16919
16920 (define_insn "fxtractxf3_i387"
16921   [(set (match_operand:XF 0 "register_operand" "=f")
16922         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16923                    UNSPEC_XTRACT_FRACT))
16924    (set (match_operand:XF 1 "register_operand" "=u")
16925         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16926   "TARGET_USE_FANCY_MATH_387
16927    && flag_unsafe_math_optimizations"
16928   "fxtract"
16929   [(set_attr "type" "fpspc")
16930    (set_attr "mode" "XF")])
16931
16932 (define_insn "fxtract_extend<mode>xf3_i387"
16933   [(set (match_operand:XF 0 "register_operand" "=f")
16934         (unspec:XF [(float_extend:XF
16935                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16936                    UNSPEC_XTRACT_FRACT))
16937    (set (match_operand:XF 1 "register_operand" "=u")
16938         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16939   "TARGET_USE_FANCY_MATH_387
16940    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16941        || TARGET_MIX_SSE_I387)
16942    && flag_unsafe_math_optimizations"
16943   "fxtract"
16944   [(set_attr "type" "fpspc")
16945    (set_attr "mode" "XF")])
16946
16947 (define_expand "logbxf2"
16948   [(parallel [(set (match_dup 2)
16949                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16950                               UNSPEC_XTRACT_FRACT))
16951               (set (match_operand:XF 0 "register_operand" "")
16952                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16953   "TARGET_USE_FANCY_MATH_387
16954    && flag_unsafe_math_optimizations"
16955 {
16956   operands[2] = gen_reg_rtx (XFmode);
16957 })
16958
16959 (define_expand "logb<mode>2"
16960   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16961    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16962   "TARGET_USE_FANCY_MATH_387
16963    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16964        || TARGET_MIX_SSE_I387)
16965    && flag_unsafe_math_optimizations"
16966 {
16967   rtx op0 = gen_reg_rtx (XFmode);
16968   rtx op1 = gen_reg_rtx (XFmode);
16969
16970   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16971   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16972   DONE;
16973 })
16974
16975 (define_expand "ilogbxf2"
16976   [(use (match_operand:SI 0 "register_operand" ""))
16977    (use (match_operand:XF 1 "register_operand" ""))]
16978   "TARGET_USE_FANCY_MATH_387
16979    && flag_unsafe_math_optimizations && !optimize_size"
16980 {
16981   rtx op0 = gen_reg_rtx (XFmode);
16982   rtx op1 = gen_reg_rtx (XFmode);
16983
16984   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16985   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16986   DONE;
16987 })
16988
16989 (define_expand "ilogb<mode>2"
16990   [(use (match_operand:SI 0 "register_operand" ""))
16991    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16992   "TARGET_USE_FANCY_MATH_387
16993    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16994        || TARGET_MIX_SSE_I387)
16995    && flag_unsafe_math_optimizations && !optimize_size"
16996 {
16997   rtx op0 = gen_reg_rtx (XFmode);
16998   rtx op1 = gen_reg_rtx (XFmode);
16999
17000   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17001   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17002   DONE;
17003 })
17004
17005 (define_insn "*f2xm1xf2_i387"
17006   [(set (match_operand:XF 0 "register_operand" "=f")
17007         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17008                    UNSPEC_F2XM1))]
17009   "TARGET_USE_FANCY_MATH_387
17010    && flag_unsafe_math_optimizations"
17011   "f2xm1"
17012   [(set_attr "type" "fpspc")
17013    (set_attr "mode" "XF")])
17014
17015 (define_insn "*fscalexf4_i387"
17016   [(set (match_operand:XF 0 "register_operand" "=f")
17017         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17018                     (match_operand:XF 3 "register_operand" "1")]
17019                    UNSPEC_FSCALE_FRACT))
17020    (set (match_operand:XF 1 "register_operand" "=u")
17021         (unspec:XF [(match_dup 2) (match_dup 3)]
17022                    UNSPEC_FSCALE_EXP))]
17023   "TARGET_USE_FANCY_MATH_387
17024    && flag_unsafe_math_optimizations"
17025   "fscale"
17026   [(set_attr "type" "fpspc")
17027    (set_attr "mode" "XF")])
17028
17029 (define_expand "expNcorexf3"
17030   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17031                                (match_operand:XF 2 "register_operand" "")))
17032    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17033    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17034    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17035    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17036    (parallel [(set (match_operand:XF 0 "register_operand" "")
17037                    (unspec:XF [(match_dup 8) (match_dup 4)]
17038                               UNSPEC_FSCALE_FRACT))
17039               (set (match_dup 9)
17040                    (unspec:XF [(match_dup 8) (match_dup 4)]
17041                               UNSPEC_FSCALE_EXP))])]
17042   "TARGET_USE_FANCY_MATH_387
17043    && flag_unsafe_math_optimizations && !optimize_size"
17044 {
17045   int i;
17046
17047   for (i = 3; i < 10; i++)
17048     operands[i] = gen_reg_rtx (XFmode);
17049
17050   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17051 })
17052
17053 (define_expand "expxf2"
17054   [(use (match_operand:XF 0 "register_operand" ""))
17055    (use (match_operand:XF 1 "register_operand" ""))]
17056   "TARGET_USE_FANCY_MATH_387
17057    && flag_unsafe_math_optimizations && !optimize_size"
17058 {
17059   rtx op2 = gen_reg_rtx (XFmode);
17060   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17061
17062   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17063   DONE;
17064 })
17065
17066 (define_expand "exp<mode>2"
17067   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17068    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17069  "TARGET_USE_FANCY_MATH_387
17070    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17071        || TARGET_MIX_SSE_I387)
17072    && flag_unsafe_math_optimizations && !optimize_size"
17073 {
17074   rtx op0 = gen_reg_rtx (XFmode);
17075   rtx op1 = gen_reg_rtx (XFmode);
17076
17077   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17078   emit_insn (gen_expxf2 (op0, op1));
17079   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17080   DONE;
17081 })
17082
17083 (define_expand "exp10xf2"
17084   [(use (match_operand:XF 0 "register_operand" ""))
17085    (use (match_operand:XF 1 "register_operand" ""))]
17086   "TARGET_USE_FANCY_MATH_387
17087    && flag_unsafe_math_optimizations && !optimize_size"
17088 {
17089   rtx op2 = gen_reg_rtx (XFmode);
17090   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17091
17092   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17093   DONE;
17094 })
17095
17096 (define_expand "exp10<mode>2"
17097   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17098    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17099  "TARGET_USE_FANCY_MATH_387
17100    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17101        || TARGET_MIX_SSE_I387)
17102    && flag_unsafe_math_optimizations && !optimize_size"
17103 {
17104   rtx op0 = gen_reg_rtx (XFmode);
17105   rtx op1 = gen_reg_rtx (XFmode);
17106
17107   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17108   emit_insn (gen_exp10xf2 (op0, op1));
17109   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17110   DONE;
17111 })
17112
17113 (define_expand "exp2xf2"
17114   [(use (match_operand:XF 0 "register_operand" ""))
17115    (use (match_operand:XF 1 "register_operand" ""))]
17116   "TARGET_USE_FANCY_MATH_387
17117    && flag_unsafe_math_optimizations && !optimize_size"
17118 {
17119   rtx op2 = gen_reg_rtx (XFmode);
17120   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17121
17122   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17123   DONE;
17124 })
17125
17126 (define_expand "exp2<mode>2"
17127   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17128    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17129  "TARGET_USE_FANCY_MATH_387
17130    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17131        || TARGET_MIX_SSE_I387)
17132    && flag_unsafe_math_optimizations && !optimize_size"
17133 {
17134   rtx op0 = gen_reg_rtx (XFmode);
17135   rtx op1 = gen_reg_rtx (XFmode);
17136
17137   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17138   emit_insn (gen_exp2xf2 (op0, op1));
17139   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17140   DONE;
17141 })
17142
17143 (define_expand "expm1xf2"
17144   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17145                                (match_dup 2)))
17146    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17147    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17148    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17149    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17150    (parallel [(set (match_dup 7)
17151                    (unspec:XF [(match_dup 6) (match_dup 4)]
17152                               UNSPEC_FSCALE_FRACT))
17153               (set (match_dup 8)
17154                    (unspec:XF [(match_dup 6) (match_dup 4)]
17155                               UNSPEC_FSCALE_EXP))])
17156    (parallel [(set (match_dup 10)
17157                    (unspec:XF [(match_dup 9) (match_dup 8)]
17158                               UNSPEC_FSCALE_FRACT))
17159               (set (match_dup 11)
17160                    (unspec:XF [(match_dup 9) (match_dup 8)]
17161                               UNSPEC_FSCALE_EXP))])
17162    (set (match_dup 12) (minus:XF (match_dup 10)
17163                                  (float_extend:XF (match_dup 13))))
17164    (set (match_operand:XF 0 "register_operand" "")
17165         (plus:XF (match_dup 12) (match_dup 7)))]
17166   "TARGET_USE_FANCY_MATH_387
17167    && flag_unsafe_math_optimizations && !optimize_size"
17168 {
17169   int i;
17170
17171   for (i = 2; i < 13; i++)
17172     operands[i] = gen_reg_rtx (XFmode);
17173
17174   operands[13]
17175     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17176
17177   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17178 })
17179
17180 (define_expand "expm1<mode>2"
17181   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17182    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17183  "TARGET_USE_FANCY_MATH_387
17184    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17185        || TARGET_MIX_SSE_I387)
17186    && flag_unsafe_math_optimizations && !optimize_size"
17187 {
17188   rtx op0 = gen_reg_rtx (XFmode);
17189   rtx op1 = gen_reg_rtx (XFmode);
17190
17191   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17192   emit_insn (gen_expm1xf2 (op0, op1));
17193   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17194   DONE;
17195 })
17196
17197 (define_expand "ldexpxf3"
17198   [(set (match_dup 3)
17199         (float:XF (match_operand:SI 2 "register_operand" "")))
17200    (parallel [(set (match_operand:XF 0 " register_operand" "")
17201                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17202                                (match_dup 3)]
17203                               UNSPEC_FSCALE_FRACT))
17204               (set (match_dup 4)
17205                    (unspec:XF [(match_dup 1) (match_dup 3)]
17206                               UNSPEC_FSCALE_EXP))])]
17207   "TARGET_USE_FANCY_MATH_387
17208    && flag_unsafe_math_optimizations && !optimize_size"
17209 {
17210   operands[3] = gen_reg_rtx (XFmode);
17211   operands[4] = gen_reg_rtx (XFmode);
17212 })
17213
17214 (define_expand "ldexp<mode>3"
17215   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17216    (use (match_operand:X87MODEF12 1 "general_operand" ""))
17217    (use (match_operand:SI 2 "register_operand" ""))]
17218  "TARGET_USE_FANCY_MATH_387
17219    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17220        || TARGET_MIX_SSE_I387)
17221    && flag_unsafe_math_optimizations && !optimize_size"
17222 {
17223   rtx op0 = gen_reg_rtx (XFmode);
17224   rtx op1 = gen_reg_rtx (XFmode);
17225
17226   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17227   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17228   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17229   DONE;
17230 })
17231
17232 (define_expand "scalbxf3"
17233   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17234                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17235                                (match_operand:XF 2 "register_operand" "")]
17236                               UNSPEC_FSCALE_FRACT))
17237               (set (match_dup 3)
17238                    (unspec:XF [(match_dup 1) (match_dup 2)]
17239                               UNSPEC_FSCALE_EXP))])]
17240   "TARGET_USE_FANCY_MATH_387
17241    && flag_unsafe_math_optimizations && !optimize_size"
17242 {
17243   operands[3] = gen_reg_rtx (XFmode);
17244 })
17245
17246 (define_expand "scalb<mode>3"
17247   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17248    (use (match_operand:X87MODEF12 1 "general_operand" ""))
17249    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
17250  "TARGET_USE_FANCY_MATH_387
17251    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17252        || TARGET_MIX_SSE_I387)
17253    && flag_unsafe_math_optimizations && !optimize_size"
17254 {
17255   rtx op0 = gen_reg_rtx (XFmode);
17256   rtx op1 = gen_reg_rtx (XFmode);
17257   rtx op2 = gen_reg_rtx (XFmode);
17258
17259   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17260   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17261   emit_insn (gen_scalbxf3 (op0, op1, op2));
17262   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17263   DONE;
17264 })
17265 \f
17266
17267 (define_insn "sse4_1_round<mode>2"
17268   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
17269         (unspec:SSEMODEF [(match_operand:SSEMODEF 1 "register_operand" "x")
17270                           (match_operand:SI 2 "const_0_to_15_operand" "n")]
17271                          UNSPEC_ROUND))]
17272   "TARGET_SSE4_1"
17273   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17274   [(set_attr "type" "ssecvt")
17275    (set_attr "prefix_extra" "1")
17276    (set_attr "mode" "<MODE>")])
17277
17278 (define_insn "rintxf2"
17279   [(set (match_operand:XF 0 "register_operand" "=f")
17280         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17281                    UNSPEC_FRNDINT))]
17282   "TARGET_USE_FANCY_MATH_387
17283    && flag_unsafe_math_optimizations"
17284   "frndint"
17285   [(set_attr "type" "fpspc")
17286    (set_attr "mode" "XF")])
17287
17288 (define_expand "rint<mode>2"
17289   [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17290    (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17291   "(TARGET_USE_FANCY_MATH_387
17292     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17293         || TARGET_MIX_SSE_I387)
17294     && flag_unsafe_math_optimizations)
17295    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17296        && !flag_trapping_math
17297        && (TARGET_SSE4_1 || !optimize_size))"
17298 {
17299   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17300       && !flag_trapping_math
17301       && (TARGET_SSE4_1 || !optimize_size))
17302     {
17303       if (TARGET_SSE4_1)
17304         emit_insn (gen_sse4_1_round<mode>2
17305                    (operands[0], operands[1], GEN_INT (0x04)));
17306       else
17307         ix86_expand_rint (operand0, operand1);
17308     }
17309   else
17310     {
17311       rtx op0 = gen_reg_rtx (XFmode);
17312       rtx op1 = gen_reg_rtx (XFmode);
17313
17314       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17315       emit_insn (gen_rintxf2 (op0, op1));
17316
17317       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17318     }
17319   DONE;
17320 })
17321
17322 (define_expand "round<mode>2"
17323   [(match_operand:SSEMODEF 0 "register_operand" "")
17324    (match_operand:SSEMODEF 1 "nonimmediate_operand" "")]
17325   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17326    && !flag_trapping_math && !flag_rounding_math
17327    && !optimize_size"
17328 {
17329   if (TARGET_64BIT || (<MODE>mode != DFmode))
17330     ix86_expand_round (operand0, operand1);
17331   else
17332     ix86_expand_rounddf_32 (operand0, operand1);
17333   DONE;
17334 })
17335
17336 (define_insn_and_split "*fistdi2_1"
17337   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17338         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17339                    UNSPEC_FIST))]
17340   "TARGET_USE_FANCY_MATH_387
17341    && !(reload_completed || reload_in_progress)"
17342   "#"
17343   "&& 1"
17344   [(const_int 0)]
17345 {
17346   if (memory_operand (operands[0], VOIDmode))
17347     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17348   else
17349     {
17350       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17351       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17352                                          operands[2]));
17353     }
17354   DONE;
17355 }
17356   [(set_attr "type" "fpspc")
17357    (set_attr "mode" "DI")])
17358
17359 (define_insn "fistdi2"
17360   [(set (match_operand:DI 0 "memory_operand" "=m")
17361         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17362                    UNSPEC_FIST))
17363    (clobber (match_scratch:XF 2 "=&1f"))]
17364   "TARGET_USE_FANCY_MATH_387"
17365   "* return output_fix_trunc (insn, operands, 0);"
17366   [(set_attr "type" "fpspc")
17367    (set_attr "mode" "DI")])
17368
17369 (define_insn "fistdi2_with_temp"
17370   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17371         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17372                    UNSPEC_FIST))
17373    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17374    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17375   "TARGET_USE_FANCY_MATH_387"
17376   "#"
17377   [(set_attr "type" "fpspc")
17378    (set_attr "mode" "DI")])
17379
17380 (define_split
17381   [(set (match_operand:DI 0 "register_operand" "")
17382         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17383                    UNSPEC_FIST))
17384    (clobber (match_operand:DI 2 "memory_operand" ""))
17385    (clobber (match_scratch 3 ""))]
17386   "reload_completed"
17387   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17388               (clobber (match_dup 3))])
17389    (set (match_dup 0) (match_dup 2))]
17390   "")
17391
17392 (define_split
17393   [(set (match_operand:DI 0 "memory_operand" "")
17394         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17395                    UNSPEC_FIST))
17396    (clobber (match_operand:DI 2 "memory_operand" ""))
17397    (clobber (match_scratch 3 ""))]
17398   "reload_completed"
17399   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17400               (clobber (match_dup 3))])]
17401   "")
17402
17403 (define_insn_and_split "*fist<mode>2_1"
17404   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17405         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17406                            UNSPEC_FIST))]
17407   "TARGET_USE_FANCY_MATH_387
17408    && !(reload_completed || reload_in_progress)"
17409   "#"
17410   "&& 1"
17411   [(const_int 0)]
17412 {
17413   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17414   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17415                                         operands[2]));
17416   DONE;
17417 }
17418   [(set_attr "type" "fpspc")
17419    (set_attr "mode" "<MODE>")])
17420
17421 (define_insn "fist<mode>2"
17422   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17423         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17424                            UNSPEC_FIST))]
17425   "TARGET_USE_FANCY_MATH_387"
17426   "* return output_fix_trunc (insn, operands, 0);"
17427   [(set_attr "type" "fpspc")
17428    (set_attr "mode" "<MODE>")])
17429
17430 (define_insn "fist<mode>2_with_temp"
17431   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17432         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17433                            UNSPEC_FIST))
17434    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17435   "TARGET_USE_FANCY_MATH_387"
17436   "#"
17437   [(set_attr "type" "fpspc")
17438    (set_attr "mode" "<MODE>")])
17439
17440 (define_split
17441   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17442         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17443                            UNSPEC_FIST))
17444    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17445   "reload_completed"
17446   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17447    (set (match_dup 0) (match_dup 2))]
17448   "")
17449
17450 (define_split
17451   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17452         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17453                            UNSPEC_FIST))
17454    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17455   "reload_completed"
17456   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17457   "")
17458
17459 (define_expand "lrintxf<mode>2"
17460   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17461      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17462                       UNSPEC_FIST))]
17463   "TARGET_USE_FANCY_MATH_387"
17464   "")
17465
17466 (define_expand "lrint<SSEMODEF:mode><SSEMODEI24:mode>2"
17467   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17468      (unspec:SSEMODEI24 [(match_operand:SSEMODEF 1 "register_operand" "")]
17469                         UNSPEC_FIX_NOTRUNC))]
17470   "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17471    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17472   "")
17473
17474 (define_expand "lround<SSEMODEF:mode><SSEMODEI24:mode>2"
17475   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17476    (match_operand:SSEMODEF 1 "register_operand" "")]
17477   "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17478    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17479    && !flag_trapping_math && !flag_rounding_math
17480    && !optimize_size"
17481 {
17482   ix86_expand_lround (operand0, operand1);
17483   DONE;
17484 })
17485
17486 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17487 (define_insn_and_split "frndintxf2_floor"
17488   [(set (match_operand:XF 0 "register_operand" "=f")
17489         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17490          UNSPEC_FRNDINT_FLOOR))
17491    (clobber (reg:CC FLAGS_REG))]
17492   "TARGET_USE_FANCY_MATH_387
17493    && flag_unsafe_math_optimizations
17494    && !(reload_completed || reload_in_progress)"
17495   "#"
17496   "&& 1"
17497   [(const_int 0)]
17498 {
17499   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17500
17501   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17502   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17503
17504   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17505                                         operands[2], operands[3]));
17506   DONE;
17507 }
17508   [(set_attr "type" "frndint")
17509    (set_attr "i387_cw" "floor")
17510    (set_attr "mode" "XF")])
17511
17512 (define_insn "frndintxf2_floor_i387"
17513   [(set (match_operand:XF 0 "register_operand" "=f")
17514         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17515          UNSPEC_FRNDINT_FLOOR))
17516    (use (match_operand:HI 2 "memory_operand" "m"))
17517    (use (match_operand:HI 3 "memory_operand" "m"))]
17518   "TARGET_USE_FANCY_MATH_387
17519    && flag_unsafe_math_optimizations"
17520   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17521   [(set_attr "type" "frndint")
17522    (set_attr "i387_cw" "floor")
17523    (set_attr "mode" "XF")])
17524
17525 (define_expand "floorxf2"
17526   [(use (match_operand:XF 0 "register_operand" ""))
17527    (use (match_operand:XF 1 "register_operand" ""))]
17528   "TARGET_USE_FANCY_MATH_387
17529    && flag_unsafe_math_optimizations && !optimize_size"
17530 {
17531   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17532   DONE;
17533 })
17534
17535 (define_expand "floor<mode>2"
17536   [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17537    (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17538   "(TARGET_USE_FANCY_MATH_387
17539     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17540         || TARGET_MIX_SSE_I387)
17541     && flag_unsafe_math_optimizations && !optimize_size)
17542    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17543        && !flag_trapping_math
17544        && (TARGET_SSE4_1 || !optimize_size))"
17545 {
17546   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17547       && !flag_trapping_math
17548       && (TARGET_SSE4_1 || !optimize_size))
17549     {
17550       if (TARGET_SSE4_1)
17551         emit_insn (gen_sse4_1_round<mode>2
17552                    (operands[0], operands[1], GEN_INT (0x01)));
17553       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17554         ix86_expand_floorceil (operand0, operand1, true);
17555       else
17556         ix86_expand_floorceildf_32 (operand0, operand1, true);
17557     }
17558   else
17559     {
17560       rtx op0 = gen_reg_rtx (XFmode);
17561       rtx op1 = gen_reg_rtx (XFmode);
17562
17563       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17564       emit_insn (gen_frndintxf2_floor (op0, op1));
17565
17566       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17567     }
17568   DONE;
17569 })
17570
17571 (define_insn_and_split "*fist<mode>2_floor_1"
17572   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17573         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17574          UNSPEC_FIST_FLOOR))
17575    (clobber (reg:CC FLAGS_REG))]
17576   "TARGET_USE_FANCY_MATH_387
17577    && flag_unsafe_math_optimizations
17578    && !(reload_completed || reload_in_progress)"
17579   "#"
17580   "&& 1"
17581   [(const_int 0)]
17582 {
17583   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17584
17585   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17586   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17587   if (memory_operand (operands[0], VOIDmode))
17588     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17589                                       operands[2], operands[3]));
17590   else
17591     {
17592       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17593       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17594                                                   operands[2], operands[3],
17595                                                   operands[4]));
17596     }
17597   DONE;
17598 }
17599   [(set_attr "type" "fistp")
17600    (set_attr "i387_cw" "floor")
17601    (set_attr "mode" "<MODE>")])
17602
17603 (define_insn "fistdi2_floor"
17604   [(set (match_operand:DI 0 "memory_operand" "=m")
17605         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17606          UNSPEC_FIST_FLOOR))
17607    (use (match_operand:HI 2 "memory_operand" "m"))
17608    (use (match_operand:HI 3 "memory_operand" "m"))
17609    (clobber (match_scratch:XF 4 "=&1f"))]
17610   "TARGET_USE_FANCY_MATH_387
17611    && flag_unsafe_math_optimizations"
17612   "* return output_fix_trunc (insn, operands, 0);"
17613   [(set_attr "type" "fistp")
17614    (set_attr "i387_cw" "floor")
17615    (set_attr "mode" "DI")])
17616
17617 (define_insn "fistdi2_floor_with_temp"
17618   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17619         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17620          UNSPEC_FIST_FLOOR))
17621    (use (match_operand:HI 2 "memory_operand" "m,m"))
17622    (use (match_operand:HI 3 "memory_operand" "m,m"))
17623    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17624    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17625   "TARGET_USE_FANCY_MATH_387
17626    && flag_unsafe_math_optimizations"
17627   "#"
17628   [(set_attr "type" "fistp")
17629    (set_attr "i387_cw" "floor")
17630    (set_attr "mode" "DI")])
17631
17632 (define_split
17633   [(set (match_operand:DI 0 "register_operand" "")
17634         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17635          UNSPEC_FIST_FLOOR))
17636    (use (match_operand:HI 2 "memory_operand" ""))
17637    (use (match_operand:HI 3 "memory_operand" ""))
17638    (clobber (match_operand:DI 4 "memory_operand" ""))
17639    (clobber (match_scratch 5 ""))]
17640   "reload_completed"
17641   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17642               (use (match_dup 2))
17643               (use (match_dup 3))
17644               (clobber (match_dup 5))])
17645    (set (match_dup 0) (match_dup 4))]
17646   "")
17647
17648 (define_split
17649   [(set (match_operand:DI 0 "memory_operand" "")
17650         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17651          UNSPEC_FIST_FLOOR))
17652    (use (match_operand:HI 2 "memory_operand" ""))
17653    (use (match_operand:HI 3 "memory_operand" ""))
17654    (clobber (match_operand:DI 4 "memory_operand" ""))
17655    (clobber (match_scratch 5 ""))]
17656   "reload_completed"
17657   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17658               (use (match_dup 2))
17659               (use (match_dup 3))
17660               (clobber (match_dup 5))])]
17661   "")
17662
17663 (define_insn "fist<mode>2_floor"
17664   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17665         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17666          UNSPEC_FIST_FLOOR))
17667    (use (match_operand:HI 2 "memory_operand" "m"))
17668    (use (match_operand:HI 3 "memory_operand" "m"))]
17669   "TARGET_USE_FANCY_MATH_387
17670    && flag_unsafe_math_optimizations"
17671   "* return output_fix_trunc (insn, operands, 0);"
17672   [(set_attr "type" "fistp")
17673    (set_attr "i387_cw" "floor")
17674    (set_attr "mode" "<MODE>")])
17675
17676 (define_insn "fist<mode>2_floor_with_temp"
17677   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17678         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17679          UNSPEC_FIST_FLOOR))
17680    (use (match_operand:HI 2 "memory_operand" "m,m"))
17681    (use (match_operand:HI 3 "memory_operand" "m,m"))
17682    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17683   "TARGET_USE_FANCY_MATH_387
17684    && flag_unsafe_math_optimizations"
17685   "#"
17686   [(set_attr "type" "fistp")
17687    (set_attr "i387_cw" "floor")
17688    (set_attr "mode" "<MODE>")])
17689
17690 (define_split
17691   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17692         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17693          UNSPEC_FIST_FLOOR))
17694    (use (match_operand:HI 2 "memory_operand" ""))
17695    (use (match_operand:HI 3 "memory_operand" ""))
17696    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17697   "reload_completed"
17698   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17699                                   UNSPEC_FIST_FLOOR))
17700               (use (match_dup 2))
17701               (use (match_dup 3))])
17702    (set (match_dup 0) (match_dup 4))]
17703   "")
17704
17705 (define_split
17706   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17707         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17708          UNSPEC_FIST_FLOOR))
17709    (use (match_operand:HI 2 "memory_operand" ""))
17710    (use (match_operand:HI 3 "memory_operand" ""))
17711    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17712   "reload_completed"
17713   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17714                                   UNSPEC_FIST_FLOOR))
17715               (use (match_dup 2))
17716               (use (match_dup 3))])]
17717   "")
17718
17719 (define_expand "lfloorxf<mode>2"
17720   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17721                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17722                     UNSPEC_FIST_FLOOR))
17723               (clobber (reg:CC FLAGS_REG))])]
17724   "TARGET_USE_FANCY_MATH_387
17725    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17726    && flag_unsafe_math_optimizations"
17727   "")
17728
17729 (define_expand "lfloor<mode>di2"
17730   [(match_operand:DI 0 "nonimmediate_operand" "")
17731    (match_operand:SSEMODEF 1 "register_operand" "")]
17732   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17733    && !flag_trapping_math
17734    && !optimize_size"
17735 {
17736   ix86_expand_lfloorceil (operand0, operand1, true);
17737   DONE;
17738 })
17739
17740 (define_expand "lfloor<mode>si2"
17741   [(match_operand:SI 0 "nonimmediate_operand" "")
17742    (match_operand:SSEMODEF 1 "register_operand" "")]
17743   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17744    && !flag_trapping_math
17745    && (!optimize_size || !TARGET_64BIT)"
17746 {
17747   ix86_expand_lfloorceil (operand0, operand1, true);
17748   DONE;
17749 })
17750
17751 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17752 (define_insn_and_split "frndintxf2_ceil"
17753   [(set (match_operand:XF 0 "register_operand" "=f")
17754         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17755          UNSPEC_FRNDINT_CEIL))
17756    (clobber (reg:CC FLAGS_REG))]
17757   "TARGET_USE_FANCY_MATH_387
17758    && flag_unsafe_math_optimizations
17759    && !(reload_completed || reload_in_progress)"
17760   "#"
17761   "&& 1"
17762   [(const_int 0)]
17763 {
17764   ix86_optimize_mode_switching[I387_CEIL] = 1;
17765
17766   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17767   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17768
17769   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17770                                        operands[2], operands[3]));
17771   DONE;
17772 }
17773   [(set_attr "type" "frndint")
17774    (set_attr "i387_cw" "ceil")
17775    (set_attr "mode" "XF")])
17776
17777 (define_insn "frndintxf2_ceil_i387"
17778   [(set (match_operand:XF 0 "register_operand" "=f")
17779         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17780          UNSPEC_FRNDINT_CEIL))
17781    (use (match_operand:HI 2 "memory_operand" "m"))
17782    (use (match_operand:HI 3 "memory_operand" "m"))]
17783   "TARGET_USE_FANCY_MATH_387
17784    && flag_unsafe_math_optimizations"
17785   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17786   [(set_attr "type" "frndint")
17787    (set_attr "i387_cw" "ceil")
17788    (set_attr "mode" "XF")])
17789
17790 (define_expand "ceilxf2"
17791   [(use (match_operand:XF 0 "register_operand" ""))
17792    (use (match_operand:XF 1 "register_operand" ""))]
17793   "TARGET_USE_FANCY_MATH_387
17794    && flag_unsafe_math_optimizations && !optimize_size"
17795 {
17796   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17797   DONE;
17798 })
17799
17800 (define_expand "ceil<mode>2"
17801   [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17802    (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17803   "(TARGET_USE_FANCY_MATH_387
17804     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17805         || TARGET_MIX_SSE_I387)
17806     && flag_unsafe_math_optimizations && !optimize_size)
17807    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17808        && !flag_trapping_math
17809        && (TARGET_SSE4_1 || !optimize_size))"
17810 {
17811   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17812       && !flag_trapping_math
17813       && (TARGET_SSE4_1 || !optimize_size))
17814     {
17815       if (TARGET_SSE4_1)
17816         emit_insn (gen_sse4_1_round<mode>2
17817                    (operands[0], operands[1], GEN_INT (0x02)));
17818       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17819         ix86_expand_floorceil (operand0, operand1, false);
17820       else
17821         ix86_expand_floorceildf_32 (operand0, operand1, false);
17822     }
17823   else
17824     {
17825       rtx op0 = gen_reg_rtx (XFmode);
17826       rtx op1 = gen_reg_rtx (XFmode);
17827
17828       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17829       emit_insn (gen_frndintxf2_ceil (op0, op1));
17830
17831       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17832     }
17833   DONE;
17834 })
17835
17836 (define_insn_and_split "*fist<mode>2_ceil_1"
17837   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17838         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17839          UNSPEC_FIST_CEIL))
17840    (clobber (reg:CC FLAGS_REG))]
17841   "TARGET_USE_FANCY_MATH_387
17842    && flag_unsafe_math_optimizations
17843    && !(reload_completed || reload_in_progress)"
17844   "#"
17845   "&& 1"
17846   [(const_int 0)]
17847 {
17848   ix86_optimize_mode_switching[I387_CEIL] = 1;
17849
17850   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17851   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17852   if (memory_operand (operands[0], VOIDmode))
17853     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17854                                      operands[2], operands[3]));
17855   else
17856     {
17857       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17858       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17859                                                  operands[2], operands[3],
17860                                                  operands[4]));
17861     }
17862   DONE;
17863 }
17864   [(set_attr "type" "fistp")
17865    (set_attr "i387_cw" "ceil")
17866    (set_attr "mode" "<MODE>")])
17867
17868 (define_insn "fistdi2_ceil"
17869   [(set (match_operand:DI 0 "memory_operand" "=m")
17870         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17871          UNSPEC_FIST_CEIL))
17872    (use (match_operand:HI 2 "memory_operand" "m"))
17873    (use (match_operand:HI 3 "memory_operand" "m"))
17874    (clobber (match_scratch:XF 4 "=&1f"))]
17875   "TARGET_USE_FANCY_MATH_387
17876    && flag_unsafe_math_optimizations"
17877   "* return output_fix_trunc (insn, operands, 0);"
17878   [(set_attr "type" "fistp")
17879    (set_attr "i387_cw" "ceil")
17880    (set_attr "mode" "DI")])
17881
17882 (define_insn "fistdi2_ceil_with_temp"
17883   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17884         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17885          UNSPEC_FIST_CEIL))
17886    (use (match_operand:HI 2 "memory_operand" "m,m"))
17887    (use (match_operand:HI 3 "memory_operand" "m,m"))
17888    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17889    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17890   "TARGET_USE_FANCY_MATH_387
17891    && flag_unsafe_math_optimizations"
17892   "#"
17893   [(set_attr "type" "fistp")
17894    (set_attr "i387_cw" "ceil")
17895    (set_attr "mode" "DI")])
17896
17897 (define_split
17898   [(set (match_operand:DI 0 "register_operand" "")
17899         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17900          UNSPEC_FIST_CEIL))
17901    (use (match_operand:HI 2 "memory_operand" ""))
17902    (use (match_operand:HI 3 "memory_operand" ""))
17903    (clobber (match_operand:DI 4 "memory_operand" ""))
17904    (clobber (match_scratch 5 ""))]
17905   "reload_completed"
17906   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17907               (use (match_dup 2))
17908               (use (match_dup 3))
17909               (clobber (match_dup 5))])
17910    (set (match_dup 0) (match_dup 4))]
17911   "")
17912
17913 (define_split
17914   [(set (match_operand:DI 0 "memory_operand" "")
17915         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17916          UNSPEC_FIST_CEIL))
17917    (use (match_operand:HI 2 "memory_operand" ""))
17918    (use (match_operand:HI 3 "memory_operand" ""))
17919    (clobber (match_operand:DI 4 "memory_operand" ""))
17920    (clobber (match_scratch 5 ""))]
17921   "reload_completed"
17922   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17923               (use (match_dup 2))
17924               (use (match_dup 3))
17925               (clobber (match_dup 5))])]
17926   "")
17927
17928 (define_insn "fist<mode>2_ceil"
17929   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17930         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17931          UNSPEC_FIST_CEIL))
17932    (use (match_operand:HI 2 "memory_operand" "m"))
17933    (use (match_operand:HI 3 "memory_operand" "m"))]
17934   "TARGET_USE_FANCY_MATH_387
17935    && flag_unsafe_math_optimizations"
17936   "* return output_fix_trunc (insn, operands, 0);"
17937   [(set_attr "type" "fistp")
17938    (set_attr "i387_cw" "ceil")
17939    (set_attr "mode" "<MODE>")])
17940
17941 (define_insn "fist<mode>2_ceil_with_temp"
17942   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17943         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17944          UNSPEC_FIST_CEIL))
17945    (use (match_operand:HI 2 "memory_operand" "m,m"))
17946    (use (match_operand:HI 3 "memory_operand" "m,m"))
17947    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17948   "TARGET_USE_FANCY_MATH_387
17949    && flag_unsafe_math_optimizations"
17950   "#"
17951   [(set_attr "type" "fistp")
17952    (set_attr "i387_cw" "ceil")
17953    (set_attr "mode" "<MODE>")])
17954
17955 (define_split
17956   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17957         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17958          UNSPEC_FIST_CEIL))
17959    (use (match_operand:HI 2 "memory_operand" ""))
17960    (use (match_operand:HI 3 "memory_operand" ""))
17961    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17962   "reload_completed"
17963   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17964                                   UNSPEC_FIST_CEIL))
17965               (use (match_dup 2))
17966               (use (match_dup 3))])
17967    (set (match_dup 0) (match_dup 4))]
17968   "")
17969
17970 (define_split
17971   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17972         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17973          UNSPEC_FIST_CEIL))
17974    (use (match_operand:HI 2 "memory_operand" ""))
17975    (use (match_operand:HI 3 "memory_operand" ""))
17976    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17977   "reload_completed"
17978   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17979                                   UNSPEC_FIST_CEIL))
17980               (use (match_dup 2))
17981               (use (match_dup 3))])]
17982   "")
17983
17984 (define_expand "lceilxf<mode>2"
17985   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17986                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17987                     UNSPEC_FIST_CEIL))
17988               (clobber (reg:CC FLAGS_REG))])]
17989   "TARGET_USE_FANCY_MATH_387
17990    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17991    && flag_unsafe_math_optimizations"
17992   "")
17993
17994 (define_expand "lceil<mode>di2"
17995   [(match_operand:DI 0 "nonimmediate_operand" "")
17996    (match_operand:SSEMODEF 1 "register_operand" "")]
17997   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17998    && !flag_trapping_math"
17999 {
18000   ix86_expand_lfloorceil (operand0, operand1, false);
18001   DONE;
18002 })
18003
18004 (define_expand "lceil<mode>si2"
18005   [(match_operand:SI 0 "nonimmediate_operand" "")
18006    (match_operand:SSEMODEF 1 "register_operand" "")]
18007   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18008    && !flag_trapping_math"
18009 {
18010   ix86_expand_lfloorceil (operand0, operand1, false);
18011   DONE;
18012 })
18013
18014 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18015 (define_insn_and_split "frndintxf2_trunc"
18016   [(set (match_operand:XF 0 "register_operand" "=f")
18017         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18018          UNSPEC_FRNDINT_TRUNC))
18019    (clobber (reg:CC FLAGS_REG))]
18020   "TARGET_USE_FANCY_MATH_387
18021    && flag_unsafe_math_optimizations
18022    && !(reload_completed || reload_in_progress)"
18023   "#"
18024   "&& 1"
18025   [(const_int 0)]
18026 {
18027   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18028
18029   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18030   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18031
18032   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18033                                         operands[2], operands[3]));
18034   DONE;
18035 }
18036   [(set_attr "type" "frndint")
18037    (set_attr "i387_cw" "trunc")
18038    (set_attr "mode" "XF")])
18039
18040 (define_insn "frndintxf2_trunc_i387"
18041   [(set (match_operand:XF 0 "register_operand" "=f")
18042         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18043          UNSPEC_FRNDINT_TRUNC))
18044    (use (match_operand:HI 2 "memory_operand" "m"))
18045    (use (match_operand:HI 3 "memory_operand" "m"))]
18046   "TARGET_USE_FANCY_MATH_387
18047    && flag_unsafe_math_optimizations"
18048   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18049   [(set_attr "type" "frndint")
18050    (set_attr "i387_cw" "trunc")
18051    (set_attr "mode" "XF")])
18052
18053 (define_expand "btruncxf2"
18054   [(use (match_operand:XF 0 "register_operand" ""))
18055    (use (match_operand:XF 1 "register_operand" ""))]
18056   "TARGET_USE_FANCY_MATH_387
18057    && flag_unsafe_math_optimizations && !optimize_size"
18058 {
18059   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18060   DONE;
18061 })
18062
18063 (define_expand "btrunc<mode>2"
18064   [(use (match_operand:SSEMODEF 0 "register_operand" ""))
18065    (use (match_operand:SSEMODEF 1 "register_operand" ""))]
18066   "(TARGET_USE_FANCY_MATH_387
18067     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18068         || TARGET_MIX_SSE_I387)
18069     && flag_unsafe_math_optimizations && !optimize_size)
18070    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18071        && !flag_trapping_math
18072        && (TARGET_SSE4_1 || !optimize_size))"
18073 {
18074   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18075       && !flag_trapping_math
18076       && (TARGET_SSE4_1 || !optimize_size))
18077     {
18078       if (TARGET_SSE4_1)
18079         emit_insn (gen_sse4_1_round<mode>2
18080                    (operands[0], operands[1], GEN_INT (0x03)));
18081       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18082         ix86_expand_trunc (operand0, operand1);
18083       else
18084         ix86_expand_truncdf_32 (operand0, operand1);
18085     }
18086   else
18087     {
18088       rtx op0 = gen_reg_rtx (XFmode);
18089       rtx op1 = gen_reg_rtx (XFmode);
18090
18091       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18092       emit_insn (gen_frndintxf2_trunc (op0, op1));
18093
18094       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18095     }
18096   DONE;
18097 })
18098
18099 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18100 (define_insn_and_split "frndintxf2_mask_pm"
18101   [(set (match_operand:XF 0 "register_operand" "=f")
18102         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18103          UNSPEC_FRNDINT_MASK_PM))
18104    (clobber (reg:CC FLAGS_REG))]
18105   "TARGET_USE_FANCY_MATH_387
18106    && flag_unsafe_math_optimizations
18107    && !(reload_completed || reload_in_progress)"
18108   "#"
18109   "&& 1"
18110   [(const_int 0)]
18111 {
18112   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18113
18114   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18115   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18116
18117   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18118                                           operands[2], operands[3]));
18119   DONE;
18120 }
18121   [(set_attr "type" "frndint")
18122    (set_attr "i387_cw" "mask_pm")
18123    (set_attr "mode" "XF")])
18124
18125 (define_insn "frndintxf2_mask_pm_i387"
18126   [(set (match_operand:XF 0 "register_operand" "=f")
18127         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18128          UNSPEC_FRNDINT_MASK_PM))
18129    (use (match_operand:HI 2 "memory_operand" "m"))
18130    (use (match_operand:HI 3 "memory_operand" "m"))]
18131   "TARGET_USE_FANCY_MATH_387
18132    && flag_unsafe_math_optimizations"
18133   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18134   [(set_attr "type" "frndint")
18135    (set_attr "i387_cw" "mask_pm")
18136    (set_attr "mode" "XF")])
18137
18138 (define_expand "nearbyintxf2"
18139   [(use (match_operand:XF 0 "register_operand" ""))
18140    (use (match_operand:XF 1 "register_operand" ""))]
18141   "TARGET_USE_FANCY_MATH_387
18142    && flag_unsafe_math_optimizations"
18143 {
18144   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18145
18146   DONE;
18147 })
18148
18149 (define_expand "nearbyintdf2"
18150   [(use (match_operand:DF 0 "register_operand" ""))
18151    (use (match_operand:DF 1 "register_operand" ""))]
18152   "TARGET_USE_FANCY_MATH_387
18153    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18154    && flag_unsafe_math_optimizations"
18155 {
18156   rtx op0 = gen_reg_rtx (XFmode);
18157   rtx op1 = gen_reg_rtx (XFmode);
18158
18159   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18160   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18161
18162   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18163   DONE;
18164 })
18165
18166 (define_expand "nearbyintsf2"
18167   [(use (match_operand:SF 0 "register_operand" ""))
18168    (use (match_operand:SF 1 "register_operand" ""))]
18169   "TARGET_USE_FANCY_MATH_387
18170    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18171    && flag_unsafe_math_optimizations"
18172 {
18173   rtx op0 = gen_reg_rtx (XFmode);
18174   rtx op1 = gen_reg_rtx (XFmode);
18175
18176   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18177   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18178
18179   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18180   DONE;
18181 })
18182
18183 (define_insn "fxam<mode>2_i387"
18184   [(set (match_operand:HI 0 "register_operand" "=a")
18185         (unspec:HI
18186           [(match_operand:X87MODEF 1 "register_operand" "f")]
18187           UNSPEC_FXAM))]
18188   "TARGET_USE_FANCY_MATH_387"
18189   "fxam\n\tfnstsw\t%0"
18190   [(set_attr "type" "multi")
18191    (set_attr "unit" "i387")
18192    (set_attr "mode" "<MODE>")])
18193
18194 (define_expand "isinf<mode>2"
18195   [(use (match_operand:SI 0 "register_operand" ""))
18196    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18197   "TARGET_USE_FANCY_MATH_387
18198    && TARGET_C99_FUNCTIONS
18199    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18200 {
18201   rtx mask = GEN_INT (0x45);
18202   rtx val = GEN_INT (0x05);
18203
18204   rtx cond;
18205
18206   rtx scratch = gen_reg_rtx (HImode);
18207   rtx res = gen_reg_rtx (QImode);
18208
18209   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18210   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18211   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18212   cond = gen_rtx_fmt_ee (EQ, QImode,
18213                          gen_rtx_REG (CCmode, FLAGS_REG),
18214                          const0_rtx);
18215   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18216   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18217   DONE;
18218 })
18219
18220 (define_expand "signbit<mode>2"
18221   [(use (match_operand:SI 0 "register_operand" ""))
18222    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18223   "TARGET_USE_FANCY_MATH_387
18224    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18225 {
18226   rtx mask = GEN_INT (0x0200);
18227
18228   rtx scratch = gen_reg_rtx (HImode);
18229
18230   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18231   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18232   DONE;
18233 })
18234 \f
18235 ;; Block operation instructions
18236
18237 (define_expand "movmemsi"
18238   [(use (match_operand:BLK 0 "memory_operand" ""))
18239    (use (match_operand:BLK 1 "memory_operand" ""))
18240    (use (match_operand:SI 2 "nonmemory_operand" ""))
18241    (use (match_operand:SI 3 "const_int_operand" ""))
18242    (use (match_operand:SI 4 "const_int_operand" ""))
18243    (use (match_operand:SI 5 "const_int_operand" ""))]
18244   ""
18245 {
18246  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18247                          operands[4], operands[5]))
18248    DONE;
18249  else
18250    FAIL;
18251 })
18252
18253 (define_expand "movmemdi"
18254   [(use (match_operand:BLK 0 "memory_operand" ""))
18255    (use (match_operand:BLK 1 "memory_operand" ""))
18256    (use (match_operand:DI 2 "nonmemory_operand" ""))
18257    (use (match_operand:DI 3 "const_int_operand" ""))
18258    (use (match_operand:SI 4 "const_int_operand" ""))
18259    (use (match_operand:SI 5 "const_int_operand" ""))]
18260   "TARGET_64BIT"
18261 {
18262  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18263                          operands[4], operands[5]))
18264    DONE;
18265  else
18266    FAIL;
18267 })
18268
18269 ;; Most CPUs don't like single string operations
18270 ;; Handle this case here to simplify previous expander.
18271
18272 (define_expand "strmov"
18273   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18274    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18275    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18276               (clobber (reg:CC FLAGS_REG))])
18277    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18278               (clobber (reg:CC FLAGS_REG))])]
18279   ""
18280 {
18281   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18282
18283   /* If .md ever supports :P for Pmode, these can be directly
18284      in the pattern above.  */
18285   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18286   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18287
18288   if (TARGET_SINGLE_STRINGOP || optimize_size)
18289     {
18290       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18291                                       operands[2], operands[3],
18292                                       operands[5], operands[6]));
18293       DONE;
18294     }
18295
18296   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18297 })
18298
18299 (define_expand "strmov_singleop"
18300   [(parallel [(set (match_operand 1 "memory_operand" "")
18301                    (match_operand 3 "memory_operand" ""))
18302               (set (match_operand 0 "register_operand" "")
18303                    (match_operand 4 "" ""))
18304               (set (match_operand 2 "register_operand" "")
18305                    (match_operand 5 "" ""))])]
18306   "TARGET_SINGLE_STRINGOP || optimize_size"
18307   "")
18308
18309 (define_insn "*strmovdi_rex_1"
18310   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18311         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18312    (set (match_operand:DI 0 "register_operand" "=D")
18313         (plus:DI (match_dup 2)
18314                  (const_int 8)))
18315    (set (match_operand:DI 1 "register_operand" "=S")
18316         (plus:DI (match_dup 3)
18317                  (const_int 8)))]
18318   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18319   "movsq"
18320   [(set_attr "type" "str")
18321    (set_attr "mode" "DI")
18322    (set_attr "memory" "both")])
18323
18324 (define_insn "*strmovsi_1"
18325   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18326         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18327    (set (match_operand:SI 0 "register_operand" "=D")
18328         (plus:SI (match_dup 2)
18329                  (const_int 4)))
18330    (set (match_operand:SI 1 "register_operand" "=S")
18331         (plus:SI (match_dup 3)
18332                  (const_int 4)))]
18333   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18334   "{movsl|movsd}"
18335   [(set_attr "type" "str")
18336    (set_attr "mode" "SI")
18337    (set_attr "memory" "both")])
18338
18339 (define_insn "*strmovsi_rex_1"
18340   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18341         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18342    (set (match_operand:DI 0 "register_operand" "=D")
18343         (plus:DI (match_dup 2)
18344                  (const_int 4)))
18345    (set (match_operand:DI 1 "register_operand" "=S")
18346         (plus:DI (match_dup 3)
18347                  (const_int 4)))]
18348   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18349   "{movsl|movsd}"
18350   [(set_attr "type" "str")
18351    (set_attr "mode" "SI")
18352    (set_attr "memory" "both")])
18353
18354 (define_insn "*strmovhi_1"
18355   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18356         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18357    (set (match_operand:SI 0 "register_operand" "=D")
18358         (plus:SI (match_dup 2)
18359                  (const_int 2)))
18360    (set (match_operand:SI 1 "register_operand" "=S")
18361         (plus:SI (match_dup 3)
18362                  (const_int 2)))]
18363   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18364   "movsw"
18365   [(set_attr "type" "str")
18366    (set_attr "memory" "both")
18367    (set_attr "mode" "HI")])
18368
18369 (define_insn "*strmovhi_rex_1"
18370   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18371         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18372    (set (match_operand:DI 0 "register_operand" "=D")
18373         (plus:DI (match_dup 2)
18374                  (const_int 2)))
18375    (set (match_operand:DI 1 "register_operand" "=S")
18376         (plus:DI (match_dup 3)
18377                  (const_int 2)))]
18378   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18379   "movsw"
18380   [(set_attr "type" "str")
18381    (set_attr "memory" "both")
18382    (set_attr "mode" "HI")])
18383
18384 (define_insn "*strmovqi_1"
18385   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18386         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18387    (set (match_operand:SI 0 "register_operand" "=D")
18388         (plus:SI (match_dup 2)
18389                  (const_int 1)))
18390    (set (match_operand:SI 1 "register_operand" "=S")
18391         (plus:SI (match_dup 3)
18392                  (const_int 1)))]
18393   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18394   "movsb"
18395   [(set_attr "type" "str")
18396    (set_attr "memory" "both")
18397    (set_attr "mode" "QI")])
18398
18399 (define_insn "*strmovqi_rex_1"
18400   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18401         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18402    (set (match_operand:DI 0 "register_operand" "=D")
18403         (plus:DI (match_dup 2)
18404                  (const_int 1)))
18405    (set (match_operand:DI 1 "register_operand" "=S")
18406         (plus:DI (match_dup 3)
18407                  (const_int 1)))]
18408   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18409   "movsb"
18410   [(set_attr "type" "str")
18411    (set_attr "memory" "both")
18412    (set_attr "mode" "QI")])
18413
18414 (define_expand "rep_mov"
18415   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18416               (set (match_operand 0 "register_operand" "")
18417                    (match_operand 5 "" ""))
18418               (set (match_operand 2 "register_operand" "")
18419                    (match_operand 6 "" ""))
18420               (set (match_operand 1 "memory_operand" "")
18421                    (match_operand 3 "memory_operand" ""))
18422               (use (match_dup 4))])]
18423   ""
18424   "")
18425
18426 (define_insn "*rep_movdi_rex64"
18427   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18428    (set (match_operand:DI 0 "register_operand" "=D")
18429         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18430                             (const_int 3))
18431                  (match_operand:DI 3 "register_operand" "0")))
18432    (set (match_operand:DI 1 "register_operand" "=S")
18433         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18434                  (match_operand:DI 4 "register_operand" "1")))
18435    (set (mem:BLK (match_dup 3))
18436         (mem:BLK (match_dup 4)))
18437    (use (match_dup 5))]
18438   "TARGET_64BIT"
18439   "rep movsq"
18440   [(set_attr "type" "str")
18441    (set_attr "prefix_rep" "1")
18442    (set_attr "memory" "both")
18443    (set_attr "mode" "DI")])
18444
18445 (define_insn "*rep_movsi"
18446   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18447    (set (match_operand:SI 0 "register_operand" "=D")
18448         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18449                             (const_int 2))
18450                  (match_operand:SI 3 "register_operand" "0")))
18451    (set (match_operand:SI 1 "register_operand" "=S")
18452         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18453                  (match_operand:SI 4 "register_operand" "1")))
18454    (set (mem:BLK (match_dup 3))
18455         (mem:BLK (match_dup 4)))
18456    (use (match_dup 5))]
18457   "!TARGET_64BIT"
18458   "rep movs{l|d}"
18459   [(set_attr "type" "str")
18460    (set_attr "prefix_rep" "1")
18461    (set_attr "memory" "both")
18462    (set_attr "mode" "SI")])
18463
18464 (define_insn "*rep_movsi_rex64"
18465   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18466    (set (match_operand:DI 0 "register_operand" "=D")
18467         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18468                             (const_int 2))
18469                  (match_operand:DI 3 "register_operand" "0")))
18470    (set (match_operand:DI 1 "register_operand" "=S")
18471         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18472                  (match_operand:DI 4 "register_operand" "1")))
18473    (set (mem:BLK (match_dup 3))
18474         (mem:BLK (match_dup 4)))
18475    (use (match_dup 5))]
18476   "TARGET_64BIT"
18477   "rep movs{l|d}"
18478   [(set_attr "type" "str")
18479    (set_attr "prefix_rep" "1")
18480    (set_attr "memory" "both")
18481    (set_attr "mode" "SI")])
18482
18483 (define_insn "*rep_movqi"
18484   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18485    (set (match_operand:SI 0 "register_operand" "=D")
18486         (plus:SI (match_operand:SI 3 "register_operand" "0")
18487                  (match_operand:SI 5 "register_operand" "2")))
18488    (set (match_operand:SI 1 "register_operand" "=S")
18489         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18490    (set (mem:BLK (match_dup 3))
18491         (mem:BLK (match_dup 4)))
18492    (use (match_dup 5))]
18493   "!TARGET_64BIT"
18494   "rep movsb"
18495   [(set_attr "type" "str")
18496    (set_attr "prefix_rep" "1")
18497    (set_attr "memory" "both")
18498    (set_attr "mode" "SI")])
18499
18500 (define_insn "*rep_movqi_rex64"
18501   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18502    (set (match_operand:DI 0 "register_operand" "=D")
18503         (plus:DI (match_operand:DI 3 "register_operand" "0")
18504                  (match_operand:DI 5 "register_operand" "2")))
18505    (set (match_operand:DI 1 "register_operand" "=S")
18506         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18507    (set (mem:BLK (match_dup 3))
18508         (mem:BLK (match_dup 4)))
18509    (use (match_dup 5))]
18510   "TARGET_64BIT"
18511   "rep movsb"
18512   [(set_attr "type" "str")
18513    (set_attr "prefix_rep" "1")
18514    (set_attr "memory" "both")
18515    (set_attr "mode" "SI")])
18516
18517 (define_expand "setmemsi"
18518    [(use (match_operand:BLK 0 "memory_operand" ""))
18519     (use (match_operand:SI 1 "nonmemory_operand" ""))
18520     (use (match_operand 2 "const_int_operand" ""))
18521     (use (match_operand 3 "const_int_operand" ""))
18522     (use (match_operand:SI 4 "const_int_operand" ""))
18523     (use (match_operand:SI 5 "const_int_operand" ""))]
18524   ""
18525 {
18526  if (ix86_expand_setmem (operands[0], operands[1],
18527                          operands[2], operands[3],
18528                          operands[4], operands[5]))
18529    DONE;
18530  else
18531    FAIL;
18532 })
18533
18534 (define_expand "setmemdi"
18535    [(use (match_operand:BLK 0 "memory_operand" ""))
18536     (use (match_operand:DI 1 "nonmemory_operand" ""))
18537     (use (match_operand 2 "const_int_operand" ""))
18538     (use (match_operand 3 "const_int_operand" ""))
18539     (use (match_operand 4 "const_int_operand" ""))
18540     (use (match_operand 5 "const_int_operand" ""))]
18541   "TARGET_64BIT"
18542 {
18543  if (ix86_expand_setmem (operands[0], operands[1],
18544                          operands[2], operands[3],
18545                          operands[4], operands[5]))
18546    DONE;
18547  else
18548    FAIL;
18549 })
18550
18551 ;; Most CPUs don't like single string operations
18552 ;; Handle this case here to simplify previous expander.
18553
18554 (define_expand "strset"
18555   [(set (match_operand 1 "memory_operand" "")
18556         (match_operand 2 "register_operand" ""))
18557    (parallel [(set (match_operand 0 "register_operand" "")
18558                    (match_dup 3))
18559               (clobber (reg:CC FLAGS_REG))])]
18560   ""
18561 {
18562   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18563     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18564
18565   /* If .md ever supports :P for Pmode, this can be directly
18566      in the pattern above.  */
18567   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18568                               GEN_INT (GET_MODE_SIZE (GET_MODE
18569                                                       (operands[2]))));
18570   if (TARGET_SINGLE_STRINGOP || optimize_size)
18571     {
18572       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18573                                       operands[3]));
18574       DONE;
18575     }
18576 })
18577
18578 (define_expand "strset_singleop"
18579   [(parallel [(set (match_operand 1 "memory_operand" "")
18580                    (match_operand 2 "register_operand" ""))
18581               (set (match_operand 0 "register_operand" "")
18582                    (match_operand 3 "" ""))])]
18583   "TARGET_SINGLE_STRINGOP || optimize_size"
18584   "")
18585
18586 (define_insn "*strsetdi_rex_1"
18587   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18588         (match_operand:DI 2 "register_operand" "a"))
18589    (set (match_operand:DI 0 "register_operand" "=D")
18590         (plus:DI (match_dup 1)
18591                  (const_int 8)))]
18592   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18593   "stosq"
18594   [(set_attr "type" "str")
18595    (set_attr "memory" "store")
18596    (set_attr "mode" "DI")])
18597
18598 (define_insn "*strsetsi_1"
18599   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18600         (match_operand:SI 2 "register_operand" "a"))
18601    (set (match_operand:SI 0 "register_operand" "=D")
18602         (plus:SI (match_dup 1)
18603                  (const_int 4)))]
18604   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18605   "{stosl|stosd}"
18606   [(set_attr "type" "str")
18607    (set_attr "memory" "store")
18608    (set_attr "mode" "SI")])
18609
18610 (define_insn "*strsetsi_rex_1"
18611   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18612         (match_operand:SI 2 "register_operand" "a"))
18613    (set (match_operand:DI 0 "register_operand" "=D")
18614         (plus:DI (match_dup 1)
18615                  (const_int 4)))]
18616   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18617   "{stosl|stosd}"
18618   [(set_attr "type" "str")
18619    (set_attr "memory" "store")
18620    (set_attr "mode" "SI")])
18621
18622 (define_insn "*strsethi_1"
18623   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18624         (match_operand:HI 2 "register_operand" "a"))
18625    (set (match_operand:SI 0 "register_operand" "=D")
18626         (plus:SI (match_dup 1)
18627                  (const_int 2)))]
18628   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18629   "stosw"
18630   [(set_attr "type" "str")
18631    (set_attr "memory" "store")
18632    (set_attr "mode" "HI")])
18633
18634 (define_insn "*strsethi_rex_1"
18635   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18636         (match_operand:HI 2 "register_operand" "a"))
18637    (set (match_operand:DI 0 "register_operand" "=D")
18638         (plus:DI (match_dup 1)
18639                  (const_int 2)))]
18640   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18641   "stosw"
18642   [(set_attr "type" "str")
18643    (set_attr "memory" "store")
18644    (set_attr "mode" "HI")])
18645
18646 (define_insn "*strsetqi_1"
18647   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18648         (match_operand:QI 2 "register_operand" "a"))
18649    (set (match_operand:SI 0 "register_operand" "=D")
18650         (plus:SI (match_dup 1)
18651                  (const_int 1)))]
18652   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18653   "stosb"
18654   [(set_attr "type" "str")
18655    (set_attr "memory" "store")
18656    (set_attr "mode" "QI")])
18657
18658 (define_insn "*strsetqi_rex_1"
18659   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18660         (match_operand:QI 2 "register_operand" "a"))
18661    (set (match_operand:DI 0 "register_operand" "=D")
18662         (plus:DI (match_dup 1)
18663                  (const_int 1)))]
18664   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18665   "stosb"
18666   [(set_attr "type" "str")
18667    (set_attr "memory" "store")
18668    (set_attr "mode" "QI")])
18669
18670 (define_expand "rep_stos"
18671   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18672               (set (match_operand 0 "register_operand" "")
18673                    (match_operand 4 "" ""))
18674               (set (match_operand 2 "memory_operand" "") (const_int 0))
18675               (use (match_operand 3 "register_operand" ""))
18676               (use (match_dup 1))])]
18677   ""
18678   "")
18679
18680 (define_insn "*rep_stosdi_rex64"
18681   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18682    (set (match_operand:DI 0 "register_operand" "=D")
18683         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18684                             (const_int 3))
18685                  (match_operand:DI 3 "register_operand" "0")))
18686    (set (mem:BLK (match_dup 3))
18687         (const_int 0))
18688    (use (match_operand:DI 2 "register_operand" "a"))
18689    (use (match_dup 4))]
18690   "TARGET_64BIT"
18691   "rep stosq"
18692   [(set_attr "type" "str")
18693    (set_attr "prefix_rep" "1")
18694    (set_attr "memory" "store")
18695    (set_attr "mode" "DI")])
18696
18697 (define_insn "*rep_stossi"
18698   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18699    (set (match_operand:SI 0 "register_operand" "=D")
18700         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18701                             (const_int 2))
18702                  (match_operand:SI 3 "register_operand" "0")))
18703    (set (mem:BLK (match_dup 3))
18704         (const_int 0))
18705    (use (match_operand:SI 2 "register_operand" "a"))
18706    (use (match_dup 4))]
18707   "!TARGET_64BIT"
18708   "rep stos{l|d}"
18709   [(set_attr "type" "str")
18710    (set_attr "prefix_rep" "1")
18711    (set_attr "memory" "store")
18712    (set_attr "mode" "SI")])
18713
18714 (define_insn "*rep_stossi_rex64"
18715   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18716    (set (match_operand:DI 0 "register_operand" "=D")
18717         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18718                             (const_int 2))
18719                  (match_operand:DI 3 "register_operand" "0")))
18720    (set (mem:BLK (match_dup 3))
18721         (const_int 0))
18722    (use (match_operand:SI 2 "register_operand" "a"))
18723    (use (match_dup 4))]
18724   "TARGET_64BIT"
18725   "rep stos{l|d}"
18726   [(set_attr "type" "str")
18727    (set_attr "prefix_rep" "1")
18728    (set_attr "memory" "store")
18729    (set_attr "mode" "SI")])
18730
18731 (define_insn "*rep_stosqi"
18732   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18733    (set (match_operand:SI 0 "register_operand" "=D")
18734         (plus:SI (match_operand:SI 3 "register_operand" "0")
18735                  (match_operand:SI 4 "register_operand" "1")))
18736    (set (mem:BLK (match_dup 3))
18737         (const_int 0))
18738    (use (match_operand:QI 2 "register_operand" "a"))
18739    (use (match_dup 4))]
18740   "!TARGET_64BIT"
18741   "rep stosb"
18742   [(set_attr "type" "str")
18743    (set_attr "prefix_rep" "1")
18744    (set_attr "memory" "store")
18745    (set_attr "mode" "QI")])
18746
18747 (define_insn "*rep_stosqi_rex64"
18748   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18749    (set (match_operand:DI 0 "register_operand" "=D")
18750         (plus:DI (match_operand:DI 3 "register_operand" "0")
18751                  (match_operand:DI 4 "register_operand" "1")))
18752    (set (mem:BLK (match_dup 3))
18753         (const_int 0))
18754    (use (match_operand:QI 2 "register_operand" "a"))
18755    (use (match_dup 4))]
18756   "TARGET_64BIT"
18757   "rep stosb"
18758   [(set_attr "type" "str")
18759    (set_attr "prefix_rep" "1")
18760    (set_attr "memory" "store")
18761    (set_attr "mode" "QI")])
18762
18763 (define_expand "cmpstrnsi"
18764   [(set (match_operand:SI 0 "register_operand" "")
18765         (compare:SI (match_operand:BLK 1 "general_operand" "")
18766                     (match_operand:BLK 2 "general_operand" "")))
18767    (use (match_operand 3 "general_operand" ""))
18768    (use (match_operand 4 "immediate_operand" ""))]
18769   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18770 {
18771   rtx addr1, addr2, out, outlow, count, countreg, align;
18772
18773   /* Can't use this if the user has appropriated esi or edi.  */
18774   if (global_regs[4] || global_regs[5])
18775     FAIL;
18776
18777   out = operands[0];
18778   if (!REG_P (out))
18779     out = gen_reg_rtx (SImode);
18780
18781   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18782   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18783   if (addr1 != XEXP (operands[1], 0))
18784     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18785   if (addr2 != XEXP (operands[2], 0))
18786     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18787
18788   count = operands[3];
18789   countreg = ix86_zero_extend_to_Pmode (count);
18790
18791   /* %%% Iff we are testing strict equality, we can use known alignment
18792      to good advantage.  This may be possible with combine, particularly
18793      once cc0 is dead.  */
18794   align = operands[4];
18795
18796   if (CONST_INT_P (count))
18797     {
18798       if (INTVAL (count) == 0)
18799         {
18800           emit_move_insn (operands[0], const0_rtx);
18801           DONE;
18802         }
18803       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18804                                      operands[1], operands[2]));
18805     }
18806   else
18807     {
18808       if (TARGET_64BIT)
18809         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18810       else
18811         emit_insn (gen_cmpsi_1 (countreg, countreg));
18812       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18813                                   operands[1], operands[2]));
18814     }
18815
18816   outlow = gen_lowpart (QImode, out);
18817   emit_insn (gen_cmpintqi (outlow));
18818   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18819
18820   if (operands[0] != out)
18821     emit_move_insn (operands[0], out);
18822
18823   DONE;
18824 })
18825
18826 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18827
18828 (define_expand "cmpintqi"
18829   [(set (match_dup 1)
18830         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18831    (set (match_dup 2)
18832         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18833    (parallel [(set (match_operand:QI 0 "register_operand" "")
18834                    (minus:QI (match_dup 1)
18835                              (match_dup 2)))
18836               (clobber (reg:CC FLAGS_REG))])]
18837   ""
18838   "operands[1] = gen_reg_rtx (QImode);
18839    operands[2] = gen_reg_rtx (QImode);")
18840
18841 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18842 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18843
18844 (define_expand "cmpstrnqi_nz_1"
18845   [(parallel [(set (reg:CC FLAGS_REG)
18846                    (compare:CC (match_operand 4 "memory_operand" "")
18847                                (match_operand 5 "memory_operand" "")))
18848               (use (match_operand 2 "register_operand" ""))
18849               (use (match_operand:SI 3 "immediate_operand" ""))
18850               (clobber (match_operand 0 "register_operand" ""))
18851               (clobber (match_operand 1 "register_operand" ""))
18852               (clobber (match_dup 2))])]
18853   ""
18854   "")
18855
18856 (define_insn "*cmpstrnqi_nz_1"
18857   [(set (reg:CC FLAGS_REG)
18858         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18859                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18860    (use (match_operand:SI 6 "register_operand" "2"))
18861    (use (match_operand:SI 3 "immediate_operand" "i"))
18862    (clobber (match_operand:SI 0 "register_operand" "=S"))
18863    (clobber (match_operand:SI 1 "register_operand" "=D"))
18864    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18865   "!TARGET_64BIT"
18866   "repz cmpsb"
18867   [(set_attr "type" "str")
18868    (set_attr "mode" "QI")
18869    (set_attr "prefix_rep" "1")])
18870
18871 (define_insn "*cmpstrnqi_nz_rex_1"
18872   [(set (reg:CC FLAGS_REG)
18873         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18874                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18875    (use (match_operand:DI 6 "register_operand" "2"))
18876    (use (match_operand:SI 3 "immediate_operand" "i"))
18877    (clobber (match_operand:DI 0 "register_operand" "=S"))
18878    (clobber (match_operand:DI 1 "register_operand" "=D"))
18879    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18880   "TARGET_64BIT"
18881   "repz cmpsb"
18882   [(set_attr "type" "str")
18883    (set_attr "mode" "QI")
18884    (set_attr "prefix_rep" "1")])
18885
18886 ;; The same, but the count is not known to not be zero.
18887
18888 (define_expand "cmpstrnqi_1"
18889   [(parallel [(set (reg:CC FLAGS_REG)
18890                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18891                                      (const_int 0))
18892                   (compare:CC (match_operand 4 "memory_operand" "")
18893                               (match_operand 5 "memory_operand" ""))
18894                   (const_int 0)))
18895               (use (match_operand:SI 3 "immediate_operand" ""))
18896               (use (reg:CC FLAGS_REG))
18897               (clobber (match_operand 0 "register_operand" ""))
18898               (clobber (match_operand 1 "register_operand" ""))
18899               (clobber (match_dup 2))])]
18900   ""
18901   "")
18902
18903 (define_insn "*cmpstrnqi_1"
18904   [(set (reg:CC FLAGS_REG)
18905         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18906                              (const_int 0))
18907           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18908                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18909           (const_int 0)))
18910    (use (match_operand:SI 3 "immediate_operand" "i"))
18911    (use (reg:CC FLAGS_REG))
18912    (clobber (match_operand:SI 0 "register_operand" "=S"))
18913    (clobber (match_operand:SI 1 "register_operand" "=D"))
18914    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18915   "!TARGET_64BIT"
18916   "repz cmpsb"
18917   [(set_attr "type" "str")
18918    (set_attr "mode" "QI")
18919    (set_attr "prefix_rep" "1")])
18920
18921 (define_insn "*cmpstrnqi_rex_1"
18922   [(set (reg:CC FLAGS_REG)
18923         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18924                              (const_int 0))
18925           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18926                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18927           (const_int 0)))
18928    (use (match_operand:SI 3 "immediate_operand" "i"))
18929    (use (reg:CC FLAGS_REG))
18930    (clobber (match_operand:DI 0 "register_operand" "=S"))
18931    (clobber (match_operand:DI 1 "register_operand" "=D"))
18932    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18933   "TARGET_64BIT"
18934   "repz cmpsb"
18935   [(set_attr "type" "str")
18936    (set_attr "mode" "QI")
18937    (set_attr "prefix_rep" "1")])
18938
18939 (define_expand "strlensi"
18940   [(set (match_operand:SI 0 "register_operand" "")
18941         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18942                     (match_operand:QI 2 "immediate_operand" "")
18943                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18944   ""
18945 {
18946  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18947    DONE;
18948  else
18949    FAIL;
18950 })
18951
18952 (define_expand "strlendi"
18953   [(set (match_operand:DI 0 "register_operand" "")
18954         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18955                     (match_operand:QI 2 "immediate_operand" "")
18956                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18957   ""
18958 {
18959  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18960    DONE;
18961  else
18962    FAIL;
18963 })
18964
18965 (define_expand "strlenqi_1"
18966   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18967               (clobber (match_operand 1 "register_operand" ""))
18968               (clobber (reg:CC FLAGS_REG))])]
18969   ""
18970   "")
18971
18972 (define_insn "*strlenqi_1"
18973   [(set (match_operand:SI 0 "register_operand" "=&c")
18974         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18975                     (match_operand:QI 2 "register_operand" "a")
18976                     (match_operand:SI 3 "immediate_operand" "i")
18977                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18978    (clobber (match_operand:SI 1 "register_operand" "=D"))
18979    (clobber (reg:CC FLAGS_REG))]
18980   "!TARGET_64BIT"
18981   "repnz scasb"
18982   [(set_attr "type" "str")
18983    (set_attr "mode" "QI")
18984    (set_attr "prefix_rep" "1")])
18985
18986 (define_insn "*strlenqi_rex_1"
18987   [(set (match_operand:DI 0 "register_operand" "=&c")
18988         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18989                     (match_operand:QI 2 "register_operand" "a")
18990                     (match_operand:DI 3 "immediate_operand" "i")
18991                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18992    (clobber (match_operand:DI 1 "register_operand" "=D"))
18993    (clobber (reg:CC FLAGS_REG))]
18994   "TARGET_64BIT"
18995   "repnz scasb"
18996   [(set_attr "type" "str")
18997    (set_attr "mode" "QI")
18998    (set_attr "prefix_rep" "1")])
18999
19000 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19001 ;; handled in combine, but it is not currently up to the task.
19002 ;; When used for their truth value, the cmpstrn* expanders generate
19003 ;; code like this:
19004 ;;
19005 ;;   repz cmpsb
19006 ;;   seta       %al
19007 ;;   setb       %dl
19008 ;;   cmpb       %al, %dl
19009 ;;   jcc        label
19010 ;;
19011 ;; The intermediate three instructions are unnecessary.
19012
19013 ;; This one handles cmpstrn*_nz_1...
19014 (define_peephole2
19015   [(parallel[
19016      (set (reg:CC FLAGS_REG)
19017           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19018                       (mem:BLK (match_operand 5 "register_operand" ""))))
19019      (use (match_operand 6 "register_operand" ""))
19020      (use (match_operand:SI 3 "immediate_operand" ""))
19021      (clobber (match_operand 0 "register_operand" ""))
19022      (clobber (match_operand 1 "register_operand" ""))
19023      (clobber (match_operand 2 "register_operand" ""))])
19024    (set (match_operand:QI 7 "register_operand" "")
19025         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19026    (set (match_operand:QI 8 "register_operand" "")
19027         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19028    (set (reg FLAGS_REG)
19029         (compare (match_dup 7) (match_dup 8)))
19030   ]
19031   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19032   [(parallel[
19033      (set (reg:CC FLAGS_REG)
19034           (compare:CC (mem:BLK (match_dup 4))
19035                       (mem:BLK (match_dup 5))))
19036      (use (match_dup 6))
19037      (use (match_dup 3))
19038      (clobber (match_dup 0))
19039      (clobber (match_dup 1))
19040      (clobber (match_dup 2))])]
19041   "")
19042
19043 ;; ...and this one handles cmpstrn*_1.
19044 (define_peephole2
19045   [(parallel[
19046      (set (reg:CC FLAGS_REG)
19047           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19048                                (const_int 0))
19049             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19050                         (mem:BLK (match_operand 5 "register_operand" "")))
19051             (const_int 0)))
19052      (use (match_operand:SI 3 "immediate_operand" ""))
19053      (use (reg:CC FLAGS_REG))
19054      (clobber (match_operand 0 "register_operand" ""))
19055      (clobber (match_operand 1 "register_operand" ""))
19056      (clobber (match_operand 2 "register_operand" ""))])
19057    (set (match_operand:QI 7 "register_operand" "")
19058         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19059    (set (match_operand:QI 8 "register_operand" "")
19060         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19061    (set (reg FLAGS_REG)
19062         (compare (match_dup 7) (match_dup 8)))
19063   ]
19064   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19065   [(parallel[
19066      (set (reg:CC FLAGS_REG)
19067           (if_then_else:CC (ne (match_dup 6)
19068                                (const_int 0))
19069             (compare:CC (mem:BLK (match_dup 4))
19070                         (mem:BLK (match_dup 5)))
19071             (const_int 0)))
19072      (use (match_dup 3))
19073      (use (reg:CC FLAGS_REG))
19074      (clobber (match_dup 0))
19075      (clobber (match_dup 1))
19076      (clobber (match_dup 2))])]
19077   "")
19078
19079
19080 \f
19081 ;; Conditional move instructions.
19082
19083 (define_expand "movdicc"
19084   [(set (match_operand:DI 0 "register_operand" "")
19085         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19086                          (match_operand:DI 2 "general_operand" "")
19087                          (match_operand:DI 3 "general_operand" "")))]
19088   "TARGET_64BIT"
19089   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19090
19091 (define_insn "x86_movdicc_0_m1_rex64"
19092   [(set (match_operand:DI 0 "register_operand" "=r")
19093         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19094           (const_int -1)
19095           (const_int 0)))
19096    (clobber (reg:CC FLAGS_REG))]
19097   "TARGET_64BIT"
19098   "sbb{q}\t%0, %0"
19099   ; Since we don't have the proper number of operands for an alu insn,
19100   ; fill in all the blanks.
19101   [(set_attr "type" "alu")
19102    (set_attr "pent_pair" "pu")
19103    (set_attr "memory" "none")
19104    (set_attr "imm_disp" "false")
19105    (set_attr "mode" "DI")
19106    (set_attr "length_immediate" "0")])
19107
19108 (define_insn "*movdicc_c_rex64"
19109   [(set (match_operand:DI 0 "register_operand" "=r,r")
19110         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19111                                 [(reg FLAGS_REG) (const_int 0)])
19112                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19113                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19114   "TARGET_64BIT && TARGET_CMOVE
19115    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19116   "@
19117    cmov%O2%C1\t{%2, %0|%0, %2}
19118    cmov%O2%c1\t{%3, %0|%0, %3}"
19119   [(set_attr "type" "icmov")
19120    (set_attr "mode" "DI")])
19121
19122 (define_expand "movsicc"
19123   [(set (match_operand:SI 0 "register_operand" "")
19124         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19125                          (match_operand:SI 2 "general_operand" "")
19126                          (match_operand:SI 3 "general_operand" "")))]
19127   ""
19128   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19129
19130 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19131 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19132 ;; So just document what we're doing explicitly.
19133
19134 (define_insn "x86_movsicc_0_m1"
19135   [(set (match_operand:SI 0 "register_operand" "=r")
19136         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19137           (const_int -1)
19138           (const_int 0)))
19139    (clobber (reg:CC FLAGS_REG))]
19140   ""
19141   "sbb{l}\t%0, %0"
19142   ; Since we don't have the proper number of operands for an alu insn,
19143   ; fill in all the blanks.
19144   [(set_attr "type" "alu")
19145    (set_attr "pent_pair" "pu")
19146    (set_attr "memory" "none")
19147    (set_attr "imm_disp" "false")
19148    (set_attr "mode" "SI")
19149    (set_attr "length_immediate" "0")])
19150
19151 (define_insn "*movsicc_noc"
19152   [(set (match_operand:SI 0 "register_operand" "=r,r")
19153         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19154                                 [(reg FLAGS_REG) (const_int 0)])
19155                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19156                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19157   "TARGET_CMOVE
19158    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19159   "@
19160    cmov%O2%C1\t{%2, %0|%0, %2}
19161    cmov%O2%c1\t{%3, %0|%0, %3}"
19162   [(set_attr "type" "icmov")
19163    (set_attr "mode" "SI")])
19164
19165 (define_expand "movhicc"
19166   [(set (match_operand:HI 0 "register_operand" "")
19167         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19168                          (match_operand:HI 2 "general_operand" "")
19169                          (match_operand:HI 3 "general_operand" "")))]
19170   "TARGET_HIMODE_MATH"
19171   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19172
19173 (define_insn "*movhicc_noc"
19174   [(set (match_operand:HI 0 "register_operand" "=r,r")
19175         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19176                                 [(reg FLAGS_REG) (const_int 0)])
19177                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19178                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19179   "TARGET_CMOVE
19180    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19181   "@
19182    cmov%O2%C1\t{%2, %0|%0, %2}
19183    cmov%O2%c1\t{%3, %0|%0, %3}"
19184   [(set_attr "type" "icmov")
19185    (set_attr "mode" "HI")])
19186
19187 (define_expand "movqicc"
19188   [(set (match_operand:QI 0 "register_operand" "")
19189         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19190                          (match_operand:QI 2 "general_operand" "")
19191                          (match_operand:QI 3 "general_operand" "")))]
19192   "TARGET_QIMODE_MATH"
19193   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19194
19195 (define_insn_and_split "*movqicc_noc"
19196   [(set (match_operand:QI 0 "register_operand" "=r,r")
19197         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19198                                 [(match_operand 4 "flags_reg_operand" "")
19199                                  (const_int 0)])
19200                       (match_operand:QI 2 "register_operand" "r,0")
19201                       (match_operand:QI 3 "register_operand" "0,r")))]
19202   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19203   "#"
19204   "&& reload_completed"
19205   [(set (match_dup 0)
19206         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19207                       (match_dup 2)
19208                       (match_dup 3)))]
19209   "operands[0] = gen_lowpart (SImode, operands[0]);
19210    operands[2] = gen_lowpart (SImode, operands[2]);
19211    operands[3] = gen_lowpart (SImode, operands[3]);"
19212   [(set_attr "type" "icmov")
19213    (set_attr "mode" "SI")])
19214
19215 (define_expand "movsfcc"
19216   [(set (match_operand:SF 0 "register_operand" "")
19217         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19218                          (match_operand:SF 2 "register_operand" "")
19219                          (match_operand:SF 3 "register_operand" "")))]
19220   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19221   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19222
19223 (define_insn "*movsfcc_1_387"
19224   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19225         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19226                                 [(reg FLAGS_REG) (const_int 0)])
19227                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19228                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19229   "TARGET_80387 && TARGET_CMOVE
19230    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19231   "@
19232    fcmov%F1\t{%2, %0|%0, %2}
19233    fcmov%f1\t{%3, %0|%0, %3}
19234    cmov%O2%C1\t{%2, %0|%0, %2}
19235    cmov%O2%c1\t{%3, %0|%0, %3}"
19236   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19237    (set_attr "mode" "SF,SF,SI,SI")])
19238
19239 (define_expand "movdfcc"
19240   [(set (match_operand:DF 0 "register_operand" "")
19241         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19242                          (match_operand:DF 2 "register_operand" "")
19243                          (match_operand:DF 3 "register_operand" "")))]
19244   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19245   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19246
19247 (define_insn "*movdfcc_1"
19248   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19249         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19250                                 [(reg FLAGS_REG) (const_int 0)])
19251                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19252                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19253   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19254    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19255   "@
19256    fcmov%F1\t{%2, %0|%0, %2}
19257    fcmov%f1\t{%3, %0|%0, %3}
19258    #
19259    #"
19260   [(set_attr "type" "fcmov,fcmov,multi,multi")
19261    (set_attr "mode" "DF")])
19262
19263 (define_insn "*movdfcc_1_rex64"
19264   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19265         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19266                                 [(reg FLAGS_REG) (const_int 0)])
19267                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19268                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19269   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19270    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19271   "@
19272    fcmov%F1\t{%2, %0|%0, %2}
19273    fcmov%f1\t{%3, %0|%0, %3}
19274    cmov%O2%C1\t{%2, %0|%0, %2}
19275    cmov%O2%c1\t{%3, %0|%0, %3}"
19276   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19277    (set_attr "mode" "DF")])
19278
19279 (define_split
19280   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19281         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19282                                 [(match_operand 4 "flags_reg_operand" "")
19283                                  (const_int 0)])
19284                       (match_operand:DF 2 "nonimmediate_operand" "")
19285                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19286   "!TARGET_64BIT && reload_completed"
19287   [(set (match_dup 2)
19288         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19289                       (match_dup 5)
19290                       (match_dup 7)))
19291    (set (match_dup 3)
19292         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19293                       (match_dup 6)
19294                       (match_dup 8)))]
19295   "split_di (operands+2, 1, operands+5, operands+6);
19296    split_di (operands+3, 1, operands+7, operands+8);
19297    split_di (operands, 1, operands+2, operands+3);")
19298
19299 (define_expand "movxfcc"
19300   [(set (match_operand:XF 0 "register_operand" "")
19301         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19302                          (match_operand:XF 2 "register_operand" "")
19303                          (match_operand:XF 3 "register_operand" "")))]
19304   "TARGET_80387 && TARGET_CMOVE"
19305   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19306
19307 (define_insn "*movxfcc_1"
19308   [(set (match_operand:XF 0 "register_operand" "=f,f")
19309         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19310                                 [(reg FLAGS_REG) (const_int 0)])
19311                       (match_operand:XF 2 "register_operand" "f,0")
19312                       (match_operand:XF 3 "register_operand" "0,f")))]
19313   "TARGET_80387 && TARGET_CMOVE"
19314   "@
19315    fcmov%F1\t{%2, %0|%0, %2}
19316    fcmov%f1\t{%3, %0|%0, %3}"
19317   [(set_attr "type" "fcmov")
19318    (set_attr "mode" "XF")])
19319
19320 ;; These versions of the min/max patterns are intentionally ignorant of
19321 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19322 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19323 ;; are undefined in this condition, we're certain this is correct.
19324
19325 (define_insn "sminsf3"
19326   [(set (match_operand:SF 0 "register_operand" "=x")
19327         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19328                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19329   "TARGET_SSE_MATH"
19330   "minss\t{%2, %0|%0, %2}"
19331   [(set_attr "type" "sseadd")
19332    (set_attr "mode" "SF")])
19333
19334 (define_insn "smaxsf3"
19335   [(set (match_operand:SF 0 "register_operand" "=x")
19336         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19337                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19338   "TARGET_SSE_MATH"
19339   "maxss\t{%2, %0|%0, %2}"
19340   [(set_attr "type" "sseadd")
19341    (set_attr "mode" "SF")])
19342
19343 (define_insn "smindf3"
19344   [(set (match_operand:DF 0 "register_operand" "=x")
19345         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19346                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19347   "TARGET_SSE2 && TARGET_SSE_MATH"
19348   "minsd\t{%2, %0|%0, %2}"
19349   [(set_attr "type" "sseadd")
19350    (set_attr "mode" "DF")])
19351
19352 (define_insn "smaxdf3"
19353   [(set (match_operand:DF 0 "register_operand" "=x")
19354         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19355                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19356   "TARGET_SSE2 && TARGET_SSE_MATH"
19357   "maxsd\t{%2, %0|%0, %2}"
19358   [(set_attr "type" "sseadd")
19359    (set_attr "mode" "DF")])
19360
19361 ;; These versions of the min/max patterns implement exactly the operations
19362 ;;   min = (op1 < op2 ? op1 : op2)
19363 ;;   max = (!(op1 < op2) ? op1 : op2)
19364 ;; Their operands are not commutative, and thus they may be used in the
19365 ;; presence of -0.0 and NaN.
19366
19367 (define_insn "*ieee_sminsf3"
19368   [(set (match_operand:SF 0 "register_operand" "=x")
19369         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19370                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19371                    UNSPEC_IEEE_MIN))]
19372   "TARGET_SSE_MATH"
19373   "minss\t{%2, %0|%0, %2}"
19374   [(set_attr "type" "sseadd")
19375    (set_attr "mode" "SF")])
19376
19377 (define_insn "*ieee_smaxsf3"
19378   [(set (match_operand:SF 0 "register_operand" "=x")
19379         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19380                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19381                    UNSPEC_IEEE_MAX))]
19382   "TARGET_SSE_MATH"
19383   "maxss\t{%2, %0|%0, %2}"
19384   [(set_attr "type" "sseadd")
19385    (set_attr "mode" "SF")])
19386
19387 (define_insn "*ieee_smindf3"
19388   [(set (match_operand:DF 0 "register_operand" "=x")
19389         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19390                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19391                    UNSPEC_IEEE_MIN))]
19392   "TARGET_SSE2 && TARGET_SSE_MATH"
19393   "minsd\t{%2, %0|%0, %2}"
19394   [(set_attr "type" "sseadd")
19395    (set_attr "mode" "DF")])
19396
19397 (define_insn "*ieee_smaxdf3"
19398   [(set (match_operand:DF 0 "register_operand" "=x")
19399         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19400                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19401                    UNSPEC_IEEE_MAX))]
19402   "TARGET_SSE2 && TARGET_SSE_MATH"
19403   "maxsd\t{%2, %0|%0, %2}"
19404   [(set_attr "type" "sseadd")
19405    (set_attr "mode" "DF")])
19406
19407 ;; Make two stack loads independent:
19408 ;;   fld aa              fld aa
19409 ;;   fld %st(0)     ->   fld bb
19410 ;;   fmul bb             fmul %st(1), %st
19411 ;;
19412 ;; Actually we only match the last two instructions for simplicity.
19413 (define_peephole2
19414   [(set (match_operand 0 "fp_register_operand" "")
19415         (match_operand 1 "fp_register_operand" ""))
19416    (set (match_dup 0)
19417         (match_operator 2 "binary_fp_operator"
19418            [(match_dup 0)
19419             (match_operand 3 "memory_operand" "")]))]
19420   "REGNO (operands[0]) != REGNO (operands[1])"
19421   [(set (match_dup 0) (match_dup 3))
19422    (set (match_dup 0) (match_dup 4))]
19423
19424   ;; The % modifier is not operational anymore in peephole2's, so we have to
19425   ;; swap the operands manually in the case of addition and multiplication.
19426   "if (COMMUTATIVE_ARITH_P (operands[2]))
19427      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19428                                  operands[0], operands[1]);
19429    else
19430      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19431                                  operands[1], operands[0]);")
19432
19433 ;; Conditional addition patterns
19434 (define_expand "addqicc"
19435   [(match_operand:QI 0 "register_operand" "")
19436    (match_operand 1 "comparison_operator" "")
19437    (match_operand:QI 2 "register_operand" "")
19438    (match_operand:QI 3 "const_int_operand" "")]
19439   ""
19440   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19441
19442 (define_expand "addhicc"
19443   [(match_operand:HI 0 "register_operand" "")
19444    (match_operand 1 "comparison_operator" "")
19445    (match_operand:HI 2 "register_operand" "")
19446    (match_operand:HI 3 "const_int_operand" "")]
19447   ""
19448   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19449
19450 (define_expand "addsicc"
19451   [(match_operand:SI 0 "register_operand" "")
19452    (match_operand 1 "comparison_operator" "")
19453    (match_operand:SI 2 "register_operand" "")
19454    (match_operand:SI 3 "const_int_operand" "")]
19455   ""
19456   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19457
19458 (define_expand "adddicc"
19459   [(match_operand:DI 0 "register_operand" "")
19460    (match_operand 1 "comparison_operator" "")
19461    (match_operand:DI 2 "register_operand" "")
19462    (match_operand:DI 3 "const_int_operand" "")]
19463   "TARGET_64BIT"
19464   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19465
19466 \f
19467 ;; Misc patterns (?)
19468
19469 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19470 ;; Otherwise there will be nothing to keep
19471 ;;
19472 ;; [(set (reg ebp) (reg esp))]
19473 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19474 ;;  (clobber (eflags)]
19475 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19476 ;;
19477 ;; in proper program order.
19478 (define_insn "pro_epilogue_adjust_stack_1"
19479   [(set (match_operand:SI 0 "register_operand" "=r,r")
19480         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19481                  (match_operand:SI 2 "immediate_operand" "i,i")))
19482    (clobber (reg:CC FLAGS_REG))
19483    (clobber (mem:BLK (scratch)))]
19484   "!TARGET_64BIT"
19485 {
19486   switch (get_attr_type (insn))
19487     {
19488     case TYPE_IMOV:
19489       return "mov{l}\t{%1, %0|%0, %1}";
19490
19491     case TYPE_ALU:
19492       if (CONST_INT_P (operands[2])
19493           && (INTVAL (operands[2]) == 128
19494               || (INTVAL (operands[2]) < 0
19495                   && INTVAL (operands[2]) != -128)))
19496         {
19497           operands[2] = GEN_INT (-INTVAL (operands[2]));
19498           return "sub{l}\t{%2, %0|%0, %2}";
19499         }
19500       return "add{l}\t{%2, %0|%0, %2}";
19501
19502     case TYPE_LEA:
19503       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19504       return "lea{l}\t{%a2, %0|%0, %a2}";
19505
19506     default:
19507       gcc_unreachable ();
19508     }
19509 }
19510   [(set (attr "type")
19511         (cond [(eq_attr "alternative" "0")
19512                  (const_string "alu")
19513                (match_operand:SI 2 "const0_operand" "")
19514                  (const_string "imov")
19515               ]
19516               (const_string "lea")))
19517    (set_attr "mode" "SI")])
19518
19519 (define_insn "pro_epilogue_adjust_stack_rex64"
19520   [(set (match_operand:DI 0 "register_operand" "=r,r")
19521         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19522                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19523    (clobber (reg:CC FLAGS_REG))
19524    (clobber (mem:BLK (scratch)))]
19525   "TARGET_64BIT"
19526 {
19527   switch (get_attr_type (insn))
19528     {
19529     case TYPE_IMOV:
19530       return "mov{q}\t{%1, %0|%0, %1}";
19531
19532     case TYPE_ALU:
19533       if (CONST_INT_P (operands[2])
19534           /* Avoid overflows.  */
19535           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19536           && (INTVAL (operands[2]) == 128
19537               || (INTVAL (operands[2]) < 0
19538                   && INTVAL (operands[2]) != -128)))
19539         {
19540           operands[2] = GEN_INT (-INTVAL (operands[2]));
19541           return "sub{q}\t{%2, %0|%0, %2}";
19542         }
19543       return "add{q}\t{%2, %0|%0, %2}";
19544
19545     case TYPE_LEA:
19546       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19547       return "lea{q}\t{%a2, %0|%0, %a2}";
19548
19549     default:
19550       gcc_unreachable ();
19551     }
19552 }
19553   [(set (attr "type")
19554         (cond [(eq_attr "alternative" "0")
19555                  (const_string "alu")
19556                (match_operand:DI 2 "const0_operand" "")
19557                  (const_string "imov")
19558               ]
19559               (const_string "lea")))
19560    (set_attr "mode" "DI")])
19561
19562 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19563   [(set (match_operand:DI 0 "register_operand" "=r,r")
19564         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19565                  (match_operand:DI 3 "immediate_operand" "i,i")))
19566    (use (match_operand:DI 2 "register_operand" "r,r"))
19567    (clobber (reg:CC FLAGS_REG))
19568    (clobber (mem:BLK (scratch)))]
19569   "TARGET_64BIT"
19570 {
19571   switch (get_attr_type (insn))
19572     {
19573     case TYPE_ALU:
19574       return "add{q}\t{%2, %0|%0, %2}";
19575
19576     case TYPE_LEA:
19577       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19578       return "lea{q}\t{%a2, %0|%0, %a2}";
19579
19580     default:
19581       gcc_unreachable ();
19582     }
19583 }
19584   [(set_attr "type" "alu,lea")
19585    (set_attr "mode" "DI")])
19586
19587 (define_insn "allocate_stack_worker_32"
19588   [(set (match_operand:SI 0 "register_operand" "+a")
19589         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19590    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19591    (clobber (reg:CC FLAGS_REG))]
19592   "!TARGET_64BIT && TARGET_STACK_PROBE"
19593   "call\t__alloca"
19594   [(set_attr "type" "multi")
19595    (set_attr "length" "5")])
19596
19597 (define_insn "allocate_stack_worker_64"
19598   [(set (match_operand:DI 0 "register_operand" "=a")
19599         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19600    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19601    (clobber (reg:DI R10_REG))
19602    (clobber (reg:DI R11_REG))
19603    (clobber (reg:CC FLAGS_REG))]
19604   "TARGET_64BIT && TARGET_STACK_PROBE"
19605   "call\t___chkstk"
19606   [(set_attr "type" "multi")
19607    (set_attr "length" "5")])
19608
19609 (define_expand "allocate_stack"
19610   [(match_operand 0 "register_operand" "")
19611    (match_operand 1 "general_operand" "")]
19612   "TARGET_STACK_PROBE"
19613 {
19614   rtx x;
19615
19616 #ifndef CHECK_STACK_LIMIT
19617 #define CHECK_STACK_LIMIT 0
19618 #endif
19619
19620   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19621       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19622     {
19623       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19624                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19625       if (x != stack_pointer_rtx)
19626         emit_move_insn (stack_pointer_rtx, x);
19627     }
19628   else
19629     {
19630       x = copy_to_mode_reg (Pmode, operands[1]);
19631       if (TARGET_64BIT)
19632         x = gen_allocate_stack_worker_64 (x);
19633       else
19634         x = gen_allocate_stack_worker_32 (x);
19635       emit_insn (x);
19636     }
19637
19638   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19639   DONE;
19640 })
19641
19642 (define_expand "builtin_setjmp_receiver"
19643   [(label_ref (match_operand 0 "" ""))]
19644   "!TARGET_64BIT && flag_pic"
19645 {
19646   if (TARGET_MACHO)
19647     {
19648       rtx xops[3];
19649       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19650       rtx label_rtx = gen_label_rtx ();
19651       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19652       xops[0] = xops[1] = picreg;
19653       xops[2] = gen_rtx_CONST (SImode,
19654                   gen_rtx_MINUS (SImode,
19655                     gen_rtx_LABEL_REF (SImode, label_rtx),
19656                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19657       ix86_expand_binary_operator (MINUS, SImode, xops);
19658     }
19659   else
19660     emit_insn (gen_set_got (pic_offset_table_rtx));
19661   DONE;
19662 })
19663 \f
19664 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19665
19666 (define_split
19667   [(set (match_operand 0 "register_operand" "")
19668         (match_operator 3 "promotable_binary_operator"
19669            [(match_operand 1 "register_operand" "")
19670             (match_operand 2 "aligned_operand" "")]))
19671    (clobber (reg:CC FLAGS_REG))]
19672   "! TARGET_PARTIAL_REG_STALL && reload_completed
19673    && ((GET_MODE (operands[0]) == HImode
19674         && ((!optimize_size && !TARGET_FAST_PREFIX)
19675             /* ??? next two lines just !satisfies_constraint_K (...) */
19676             || !CONST_INT_P (operands[2])
19677             || satisfies_constraint_K (operands[2])))
19678        || (GET_MODE (operands[0]) == QImode
19679            && (TARGET_PROMOTE_QImode || optimize_size)))"
19680   [(parallel [(set (match_dup 0)
19681                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19682               (clobber (reg:CC FLAGS_REG))])]
19683   "operands[0] = gen_lowpart (SImode, operands[0]);
19684    operands[1] = gen_lowpart (SImode, operands[1]);
19685    if (GET_CODE (operands[3]) != ASHIFT)
19686      operands[2] = gen_lowpart (SImode, operands[2]);
19687    PUT_MODE (operands[3], SImode);")
19688
19689 ; Promote the QImode tests, as i386 has encoding of the AND
19690 ; instruction with 32-bit sign-extended immediate and thus the
19691 ; instruction size is unchanged, except in the %eax case for
19692 ; which it is increased by one byte, hence the ! optimize_size.
19693 (define_split
19694   [(set (match_operand 0 "flags_reg_operand" "")
19695         (match_operator 2 "compare_operator"
19696           [(and (match_operand 3 "aligned_operand" "")
19697                 (match_operand 4 "const_int_operand" ""))
19698            (const_int 0)]))
19699    (set (match_operand 1 "register_operand" "")
19700         (and (match_dup 3) (match_dup 4)))]
19701   "! TARGET_PARTIAL_REG_STALL && reload_completed
19702    && ! optimize_size
19703    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19704        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19705    /* Ensure that the operand will remain sign-extended immediate.  */
19706    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19707   [(parallel [(set (match_dup 0)
19708                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19709                                     (const_int 0)]))
19710               (set (match_dup 1)
19711                    (and:SI (match_dup 3) (match_dup 4)))])]
19712 {
19713   operands[4]
19714     = gen_int_mode (INTVAL (operands[4])
19715                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19716   operands[1] = gen_lowpart (SImode, operands[1]);
19717   operands[3] = gen_lowpart (SImode, operands[3]);
19718 })
19719
19720 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19721 ; the TEST instruction with 32-bit sign-extended immediate and thus
19722 ; the instruction size would at least double, which is not what we
19723 ; want even with ! optimize_size.
19724 (define_split
19725   [(set (match_operand 0 "flags_reg_operand" "")
19726         (match_operator 1 "compare_operator"
19727           [(and (match_operand:HI 2 "aligned_operand" "")
19728                 (match_operand:HI 3 "const_int_operand" ""))
19729            (const_int 0)]))]
19730   "! TARGET_PARTIAL_REG_STALL && reload_completed
19731    && ! TARGET_FAST_PREFIX
19732    && ! optimize_size
19733    /* Ensure that the operand will remain sign-extended immediate.  */
19734    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19735   [(set (match_dup 0)
19736         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19737                          (const_int 0)]))]
19738 {
19739   operands[3]
19740     = gen_int_mode (INTVAL (operands[3])
19741                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19742   operands[2] = gen_lowpart (SImode, operands[2]);
19743 })
19744
19745 (define_split
19746   [(set (match_operand 0 "register_operand" "")
19747         (neg (match_operand 1 "register_operand" "")))
19748    (clobber (reg:CC FLAGS_REG))]
19749   "! TARGET_PARTIAL_REG_STALL && reload_completed
19750    && (GET_MODE (operands[0]) == HImode
19751        || (GET_MODE (operands[0]) == QImode
19752            && (TARGET_PROMOTE_QImode || optimize_size)))"
19753   [(parallel [(set (match_dup 0)
19754                    (neg:SI (match_dup 1)))
19755               (clobber (reg:CC FLAGS_REG))])]
19756   "operands[0] = gen_lowpart (SImode, operands[0]);
19757    operands[1] = gen_lowpart (SImode, operands[1]);")
19758
19759 (define_split
19760   [(set (match_operand 0 "register_operand" "")
19761         (not (match_operand 1 "register_operand" "")))]
19762   "! TARGET_PARTIAL_REG_STALL && reload_completed
19763    && (GET_MODE (operands[0]) == HImode
19764        || (GET_MODE (operands[0]) == QImode
19765            && (TARGET_PROMOTE_QImode || optimize_size)))"
19766   [(set (match_dup 0)
19767         (not:SI (match_dup 1)))]
19768   "operands[0] = gen_lowpart (SImode, operands[0]);
19769    operands[1] = gen_lowpart (SImode, operands[1]);")
19770
19771 (define_split
19772   [(set (match_operand 0 "register_operand" "")
19773         (if_then_else (match_operator 1 "comparison_operator"
19774                                 [(reg FLAGS_REG) (const_int 0)])
19775                       (match_operand 2 "register_operand" "")
19776                       (match_operand 3 "register_operand" "")))]
19777   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19778    && (GET_MODE (operands[0]) == HImode
19779        || (GET_MODE (operands[0]) == QImode
19780            && (TARGET_PROMOTE_QImode || optimize_size)))"
19781   [(set (match_dup 0)
19782         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19783   "operands[0] = gen_lowpart (SImode, operands[0]);
19784    operands[2] = gen_lowpart (SImode, operands[2]);
19785    operands[3] = gen_lowpart (SImode, operands[3]);")
19786
19787 \f
19788 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19789 ;; transform a complex memory operation into two memory to register operations.
19790
19791 ;; Don't push memory operands
19792 (define_peephole2
19793   [(set (match_operand:SI 0 "push_operand" "")
19794         (match_operand:SI 1 "memory_operand" ""))
19795    (match_scratch:SI 2 "r")]
19796   "!optimize_size && !TARGET_PUSH_MEMORY
19797    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19798   [(set (match_dup 2) (match_dup 1))
19799    (set (match_dup 0) (match_dup 2))]
19800   "")
19801
19802 (define_peephole2
19803   [(set (match_operand:DI 0 "push_operand" "")
19804         (match_operand:DI 1 "memory_operand" ""))
19805    (match_scratch:DI 2 "r")]
19806   "!optimize_size && !TARGET_PUSH_MEMORY
19807    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19808   [(set (match_dup 2) (match_dup 1))
19809    (set (match_dup 0) (match_dup 2))]
19810   "")
19811
19812 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19813 ;; SImode pushes.
19814 (define_peephole2
19815   [(set (match_operand:SF 0 "push_operand" "")
19816         (match_operand:SF 1 "memory_operand" ""))
19817    (match_scratch:SF 2 "r")]
19818   "!optimize_size && !TARGET_PUSH_MEMORY
19819    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19820   [(set (match_dup 2) (match_dup 1))
19821    (set (match_dup 0) (match_dup 2))]
19822   "")
19823
19824 (define_peephole2
19825   [(set (match_operand:HI 0 "push_operand" "")
19826         (match_operand:HI 1 "memory_operand" ""))
19827    (match_scratch:HI 2 "r")]
19828   "!optimize_size && !TARGET_PUSH_MEMORY
19829    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19830   [(set (match_dup 2) (match_dup 1))
19831    (set (match_dup 0) (match_dup 2))]
19832   "")
19833
19834 (define_peephole2
19835   [(set (match_operand:QI 0 "push_operand" "")
19836         (match_operand:QI 1 "memory_operand" ""))
19837    (match_scratch:QI 2 "q")]
19838   "!optimize_size && !TARGET_PUSH_MEMORY
19839    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19840   [(set (match_dup 2) (match_dup 1))
19841    (set (match_dup 0) (match_dup 2))]
19842   "")
19843
19844 ;; Don't move an immediate directly to memory when the instruction
19845 ;; gets too big.
19846 (define_peephole2
19847   [(match_scratch:SI 1 "r")
19848    (set (match_operand:SI 0 "memory_operand" "")
19849         (const_int 0))]
19850   "! optimize_size
19851    && ! TARGET_USE_MOV0
19852    && TARGET_SPLIT_LONG_MOVES
19853    && get_attr_length (insn) >= ix86_cost->large_insn
19854    && peep2_regno_dead_p (0, FLAGS_REG)"
19855   [(parallel [(set (match_dup 1) (const_int 0))
19856               (clobber (reg:CC FLAGS_REG))])
19857    (set (match_dup 0) (match_dup 1))]
19858   "")
19859
19860 (define_peephole2
19861   [(match_scratch:HI 1 "r")
19862    (set (match_operand:HI 0 "memory_operand" "")
19863         (const_int 0))]
19864   "! optimize_size
19865    && ! TARGET_USE_MOV0
19866    && TARGET_SPLIT_LONG_MOVES
19867    && get_attr_length (insn) >= ix86_cost->large_insn
19868    && peep2_regno_dead_p (0, FLAGS_REG)"
19869   [(parallel [(set (match_dup 2) (const_int 0))
19870               (clobber (reg:CC FLAGS_REG))])
19871    (set (match_dup 0) (match_dup 1))]
19872   "operands[2] = gen_lowpart (SImode, operands[1]);")
19873
19874 (define_peephole2
19875   [(match_scratch:QI 1 "q")
19876    (set (match_operand:QI 0 "memory_operand" "")
19877         (const_int 0))]
19878   "! optimize_size
19879    && ! TARGET_USE_MOV0
19880    && TARGET_SPLIT_LONG_MOVES
19881    && get_attr_length (insn) >= ix86_cost->large_insn
19882    && peep2_regno_dead_p (0, FLAGS_REG)"
19883   [(parallel [(set (match_dup 2) (const_int 0))
19884               (clobber (reg:CC FLAGS_REG))])
19885    (set (match_dup 0) (match_dup 1))]
19886   "operands[2] = gen_lowpart (SImode, operands[1]);")
19887
19888 (define_peephole2
19889   [(match_scratch:SI 2 "r")
19890    (set (match_operand:SI 0 "memory_operand" "")
19891         (match_operand:SI 1 "immediate_operand" ""))]
19892   "! optimize_size
19893    && TARGET_SPLIT_LONG_MOVES
19894    && get_attr_length (insn) >= ix86_cost->large_insn"
19895   [(set (match_dup 2) (match_dup 1))
19896    (set (match_dup 0) (match_dup 2))]
19897   "")
19898
19899 (define_peephole2
19900   [(match_scratch:HI 2 "r")
19901    (set (match_operand:HI 0 "memory_operand" "")
19902         (match_operand:HI 1 "immediate_operand" ""))]
19903   "! optimize_size
19904    && TARGET_SPLIT_LONG_MOVES
19905    && get_attr_length (insn) >= ix86_cost->large_insn"
19906   [(set (match_dup 2) (match_dup 1))
19907    (set (match_dup 0) (match_dup 2))]
19908   "")
19909
19910 (define_peephole2
19911   [(match_scratch:QI 2 "q")
19912    (set (match_operand:QI 0 "memory_operand" "")
19913         (match_operand:QI 1 "immediate_operand" ""))]
19914   "! optimize_size
19915    && TARGET_SPLIT_LONG_MOVES
19916    && get_attr_length (insn) >= ix86_cost->large_insn"
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   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
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    && ((TARGET_NOT_UNPAIRABLE
19949         && (!MEM_P (operands[0])
19950             || !memory_displacement_operand (operands[0], SImode)))
19951        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19952    && peep2_regno_dead_p (0, FLAGS_REG)"
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    && ((TARGET_NOT_UNPAIRABLE
19963         && (!MEM_P (operands[0])
19964             || !memory_displacement_operand (operands[0], HImode)))
19965        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19966    && peep2_regno_dead_p (0, FLAGS_REG)"
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    && ((TARGET_NOT_UNPAIRABLE
19977         && (!MEM_P (operands[0])
19978             || !memory_displacement_operand (operands[0], QImode)))
19979        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19980    && peep2_regno_dead_p (0, FLAGS_REG)"
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_MOVE_M1_VIA_OR)
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_SLOW_IMUL_IMM32_MEM && !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_SLOW_IMUL_IMM32_MEM && !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_SLOW_IMUL_IMM32_MEM && !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_SLOW_IMUL_IMM8 && !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_SLOW_IMUL_IMM8 && !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_SLOW_IMUL_IMM8 && !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    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20805 {
20806   if (constant_call_address_operand (operands[1], Pmode))
20807     return "call\t%P1";
20808   return "call\t%A1";
20809 }
20810   [(set_attr "type" "callv")])
20811
20812 (define_insn "*call_value_1_rex64_large"
20813   [(set (match_operand 0 "" "")
20814         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20815               (match_operand:DI 2 "" "")))]
20816   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20817   "call\t%A1"
20818   [(set_attr "type" "callv")])
20819
20820 (define_insn "*sibcall_value_1_rex64"
20821   [(set (match_operand 0 "" "")
20822         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20823               (match_operand:DI 2 "" "")))]
20824   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20825   "jmp\t%P1"
20826   [(set_attr "type" "callv")])
20827
20828 (define_insn "*sibcall_value_1_rex64_v"
20829   [(set (match_operand 0 "" "")
20830         (call (mem:QI (reg:DI R11_REG))
20831               (match_operand:DI 1 "" "")))]
20832   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20833   "jmp\t*%%r11"
20834   [(set_attr "type" "callv")])
20835 \f
20836 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20837 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20838 ;; caught for use by garbage collectors and the like.  Using an insn that
20839 ;; maps to SIGILL makes it more likely the program will rightfully die.
20840 ;; Keeping with tradition, "6" is in honor of #UD.
20841 (define_insn "trap"
20842   [(trap_if (const_int 1) (const_int 6))]
20843   ""
20844   { return ASM_SHORT "0x0b0f"; }
20845   [(set_attr "length" "2")])
20846
20847 (define_expand "sse_prologue_save"
20848   [(parallel [(set (match_operand:BLK 0 "" "")
20849                    (unspec:BLK [(reg:DI 21)
20850                                 (reg:DI 22)
20851                                 (reg:DI 23)
20852                                 (reg:DI 24)
20853                                 (reg:DI 25)
20854                                 (reg:DI 26)
20855                                 (reg:DI 27)
20856                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20857               (use (match_operand:DI 1 "register_operand" ""))
20858               (use (match_operand:DI 2 "immediate_operand" ""))
20859               (use (label_ref:DI (match_operand 3 "" "")))])]
20860   "TARGET_64BIT"
20861   "")
20862
20863 (define_insn "*sse_prologue_save_insn"
20864   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20865                           (match_operand:DI 4 "const_int_operand" "n")))
20866         (unspec:BLK [(reg:DI 21)
20867                      (reg:DI 22)
20868                      (reg:DI 23)
20869                      (reg:DI 24)
20870                      (reg:DI 25)
20871                      (reg:DI 26)
20872                      (reg:DI 27)
20873                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20874    (use (match_operand:DI 1 "register_operand" "r"))
20875    (use (match_operand:DI 2 "const_int_operand" "i"))
20876    (use (label_ref:DI (match_operand 3 "" "X")))]
20877   "TARGET_64BIT
20878    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20879    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20880   "*
20881 {
20882   int i;
20883   operands[0] = gen_rtx_MEM (Pmode,
20884                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20885   output_asm_insn (\"jmp\\t%A1\", operands);
20886   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20887     {
20888       operands[4] = adjust_address (operands[0], DImode, i*16);
20889       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20890       PUT_MODE (operands[4], TImode);
20891       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20892         output_asm_insn (\"rex\", operands);
20893       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20894     }
20895   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20896                              CODE_LABEL_NUMBER (operands[3]));
20897   return \"\";
20898 }
20899   "
20900   [(set_attr "type" "other")
20901    (set_attr "length_immediate" "0")
20902    (set_attr "length_address" "0")
20903    (set_attr "length" "135")
20904    (set_attr "memory" "store")
20905    (set_attr "modrm" "0")
20906    (set_attr "mode" "DI")])
20907
20908 (define_expand "prefetch"
20909   [(prefetch (match_operand 0 "address_operand" "")
20910              (match_operand:SI 1 "const_int_operand" "")
20911              (match_operand:SI 2 "const_int_operand" ""))]
20912   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20913 {
20914   int rw = INTVAL (operands[1]);
20915   int locality = INTVAL (operands[2]);
20916
20917   gcc_assert (rw == 0 || rw == 1);
20918   gcc_assert (locality >= 0 && locality <= 3);
20919   gcc_assert (GET_MODE (operands[0]) == Pmode
20920               || GET_MODE (operands[0]) == VOIDmode);
20921
20922   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20923      supported by SSE counterpart or the SSE prefetch is not available
20924      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20925      of locality.  */
20926   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20927     operands[2] = GEN_INT (3);
20928   else
20929     operands[1] = const0_rtx;
20930 })
20931
20932 (define_insn "*prefetch_sse"
20933   [(prefetch (match_operand:SI 0 "address_operand" "p")
20934              (const_int 0)
20935              (match_operand:SI 1 "const_int_operand" ""))]
20936   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20937 {
20938   static const char * const patterns[4] = {
20939    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20940   };
20941
20942   int locality = INTVAL (operands[1]);
20943   gcc_assert (locality >= 0 && locality <= 3);
20944
20945   return patterns[locality];
20946 }
20947   [(set_attr "type" "sse")
20948    (set_attr "memory" "none")])
20949
20950 (define_insn "*prefetch_sse_rex"
20951   [(prefetch (match_operand:DI 0 "address_operand" "p")
20952              (const_int 0)
20953              (match_operand:SI 1 "const_int_operand" ""))]
20954   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20955 {
20956   static const char * const patterns[4] = {
20957    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20958   };
20959
20960   int locality = INTVAL (operands[1]);
20961   gcc_assert (locality >= 0 && locality <= 3);
20962
20963   return patterns[locality];
20964 }
20965   [(set_attr "type" "sse")
20966    (set_attr "memory" "none")])
20967
20968 (define_insn "*prefetch_3dnow"
20969   [(prefetch (match_operand:SI 0 "address_operand" "p")
20970              (match_operand:SI 1 "const_int_operand" "n")
20971              (const_int 3))]
20972   "TARGET_3DNOW && !TARGET_64BIT"
20973 {
20974   if (INTVAL (operands[1]) == 0)
20975     return "prefetch\t%a0";
20976   else
20977     return "prefetchw\t%a0";
20978 }
20979   [(set_attr "type" "mmx")
20980    (set_attr "memory" "none")])
20981
20982 (define_insn "*prefetch_3dnow_rex"
20983   [(prefetch (match_operand:DI 0 "address_operand" "p")
20984              (match_operand:SI 1 "const_int_operand" "n")
20985              (const_int 3))]
20986   "TARGET_3DNOW && TARGET_64BIT"
20987 {
20988   if (INTVAL (operands[1]) == 0)
20989     return "prefetch\t%a0";
20990   else
20991     return "prefetchw\t%a0";
20992 }
20993   [(set_attr "type" "mmx")
20994    (set_attr "memory" "none")])
20995
20996 (define_expand "stack_protect_set"
20997   [(match_operand 0 "memory_operand" "")
20998    (match_operand 1 "memory_operand" "")]
20999   ""
21000 {
21001 #ifdef TARGET_THREAD_SSP_OFFSET
21002   if (TARGET_64BIT)
21003     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21004                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21005   else
21006     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21007                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21008 #else
21009   if (TARGET_64BIT)
21010     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21011   else
21012     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21013 #endif
21014   DONE;
21015 })
21016
21017 (define_insn "stack_protect_set_si"
21018   [(set (match_operand:SI 0 "memory_operand" "=m")
21019         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21020    (set (match_scratch:SI 2 "=&r") (const_int 0))
21021    (clobber (reg:CC FLAGS_REG))]
21022   ""
21023   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21024   [(set_attr "type" "multi")])
21025
21026 (define_insn "stack_protect_set_di"
21027   [(set (match_operand:DI 0 "memory_operand" "=m")
21028         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21029    (set (match_scratch:DI 2 "=&r") (const_int 0))
21030    (clobber (reg:CC FLAGS_REG))]
21031   "TARGET_64BIT"
21032   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21033   [(set_attr "type" "multi")])
21034
21035 (define_insn "stack_tls_protect_set_si"
21036   [(set (match_operand:SI 0 "memory_operand" "=m")
21037         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21038    (set (match_scratch:SI 2 "=&r") (const_int 0))
21039    (clobber (reg:CC FLAGS_REG))]
21040   ""
21041   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21042   [(set_attr "type" "multi")])
21043
21044 (define_insn "stack_tls_protect_set_di"
21045   [(set (match_operand:DI 0 "memory_operand" "=m")
21046         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21047    (set (match_scratch:DI 2 "=&r") (const_int 0))
21048    (clobber (reg:CC FLAGS_REG))]
21049   "TARGET_64BIT"
21050   {
21051      /* The kernel uses a different segment register for performance reasons; a
21052         system call would not have to trash the userspace segment register,
21053         which would be expensive */
21054      if (ix86_cmodel != CM_KERNEL)
21055         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21056      else
21057         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21058   }
21059   [(set_attr "type" "multi")])
21060
21061 (define_expand "stack_protect_test"
21062   [(match_operand 0 "memory_operand" "")
21063    (match_operand 1 "memory_operand" "")
21064    (match_operand 2 "" "")]
21065   ""
21066 {
21067   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21068   ix86_compare_op0 = operands[0];
21069   ix86_compare_op1 = operands[1];
21070   ix86_compare_emitted = flags;
21071
21072 #ifdef TARGET_THREAD_SSP_OFFSET
21073   if (TARGET_64BIT)
21074     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21075                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21076   else
21077     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21078                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21079 #else
21080   if (TARGET_64BIT)
21081     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21082   else
21083     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21084 #endif
21085   emit_jump_insn (gen_beq (operands[2]));
21086   DONE;
21087 })
21088
21089 (define_insn "stack_protect_test_si"
21090   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21091         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21092                      (match_operand:SI 2 "memory_operand" "m")]
21093                     UNSPEC_SP_TEST))
21094    (clobber (match_scratch:SI 3 "=&r"))]
21095   ""
21096   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21097   [(set_attr "type" "multi")])
21098
21099 (define_insn "stack_protect_test_di"
21100   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21101         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21102                      (match_operand:DI 2 "memory_operand" "m")]
21103                     UNSPEC_SP_TEST))
21104    (clobber (match_scratch:DI 3 "=&r"))]
21105   "TARGET_64BIT"
21106   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21107   [(set_attr "type" "multi")])
21108
21109 (define_insn "stack_tls_protect_test_si"
21110   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21111         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21112                      (match_operand:SI 2 "const_int_operand" "i")]
21113                     UNSPEC_SP_TLS_TEST))
21114    (clobber (match_scratch:SI 3 "=r"))]
21115   ""
21116   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21117   [(set_attr "type" "multi")])
21118
21119 (define_insn "stack_tls_protect_test_di"
21120   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21121         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21122                      (match_operand:DI 2 "const_int_operand" "i")]
21123                     UNSPEC_SP_TLS_TEST))
21124    (clobber (match_scratch:DI 3 "=r"))]
21125   "TARGET_64BIT"
21126   {
21127      /* The kernel uses a different segment register for performance reasons; a
21128         system call would not have to trash the userspace segment register,
21129         which would be expensive */
21130      if (ix86_cmodel != CM_KERNEL)
21131         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21132      else
21133         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21134   }
21135   [(set_attr "type" "multi")])
21136
21137 (define_mode_iterator CRC32MODE [QI HI SI])
21138 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21139 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21140
21141 (define_insn "sse4_2_crc32<mode>"
21142   [(set (match_operand:SI 0 "register_operand" "=r")
21143         (unspec:SI
21144           [(match_operand:SI 1 "register_operand" "0")
21145            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21146           UNSPEC_CRC32))]
21147   "TARGET_SSE4_2"
21148   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21149   [(set_attr "type" "sselog1")
21150    (set_attr "prefix_rep" "1")
21151    (set_attr "prefix_extra" "1")
21152    (set_attr "mode" "SI")])
21153
21154 (define_insn "sse4_2_crc32di"
21155   [(set (match_operand:DI 0 "register_operand" "=r")
21156         (unspec:DI
21157           [(match_operand:DI 1 "register_operand" "0")
21158            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21159           UNSPEC_CRC32))]
21160   "TARGET_SSE4_2 && TARGET_64BIT"
21161   "crc32q\t{%2, %0|%0, %2}"
21162   [(set_attr "type" "sselog1")
21163    (set_attr "prefix_rep" "1")
21164    (set_attr "prefix_extra" "1")
21165    (set_attr "mode" "DI")])
21166
21167 (include "mmx.md")
21168 (include "sse.md")
21169 (include "sync.md")