OSDN Git Service

PR target/33393
[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 ;; SSE and x87 SFmode and DFmode floating point modes
519 (define_mode_iterator MODEF [SF DF])
520
521 ;; All x87 floating point modes
522 (define_mode_iterator X87MODEF [SF DF XF])
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 integer modes handled by SSE cvtts?2si* operators.
531 (define_mode_iterator SSEMODEI24 [SI DI])
532
533 ;; SSE asm suffix for floating point modes
534 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
535
536 ;; SSE vector mode corresponding to a scalar mode
537 (define_mode_attr ssevecmode
538   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
539 \f
540 ;; Scheduling descriptions
541
542 (include "pentium.md")
543 (include "ppro.md")
544 (include "k6.md")
545 (include "athlon.md")
546 (include "geode.md")
547
548 \f
549 ;; Operand and operator predicates and constraints
550
551 (include "predicates.md")
552 (include "constraints.md")
553
554 \f
555 ;; Compare instructions.
556
557 ;; All compare insns have expanders that save the operands away without
558 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
559 ;; after the cmp) will actually emit the cmpM.
560
561 (define_expand "cmpti"
562   [(set (reg:CC FLAGS_REG)
563         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
564                     (match_operand:TI 1 "x86_64_general_operand" "")))]
565   "TARGET_64BIT"
566 {
567   if (MEM_P (operands[0]) && MEM_P (operands[1]))
568     operands[0] = force_reg (TImode, operands[0]);
569   ix86_compare_op0 = operands[0];
570   ix86_compare_op1 = operands[1];
571   DONE;
572 })
573
574 (define_expand "cmpdi"
575   [(set (reg:CC FLAGS_REG)
576         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
577                     (match_operand:DI 1 "x86_64_general_operand" "")))]
578   ""
579 {
580   if (MEM_P (operands[0]) && MEM_P (operands[1]))
581     operands[0] = force_reg (DImode, operands[0]);
582   ix86_compare_op0 = operands[0];
583   ix86_compare_op1 = operands[1];
584   DONE;
585 })
586
587 (define_expand "cmpsi"
588   [(set (reg:CC FLAGS_REG)
589         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
590                     (match_operand:SI 1 "general_operand" "")))]
591   ""
592 {
593   if (MEM_P (operands[0]) && MEM_P (operands[1]))
594     operands[0] = force_reg (SImode, operands[0]);
595   ix86_compare_op0 = operands[0];
596   ix86_compare_op1 = operands[1];
597   DONE;
598 })
599
600 (define_expand "cmphi"
601   [(set (reg:CC FLAGS_REG)
602         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
603                     (match_operand:HI 1 "general_operand" "")))]
604   ""
605 {
606   if (MEM_P (operands[0]) && MEM_P (operands[1]))
607     operands[0] = force_reg (HImode, operands[0]);
608   ix86_compare_op0 = operands[0];
609   ix86_compare_op1 = operands[1];
610   DONE;
611 })
612
613 (define_expand "cmpqi"
614   [(set (reg:CC FLAGS_REG)
615         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
616                     (match_operand:QI 1 "general_operand" "")))]
617   "TARGET_QIMODE_MATH"
618 {
619   if (MEM_P (operands[0]) && MEM_P (operands[1]))
620     operands[0] = force_reg (QImode, operands[0]);
621   ix86_compare_op0 = operands[0];
622   ix86_compare_op1 = operands[1];
623   DONE;
624 })
625
626 (define_insn "cmpdi_ccno_1_rex64"
627   [(set (reg FLAGS_REG)
628         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
629                  (match_operand:DI 1 "const0_operand" "n,n")))]
630   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
631   "@
632    test{q}\t%0, %0
633    cmp{q}\t{%1, %0|%0, %1}"
634   [(set_attr "type" "test,icmp")
635    (set_attr "length_immediate" "0,1")
636    (set_attr "mode" "DI")])
637
638 (define_insn "*cmpdi_minus_1_rex64"
639   [(set (reg FLAGS_REG)
640         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
641                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
642                  (const_int 0)))]
643   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
644   "cmp{q}\t{%1, %0|%0, %1}"
645   [(set_attr "type" "icmp")
646    (set_attr "mode" "DI")])
647
648 (define_expand "cmpdi_1_rex64"
649   [(set (reg:CC FLAGS_REG)
650         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
651                     (match_operand:DI 1 "general_operand" "")))]
652   "TARGET_64BIT"
653   "")
654
655 (define_insn "cmpdi_1_insn_rex64"
656   [(set (reg FLAGS_REG)
657         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
658                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
659   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
660   "cmp{q}\t{%1, %0|%0, %1}"
661   [(set_attr "type" "icmp")
662    (set_attr "mode" "DI")])
663
664
665 (define_insn "*cmpsi_ccno_1"
666   [(set (reg FLAGS_REG)
667         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
668                  (match_operand:SI 1 "const0_operand" "n,n")))]
669   "ix86_match_ccmode (insn, CCNOmode)"
670   "@
671    test{l}\t%0, %0
672    cmp{l}\t{%1, %0|%0, %1}"
673   [(set_attr "type" "test,icmp")
674    (set_attr "length_immediate" "0,1")
675    (set_attr "mode" "SI")])
676
677 (define_insn "*cmpsi_minus_1"
678   [(set (reg FLAGS_REG)
679         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
680                            (match_operand:SI 1 "general_operand" "ri,mr"))
681                  (const_int 0)))]
682   "ix86_match_ccmode (insn, CCGOCmode)"
683   "cmp{l}\t{%1, %0|%0, %1}"
684   [(set_attr "type" "icmp")
685    (set_attr "mode" "SI")])
686
687 (define_expand "cmpsi_1"
688   [(set (reg:CC FLAGS_REG)
689         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
690                     (match_operand:SI 1 "general_operand" "")))]
691   ""
692   "")
693
694 (define_insn "*cmpsi_1_insn"
695   [(set (reg FLAGS_REG)
696         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
697                  (match_operand:SI 1 "general_operand" "ri,mr")))]
698   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
699     && ix86_match_ccmode (insn, CCmode)"
700   "cmp{l}\t{%1, %0|%0, %1}"
701   [(set_attr "type" "icmp")
702    (set_attr "mode" "SI")])
703
704 (define_insn "*cmphi_ccno_1"
705   [(set (reg FLAGS_REG)
706         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
707                  (match_operand:HI 1 "const0_operand" "n,n")))]
708   "ix86_match_ccmode (insn, CCNOmode)"
709   "@
710    test{w}\t%0, %0
711    cmp{w}\t{%1, %0|%0, %1}"
712   [(set_attr "type" "test,icmp")
713    (set_attr "length_immediate" "0,1")
714    (set_attr "mode" "HI")])
715
716 (define_insn "*cmphi_minus_1"
717   [(set (reg FLAGS_REG)
718         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
719                            (match_operand:HI 1 "general_operand" "ri,mr"))
720                  (const_int 0)))]
721   "ix86_match_ccmode (insn, CCGOCmode)"
722   "cmp{w}\t{%1, %0|%0, %1}"
723   [(set_attr "type" "icmp")
724    (set_attr "mode" "HI")])
725
726 (define_insn "*cmphi_1"
727   [(set (reg FLAGS_REG)
728         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
729                  (match_operand:HI 1 "general_operand" "ri,mr")))]
730   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
731    && ix86_match_ccmode (insn, CCmode)"
732   "cmp{w}\t{%1, %0|%0, %1}"
733   [(set_attr "type" "icmp")
734    (set_attr "mode" "HI")])
735
736 (define_insn "*cmpqi_ccno_1"
737   [(set (reg FLAGS_REG)
738         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
739                  (match_operand:QI 1 "const0_operand" "n,n")))]
740   "ix86_match_ccmode (insn, CCNOmode)"
741   "@
742    test{b}\t%0, %0
743    cmp{b}\t{$0, %0|%0, 0}"
744   [(set_attr "type" "test,icmp")
745    (set_attr "length_immediate" "0,1")
746    (set_attr "mode" "QI")])
747
748 (define_insn "*cmpqi_1"
749   [(set (reg FLAGS_REG)
750         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
751                  (match_operand:QI 1 "general_operand" "qi,mq")))]
752   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
753     && ix86_match_ccmode (insn, CCmode)"
754   "cmp{b}\t{%1, %0|%0, %1}"
755   [(set_attr "type" "icmp")
756    (set_attr "mode" "QI")])
757
758 (define_insn "*cmpqi_minus_1"
759   [(set (reg FLAGS_REG)
760         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
761                            (match_operand:QI 1 "general_operand" "qi,mq"))
762                  (const_int 0)))]
763   "ix86_match_ccmode (insn, CCGOCmode)"
764   "cmp{b}\t{%1, %0|%0, %1}"
765   [(set_attr "type" "icmp")
766    (set_attr "mode" "QI")])
767
768 (define_insn "*cmpqi_ext_1"
769   [(set (reg FLAGS_REG)
770         (compare
771           (match_operand:QI 0 "general_operand" "Qm")
772           (subreg:QI
773             (zero_extract:SI
774               (match_operand 1 "ext_register_operand" "Q")
775               (const_int 8)
776               (const_int 8)) 0)))]
777   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
778   "cmp{b}\t{%h1, %0|%0, %h1}"
779   [(set_attr "type" "icmp")
780    (set_attr "mode" "QI")])
781
782 (define_insn "*cmpqi_ext_1_rex64"
783   [(set (reg FLAGS_REG)
784         (compare
785           (match_operand:QI 0 "register_operand" "Q")
786           (subreg:QI
787             (zero_extract:SI
788               (match_operand 1 "ext_register_operand" "Q")
789               (const_int 8)
790               (const_int 8)) 0)))]
791   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
792   "cmp{b}\t{%h1, %0|%0, %h1}"
793   [(set_attr "type" "icmp")
794    (set_attr "mode" "QI")])
795
796 (define_insn "*cmpqi_ext_2"
797   [(set (reg FLAGS_REG)
798         (compare
799           (subreg:QI
800             (zero_extract:SI
801               (match_operand 0 "ext_register_operand" "Q")
802               (const_int 8)
803               (const_int 8)) 0)
804           (match_operand:QI 1 "const0_operand" "n")))]
805   "ix86_match_ccmode (insn, CCNOmode)"
806   "test{b}\t%h0, %h0"
807   [(set_attr "type" "test")
808    (set_attr "length_immediate" "0")
809    (set_attr "mode" "QI")])
810
811 (define_expand "cmpqi_ext_3"
812   [(set (reg:CC FLAGS_REG)
813         (compare:CC
814           (subreg:QI
815             (zero_extract:SI
816               (match_operand 0 "ext_register_operand" "")
817               (const_int 8)
818               (const_int 8)) 0)
819           (match_operand:QI 1 "general_operand" "")))]
820   ""
821   "")
822
823 (define_insn "cmpqi_ext_3_insn"
824   [(set (reg FLAGS_REG)
825         (compare
826           (subreg:QI
827             (zero_extract:SI
828               (match_operand 0 "ext_register_operand" "Q")
829               (const_int 8)
830               (const_int 8)) 0)
831           (match_operand:QI 1 "general_operand" "Qmn")))]
832   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
833   "cmp{b}\t{%1, %h0|%h0, %1}"
834   [(set_attr "type" "icmp")
835    (set_attr "mode" "QI")])
836
837 (define_insn "cmpqi_ext_3_insn_rex64"
838   [(set (reg FLAGS_REG)
839         (compare
840           (subreg:QI
841             (zero_extract:SI
842               (match_operand 0 "ext_register_operand" "Q")
843               (const_int 8)
844               (const_int 8)) 0)
845           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
846   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
847   "cmp{b}\t{%1, %h0|%h0, %1}"
848   [(set_attr "type" "icmp")
849    (set_attr "mode" "QI")])
850
851 (define_insn "*cmpqi_ext_4"
852   [(set (reg FLAGS_REG)
853         (compare
854           (subreg:QI
855             (zero_extract:SI
856               (match_operand 0 "ext_register_operand" "Q")
857               (const_int 8)
858               (const_int 8)) 0)
859           (subreg:QI
860             (zero_extract:SI
861               (match_operand 1 "ext_register_operand" "Q")
862               (const_int 8)
863               (const_int 8)) 0)))]
864   "ix86_match_ccmode (insn, CCmode)"
865   "cmp{b}\t{%h1, %h0|%h0, %h1}"
866   [(set_attr "type" "icmp")
867    (set_attr "mode" "QI")])
868
869 ;; These implement float point compares.
870 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
871 ;; which would allow mix and match FP modes on the compares.  Which is what
872 ;; the old patterns did, but with many more of them.
873
874 (define_expand "cmpxf"
875   [(set (reg:CC FLAGS_REG)
876         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
877                     (match_operand:XF 1 "nonmemory_operand" "")))]
878   "TARGET_80387"
879 {
880   ix86_compare_op0 = operands[0];
881   ix86_compare_op1 = operands[1];
882   DONE;
883 })
884
885 (define_expand "cmp<mode>"
886   [(set (reg:CC FLAGS_REG)
887         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
888                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
889   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
890 {
891   ix86_compare_op0 = operands[0];
892   ix86_compare_op1 = operands[1];
893   DONE;
894 })
895
896 ;; FP compares, step 1:
897 ;; Set the FP condition codes.
898 ;;
899 ;; CCFPmode     compare with exceptions
900 ;; CCFPUmode    compare with no exceptions
901
902 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
903 ;; used to manage the reg stack popping would not be preserved.
904
905 (define_insn "*cmpfp_0"
906   [(set (match_operand:HI 0 "register_operand" "=a")
907         (unspec:HI
908           [(compare:CCFP
909              (match_operand 1 "register_operand" "f")
910              (match_operand 2 "const0_operand" "X"))]
911         UNSPEC_FNSTSW))]
912   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
913    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
914   "* return output_fp_compare (insn, operands, 0, 0);"
915   [(set_attr "type" "multi")
916    (set_attr "unit" "i387")
917    (set (attr "mode")
918      (cond [(match_operand:SF 1 "" "")
919               (const_string "SF")
920             (match_operand:DF 1 "" "")
921               (const_string "DF")
922            ]
923            (const_string "XF")))])
924
925 (define_insn_and_split "*cmpfp_0_cc"
926   [(set (reg:CCFP FLAGS_REG)
927         (compare:CCFP
928           (match_operand 1 "register_operand" "f")
929           (match_operand 2 "const0_operand" "X")))
930    (clobber (match_operand:HI 0 "register_operand" "=a"))]
931   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
932    && TARGET_SAHF && !TARGET_CMOVE
933    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
934   "#"
935   "&& reload_completed"
936   [(set (match_dup 0)
937         (unspec:HI
938           [(compare:CCFP (match_dup 1)(match_dup 2))]
939         UNSPEC_FNSTSW))
940    (set (reg:CC FLAGS_REG)
941         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
942   ""
943   [(set_attr "type" "multi")
944    (set_attr "unit" "i387")
945    (set (attr "mode")
946      (cond [(match_operand:SF 1 "" "")
947               (const_string "SF")
948             (match_operand:DF 1 "" "")
949               (const_string "DF")
950            ]
951            (const_string "XF")))])
952
953 (define_insn "*cmpfp_xf"
954   [(set (match_operand:HI 0 "register_operand" "=a")
955         (unspec:HI
956           [(compare:CCFP
957              (match_operand:XF 1 "register_operand" "f")
958              (match_operand:XF 2 "register_operand" "f"))]
959           UNSPEC_FNSTSW))]
960   "TARGET_80387"
961   "* return output_fp_compare (insn, operands, 0, 0);"
962   [(set_attr "type" "multi")
963    (set_attr "unit" "i387")
964    (set_attr "mode" "XF")])
965
966 (define_insn_and_split "*cmpfp_xf_cc"
967   [(set (reg:CCFP FLAGS_REG)
968         (compare:CCFP
969           (match_operand:XF 1 "register_operand" "f")
970           (match_operand:XF 2 "register_operand" "f")))
971    (clobber (match_operand:HI 0 "register_operand" "=a"))]
972   "TARGET_80387
973    && TARGET_SAHF && !TARGET_CMOVE"
974   "#"
975   "&& reload_completed"
976   [(set (match_dup 0)
977         (unspec:HI
978           [(compare:CCFP (match_dup 1)(match_dup 2))]
979         UNSPEC_FNSTSW))
980    (set (reg:CC FLAGS_REG)
981         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
982   ""
983   [(set_attr "type" "multi")
984    (set_attr "unit" "i387")
985    (set_attr "mode" "XF")])
986
987 (define_insn "*cmpfp_<mode>"
988   [(set (match_operand:HI 0 "register_operand" "=a")
989         (unspec:HI
990           [(compare:CCFP
991              (match_operand:MODEF 1 "register_operand" "f")
992              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
993           UNSPEC_FNSTSW))]
994   "TARGET_80387"
995   "* return output_fp_compare (insn, operands, 0, 0);"
996   [(set_attr "type" "multi")
997    (set_attr "unit" "i387")
998    (set_attr "mode" "<MODE>")])
999
1000 (define_insn_and_split "*cmpfp_<mode>_cc"
1001   [(set (reg:CCFP FLAGS_REG)
1002         (compare:CCFP
1003           (match_operand:MODEF 1 "register_operand" "f")
1004           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1005    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1006   "TARGET_80387
1007    && TARGET_SAHF && !TARGET_CMOVE"
1008   "#"
1009   "&& reload_completed"
1010   [(set (match_dup 0)
1011         (unspec:HI
1012           [(compare:CCFP (match_dup 1)(match_dup 2))]
1013         UNSPEC_FNSTSW))
1014    (set (reg:CC FLAGS_REG)
1015         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1016   ""
1017   [(set_attr "type" "multi")
1018    (set_attr "unit" "i387")
1019    (set_attr "mode" "<MODE>")])
1020
1021 (define_insn "*cmpfp_u"
1022   [(set (match_operand:HI 0 "register_operand" "=a")
1023         (unspec:HI
1024           [(compare:CCFPU
1025              (match_operand 1 "register_operand" "f")
1026              (match_operand 2 "register_operand" "f"))]
1027           UNSPEC_FNSTSW))]
1028   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1029    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1030   "* return output_fp_compare (insn, operands, 0, 1);"
1031   [(set_attr "type" "multi")
1032    (set_attr "unit" "i387")
1033    (set (attr "mode")
1034      (cond [(match_operand:SF 1 "" "")
1035               (const_string "SF")
1036             (match_operand:DF 1 "" "")
1037               (const_string "DF")
1038            ]
1039            (const_string "XF")))])
1040
1041 (define_insn_and_split "*cmpfp_u_cc"
1042   [(set (reg:CCFPU FLAGS_REG)
1043         (compare:CCFPU
1044           (match_operand 1 "register_operand" "f")
1045           (match_operand 2 "register_operand" "f")))
1046    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1047   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1048    && TARGET_SAHF && !TARGET_CMOVE
1049    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1050   "#"
1051   "&& reload_completed"
1052   [(set (match_dup 0)
1053         (unspec:HI
1054           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1055         UNSPEC_FNSTSW))
1056    (set (reg:CC FLAGS_REG)
1057         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1058   ""
1059   [(set_attr "type" "multi")
1060    (set_attr "unit" "i387")
1061    (set (attr "mode")
1062      (cond [(match_operand:SF 1 "" "")
1063               (const_string "SF")
1064             (match_operand:DF 1 "" "")
1065               (const_string "DF")
1066            ]
1067            (const_string "XF")))])
1068
1069 (define_insn "*cmpfp_<mode>"
1070   [(set (match_operand:HI 0 "register_operand" "=a")
1071         (unspec:HI
1072           [(compare:CCFP
1073              (match_operand 1 "register_operand" "f")
1074              (match_operator 3 "float_operator"
1075                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1076           UNSPEC_FNSTSW))]
1077   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1078    && TARGET_USE_<MODE>MODE_FIOP
1079    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1080   "* return output_fp_compare (insn, operands, 0, 0);"
1081   [(set_attr "type" "multi")
1082    (set_attr "unit" "i387")
1083    (set_attr "fp_int_src" "true")
1084    (set_attr "mode" "<MODE>")])
1085
1086 (define_insn_and_split "*cmpfp_<mode>_cc"
1087   [(set (reg:CCFP FLAGS_REG)
1088         (compare:CCFP
1089           (match_operand 1 "register_operand" "f")
1090           (match_operator 3 "float_operator"
1091             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1092    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1093   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1094    && TARGET_SAHF && !TARGET_CMOVE
1095    && TARGET_USE_<MODE>MODE_FIOP
1096    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1097   "#"
1098   "&& reload_completed"
1099   [(set (match_dup 0)
1100         (unspec:HI
1101           [(compare:CCFP
1102              (match_dup 1)
1103              (match_op_dup 3 [(match_dup 2)]))]
1104         UNSPEC_FNSTSW))
1105    (set (reg:CC FLAGS_REG)
1106         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1107   ""
1108   [(set_attr "type" "multi")
1109    (set_attr "unit" "i387")
1110    (set_attr "fp_int_src" "true")
1111    (set_attr "mode" "<MODE>")])
1112
1113 ;; FP compares, step 2
1114 ;; Move the fpsw to ax.
1115
1116 (define_insn "x86_fnstsw_1"
1117   [(set (match_operand:HI 0 "register_operand" "=a")
1118         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1119   "TARGET_80387"
1120   "fnstsw\t%0"
1121   [(set_attr "length" "2")
1122    (set_attr "mode" "SI")
1123    (set_attr "unit" "i387")])
1124
1125 ;; FP compares, step 3
1126 ;; Get ax into flags, general case.
1127
1128 (define_insn "x86_sahf_1"
1129   [(set (reg:CC FLAGS_REG)
1130         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1131                    UNSPEC_SAHF))]
1132   "TARGET_SAHF"
1133 {
1134 #ifdef HAVE_AS_IX86_SAHF
1135   return "sahf";
1136 #else
1137   return ".byte\t0x9e";
1138 #endif
1139 }
1140   [(set_attr "length" "1")
1141    (set_attr "athlon_decode" "vector")
1142    (set_attr "amdfam10_decode" "direct")
1143    (set_attr "mode" "SI")])
1144
1145 ;; Pentium Pro can do steps 1 through 3 in one go.
1146 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
1147 (define_insn "*cmpfp_i_mixed"
1148   [(set (reg:CCFP FLAGS_REG)
1149         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1150                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1151   "TARGET_MIX_SSE_I387
1152    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1153    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1154   "* return output_fp_compare (insn, operands, 1, 0);"
1155   [(set_attr "type" "fcmp,ssecomi")
1156    (set (attr "mode")
1157      (if_then_else (match_operand:SF 1 "" "")
1158         (const_string "SF")
1159         (const_string "DF")))
1160    (set_attr "athlon_decode" "vector")
1161    (set_attr "amdfam10_decode" "direct")])
1162
1163 (define_insn "*cmpfp_i_sse"
1164   [(set (reg:CCFP FLAGS_REG)
1165         (compare:CCFP (match_operand 0 "register_operand" "x")
1166                       (match_operand 1 "nonimmediate_operand" "xm")))]
1167   "TARGET_SSE_MATH
1168    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1169    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1170   "* return output_fp_compare (insn, operands, 1, 0);"
1171   [(set_attr "type" "ssecomi")
1172    (set (attr "mode")
1173      (if_then_else (match_operand:SF 1 "" "")
1174         (const_string "SF")
1175         (const_string "DF")))
1176    (set_attr "athlon_decode" "vector")
1177    (set_attr "amdfam10_decode" "direct")])
1178
1179 (define_insn "*cmpfp_i_i387"
1180   [(set (reg:CCFP FLAGS_REG)
1181         (compare:CCFP (match_operand 0 "register_operand" "f")
1182                       (match_operand 1 "register_operand" "f")))]
1183   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1184    && TARGET_CMOVE
1185    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1186    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1187   "* return output_fp_compare (insn, operands, 1, 0);"
1188   [(set_attr "type" "fcmp")
1189    (set (attr "mode")
1190      (cond [(match_operand:SF 1 "" "")
1191               (const_string "SF")
1192             (match_operand:DF 1 "" "")
1193               (const_string "DF")
1194            ]
1195            (const_string "XF")))
1196    (set_attr "athlon_decode" "vector")
1197    (set_attr "amdfam10_decode" "direct")])
1198
1199 (define_insn "*cmpfp_iu_mixed"
1200   [(set (reg:CCFPU FLAGS_REG)
1201         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1202                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1203   "TARGET_MIX_SSE_I387
1204    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1205    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1206   "* return output_fp_compare (insn, operands, 1, 1);"
1207   [(set_attr "type" "fcmp,ssecomi")
1208    (set (attr "mode")
1209      (if_then_else (match_operand:SF 1 "" "")
1210         (const_string "SF")
1211         (const_string "DF")))
1212    (set_attr "athlon_decode" "vector")
1213    (set_attr "amdfam10_decode" "direct")])
1214
1215 (define_insn "*cmpfp_iu_sse"
1216   [(set (reg:CCFPU FLAGS_REG)
1217         (compare:CCFPU (match_operand 0 "register_operand" "x")
1218                        (match_operand 1 "nonimmediate_operand" "xm")))]
1219   "TARGET_SSE_MATH
1220    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1221    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1222   "* return output_fp_compare (insn, operands, 1, 1);"
1223   [(set_attr "type" "ssecomi")
1224    (set (attr "mode")
1225      (if_then_else (match_operand:SF 1 "" "")
1226         (const_string "SF")
1227         (const_string "DF")))
1228    (set_attr "athlon_decode" "vector")
1229    (set_attr "amdfam10_decode" "direct")])
1230
1231 (define_insn "*cmpfp_iu_387"
1232   [(set (reg:CCFPU FLAGS_REG)
1233         (compare:CCFPU (match_operand 0 "register_operand" "f")
1234                        (match_operand 1 "register_operand" "f")))]
1235   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1236    && TARGET_CMOVE
1237    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1238    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1239   "* return output_fp_compare (insn, operands, 1, 1);"
1240   [(set_attr "type" "fcmp")
1241    (set (attr "mode")
1242      (cond [(match_operand:SF 1 "" "")
1243               (const_string "SF")
1244             (match_operand:DF 1 "" "")
1245               (const_string "DF")
1246            ]
1247            (const_string "XF")))
1248    (set_attr "athlon_decode" "vector")
1249    (set_attr "amdfam10_decode" "direct")])
1250 \f
1251 ;; Move instructions.
1252
1253 ;; General case of fullword move.
1254
1255 (define_expand "movsi"
1256   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1257         (match_operand:SI 1 "general_operand" ""))]
1258   ""
1259   "ix86_expand_move (SImode, operands); DONE;")
1260
1261 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1262 ;; general_operand.
1263 ;;
1264 ;; %%% We don't use a post-inc memory reference because x86 is not a
1265 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1266 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1267 ;; targets without our curiosities, and it is just as easy to represent
1268 ;; this differently.
1269
1270 (define_insn "*pushsi2"
1271   [(set (match_operand:SI 0 "push_operand" "=<")
1272         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1273   "!TARGET_64BIT"
1274   "push{l}\t%1"
1275   [(set_attr "type" "push")
1276    (set_attr "mode" "SI")])
1277
1278 ;; For 64BIT abi we always round up to 8 bytes.
1279 (define_insn "*pushsi2_rex64"
1280   [(set (match_operand:SI 0 "push_operand" "=X")
1281         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1282   "TARGET_64BIT"
1283   "push{q}\t%q1"
1284   [(set_attr "type" "push")
1285    (set_attr "mode" "SI")])
1286
1287 (define_insn "*pushsi2_prologue"
1288   [(set (match_operand:SI 0 "push_operand" "=<")
1289         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1290    (clobber (mem:BLK (scratch)))]
1291   "!TARGET_64BIT"
1292   "push{l}\t%1"
1293   [(set_attr "type" "push")
1294    (set_attr "mode" "SI")])
1295
1296 (define_insn "*popsi1_epilogue"
1297   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1298         (mem:SI (reg:SI SP_REG)))
1299    (set (reg:SI SP_REG)
1300         (plus:SI (reg:SI SP_REG) (const_int 4)))
1301    (clobber (mem:BLK (scratch)))]
1302   "!TARGET_64BIT"
1303   "pop{l}\t%0"
1304   [(set_attr "type" "pop")
1305    (set_attr "mode" "SI")])
1306
1307 (define_insn "popsi1"
1308   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1309         (mem:SI (reg:SI SP_REG)))
1310    (set (reg:SI SP_REG)
1311         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1312   "!TARGET_64BIT"
1313   "pop{l}\t%0"
1314   [(set_attr "type" "pop")
1315    (set_attr "mode" "SI")])
1316
1317 (define_insn "*movsi_xor"
1318   [(set (match_operand:SI 0 "register_operand" "=r")
1319         (match_operand:SI 1 "const0_operand" "i"))
1320    (clobber (reg:CC FLAGS_REG))]
1321   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1322   "xor{l}\t%0, %0"
1323   [(set_attr "type" "alu1")
1324    (set_attr "mode" "SI")
1325    (set_attr "length_immediate" "0")])
1326
1327 (define_insn "*movsi_or"
1328   [(set (match_operand:SI 0 "register_operand" "=r")
1329         (match_operand:SI 1 "immediate_operand" "i"))
1330    (clobber (reg:CC FLAGS_REG))]
1331   "reload_completed
1332    && operands[1] == constm1_rtx
1333    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1334 {
1335   operands[1] = constm1_rtx;
1336   return "or{l}\t{%1, %0|%0, %1}";
1337 }
1338   [(set_attr "type" "alu1")
1339    (set_attr "mode" "SI")
1340    (set_attr "length_immediate" "1")])
1341
1342 (define_insn "*movsi_1"
1343   [(set (match_operand:SI 0 "nonimmediate_operand"
1344                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1345         (match_operand:SI 1 "general_operand"
1346                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1347   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1348 {
1349   switch (get_attr_type (insn))
1350     {
1351     case TYPE_SSELOG1:
1352       if (get_attr_mode (insn) == MODE_TI)
1353         return "pxor\t%0, %0";
1354       return "xorps\t%0, %0";
1355
1356     case TYPE_SSEMOV:
1357       switch (get_attr_mode (insn))
1358         {
1359         case MODE_TI:
1360           return "movdqa\t{%1, %0|%0, %1}";
1361         case MODE_V4SF:
1362           return "movaps\t{%1, %0|%0, %1}";
1363         case MODE_SI:
1364           return "movd\t{%1, %0|%0, %1}";
1365         case MODE_SF:
1366           return "movss\t{%1, %0|%0, %1}";
1367         default:
1368           gcc_unreachable ();
1369         }
1370
1371     case TYPE_MMXADD:
1372       return "pxor\t%0, %0";
1373
1374     case TYPE_MMXMOV:
1375       if (get_attr_mode (insn) == MODE_DI)
1376         return "movq\t{%1, %0|%0, %1}";
1377       return "movd\t{%1, %0|%0, %1}";
1378
1379     case TYPE_LEA:
1380       return "lea{l}\t{%1, %0|%0, %1}";
1381
1382     default:
1383       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1384       return "mov{l}\t{%1, %0|%0, %1}";
1385     }
1386 }
1387   [(set (attr "type")
1388      (cond [(eq_attr "alternative" "2")
1389               (const_string "mmxadd")
1390             (eq_attr "alternative" "3,4,5")
1391               (const_string "mmxmov")
1392             (eq_attr "alternative" "6")
1393               (const_string "sselog1")
1394             (eq_attr "alternative" "7,8,9,10,11")
1395               (const_string "ssemov")
1396             (match_operand:DI 1 "pic_32bit_operand" "")
1397               (const_string "lea")
1398            ]
1399            (const_string "imov")))
1400    (set (attr "mode")
1401      (cond [(eq_attr "alternative" "2,3")
1402               (const_string "DI")
1403             (eq_attr "alternative" "6,7")
1404               (if_then_else
1405                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1406                 (const_string "V4SF")
1407                 (const_string "TI"))
1408             (and (eq_attr "alternative" "8,9,10,11")
1409                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1410               (const_string "SF")
1411            ]
1412            (const_string "SI")))])
1413
1414 ;; Stores and loads of ax to arbitrary constant address.
1415 ;; We fake an second form of instruction to force reload to load address
1416 ;; into register when rax is not available
1417 (define_insn "*movabssi_1_rex64"
1418   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1419         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1420   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1421   "@
1422    movabs{l}\t{%1, %P0|%P0, %1}
1423    mov{l}\t{%1, %a0|%a0, %1}"
1424   [(set_attr "type" "imov")
1425    (set_attr "modrm" "0,*")
1426    (set_attr "length_address" "8,0")
1427    (set_attr "length_immediate" "0,*")
1428    (set_attr "memory" "store")
1429    (set_attr "mode" "SI")])
1430
1431 (define_insn "*movabssi_2_rex64"
1432   [(set (match_operand:SI 0 "register_operand" "=a,r")
1433         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1434   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1435   "@
1436    movabs{l}\t{%P1, %0|%0, %P1}
1437    mov{l}\t{%a1, %0|%0, %a1}"
1438   [(set_attr "type" "imov")
1439    (set_attr "modrm" "0,*")
1440    (set_attr "length_address" "8,0")
1441    (set_attr "length_immediate" "0")
1442    (set_attr "memory" "load")
1443    (set_attr "mode" "SI")])
1444
1445 (define_insn "*swapsi"
1446   [(set (match_operand:SI 0 "register_operand" "+r")
1447         (match_operand:SI 1 "register_operand" "+r"))
1448    (set (match_dup 1)
1449         (match_dup 0))]
1450   ""
1451   "xchg{l}\t%1, %0"
1452   [(set_attr "type" "imov")
1453    (set_attr "mode" "SI")
1454    (set_attr "pent_pair" "np")
1455    (set_attr "athlon_decode" "vector")
1456    (set_attr "amdfam10_decode" "double")])   
1457
1458 (define_expand "movhi"
1459   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1460         (match_operand:HI 1 "general_operand" ""))]
1461   ""
1462   "ix86_expand_move (HImode, operands); DONE;")
1463
1464 (define_insn "*pushhi2"
1465   [(set (match_operand:HI 0 "push_operand" "=X")
1466         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1467   "!TARGET_64BIT"
1468   "push{l}\t%k1"
1469   [(set_attr "type" "push")
1470    (set_attr "mode" "SI")])
1471
1472 ;; For 64BIT abi we always round up to 8 bytes.
1473 (define_insn "*pushhi2_rex64"
1474   [(set (match_operand:HI 0 "push_operand" "=X")
1475         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1476   "TARGET_64BIT"
1477   "push{q}\t%q1"
1478   [(set_attr "type" "push")
1479    (set_attr "mode" "DI")])
1480
1481 (define_insn "*movhi_1"
1482   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1483         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1484   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1485 {
1486   switch (get_attr_type (insn))
1487     {
1488     case TYPE_IMOVX:
1489       /* movzwl is faster than movw on p2 due to partial word stalls,
1490          though not as fast as an aligned movl.  */
1491       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1492     default:
1493       if (get_attr_mode (insn) == MODE_SI)
1494         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1495       else
1496         return "mov{w}\t{%1, %0|%0, %1}";
1497     }
1498 }
1499   [(set (attr "type")
1500      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1501               (const_string "imov")
1502             (and (eq_attr "alternative" "0")
1503                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1504                           (const_int 0))
1505                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1506                           (const_int 0))))
1507               (const_string "imov")
1508             (and (eq_attr "alternative" "1,2")
1509                  (match_operand:HI 1 "aligned_operand" ""))
1510               (const_string "imov")
1511             (and (ne (symbol_ref "TARGET_MOVX")
1512                      (const_int 0))
1513                  (eq_attr "alternative" "0,2"))
1514               (const_string "imovx")
1515            ]
1516            (const_string "imov")))
1517     (set (attr "mode")
1518       (cond [(eq_attr "type" "imovx")
1519                (const_string "SI")
1520              (and (eq_attr "alternative" "1,2")
1521                   (match_operand:HI 1 "aligned_operand" ""))
1522                (const_string "SI")
1523              (and (eq_attr "alternative" "0")
1524                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1525                            (const_int 0))
1526                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1527                            (const_int 0))))
1528                (const_string "SI")
1529             ]
1530             (const_string "HI")))])
1531
1532 ;; Stores and loads of ax to arbitrary constant address.
1533 ;; We fake an second form of instruction to force reload to load address
1534 ;; into register when rax is not available
1535 (define_insn "*movabshi_1_rex64"
1536   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1537         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1538   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1539   "@
1540    movabs{w}\t{%1, %P0|%P0, %1}
1541    mov{w}\t{%1, %a0|%a0, %1}"
1542   [(set_attr "type" "imov")
1543    (set_attr "modrm" "0,*")
1544    (set_attr "length_address" "8,0")
1545    (set_attr "length_immediate" "0,*")
1546    (set_attr "memory" "store")
1547    (set_attr "mode" "HI")])
1548
1549 (define_insn "*movabshi_2_rex64"
1550   [(set (match_operand:HI 0 "register_operand" "=a,r")
1551         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1552   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1553   "@
1554    movabs{w}\t{%P1, %0|%0, %P1}
1555    mov{w}\t{%a1, %0|%0, %a1}"
1556   [(set_attr "type" "imov")
1557    (set_attr "modrm" "0,*")
1558    (set_attr "length_address" "8,0")
1559    (set_attr "length_immediate" "0")
1560    (set_attr "memory" "load")
1561    (set_attr "mode" "HI")])
1562
1563 (define_insn "*swaphi_1"
1564   [(set (match_operand:HI 0 "register_operand" "+r")
1565         (match_operand:HI 1 "register_operand" "+r"))
1566    (set (match_dup 1)
1567         (match_dup 0))]
1568   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1569   "xchg{l}\t%k1, %k0"
1570   [(set_attr "type" "imov")
1571    (set_attr "mode" "SI")
1572    (set_attr "pent_pair" "np")
1573    (set_attr "athlon_decode" "vector")
1574    (set_attr "amdfam10_decode" "double")])   
1575
1576 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1577 (define_insn "*swaphi_2"
1578   [(set (match_operand:HI 0 "register_operand" "+r")
1579         (match_operand:HI 1 "register_operand" "+r"))
1580    (set (match_dup 1)
1581         (match_dup 0))]
1582   "TARGET_PARTIAL_REG_STALL"
1583   "xchg{w}\t%1, %0"
1584   [(set_attr "type" "imov")
1585    (set_attr "mode" "HI")
1586    (set_attr "pent_pair" "np")
1587    (set_attr "athlon_decode" "vector")])
1588
1589 (define_expand "movstricthi"
1590   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1591         (match_operand:HI 1 "general_operand" ""))]
1592   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1593 {
1594   /* Don't generate memory->memory moves, go through a register */
1595   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1596     operands[1] = force_reg (HImode, operands[1]);
1597 })
1598
1599 (define_insn "*movstricthi_1"
1600   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1601         (match_operand:HI 1 "general_operand" "rn,m"))]
1602   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1603    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1604   "mov{w}\t{%1, %0|%0, %1}"
1605   [(set_attr "type" "imov")
1606    (set_attr "mode" "HI")])
1607
1608 (define_insn "*movstricthi_xor"
1609   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1610         (match_operand:HI 1 "const0_operand" "i"))
1611    (clobber (reg:CC FLAGS_REG))]
1612   "reload_completed
1613    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1614   "xor{w}\t%0, %0"
1615   [(set_attr "type" "alu1")
1616    (set_attr "mode" "HI")
1617    (set_attr "length_immediate" "0")])
1618
1619 (define_expand "movqi"
1620   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1621         (match_operand:QI 1 "general_operand" ""))]
1622   ""
1623   "ix86_expand_move (QImode, operands); DONE;")
1624
1625 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1626 ;; "push a byte".  But actually we use pushl, which has the effect
1627 ;; of rounding the amount pushed up to a word.
1628
1629 (define_insn "*pushqi2"
1630   [(set (match_operand:QI 0 "push_operand" "=X")
1631         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1632   "!TARGET_64BIT"
1633   "push{l}\t%k1"
1634   [(set_attr "type" "push")
1635    (set_attr "mode" "SI")])
1636
1637 ;; For 64BIT abi we always round up to 8 bytes.
1638 (define_insn "*pushqi2_rex64"
1639   [(set (match_operand:QI 0 "push_operand" "=X")
1640         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1641   "TARGET_64BIT"
1642   "push{q}\t%q1"
1643   [(set_attr "type" "push")
1644    (set_attr "mode" "DI")])
1645
1646 ;; Situation is quite tricky about when to choose full sized (SImode) move
1647 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1648 ;; partial register dependency machines (such as AMD Athlon), where QImode
1649 ;; moves issue extra dependency and for partial register stalls machines
1650 ;; that don't use QImode patterns (and QImode move cause stall on the next
1651 ;; instruction).
1652 ;;
1653 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1654 ;; register stall machines with, where we use QImode instructions, since
1655 ;; partial register stall can be caused there.  Then we use movzx.
1656 (define_insn "*movqi_1"
1657   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1658         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1659   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1660 {
1661   switch (get_attr_type (insn))
1662     {
1663     case TYPE_IMOVX:
1664       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1665       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1666     default:
1667       if (get_attr_mode (insn) == MODE_SI)
1668         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1669       else
1670         return "mov{b}\t{%1, %0|%0, %1}";
1671     }
1672 }
1673   [(set (attr "type")
1674      (cond [(and (eq_attr "alternative" "5")
1675                  (not (match_operand:QI 1 "aligned_operand" "")))
1676               (const_string "imovx")
1677             (ne (symbol_ref "optimize_size") (const_int 0))
1678               (const_string "imov")
1679             (and (eq_attr "alternative" "3")
1680                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1681                           (const_int 0))
1682                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1683                           (const_int 0))))
1684               (const_string "imov")
1685             (eq_attr "alternative" "3,5")
1686               (const_string "imovx")
1687             (and (ne (symbol_ref "TARGET_MOVX")
1688                      (const_int 0))
1689                  (eq_attr "alternative" "2"))
1690               (const_string "imovx")
1691            ]
1692            (const_string "imov")))
1693    (set (attr "mode")
1694       (cond [(eq_attr "alternative" "3,4,5")
1695                (const_string "SI")
1696              (eq_attr "alternative" "6")
1697                (const_string "QI")
1698              (eq_attr "type" "imovx")
1699                (const_string "SI")
1700              (and (eq_attr "type" "imov")
1701                   (and (eq_attr "alternative" "0,1")
1702                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1703                                 (const_int 0))
1704                             (and (eq (symbol_ref "optimize_size")
1705                                      (const_int 0))
1706                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1707                                      (const_int 0))))))
1708                (const_string "SI")
1709              ;; Avoid partial register stalls when not using QImode arithmetic
1710              (and (eq_attr "type" "imov")
1711                   (and (eq_attr "alternative" "0,1")
1712                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1713                                 (const_int 0))
1714                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1715                                 (const_int 0)))))
1716                (const_string "SI")
1717            ]
1718            (const_string "QI")))])
1719
1720 (define_expand "reload_outqi"
1721   [(parallel [(match_operand:QI 0 "" "=m")
1722               (match_operand:QI 1 "register_operand" "r")
1723               (match_operand:QI 2 "register_operand" "=&q")])]
1724   ""
1725 {
1726   rtx op0, op1, op2;
1727   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1728
1729   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1730   if (! q_regs_operand (op1, QImode))
1731     {
1732       emit_insn (gen_movqi (op2, op1));
1733       op1 = op2;
1734     }
1735   emit_insn (gen_movqi (op0, op1));
1736   DONE;
1737 })
1738
1739 (define_insn "*swapqi_1"
1740   [(set (match_operand:QI 0 "register_operand" "+r")
1741         (match_operand:QI 1 "register_operand" "+r"))
1742    (set (match_dup 1)
1743         (match_dup 0))]
1744   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1745   "xchg{l}\t%k1, %k0"
1746   [(set_attr "type" "imov")
1747    (set_attr "mode" "SI")
1748    (set_attr "pent_pair" "np")
1749    (set_attr "athlon_decode" "vector")
1750    (set_attr "amdfam10_decode" "vector")])   
1751
1752 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1753 (define_insn "*swapqi_2"
1754   [(set (match_operand:QI 0 "register_operand" "+q")
1755         (match_operand:QI 1 "register_operand" "+q"))
1756    (set (match_dup 1)
1757         (match_dup 0))]
1758   "TARGET_PARTIAL_REG_STALL"
1759   "xchg{b}\t%1, %0"
1760   [(set_attr "type" "imov")
1761    (set_attr "mode" "QI")
1762    (set_attr "pent_pair" "np")
1763    (set_attr "athlon_decode" "vector")])
1764
1765 (define_expand "movstrictqi"
1766   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1767         (match_operand:QI 1 "general_operand" ""))]
1768   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1769 {
1770   /* Don't generate memory->memory moves, go through a register.  */
1771   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1772     operands[1] = force_reg (QImode, operands[1]);
1773 })
1774
1775 (define_insn "*movstrictqi_1"
1776   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1777         (match_operand:QI 1 "general_operand" "*qn,m"))]
1778   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1779    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1780   "mov{b}\t{%1, %0|%0, %1}"
1781   [(set_attr "type" "imov")
1782    (set_attr "mode" "QI")])
1783
1784 (define_insn "*movstrictqi_xor"
1785   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1786         (match_operand:QI 1 "const0_operand" "i"))
1787    (clobber (reg:CC FLAGS_REG))]
1788   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1789   "xor{b}\t%0, %0"
1790   [(set_attr "type" "alu1")
1791    (set_attr "mode" "QI")
1792    (set_attr "length_immediate" "0")])
1793
1794 (define_insn "*movsi_extv_1"
1795   [(set (match_operand:SI 0 "register_operand" "=R")
1796         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1797                          (const_int 8)
1798                          (const_int 8)))]
1799   ""
1800   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1801   [(set_attr "type" "imovx")
1802    (set_attr "mode" "SI")])
1803
1804 (define_insn "*movhi_extv_1"
1805   [(set (match_operand:HI 0 "register_operand" "=R")
1806         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1807                          (const_int 8)
1808                          (const_int 8)))]
1809   ""
1810   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1811   [(set_attr "type" "imovx")
1812    (set_attr "mode" "SI")])
1813
1814 (define_insn "*movqi_extv_1"
1815   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1816         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1817                          (const_int 8)
1818                          (const_int 8)))]
1819   "!TARGET_64BIT"
1820 {
1821   switch (get_attr_type (insn))
1822     {
1823     case TYPE_IMOVX:
1824       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1825     default:
1826       return "mov{b}\t{%h1, %0|%0, %h1}";
1827     }
1828 }
1829   [(set (attr "type")
1830      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1831                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1832                              (ne (symbol_ref "TARGET_MOVX")
1833                                  (const_int 0))))
1834         (const_string "imovx")
1835         (const_string "imov")))
1836    (set (attr "mode")
1837      (if_then_else (eq_attr "type" "imovx")
1838         (const_string "SI")
1839         (const_string "QI")))])
1840
1841 (define_insn "*movqi_extv_1_rex64"
1842   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1843         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1844                          (const_int 8)
1845                          (const_int 8)))]
1846   "TARGET_64BIT"
1847 {
1848   switch (get_attr_type (insn))
1849     {
1850     case TYPE_IMOVX:
1851       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1852     default:
1853       return "mov{b}\t{%h1, %0|%0, %h1}";
1854     }
1855 }
1856   [(set (attr "type")
1857      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1858                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1859                              (ne (symbol_ref "TARGET_MOVX")
1860                                  (const_int 0))))
1861         (const_string "imovx")
1862         (const_string "imov")))
1863    (set (attr "mode")
1864      (if_then_else (eq_attr "type" "imovx")
1865         (const_string "SI")
1866         (const_string "QI")))])
1867
1868 ;; Stores and loads of ax to arbitrary constant address.
1869 ;; We fake an second form of instruction to force reload to load address
1870 ;; into register when rax is not available
1871 (define_insn "*movabsqi_1_rex64"
1872   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1873         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1874   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1875   "@
1876    movabs{b}\t{%1, %P0|%P0, %1}
1877    mov{b}\t{%1, %a0|%a0, %1}"
1878   [(set_attr "type" "imov")
1879    (set_attr "modrm" "0,*")
1880    (set_attr "length_address" "8,0")
1881    (set_attr "length_immediate" "0,*")
1882    (set_attr "memory" "store")
1883    (set_attr "mode" "QI")])
1884
1885 (define_insn "*movabsqi_2_rex64"
1886   [(set (match_operand:QI 0 "register_operand" "=a,r")
1887         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1888   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1889   "@
1890    movabs{b}\t{%P1, %0|%0, %P1}
1891    mov{b}\t{%a1, %0|%0, %a1}"
1892   [(set_attr "type" "imov")
1893    (set_attr "modrm" "0,*")
1894    (set_attr "length_address" "8,0")
1895    (set_attr "length_immediate" "0")
1896    (set_attr "memory" "load")
1897    (set_attr "mode" "QI")])
1898
1899 (define_insn "*movdi_extzv_1"
1900   [(set (match_operand:DI 0 "register_operand" "=R")
1901         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1902                          (const_int 8)
1903                          (const_int 8)))]
1904   "TARGET_64BIT"
1905   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1906   [(set_attr "type" "imovx")
1907    (set_attr "mode" "DI")])
1908
1909 (define_insn "*movsi_extzv_1"
1910   [(set (match_operand:SI 0 "register_operand" "=R")
1911         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1912                          (const_int 8)
1913                          (const_int 8)))]
1914   ""
1915   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1916   [(set_attr "type" "imovx")
1917    (set_attr "mode" "SI")])
1918
1919 (define_insn "*movqi_extzv_2"
1920   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1921         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1922                                     (const_int 8)
1923                                     (const_int 8)) 0))]
1924   "!TARGET_64BIT"
1925 {
1926   switch (get_attr_type (insn))
1927     {
1928     case TYPE_IMOVX:
1929       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1930     default:
1931       return "mov{b}\t{%h1, %0|%0, %h1}";
1932     }
1933 }
1934   [(set (attr "type")
1935      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1936                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1937                              (ne (symbol_ref "TARGET_MOVX")
1938                                  (const_int 0))))
1939         (const_string "imovx")
1940         (const_string "imov")))
1941    (set (attr "mode")
1942      (if_then_else (eq_attr "type" "imovx")
1943         (const_string "SI")
1944         (const_string "QI")))])
1945
1946 (define_insn "*movqi_extzv_2_rex64"
1947   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1948         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1949                                     (const_int 8)
1950                                     (const_int 8)) 0))]
1951   "TARGET_64BIT"
1952 {
1953   switch (get_attr_type (insn))
1954     {
1955     case TYPE_IMOVX:
1956       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1957     default:
1958       return "mov{b}\t{%h1, %0|%0, %h1}";
1959     }
1960 }
1961   [(set (attr "type")
1962      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1963                         (ne (symbol_ref "TARGET_MOVX")
1964                             (const_int 0)))
1965         (const_string "imovx")
1966         (const_string "imov")))
1967    (set (attr "mode")
1968      (if_then_else (eq_attr "type" "imovx")
1969         (const_string "SI")
1970         (const_string "QI")))])
1971
1972 (define_insn "movsi_insv_1"
1973   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1974                          (const_int 8)
1975                          (const_int 8))
1976         (match_operand:SI 1 "general_operand" "Qmn"))]
1977   "!TARGET_64BIT"
1978   "mov{b}\t{%b1, %h0|%h0, %b1}"
1979   [(set_attr "type" "imov")
1980    (set_attr "mode" "QI")])
1981
1982 (define_insn "*movsi_insv_1_rex64"
1983   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1984                          (const_int 8)
1985                          (const_int 8))
1986         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1987   "TARGET_64BIT"
1988   "mov{b}\t{%b1, %h0|%h0, %b1}"
1989   [(set_attr "type" "imov")
1990    (set_attr "mode" "QI")])
1991
1992 (define_insn "movdi_insv_1_rex64"
1993   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1994                          (const_int 8)
1995                          (const_int 8))
1996         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1997   "TARGET_64BIT"
1998   "mov{b}\t{%b1, %h0|%h0, %b1}"
1999   [(set_attr "type" "imov")
2000    (set_attr "mode" "QI")])
2001
2002 (define_insn "*movqi_insv_2"
2003   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2004                          (const_int 8)
2005                          (const_int 8))
2006         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2007                      (const_int 8)))]
2008   ""
2009   "mov{b}\t{%h1, %h0|%h0, %h1}"
2010   [(set_attr "type" "imov")
2011    (set_attr "mode" "QI")])
2012
2013 (define_expand "movdi"
2014   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2015         (match_operand:DI 1 "general_operand" ""))]
2016   ""
2017   "ix86_expand_move (DImode, operands); DONE;")
2018
2019 (define_insn "*pushdi"
2020   [(set (match_operand:DI 0 "push_operand" "=<")
2021         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2022   "!TARGET_64BIT"
2023   "#")
2024
2025 (define_insn "*pushdi2_rex64"
2026   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2027         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2028   "TARGET_64BIT"
2029   "@
2030    push{q}\t%1
2031    #"
2032   [(set_attr "type" "push,multi")
2033    (set_attr "mode" "DI")])
2034
2035 ;; Convert impossible pushes of immediate to existing instructions.
2036 ;; First try to get scratch register and go through it.  In case this
2037 ;; fails, push sign extended lower part first and then overwrite
2038 ;; upper part by 32bit move.
2039 (define_peephole2
2040   [(match_scratch:DI 2 "r")
2041    (set (match_operand:DI 0 "push_operand" "")
2042         (match_operand:DI 1 "immediate_operand" ""))]
2043   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2044    && !x86_64_immediate_operand (operands[1], DImode)"
2045   [(set (match_dup 2) (match_dup 1))
2046    (set (match_dup 0) (match_dup 2))]
2047   "")
2048
2049 ;; We need to define this as both peepholer and splitter for case
2050 ;; peephole2 pass is not run.
2051 ;; "&& 1" is needed to keep it from matching the previous pattern.
2052 (define_peephole2
2053   [(set (match_operand:DI 0 "push_operand" "")
2054         (match_operand:DI 1 "immediate_operand" ""))]
2055   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2056    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2057   [(set (match_dup 0) (match_dup 1))
2058    (set (match_dup 2) (match_dup 3))]
2059   "split_di (operands + 1, 1, operands + 2, operands + 3);
2060    operands[1] = gen_lowpart (DImode, operands[2]);
2061    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2062                                                     GEN_INT (4)));
2063   ")
2064
2065 (define_split
2066   [(set (match_operand:DI 0 "push_operand" "")
2067         (match_operand:DI 1 "immediate_operand" ""))]
2068   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2069                     ? epilogue_completed : reload_completed)
2070    && !symbolic_operand (operands[1], DImode)
2071    && !x86_64_immediate_operand (operands[1], DImode)"
2072   [(set (match_dup 0) (match_dup 1))
2073    (set (match_dup 2) (match_dup 3))]
2074   "split_di (operands + 1, 1, operands + 2, operands + 3);
2075    operands[1] = gen_lowpart (DImode, operands[2]);
2076    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2077                                                     GEN_INT (4)));
2078   ")
2079
2080 (define_insn "*pushdi2_prologue_rex64"
2081   [(set (match_operand:DI 0 "push_operand" "=<")
2082         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2083    (clobber (mem:BLK (scratch)))]
2084   "TARGET_64BIT"
2085   "push{q}\t%1"
2086   [(set_attr "type" "push")
2087    (set_attr "mode" "DI")])
2088
2089 (define_insn "*popdi1_epilogue_rex64"
2090   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2091         (mem:DI (reg:DI SP_REG)))
2092    (set (reg:DI SP_REG)
2093         (plus:DI (reg:DI SP_REG) (const_int 8)))
2094    (clobber (mem:BLK (scratch)))]
2095   "TARGET_64BIT"
2096   "pop{q}\t%0"
2097   [(set_attr "type" "pop")
2098    (set_attr "mode" "DI")])
2099
2100 (define_insn "popdi1"
2101   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2102         (mem:DI (reg:DI SP_REG)))
2103    (set (reg:DI SP_REG)
2104         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2105   "TARGET_64BIT"
2106   "pop{q}\t%0"
2107   [(set_attr "type" "pop")
2108    (set_attr "mode" "DI")])
2109
2110 (define_insn "*movdi_xor_rex64"
2111   [(set (match_operand:DI 0 "register_operand" "=r")
2112         (match_operand:DI 1 "const0_operand" "i"))
2113    (clobber (reg:CC FLAGS_REG))]
2114   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2115    && reload_completed"
2116   "xor{l}\t%k0, %k0";
2117   [(set_attr "type" "alu1")
2118    (set_attr "mode" "SI")
2119    (set_attr "length_immediate" "0")])
2120
2121 (define_insn "*movdi_or_rex64"
2122   [(set (match_operand:DI 0 "register_operand" "=r")
2123         (match_operand:DI 1 "const_int_operand" "i"))
2124    (clobber (reg:CC FLAGS_REG))]
2125   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2126    && reload_completed
2127    && operands[1] == constm1_rtx"
2128 {
2129   operands[1] = constm1_rtx;
2130   return "or{q}\t{%1, %0|%0, %1}";
2131 }
2132   [(set_attr "type" "alu1")
2133    (set_attr "mode" "DI")
2134    (set_attr "length_immediate" "1")])
2135
2136 (define_insn "*movdi_2"
2137   [(set (match_operand:DI 0 "nonimmediate_operand"
2138                         "=r  ,o  ,*y,m*y,*y,*Yt,m  ,*Yt,*Yt,*x,m ,*x,*x")
2139         (match_operand:DI 1 "general_operand"
2140                         "riFo,riF,C ,*y ,m ,C  ,*Yt,*Yt,m  ,C ,*x,*x,m "))]
2141   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2142   "@
2143    #
2144    #
2145    pxor\t%0, %0
2146    movq\t{%1, %0|%0, %1}
2147    movq\t{%1, %0|%0, %1}
2148    pxor\t%0, %0
2149    movq\t{%1, %0|%0, %1}
2150    movdqa\t{%1, %0|%0, %1}
2151    movq\t{%1, %0|%0, %1}
2152    xorps\t%0, %0
2153    movlps\t{%1, %0|%0, %1}
2154    movaps\t{%1, %0|%0, %1}
2155    movlps\t{%1, %0|%0, %1}"
2156   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2157    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2158
2159 (define_split
2160   [(set (match_operand:DI 0 "push_operand" "")
2161         (match_operand:DI 1 "general_operand" ""))]
2162   "!TARGET_64BIT && reload_completed
2163    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2164   [(const_int 0)]
2165   "ix86_split_long_move (operands); DONE;")
2166
2167 ;; %%% This multiword shite has got to go.
2168 (define_split
2169   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2170         (match_operand:DI 1 "general_operand" ""))]
2171   "!TARGET_64BIT && reload_completed
2172    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2173    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2174   [(const_int 0)]
2175   "ix86_split_long_move (operands); DONE;")
2176
2177 (define_insn "*movdi_1_rex64"
2178   [(set (match_operand:DI 0 "nonimmediate_operand"
2179           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2180         (match_operand:DI 1 "general_operand"
2181           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2182   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2183 {
2184   switch (get_attr_type (insn))
2185     {
2186     case TYPE_SSECVT:
2187       if (SSE_REG_P (operands[0]))
2188         return "movq2dq\t{%1, %0|%0, %1}";
2189       else
2190         return "movdq2q\t{%1, %0|%0, %1}";
2191
2192     case TYPE_SSEMOV:
2193       if (get_attr_mode (insn) == MODE_TI)
2194         return "movdqa\t{%1, %0|%0, %1}";
2195       /* FALLTHRU */
2196
2197     case TYPE_MMXMOV:
2198       /* Moves from and into integer register is done using movd
2199          opcode with REX prefix.  */
2200       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2201         return "movd\t{%1, %0|%0, %1}";
2202       return "movq\t{%1, %0|%0, %1}";
2203
2204     case TYPE_SSELOG1:
2205     case TYPE_MMXADD:
2206       return "pxor\t%0, %0";
2207
2208     case TYPE_MULTI:
2209       return "#";
2210
2211     case TYPE_LEA:
2212       return "lea{q}\t{%a1, %0|%0, %a1}";
2213
2214     default:
2215       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2216       if (get_attr_mode (insn) == MODE_SI)
2217         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2218       else if (which_alternative == 2)
2219         return "movabs{q}\t{%1, %0|%0, %1}";
2220       else
2221         return "mov{q}\t{%1, %0|%0, %1}";
2222     }
2223 }
2224   [(set (attr "type")
2225      (cond [(eq_attr "alternative" "5")
2226               (const_string "mmxadd")
2227             (eq_attr "alternative" "6,7,8,9,10")
2228               (const_string "mmxmov")
2229             (eq_attr "alternative" "11")
2230               (const_string "sselog1")
2231             (eq_attr "alternative" "12,13,14,15,16")
2232               (const_string "ssemov")
2233             (eq_attr "alternative" "17,18")
2234               (const_string "ssecvt")
2235             (eq_attr "alternative" "4")
2236               (const_string "multi")
2237             (match_operand:DI 1 "pic_32bit_operand" "")
2238               (const_string "lea")
2239            ]
2240            (const_string "imov")))
2241    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2242    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2243    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2244
2245 ;; Stores and loads of ax to arbitrary constant address.
2246 ;; We fake an second form of instruction to force reload to load address
2247 ;; into register when rax is not available
2248 (define_insn "*movabsdi_1_rex64"
2249   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2250         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2251   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2252   "@
2253    movabs{q}\t{%1, %P0|%P0, %1}
2254    mov{q}\t{%1, %a0|%a0, %1}"
2255   [(set_attr "type" "imov")
2256    (set_attr "modrm" "0,*")
2257    (set_attr "length_address" "8,0")
2258    (set_attr "length_immediate" "0,*")
2259    (set_attr "memory" "store")
2260    (set_attr "mode" "DI")])
2261
2262 (define_insn "*movabsdi_2_rex64"
2263   [(set (match_operand:DI 0 "register_operand" "=a,r")
2264         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2265   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2266   "@
2267    movabs{q}\t{%P1, %0|%0, %P1}
2268    mov{q}\t{%a1, %0|%0, %a1}"
2269   [(set_attr "type" "imov")
2270    (set_attr "modrm" "0,*")
2271    (set_attr "length_address" "8,0")
2272    (set_attr "length_immediate" "0")
2273    (set_attr "memory" "load")
2274    (set_attr "mode" "DI")])
2275
2276 ;; Convert impossible stores of immediate to existing instructions.
2277 ;; First try to get scratch register and go through it.  In case this
2278 ;; fails, move by 32bit parts.
2279 (define_peephole2
2280   [(match_scratch:DI 2 "r")
2281    (set (match_operand:DI 0 "memory_operand" "")
2282         (match_operand:DI 1 "immediate_operand" ""))]
2283   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2284    && !x86_64_immediate_operand (operands[1], DImode)"
2285   [(set (match_dup 2) (match_dup 1))
2286    (set (match_dup 0) (match_dup 2))]
2287   "")
2288
2289 ;; We need to define this as both peepholer and splitter for case
2290 ;; peephole2 pass is not run.
2291 ;; "&& 1" is needed to keep it from matching the previous pattern.
2292 (define_peephole2
2293   [(set (match_operand:DI 0 "memory_operand" "")
2294         (match_operand:DI 1 "immediate_operand" ""))]
2295   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2296    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2297   [(set (match_dup 2) (match_dup 3))
2298    (set (match_dup 4) (match_dup 5))]
2299   "split_di (operands, 2, operands + 2, operands + 4);")
2300
2301 (define_split
2302   [(set (match_operand:DI 0 "memory_operand" "")
2303         (match_operand:DI 1 "immediate_operand" ""))]
2304   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2305                     ? epilogue_completed : reload_completed)
2306    && !symbolic_operand (operands[1], DImode)
2307    && !x86_64_immediate_operand (operands[1], DImode)"
2308   [(set (match_dup 2) (match_dup 3))
2309    (set (match_dup 4) (match_dup 5))]
2310   "split_di (operands, 2, operands + 2, operands + 4);")
2311
2312 (define_insn "*swapdi_rex64"
2313   [(set (match_operand:DI 0 "register_operand" "+r")
2314         (match_operand:DI 1 "register_operand" "+r"))
2315    (set (match_dup 1)
2316         (match_dup 0))]
2317   "TARGET_64BIT"
2318   "xchg{q}\t%1, %0"
2319   [(set_attr "type" "imov")
2320    (set_attr "mode" "DI")
2321    (set_attr "pent_pair" "np")
2322    (set_attr "athlon_decode" "vector")
2323    (set_attr "amdfam10_decode" "double")])   
2324
2325 (define_expand "movti"
2326   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2327         (match_operand:TI 1 "nonimmediate_operand" ""))]
2328   "TARGET_SSE || TARGET_64BIT"
2329 {
2330   if (TARGET_64BIT)
2331     ix86_expand_move (TImode, operands);
2332   else if (push_operand (operands[0], TImode))
2333     ix86_expand_push (TImode, operands[1]);
2334   else
2335     ix86_expand_vector_move (TImode, operands);
2336   DONE;
2337 })
2338
2339 (define_insn "*movti_internal"
2340   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2341         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2342   "TARGET_SSE && !TARGET_64BIT
2343    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2344 {
2345   switch (which_alternative)
2346     {
2347     case 0:
2348       if (get_attr_mode (insn) == MODE_V4SF)
2349         return "xorps\t%0, %0";
2350       else
2351         return "pxor\t%0, %0";
2352     case 1:
2353     case 2:
2354       if (get_attr_mode (insn) == MODE_V4SF)
2355         return "movaps\t{%1, %0|%0, %1}";
2356       else
2357         return "movdqa\t{%1, %0|%0, %1}";
2358     default:
2359       gcc_unreachable ();
2360     }
2361 }
2362   [(set_attr "type" "sselog1,ssemov,ssemov")
2363    (set (attr "mode")
2364         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2365                     (ne (symbol_ref "optimize_size") (const_int 0)))
2366                  (const_string "V4SF")
2367                (and (eq_attr "alternative" "2")
2368                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2369                         (const_int 0)))
2370                  (const_string "V4SF")]
2371               (const_string "TI")))])
2372
2373 (define_insn "*movti_rex64"
2374   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2375         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2376   "TARGET_64BIT
2377    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2378 {
2379   switch (which_alternative)
2380     {
2381     case 0:
2382     case 1:
2383       return "#";
2384     case 2:
2385       if (get_attr_mode (insn) == MODE_V4SF)
2386         return "xorps\t%0, %0";
2387       else
2388         return "pxor\t%0, %0";
2389     case 3:
2390     case 4:
2391       if (get_attr_mode (insn) == MODE_V4SF)
2392         return "movaps\t{%1, %0|%0, %1}";
2393       else
2394         return "movdqa\t{%1, %0|%0, %1}";
2395     default:
2396       gcc_unreachable ();
2397     }
2398 }
2399   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2400    (set (attr "mode")
2401         (cond [(eq_attr "alternative" "2,3")
2402                  (if_then_else
2403                    (ne (symbol_ref "optimize_size")
2404                        (const_int 0))
2405                    (const_string "V4SF")
2406                    (const_string "TI"))
2407                (eq_attr "alternative" "4")
2408                  (if_then_else
2409                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2410                             (const_int 0))
2411                         (ne (symbol_ref "optimize_size")
2412                             (const_int 0)))
2413                    (const_string "V4SF")
2414                    (const_string "TI"))]
2415                (const_string "DI")))])
2416
2417 (define_split
2418   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2419         (match_operand:TI 1 "general_operand" ""))]
2420   "reload_completed && !SSE_REG_P (operands[0])
2421    && !SSE_REG_P (operands[1])"
2422   [(const_int 0)]
2423   "ix86_split_long_move (operands); DONE;")
2424
2425 ;; This expands to what emit_move_complex would generate if we didn't
2426 ;; have a movti pattern.  Having this avoids problems with reload on
2427 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2428 ;; to have around all the time.
2429 (define_expand "movcdi"
2430   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2431         (match_operand:CDI 1 "general_operand" ""))]
2432   ""
2433 {
2434   if (push_operand (operands[0], CDImode))
2435     emit_move_complex_push (CDImode, operands[0], operands[1]);
2436   else
2437     emit_move_complex_parts (operands[0], operands[1]);
2438   DONE;
2439 })
2440
2441 (define_expand "movsf"
2442   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2443         (match_operand:SF 1 "general_operand" ""))]
2444   ""
2445   "ix86_expand_move (SFmode, operands); DONE;")
2446
2447 (define_insn "*pushsf"
2448   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2449         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2450   "!TARGET_64BIT"
2451 {
2452   /* Anything else should be already split before reg-stack.  */
2453   gcc_assert (which_alternative == 1);
2454   return "push{l}\t%1";
2455 }
2456   [(set_attr "type" "multi,push,multi")
2457    (set_attr "unit" "i387,*,*")
2458    (set_attr "mode" "SF,SI,SF")])
2459
2460 (define_insn "*pushsf_rex64"
2461   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2462         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2463   "TARGET_64BIT"
2464 {
2465   /* Anything else should be already split before reg-stack.  */
2466   gcc_assert (which_alternative == 1);
2467   return "push{q}\t%q1";
2468 }
2469   [(set_attr "type" "multi,push,multi")
2470    (set_attr "unit" "i387,*,*")
2471    (set_attr "mode" "SF,DI,SF")])
2472
2473 (define_split
2474   [(set (match_operand:SF 0 "push_operand" "")
2475         (match_operand:SF 1 "memory_operand" ""))]
2476   "reload_completed
2477    && MEM_P (operands[1])
2478    && (operands[2] = find_constant_src (insn))"
2479   [(set (match_dup 0)
2480         (match_dup 2))])
2481
2482
2483 ;; %%% Kill this when call knows how to work this out.
2484 (define_split
2485   [(set (match_operand:SF 0 "push_operand" "")
2486         (match_operand:SF 1 "any_fp_register_operand" ""))]
2487   "!TARGET_64BIT"
2488   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2489    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2490
2491 (define_split
2492   [(set (match_operand:SF 0 "push_operand" "")
2493         (match_operand:SF 1 "any_fp_register_operand" ""))]
2494   "TARGET_64BIT"
2495   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2496    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2497
2498 (define_insn "*movsf_1"
2499   [(set (match_operand:SF 0 "nonimmediate_operand"
2500           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2501         (match_operand:SF 1 "general_operand"
2502           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2503   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2504    && (reload_in_progress || reload_completed
2505        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2506        || (!TARGET_SSE_MATH && optimize_size
2507            && standard_80387_constant_p (operands[1]))
2508        || GET_CODE (operands[1]) != CONST_DOUBLE
2509        || memory_operand (operands[0], SFmode))"
2510 {
2511   switch (which_alternative)
2512     {
2513     case 0:
2514     case 1:
2515       return output_387_reg_move (insn, operands);
2516
2517     case 2:
2518       return standard_80387_constant_opcode (operands[1]);
2519
2520     case 3:
2521     case 4:
2522       return "mov{l}\t{%1, %0|%0, %1}";
2523     case 5:
2524       if (get_attr_mode (insn) == MODE_TI)
2525         return "pxor\t%0, %0";
2526       else
2527         return "xorps\t%0, %0";
2528     case 6:
2529       if (get_attr_mode (insn) == MODE_V4SF)
2530         return "movaps\t{%1, %0|%0, %1}";
2531       else
2532         return "movss\t{%1, %0|%0, %1}";
2533     case 7: case 8:
2534       return "movss\t{%1, %0|%0, %1}";
2535
2536     case 9: case 10:
2537     case 12: case 13: case 14: case 15:
2538       return "movd\t{%1, %0|%0, %1}";
2539
2540     case 11:
2541       return "movq\t{%1, %0|%0, %1}";
2542
2543     default:
2544       gcc_unreachable ();
2545     }
2546 }
2547   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2548    (set (attr "mode")
2549         (cond [(eq_attr "alternative" "3,4,9,10")
2550                  (const_string "SI")
2551                (eq_attr "alternative" "5")
2552                  (if_then_else
2553                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2554                                  (const_int 0))
2555                              (ne (symbol_ref "TARGET_SSE2")
2556                                  (const_int 0)))
2557                         (eq (symbol_ref "optimize_size")
2558                             (const_int 0)))
2559                    (const_string "TI")
2560                    (const_string "V4SF"))
2561                /* For architectures resolving dependencies on
2562                   whole SSE registers use APS move to break dependency
2563                   chains, otherwise use short move to avoid extra work.
2564
2565                   Do the same for architectures resolving dependencies on
2566                   the parts.  While in DF mode it is better to always handle
2567                   just register parts, the SF mode is different due to lack
2568                   of instructions to load just part of the register.  It is
2569                   better to maintain the whole registers in single format
2570                   to avoid problems on using packed logical operations.  */
2571                (eq_attr "alternative" "6")
2572                  (if_then_else
2573                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2574                             (const_int 0))
2575                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2576                             (const_int 0)))
2577                    (const_string "V4SF")
2578                    (const_string "SF"))
2579                (eq_attr "alternative" "11")
2580                  (const_string "DI")]
2581                (const_string "SF")))])
2582
2583 (define_insn "*swapsf"
2584   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2585         (match_operand:SF 1 "fp_register_operand" "+f"))
2586    (set (match_dup 1)
2587         (match_dup 0))]
2588   "reload_completed || TARGET_80387"
2589 {
2590   if (STACK_TOP_P (operands[0]))
2591     return "fxch\t%1";
2592   else
2593     return "fxch\t%0";
2594 }
2595   [(set_attr "type" "fxch")
2596    (set_attr "mode" "SF")])
2597
2598 (define_expand "movdf"
2599   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2600         (match_operand:DF 1 "general_operand" ""))]
2601   ""
2602   "ix86_expand_move (DFmode, operands); DONE;")
2603
2604 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2605 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2606 ;; On the average, pushdf using integers can be still shorter.  Allow this
2607 ;; pattern for optimize_size too.
2608
2609 (define_insn "*pushdf_nointeger"
2610   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2611         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Yt"))]
2612   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2613 {
2614   /* This insn should be already split before reg-stack.  */
2615   gcc_unreachable ();
2616 }
2617   [(set_attr "type" "multi")
2618    (set_attr "unit" "i387,*,*,*")
2619    (set_attr "mode" "DF,SI,SI,DF")])
2620
2621 (define_insn "*pushdf_integer"
2622   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2623         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Yt"))]
2624   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2625 {
2626   /* This insn should be already split before reg-stack.  */
2627   gcc_unreachable ();
2628 }
2629   [(set_attr "type" "multi")
2630    (set_attr "unit" "i387,*,*")
2631    (set_attr "mode" "DF,SI,DF")])
2632
2633 ;; %%% Kill this when call knows how to work this out.
2634 (define_split
2635   [(set (match_operand:DF 0 "push_operand" "")
2636         (match_operand:DF 1 "any_fp_register_operand" ""))]
2637   "!TARGET_64BIT && reload_completed"
2638   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2639    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2640   "")
2641
2642 (define_split
2643   [(set (match_operand:DF 0 "push_operand" "")
2644         (match_operand:DF 1 "any_fp_register_operand" ""))]
2645   "TARGET_64BIT && reload_completed"
2646   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2647    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2648   "")
2649
2650 (define_split
2651   [(set (match_operand:DF 0 "push_operand" "")
2652         (match_operand:DF 1 "general_operand" ""))]
2653   "reload_completed"
2654   [(const_int 0)]
2655   "ix86_split_long_move (operands); DONE;")
2656
2657 ;; Moving is usually shorter when only FP registers are used. This separate
2658 ;; movdf pattern avoids the use of integer registers for FP operations
2659 ;; when optimizing for size.
2660
2661 (define_insn "*movdf_nointeger"
2662   [(set (match_operand:DF 0 "nonimmediate_operand"
2663                         "=f,m,f,*r  ,o  ,Yt*x,Yt*x,Yt*x ,m  ")
2664         (match_operand:DF 1 "general_operand"
2665                         "fm,f,G,*roF,F*r,C   ,Yt*x,mYt*x,Yt*x"))]
2666   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2667    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2668    && (reload_in_progress || reload_completed
2669        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2670        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2671            && standard_80387_constant_p (operands[1]))
2672        || GET_CODE (operands[1]) != CONST_DOUBLE
2673        || memory_operand (operands[0], DFmode))"
2674 {
2675   switch (which_alternative)
2676     {
2677     case 0:
2678     case 1:
2679       return output_387_reg_move (insn, operands);
2680
2681     case 2:
2682       return standard_80387_constant_opcode (operands[1]);
2683
2684     case 3:
2685     case 4:
2686       return "#";
2687     case 5:
2688       switch (get_attr_mode (insn))
2689         {
2690         case MODE_V4SF:
2691           return "xorps\t%0, %0";
2692         case MODE_V2DF:
2693           return "xorpd\t%0, %0";
2694         case MODE_TI:
2695           return "pxor\t%0, %0";
2696         default:
2697           gcc_unreachable ();
2698         }
2699     case 6:
2700     case 7:
2701     case 8:
2702       switch (get_attr_mode (insn))
2703         {
2704         case MODE_V4SF:
2705           return "movaps\t{%1, %0|%0, %1}";
2706         case MODE_V2DF:
2707           return "movapd\t{%1, %0|%0, %1}";
2708         case MODE_TI:
2709           return "movdqa\t{%1, %0|%0, %1}";
2710         case MODE_DI:
2711           return "movq\t{%1, %0|%0, %1}";
2712         case MODE_DF:
2713           return "movsd\t{%1, %0|%0, %1}";
2714         case MODE_V1DF:
2715           return "movlpd\t{%1, %0|%0, %1}";
2716         case MODE_V2SF:
2717           return "movlps\t{%1, %0|%0, %1}";
2718         default:
2719           gcc_unreachable ();
2720         }
2721
2722     default:
2723       gcc_unreachable ();
2724     }
2725 }
2726   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2727    (set (attr "mode")
2728         (cond [(eq_attr "alternative" "0,1,2")
2729                  (const_string "DF")
2730                (eq_attr "alternative" "3,4")
2731                  (const_string "SI")
2732
2733                /* For SSE1, we have many fewer alternatives.  */
2734                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2735                  (cond [(eq_attr "alternative" "5,6")
2736                           (const_string "V4SF")
2737                        ]
2738                    (const_string "V2SF"))
2739
2740                /* xorps is one byte shorter.  */
2741                (eq_attr "alternative" "5")
2742                  (cond [(ne (symbol_ref "optimize_size")
2743                             (const_int 0))
2744                           (const_string "V4SF")
2745                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2746                             (const_int 0))
2747                           (const_string "TI")
2748                        ]
2749                        (const_string "V2DF"))
2750
2751                /* For architectures resolving dependencies on
2752                   whole SSE registers use APD move to break dependency
2753                   chains, otherwise use short move to avoid extra work.
2754
2755                   movaps encodes one byte shorter.  */
2756                (eq_attr "alternative" "6")
2757                  (cond
2758                    [(ne (symbol_ref "optimize_size")
2759                         (const_int 0))
2760                       (const_string "V4SF")
2761                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2762                         (const_int 0))
2763                       (const_string "V2DF")
2764                    ]
2765                    (const_string "DF"))
2766                /* For architectures resolving dependencies on register
2767                   parts we may avoid extra work to zero out upper part
2768                   of register.  */
2769                (eq_attr "alternative" "7")
2770                  (if_then_else
2771                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2772                        (const_int 0))
2773                    (const_string "V1DF")
2774                    (const_string "DF"))
2775               ]
2776               (const_string "DF")))])
2777
2778 (define_insn "*movdf_integer_rex64"
2779   [(set (match_operand:DF 0 "nonimmediate_operand"
2780                 "=f,m,f,r  ,m ,Yt*x,Yt*x,Yt*x,m   ,Yi,r ")
2781         (match_operand:DF 1 "general_operand"
2782                 "fm,f,G,rmF,Fr,C   ,Yt*x,m   ,Yt*x,r ,Yi"))]
2783   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2784    && (reload_in_progress || reload_completed
2785        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2786        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2787            && standard_80387_constant_p (operands[1]))
2788        || GET_CODE (operands[1]) != CONST_DOUBLE
2789        || memory_operand (operands[0], DFmode))"
2790 {
2791   switch (which_alternative)
2792     {
2793     case 0:
2794     case 1:
2795       return output_387_reg_move (insn, operands);
2796
2797     case 2:
2798       return standard_80387_constant_opcode (operands[1]);
2799
2800     case 3:
2801     case 4:
2802       return "#";
2803
2804     case 5:
2805       switch (get_attr_mode (insn))
2806         {
2807         case MODE_V4SF:
2808           return "xorps\t%0, %0";
2809         case MODE_V2DF:
2810           return "xorpd\t%0, %0";
2811         case MODE_TI:
2812           return "pxor\t%0, %0";
2813         default:
2814           gcc_unreachable ();
2815         }
2816     case 6:
2817     case 7:
2818     case 8:
2819       switch (get_attr_mode (insn))
2820         {
2821         case MODE_V4SF:
2822           return "movaps\t{%1, %0|%0, %1}";
2823         case MODE_V2DF:
2824           return "movapd\t{%1, %0|%0, %1}";
2825         case MODE_TI:
2826           return "movdqa\t{%1, %0|%0, %1}";
2827         case MODE_DI:
2828           return "movq\t{%1, %0|%0, %1}";
2829         case MODE_DF:
2830           return "movsd\t{%1, %0|%0, %1}";
2831         case MODE_V1DF:
2832           return "movlpd\t{%1, %0|%0, %1}";
2833         case MODE_V2SF:
2834           return "movlps\t{%1, %0|%0, %1}";
2835         default:
2836           gcc_unreachable ();
2837         }
2838
2839     case 9:
2840     case 10:
2841       return "movd\t{%1, %0|%0, %1}";
2842
2843     default:
2844       gcc_unreachable();
2845     }
2846 }
2847   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2848    (set (attr "mode")
2849         (cond [(eq_attr "alternative" "0,1,2")
2850                  (const_string "DF")
2851                (eq_attr "alternative" "3,4,9,10")
2852                  (const_string "DI")
2853
2854                /* For SSE1, we have many fewer alternatives.  */
2855                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2856                  (cond [(eq_attr "alternative" "5,6")
2857                           (const_string "V4SF")
2858                        ]
2859                    (const_string "V2SF"))
2860
2861                /* xorps is one byte shorter.  */
2862                (eq_attr "alternative" "5")
2863                  (cond [(ne (symbol_ref "optimize_size")
2864                             (const_int 0))
2865                           (const_string "V4SF")
2866                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2867                             (const_int 0))
2868                           (const_string "TI")
2869                        ]
2870                        (const_string "V2DF"))
2871
2872                /* For architectures resolving dependencies on
2873                   whole SSE registers use APD move to break dependency
2874                   chains, otherwise use short move to avoid extra work.
2875
2876                   movaps encodes one byte shorter.  */
2877                (eq_attr "alternative" "6")
2878                  (cond
2879                    [(ne (symbol_ref "optimize_size")
2880                         (const_int 0))
2881                       (const_string "V4SF")
2882                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2883                         (const_int 0))
2884                       (const_string "V2DF")
2885                    ]
2886                    (const_string "DF"))
2887                /* For architectures resolving dependencies on register
2888                   parts we may avoid extra work to zero out upper part
2889                   of register.  */
2890                (eq_attr "alternative" "7")
2891                  (if_then_else
2892                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2893                        (const_int 0))
2894                    (const_string "V1DF")
2895                    (const_string "DF"))
2896               ]
2897               (const_string "DF")))])
2898
2899 (define_insn "*movdf_integer"
2900   [(set (match_operand:DF 0 "nonimmediate_operand"
2901                 "=f,m,f,r  ,o ,Yt*x,Yt*x,Yt*x,m   ")
2902         (match_operand:DF 1 "general_operand"
2903                 "fm,f,G,roF,Fr,C   ,Yt*x,m   ,Yt*x"))]
2904   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2905    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2906    && (reload_in_progress || reload_completed
2907        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2908        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2909            && standard_80387_constant_p (operands[1]))
2910        || GET_CODE (operands[1]) != CONST_DOUBLE
2911        || memory_operand (operands[0], DFmode))"
2912 {
2913   switch (which_alternative)
2914     {
2915     case 0:
2916     case 1:
2917       return output_387_reg_move (insn, operands);
2918
2919     case 2:
2920       return standard_80387_constant_opcode (operands[1]);
2921
2922     case 3:
2923     case 4:
2924       return "#";
2925
2926     case 5:
2927       switch (get_attr_mode (insn))
2928         {
2929         case MODE_V4SF:
2930           return "xorps\t%0, %0";
2931         case MODE_V2DF:
2932           return "xorpd\t%0, %0";
2933         case MODE_TI:
2934           return "pxor\t%0, %0";
2935         default:
2936           gcc_unreachable ();
2937         }
2938     case 6:
2939     case 7:
2940     case 8:
2941       switch (get_attr_mode (insn))
2942         {
2943         case MODE_V4SF:
2944           return "movaps\t{%1, %0|%0, %1}";
2945         case MODE_V2DF:
2946           return "movapd\t{%1, %0|%0, %1}";
2947         case MODE_TI:
2948           return "movdqa\t{%1, %0|%0, %1}";
2949         case MODE_DI:
2950           return "movq\t{%1, %0|%0, %1}";
2951         case MODE_DF:
2952           return "movsd\t{%1, %0|%0, %1}";
2953         case MODE_V1DF:
2954           return "movlpd\t{%1, %0|%0, %1}";
2955         case MODE_V2SF:
2956           return "movlps\t{%1, %0|%0, %1}";
2957         default:
2958           gcc_unreachable ();
2959         }
2960
2961     default:
2962       gcc_unreachable();
2963     }
2964 }
2965   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2966    (set (attr "mode")
2967         (cond [(eq_attr "alternative" "0,1,2")
2968                  (const_string "DF")
2969                (eq_attr "alternative" "3,4")
2970                  (const_string "SI")
2971
2972                /* For SSE1, we have many fewer alternatives.  */
2973                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2974                  (cond [(eq_attr "alternative" "5,6")
2975                           (const_string "V4SF")
2976                        ]
2977                    (const_string "V2SF"))
2978
2979                /* xorps is one byte shorter.  */
2980                (eq_attr "alternative" "5")
2981                  (cond [(ne (symbol_ref "optimize_size")
2982                             (const_int 0))
2983                           (const_string "V4SF")
2984                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2985                             (const_int 0))
2986                           (const_string "TI")
2987                        ]
2988                        (const_string "V2DF"))
2989
2990                /* For architectures resolving dependencies on
2991                   whole SSE registers use APD move to break dependency
2992                   chains, otherwise use short move to avoid extra work.
2993
2994                   movaps encodes one byte shorter.  */
2995                (eq_attr "alternative" "6")
2996                  (cond
2997                    [(ne (symbol_ref "optimize_size")
2998                         (const_int 0))
2999                       (const_string "V4SF")
3000                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3001                         (const_int 0))
3002                       (const_string "V2DF")
3003                    ]
3004                    (const_string "DF"))
3005                /* For architectures resolving dependencies on register
3006                   parts we may avoid extra work to zero out upper part
3007                   of register.  */
3008                (eq_attr "alternative" "7")
3009                  (if_then_else
3010                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3011                        (const_int 0))
3012                    (const_string "V1DF")
3013                    (const_string "DF"))
3014               ]
3015               (const_string "DF")))])
3016
3017 (define_split
3018   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3019         (match_operand:DF 1 "general_operand" ""))]
3020   "reload_completed
3021    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3022    && ! (ANY_FP_REG_P (operands[0]) ||
3023          (GET_CODE (operands[0]) == SUBREG
3024           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3025    && ! (ANY_FP_REG_P (operands[1]) ||
3026          (GET_CODE (operands[1]) == SUBREG
3027           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3028   [(const_int 0)]
3029   "ix86_split_long_move (operands); DONE;")
3030
3031 (define_insn "*swapdf"
3032   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3033         (match_operand:DF 1 "fp_register_operand" "+f"))
3034    (set (match_dup 1)
3035         (match_dup 0))]
3036   "reload_completed || TARGET_80387"
3037 {
3038   if (STACK_TOP_P (operands[0]))
3039     return "fxch\t%1";
3040   else
3041     return "fxch\t%0";
3042 }
3043   [(set_attr "type" "fxch")
3044    (set_attr "mode" "DF")])
3045
3046 (define_expand "movxf"
3047   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3048         (match_operand:XF 1 "general_operand" ""))]
3049   ""
3050   "ix86_expand_move (XFmode, operands); DONE;")
3051
3052 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3053 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3054 ;; Pushing using integer instructions is longer except for constants
3055 ;; and direct memory references.
3056 ;; (assuming that any given constant is pushed only once, but this ought to be
3057 ;;  handled elsewhere).
3058
3059 (define_insn "*pushxf_nointeger"
3060   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3061         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3062   "optimize_size"
3063 {
3064   /* This insn should be already split before reg-stack.  */
3065   gcc_unreachable ();
3066 }
3067   [(set_attr "type" "multi")
3068    (set_attr "unit" "i387,*,*")
3069    (set_attr "mode" "XF,SI,SI")])
3070
3071 (define_insn "*pushxf_integer"
3072   [(set (match_operand:XF 0 "push_operand" "=<,<")
3073         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3074   "!optimize_size"
3075 {
3076   /* This insn should be already split before reg-stack.  */
3077   gcc_unreachable ();
3078 }
3079   [(set_attr "type" "multi")
3080    (set_attr "unit" "i387,*")
3081    (set_attr "mode" "XF,SI")])
3082
3083 (define_split
3084   [(set (match_operand 0 "push_operand" "")
3085         (match_operand 1 "general_operand" ""))]
3086   "reload_completed
3087    && (GET_MODE (operands[0]) == XFmode
3088        || GET_MODE (operands[0]) == DFmode)
3089    && !ANY_FP_REG_P (operands[1])"
3090   [(const_int 0)]
3091   "ix86_split_long_move (operands); DONE;")
3092
3093 (define_split
3094   [(set (match_operand:XF 0 "push_operand" "")
3095         (match_operand:XF 1 "any_fp_register_operand" ""))]
3096   "!TARGET_64BIT"
3097   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3098    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3099   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3100
3101 (define_split
3102   [(set (match_operand:XF 0 "push_operand" "")
3103         (match_operand:XF 1 "any_fp_register_operand" ""))]
3104   "TARGET_64BIT"
3105   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3106    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3107   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3108
3109 ;; Do not use integer registers when optimizing for size
3110 (define_insn "*movxf_nointeger"
3111   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3112         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3113   "optimize_size
3114    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3115    && (reload_in_progress || reload_completed
3116        || (optimize_size && standard_80387_constant_p (operands[1]))
3117        || GET_CODE (operands[1]) != CONST_DOUBLE
3118        || memory_operand (operands[0], XFmode))"
3119 {
3120   switch (which_alternative)
3121     {
3122     case 0:
3123     case 1:
3124       return output_387_reg_move (insn, operands);
3125
3126     case 2:
3127       return standard_80387_constant_opcode (operands[1]);
3128
3129     case 3: case 4:
3130       return "#";
3131     default:
3132       gcc_unreachable ();
3133     }
3134 }
3135   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3136    (set_attr "mode" "XF,XF,XF,SI,SI")])
3137
3138 (define_insn "*movxf_integer"
3139   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3140         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3141   "!optimize_size
3142    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3143    && (reload_in_progress || reload_completed
3144        || (optimize_size && standard_80387_constant_p (operands[1]))
3145        || GET_CODE (operands[1]) != CONST_DOUBLE
3146        || memory_operand (operands[0], XFmode))"
3147 {
3148   switch (which_alternative)
3149     {
3150     case 0:
3151     case 1:
3152       return output_387_reg_move (insn, operands);
3153
3154     case 2:
3155       return standard_80387_constant_opcode (operands[1]);
3156
3157     case 3: case 4:
3158       return "#";
3159
3160     default:
3161       gcc_unreachable ();
3162     }
3163 }
3164   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3165    (set_attr "mode" "XF,XF,XF,SI,SI")])
3166
3167 (define_expand "movtf"
3168   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3169         (match_operand:TF 1 "nonimmediate_operand" ""))]
3170   "TARGET_64BIT"
3171 {
3172   ix86_expand_move (TFmode, operands);
3173   DONE;
3174 })
3175
3176 (define_insn "*movtf_internal"
3177   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3178         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3179   "TARGET_64BIT
3180    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3181 {
3182   switch (which_alternative)
3183     {
3184     case 0:
3185     case 1:
3186       if (get_attr_mode (insn) == MODE_V4SF)
3187         return "movaps\t{%1, %0|%0, %1}";
3188       else
3189         return "movdqa\t{%1, %0|%0, %1}";
3190     case 2:
3191       if (get_attr_mode (insn) == MODE_V4SF)
3192         return "xorps\t%0, %0";
3193       else
3194         return "pxor\t%0, %0";
3195     case 3:
3196     case 4:
3197         return "#";
3198     default:
3199       gcc_unreachable ();
3200     }
3201 }
3202   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3203    (set (attr "mode")
3204         (cond [(eq_attr "alternative" "0,2")
3205                  (if_then_else
3206                    (ne (symbol_ref "optimize_size")
3207                        (const_int 0))
3208                    (const_string "V4SF")
3209                    (const_string "TI"))
3210                (eq_attr "alternative" "1")
3211                  (if_then_else
3212                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3213                             (const_int 0))
3214                         (ne (symbol_ref "optimize_size")
3215                             (const_int 0)))
3216                    (const_string "V4SF")
3217                    (const_string "TI"))]
3218                (const_string "DI")))])
3219
3220 (define_split
3221   [(set (match_operand 0 "nonimmediate_operand" "")
3222         (match_operand 1 "general_operand" ""))]
3223   "reload_completed
3224    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3225    && GET_MODE (operands[0]) == XFmode
3226    && ! (ANY_FP_REG_P (operands[0]) ||
3227          (GET_CODE (operands[0]) == SUBREG
3228           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3229    && ! (ANY_FP_REG_P (operands[1]) ||
3230          (GET_CODE (operands[1]) == SUBREG
3231           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3232   [(const_int 0)]
3233   "ix86_split_long_move (operands); DONE;")
3234
3235 (define_split
3236   [(set (match_operand 0 "register_operand" "")
3237         (match_operand 1 "memory_operand" ""))]
3238   "reload_completed
3239    && MEM_P (operands[1])
3240    && (GET_MODE (operands[0]) == TFmode
3241        || GET_MODE (operands[0]) == XFmode
3242        || GET_MODE (operands[0]) == SFmode
3243        || GET_MODE (operands[0]) == DFmode)
3244    && (operands[2] = find_constant_src (insn))"
3245   [(set (match_dup 0) (match_dup 2))]
3246 {
3247   rtx c = operands[2];
3248   rtx r = operands[0];
3249
3250   if (GET_CODE (r) == SUBREG)
3251     r = SUBREG_REG (r);
3252
3253   if (SSE_REG_P (r))
3254     {
3255       if (!standard_sse_constant_p (c))
3256         FAIL;
3257     }
3258   else if (FP_REG_P (r))
3259     {
3260       if (!standard_80387_constant_p (c))
3261         FAIL;
3262     }
3263   else if (MMX_REG_P (r))
3264     FAIL;
3265 })
3266
3267 (define_split
3268   [(set (match_operand 0 "register_operand" "")
3269         (float_extend (match_operand 1 "memory_operand" "")))]
3270   "reload_completed
3271    && MEM_P (operands[1])
3272    && (GET_MODE (operands[0]) == TFmode
3273        || GET_MODE (operands[0]) == XFmode
3274        || GET_MODE (operands[0]) == SFmode
3275        || GET_MODE (operands[0]) == DFmode)
3276    && (operands[2] = find_constant_src (insn))"
3277   [(set (match_dup 0) (match_dup 2))]
3278 {
3279   rtx c = operands[2];
3280   rtx r = operands[0];
3281
3282   if (GET_CODE (r) == SUBREG)
3283     r = SUBREG_REG (r);
3284
3285   if (SSE_REG_P (r))
3286     {
3287       if (!standard_sse_constant_p (c))
3288         FAIL;
3289     }
3290   else if (FP_REG_P (r))
3291     {
3292       if (!standard_80387_constant_p (c))
3293         FAIL;
3294     }
3295   else if (MMX_REG_P (r))
3296     FAIL;
3297 })
3298
3299 (define_insn "swapxf"
3300   [(set (match_operand:XF 0 "register_operand" "+f")
3301         (match_operand:XF 1 "register_operand" "+f"))
3302    (set (match_dup 1)
3303         (match_dup 0))]
3304   "TARGET_80387"
3305 {
3306   if (STACK_TOP_P (operands[0]))
3307     return "fxch\t%1";
3308   else
3309     return "fxch\t%0";
3310 }
3311   [(set_attr "type" "fxch")
3312    (set_attr "mode" "XF")])
3313
3314 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3315 (define_split
3316   [(set (match_operand:X87MODEF 0 "register_operand" "")
3317         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3318   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3319    && (standard_80387_constant_p (operands[1]) == 8
3320        || standard_80387_constant_p (operands[1]) == 9)"
3321   [(set (match_dup 0)(match_dup 1))
3322    (set (match_dup 0)
3323         (neg:X87MODEF (match_dup 0)))]
3324 {
3325   REAL_VALUE_TYPE r;
3326
3327   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3328   if (real_isnegzero (&r))
3329     operands[1] = CONST0_RTX (<MODE>mode);
3330   else
3331     operands[1] = CONST1_RTX (<MODE>mode);
3332 })
3333
3334 (define_split
3335   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3336         (match_operand:TF 1 "general_operand" ""))]
3337   "reload_completed
3338    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3339   [(const_int 0)]
3340   "ix86_split_long_move (operands); DONE;")
3341 \f
3342 ;; Zero extension instructions
3343
3344 (define_expand "zero_extendhisi2"
3345   [(set (match_operand:SI 0 "register_operand" "")
3346      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3347   ""
3348 {
3349   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3350     {
3351       operands[1] = force_reg (HImode, operands[1]);
3352       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3353       DONE;
3354     }
3355 })
3356
3357 (define_insn "zero_extendhisi2_and"
3358   [(set (match_operand:SI 0 "register_operand" "=r")
3359      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3360    (clobber (reg:CC FLAGS_REG))]
3361   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3362   "#"
3363   [(set_attr "type" "alu1")
3364    (set_attr "mode" "SI")])
3365
3366 (define_split
3367   [(set (match_operand:SI 0 "register_operand" "")
3368         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3369    (clobber (reg:CC FLAGS_REG))]
3370   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3371   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3372               (clobber (reg:CC FLAGS_REG))])]
3373   "")
3374
3375 (define_insn "*zero_extendhisi2_movzwl"
3376   [(set (match_operand:SI 0 "register_operand" "=r")
3377      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3378   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3379   "movz{wl|x}\t{%1, %0|%0, %1}"
3380   [(set_attr "type" "imovx")
3381    (set_attr "mode" "SI")])
3382
3383 (define_expand "zero_extendqihi2"
3384   [(parallel
3385     [(set (match_operand:HI 0 "register_operand" "")
3386        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3387      (clobber (reg:CC FLAGS_REG))])]
3388   ""
3389   "")
3390
3391 (define_insn "*zero_extendqihi2_and"
3392   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3393      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3394    (clobber (reg:CC FLAGS_REG))]
3395   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3396   "#"
3397   [(set_attr "type" "alu1")
3398    (set_attr "mode" "HI")])
3399
3400 (define_insn "*zero_extendqihi2_movzbw_and"
3401   [(set (match_operand:HI 0 "register_operand" "=r,r")
3402      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3403    (clobber (reg:CC FLAGS_REG))]
3404   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3405   "#"
3406   [(set_attr "type" "imovx,alu1")
3407    (set_attr "mode" "HI")])
3408
3409 ; zero extend to SImode here to avoid partial register stalls
3410 (define_insn "*zero_extendqihi2_movzbl"
3411   [(set (match_operand:HI 0 "register_operand" "=r")
3412      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3413   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3414   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3415   [(set_attr "type" "imovx")
3416    (set_attr "mode" "SI")])
3417
3418 ;; For the movzbw case strip only the clobber
3419 (define_split
3420   [(set (match_operand:HI 0 "register_operand" "")
3421         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3422    (clobber (reg:CC FLAGS_REG))]
3423   "reload_completed
3424    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3425    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3426   [(set (match_operand:HI 0 "register_operand" "")
3427         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3428
3429 ;; When source and destination does not overlap, clear destination
3430 ;; first and then do the movb
3431 (define_split
3432   [(set (match_operand:HI 0 "register_operand" "")
3433         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3434    (clobber (reg:CC FLAGS_REG))]
3435   "reload_completed
3436    && ANY_QI_REG_P (operands[0])
3437    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3438    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3439   [(set (match_dup 0) (const_int 0))
3440    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3441   "operands[2] = gen_lowpart (QImode, operands[0]);")
3442
3443 ;; Rest is handled by single and.
3444 (define_split
3445   [(set (match_operand:HI 0 "register_operand" "")
3446         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3447    (clobber (reg:CC FLAGS_REG))]
3448   "reload_completed
3449    && true_regnum (operands[0]) == true_regnum (operands[1])"
3450   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3451               (clobber (reg:CC FLAGS_REG))])]
3452   "")
3453
3454 (define_expand "zero_extendqisi2"
3455   [(parallel
3456     [(set (match_operand:SI 0 "register_operand" "")
3457        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3458      (clobber (reg:CC FLAGS_REG))])]
3459   ""
3460   "")
3461
3462 (define_insn "*zero_extendqisi2_and"
3463   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3464      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3465    (clobber (reg:CC FLAGS_REG))]
3466   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3467   "#"
3468   [(set_attr "type" "alu1")
3469    (set_attr "mode" "SI")])
3470
3471 (define_insn "*zero_extendqisi2_movzbw_and"
3472   [(set (match_operand:SI 0 "register_operand" "=r,r")
3473      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3474    (clobber (reg:CC FLAGS_REG))]
3475   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3476   "#"
3477   [(set_attr "type" "imovx,alu1")
3478    (set_attr "mode" "SI")])
3479
3480 (define_insn "*zero_extendqisi2_movzbw"
3481   [(set (match_operand:SI 0 "register_operand" "=r")
3482      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3483   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3484   "movz{bl|x}\t{%1, %0|%0, %1}"
3485   [(set_attr "type" "imovx")
3486    (set_attr "mode" "SI")])
3487
3488 ;; For the movzbl case strip only the clobber
3489 (define_split
3490   [(set (match_operand:SI 0 "register_operand" "")
3491         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3492    (clobber (reg:CC FLAGS_REG))]
3493   "reload_completed
3494    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3495    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3496   [(set (match_dup 0)
3497         (zero_extend:SI (match_dup 1)))])
3498
3499 ;; When source and destination does not overlap, clear destination
3500 ;; first and then do the movb
3501 (define_split
3502   [(set (match_operand:SI 0 "register_operand" "")
3503         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3504    (clobber (reg:CC FLAGS_REG))]
3505   "reload_completed
3506    && ANY_QI_REG_P (operands[0])
3507    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3508    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3509    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3510   [(set (match_dup 0) (const_int 0))
3511    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3512   "operands[2] = gen_lowpart (QImode, operands[0]);")
3513
3514 ;; Rest is handled by single and.
3515 (define_split
3516   [(set (match_operand:SI 0 "register_operand" "")
3517         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3518    (clobber (reg:CC FLAGS_REG))]
3519   "reload_completed
3520    && true_regnum (operands[0]) == true_regnum (operands[1])"
3521   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3522               (clobber (reg:CC FLAGS_REG))])]
3523   "")
3524
3525 ;; %%% Kill me once multi-word ops are sane.
3526 (define_expand "zero_extendsidi2"
3527   [(set (match_operand:DI 0 "register_operand" "")
3528      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3529   ""
3530 {
3531   if (!TARGET_64BIT)
3532     {
3533       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3534       DONE;
3535     }
3536 })
3537
3538 (define_insn "zero_extendsidi2_32"
3539   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Yt")
3540         (zero_extend:DI
3541          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3542    (clobber (reg:CC FLAGS_REG))]
3543   "!TARGET_64BIT"
3544   "@
3545    #
3546    #
3547    #
3548    movd\t{%1, %0|%0, %1}
3549    movd\t{%1, %0|%0, %1}
3550    movd\t{%1, %0|%0, %1}
3551    movd\t{%1, %0|%0, %1}"
3552   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3553    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3554
3555 (define_insn "zero_extendsidi2_rex64"
3556   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Yt")
3557      (zero_extend:DI
3558        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3559   "TARGET_64BIT"
3560   "@
3561    mov\t{%k1, %k0|%k0, %k1}
3562    #
3563    movd\t{%1, %0|%0, %1}
3564    movd\t{%1, %0|%0, %1}
3565    movd\t{%1, %0|%0, %1}
3566    movd\t{%1, %0|%0, %1}"
3567   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3568    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3569
3570 (define_split
3571   [(set (match_operand:DI 0 "memory_operand" "")
3572      (zero_extend:DI (match_dup 0)))]
3573   "TARGET_64BIT"
3574   [(set (match_dup 4) (const_int 0))]
3575   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3576
3577 (define_split
3578   [(set (match_operand:DI 0 "register_operand" "")
3579         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3580    (clobber (reg:CC FLAGS_REG))]
3581   "!TARGET_64BIT && reload_completed
3582    && true_regnum (operands[0]) == true_regnum (operands[1])"
3583   [(set (match_dup 4) (const_int 0))]
3584   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3585
3586 (define_split
3587   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3588         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3589    (clobber (reg:CC FLAGS_REG))]
3590   "!TARGET_64BIT && reload_completed
3591    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3592   [(set (match_dup 3) (match_dup 1))
3593    (set (match_dup 4) (const_int 0))]
3594   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3595
3596 (define_insn "zero_extendhidi2"
3597   [(set (match_operand:DI 0 "register_operand" "=r")
3598      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3599   "TARGET_64BIT"
3600   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3601   [(set_attr "type" "imovx")
3602    (set_attr "mode" "DI")])
3603
3604 (define_insn "zero_extendqidi2"
3605   [(set (match_operand:DI 0 "register_operand" "=r")
3606      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3607   "TARGET_64BIT"
3608   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3609   [(set_attr "type" "imovx")
3610    (set_attr "mode" "DI")])
3611 \f
3612 ;; Sign extension instructions
3613
3614 (define_expand "extendsidi2"
3615   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3616                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3617               (clobber (reg:CC FLAGS_REG))
3618               (clobber (match_scratch:SI 2 ""))])]
3619   ""
3620 {
3621   if (TARGET_64BIT)
3622     {
3623       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3624       DONE;
3625     }
3626 })
3627
3628 (define_insn "*extendsidi2_1"
3629   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3630         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3631    (clobber (reg:CC FLAGS_REG))
3632    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3633   "!TARGET_64BIT"
3634   "#")
3635
3636 (define_insn "extendsidi2_rex64"
3637   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3638         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3639   "TARGET_64BIT"
3640   "@
3641    {cltq|cdqe}
3642    movs{lq|x}\t{%1,%0|%0, %1}"
3643   [(set_attr "type" "imovx")
3644    (set_attr "mode" "DI")
3645    (set_attr "prefix_0f" "0")
3646    (set_attr "modrm" "0,1")])
3647
3648 (define_insn "extendhidi2"
3649   [(set (match_operand:DI 0 "register_operand" "=r")
3650         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3651   "TARGET_64BIT"
3652   "movs{wq|x}\t{%1,%0|%0, %1}"
3653   [(set_attr "type" "imovx")
3654    (set_attr "mode" "DI")])
3655
3656 (define_insn "extendqidi2"
3657   [(set (match_operand:DI 0 "register_operand" "=r")
3658         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3659   "TARGET_64BIT"
3660   "movs{bq|x}\t{%1,%0|%0, %1}"
3661    [(set_attr "type" "imovx")
3662     (set_attr "mode" "DI")])
3663
3664 ;; Extend to memory case when source register does die.
3665 (define_split
3666   [(set (match_operand:DI 0 "memory_operand" "")
3667         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3668    (clobber (reg:CC FLAGS_REG))
3669    (clobber (match_operand:SI 2 "register_operand" ""))]
3670   "(reload_completed
3671     && dead_or_set_p (insn, operands[1])
3672     && !reg_mentioned_p (operands[1], operands[0]))"
3673   [(set (match_dup 3) (match_dup 1))
3674    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3675               (clobber (reg:CC FLAGS_REG))])
3676    (set (match_dup 4) (match_dup 1))]
3677   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3678
3679 ;; Extend to memory case when source register does not die.
3680 (define_split
3681   [(set (match_operand:DI 0 "memory_operand" "")
3682         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3683    (clobber (reg:CC FLAGS_REG))
3684    (clobber (match_operand:SI 2 "register_operand" ""))]
3685   "reload_completed"
3686   [(const_int 0)]
3687 {
3688   split_di (&operands[0], 1, &operands[3], &operands[4]);
3689
3690   emit_move_insn (operands[3], operands[1]);
3691
3692   /* Generate a cltd if possible and doing so it profitable.  */
3693   if ((optimize_size || TARGET_USE_CLTD)
3694       && true_regnum (operands[1]) == 0
3695       && true_regnum (operands[2]) == 1)
3696     {
3697       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3698     }
3699   else
3700     {
3701       emit_move_insn (operands[2], operands[1]);
3702       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3703     }
3704   emit_move_insn (operands[4], operands[2]);
3705   DONE;
3706 })
3707
3708 ;; Extend to register case.  Optimize case where source and destination
3709 ;; registers match and cases where we can use cltd.
3710 (define_split
3711   [(set (match_operand:DI 0 "register_operand" "")
3712         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3713    (clobber (reg:CC FLAGS_REG))
3714    (clobber (match_scratch:SI 2 ""))]
3715   "reload_completed"
3716   [(const_int 0)]
3717 {
3718   split_di (&operands[0], 1, &operands[3], &operands[4]);
3719
3720   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3721     emit_move_insn (operands[3], operands[1]);
3722
3723   /* Generate a cltd if possible and doing so it profitable.  */
3724   if ((optimize_size || TARGET_USE_CLTD)
3725       && true_regnum (operands[3]) == 0)
3726     {
3727       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3728       DONE;
3729     }
3730
3731   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3732     emit_move_insn (operands[4], operands[1]);
3733
3734   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3735   DONE;
3736 })
3737
3738 (define_insn "extendhisi2"
3739   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3740         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3741   ""
3742 {
3743   switch (get_attr_prefix_0f (insn))
3744     {
3745     case 0:
3746       return "{cwtl|cwde}";
3747     default:
3748       return "movs{wl|x}\t{%1,%0|%0, %1}";
3749     }
3750 }
3751   [(set_attr "type" "imovx")
3752    (set_attr "mode" "SI")
3753    (set (attr "prefix_0f")
3754      ;; movsx is short decodable while cwtl is vector decoded.
3755      (if_then_else (and (eq_attr "cpu" "!k6")
3756                         (eq_attr "alternative" "0"))
3757         (const_string "0")
3758         (const_string "1")))
3759    (set (attr "modrm")
3760      (if_then_else (eq_attr "prefix_0f" "0")
3761         (const_string "0")
3762         (const_string "1")))])
3763
3764 (define_insn "*extendhisi2_zext"
3765   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3766         (zero_extend:DI
3767           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3768   "TARGET_64BIT"
3769 {
3770   switch (get_attr_prefix_0f (insn))
3771     {
3772     case 0:
3773       return "{cwtl|cwde}";
3774     default:
3775       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3776     }
3777 }
3778   [(set_attr "type" "imovx")
3779    (set_attr "mode" "SI")
3780    (set (attr "prefix_0f")
3781      ;; movsx is short decodable while cwtl is vector decoded.
3782      (if_then_else (and (eq_attr "cpu" "!k6")
3783                         (eq_attr "alternative" "0"))
3784         (const_string "0")
3785         (const_string "1")))
3786    (set (attr "modrm")
3787      (if_then_else (eq_attr "prefix_0f" "0")
3788         (const_string "0")
3789         (const_string "1")))])
3790
3791 (define_insn "extendqihi2"
3792   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3793         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3794   ""
3795 {
3796   switch (get_attr_prefix_0f (insn))
3797     {
3798     case 0:
3799       return "{cbtw|cbw}";
3800     default:
3801       return "movs{bw|x}\t{%1,%0|%0, %1}";
3802     }
3803 }
3804   [(set_attr "type" "imovx")
3805    (set_attr "mode" "HI")
3806    (set (attr "prefix_0f")
3807      ;; movsx is short decodable while cwtl is vector decoded.
3808      (if_then_else (and (eq_attr "cpu" "!k6")
3809                         (eq_attr "alternative" "0"))
3810         (const_string "0")
3811         (const_string "1")))
3812    (set (attr "modrm")
3813      (if_then_else (eq_attr "prefix_0f" "0")
3814         (const_string "0")
3815         (const_string "1")))])
3816
3817 (define_insn "extendqisi2"
3818   [(set (match_operand:SI 0 "register_operand" "=r")
3819         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3820   ""
3821   "movs{bl|x}\t{%1,%0|%0, %1}"
3822    [(set_attr "type" "imovx")
3823     (set_attr "mode" "SI")])
3824
3825 (define_insn "*extendqisi2_zext"
3826   [(set (match_operand:DI 0 "register_operand" "=r")
3827         (zero_extend:DI
3828           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3829   "TARGET_64BIT"
3830   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3831    [(set_attr "type" "imovx")
3832     (set_attr "mode" "SI")])
3833 \f
3834 ;; Conversions between float and double.
3835
3836 ;; These are all no-ops in the model used for the 80387.  So just
3837 ;; emit moves.
3838
3839 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3840 (define_insn "*dummy_extendsfdf2"
3841   [(set (match_operand:DF 0 "push_operand" "=<")
3842         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3843   "0"
3844   "#")
3845
3846 (define_split
3847   [(set (match_operand:DF 0 "push_operand" "")
3848         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3849   "!TARGET_64BIT"
3850   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3851    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3852
3853 (define_split
3854   [(set (match_operand:DF 0 "push_operand" "")
3855         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3856   "TARGET_64BIT"
3857   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3858    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3859
3860 (define_insn "*dummy_extendsfxf2"
3861   [(set (match_operand:XF 0 "push_operand" "=<")
3862         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3863   "0"
3864   "#")
3865
3866 (define_split
3867   [(set (match_operand:XF 0 "push_operand" "")
3868         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3869   ""
3870   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3871    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3872   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3873
3874 (define_split
3875   [(set (match_operand:XF 0 "push_operand" "")
3876         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3877   "TARGET_64BIT"
3878   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3879    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3880   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3881
3882 (define_split
3883   [(set (match_operand:XF 0 "push_operand" "")
3884         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3885   ""
3886   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3887    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3888   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3889
3890 (define_split
3891   [(set (match_operand:XF 0 "push_operand" "")
3892         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3893   "TARGET_64BIT"
3894   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3895    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3896   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3897
3898 (define_expand "extendsfdf2"
3899   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3900         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3901   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3902 {
3903   /* ??? Needed for compress_float_constant since all fp constants
3904      are LEGITIMATE_CONSTANT_P.  */
3905   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3906     {
3907       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3908           && standard_80387_constant_p (operands[1]) > 0)
3909         {
3910           operands[1] = simplify_const_unary_operation
3911             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3912           emit_move_insn_1 (operands[0], operands[1]);
3913           DONE;
3914         }
3915       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3916     }
3917 })
3918
3919 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3920    cvtss2sd:
3921       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3922       cvtps2pd xmm2,xmm1
3923    We do the conversion post reload to avoid producing of 128bit spills
3924    that might lead to ICE on 32bit target.  The sequence unlikely combine
3925    anyway.  */
3926 (define_split
3927   [(set (match_operand:DF 0 "register_operand" "")
3928         (float_extend:DF
3929           (match_operand:SF 1 "nonimmediate_operand" "")))]
3930   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size 
3931    && reload_completed && SSE_REG_P (operands[0])"
3932    [(set (match_dup 2)
3933          (float_extend:V2DF
3934            (vec_select:V2SF
3935              (match_dup 3)
3936              (parallel [(const_int 0) (const_int 1)]))))]
3937 {
3938   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3939   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3940   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3941      Try to avoid move when unpacking can be done in source.  */
3942   if (REG_P (operands[1]))
3943     {
3944       /* If it is unsafe to overwrite upper half of source, we need
3945          to move to destination and unpack there.  */
3946       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3947            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3948           && true_regnum (operands[0]) != true_regnum (operands[1]))
3949         {
3950           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3951           emit_move_insn (tmp, operands[1]);
3952         }
3953       else
3954         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3955       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
3956     }
3957   else
3958     emit_insn (gen_vec_setv4sf_0 (operands[3], 
3959                                   CONST0_RTX (V4SFmode), operands[1]));
3960 })
3961
3962 (define_insn "*extendsfdf2_mixed"
3963   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3964         (float_extend:DF
3965           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3966   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3967 {
3968   switch (which_alternative)
3969     {
3970     case 0:
3971     case 1:
3972       return output_387_reg_move (insn, operands);
3973
3974     case 2:
3975       return "cvtss2sd\t{%1, %0|%0, %1}";
3976
3977     default:
3978       gcc_unreachable ();
3979     }
3980 }
3981   [(set_attr "type" "fmov,fmov,ssecvt")
3982    (set_attr "mode" "SF,XF,DF")])
3983
3984 (define_insn "*extendsfdf2_sse"
3985   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3986         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3987   "TARGET_SSE2 && TARGET_SSE_MATH"
3988   "cvtss2sd\t{%1, %0|%0, %1}"
3989   [(set_attr "type" "ssecvt")
3990    (set_attr "mode" "DF")])
3991
3992 (define_insn "*extendsfdf2_i387"
3993   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3994         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3995   "TARGET_80387"
3996   "* return output_387_reg_move (insn, operands);"
3997   [(set_attr "type" "fmov")
3998    (set_attr "mode" "SF,XF")])
3999
4000 (define_expand "extend<mode>xf2"
4001   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4002         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4003   "TARGET_80387"
4004 {
4005   /* ??? Needed for compress_float_constant since all fp constants
4006      are LEGITIMATE_CONSTANT_P.  */
4007   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4008     {
4009       if (standard_80387_constant_p (operands[1]) > 0)
4010         {
4011           operands[1] = simplify_const_unary_operation
4012             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4013           emit_move_insn_1 (operands[0], operands[1]);
4014           DONE;
4015         }
4016       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4017     }
4018 })
4019
4020 (define_insn "*extend<mode>xf2_i387"
4021   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4022         (float_extend:XF
4023           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4024   "TARGET_80387"
4025   "* return output_387_reg_move (insn, operands);"
4026   [(set_attr "type" "fmov")
4027    (set_attr "mode" "<MODE>,XF")])
4028
4029 ;; %%% This seems bad bad news.
4030 ;; This cannot output into an f-reg because there is no way to be sure
4031 ;; of truncating in that case.  Otherwise this is just like a simple move
4032 ;; insn.  So we pretend we can output to a reg in order to get better
4033 ;; register preferencing, but we really use a stack slot.
4034
4035 ;; Conversion from DFmode to SFmode.
4036
4037 (define_expand "truncdfsf2"
4038   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4039         (float_truncate:SF
4040           (match_operand:DF 1 "nonimmediate_operand" "")))]
4041   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4042 {
4043   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4044     ;
4045   else if (flag_unsafe_math_optimizations)
4046     ;
4047   else
4048     {
4049       rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
4050       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4051       DONE;
4052     }
4053 })
4054
4055 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4056    cvtsd2ss:
4057       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4058       cvtpd2ps xmm2,xmm1
4059    We do the conversion post reload to avoid producing of 128bit spills
4060    that might lead to ICE on 32bit target.  The sequence unlikely combine
4061    anyway.  */
4062 (define_split
4063   [(set (match_operand:SF 0 "register_operand" "")
4064         (float_truncate:SF
4065           (match_operand:DF 1 "nonimmediate_operand" "")))]
4066   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size 
4067    && reload_completed && SSE_REG_P (operands[0])"
4068    [(set (match_dup 2)
4069          (vec_concat:V4SF
4070            (float_truncate:V2SF
4071              (match_dup 4))
4072            (match_dup 3)))]
4073 {
4074   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4075   operands[3] = CONST0_RTX (V2SFmode);
4076   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4077   /* Use movsd for loading from memory, unpcklpd for registers.
4078      Try to avoid move when unpacking can be done in source, or SSE3
4079      movddup is available.  */
4080   if (REG_P (operands[1]))
4081     {
4082       if (!TARGET_SSE3
4083           && true_regnum (operands[0]) != true_regnum (operands[1])
4084           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4085               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4086         {
4087           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4088           emit_move_insn (tmp, operands[1]);
4089           operands[1] = tmp;
4090         }
4091       else if (!TARGET_SSE3)
4092         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4093       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4094     }
4095   else
4096     emit_insn (gen_sse2_loadlpd (operands[4],
4097                                  CONST0_RTX (V2DFmode), operands[1]));
4098 })
4099
4100 (define_expand "truncdfsf2_with_temp"
4101   [(parallel [(set (match_operand:SF 0 "" "")
4102                    (float_truncate:SF (match_operand:DF 1 "" "")))
4103               (clobber (match_operand:SF 2 "" ""))])]
4104   "")
4105
4106 (define_insn "*truncdfsf_fast_mixed"
4107   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
4108         (float_truncate:SF
4109           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4110   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4111 {
4112   switch (which_alternative)
4113     {
4114     case 0:
4115     case 1:
4116       return output_387_reg_move (insn, operands);
4117     case 2:
4118       return "cvtsd2ss\t{%1, %0|%0, %1}";
4119     default:
4120       gcc_unreachable ();
4121     }
4122 }
4123   [(set_attr "type" "fmov,fmov,ssecvt")
4124    (set_attr "mode" "SF")])
4125
4126 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4127 ;; because nothing we do here is unsafe.
4128 (define_insn "*truncdfsf_fast_sse"
4129   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4130         (float_truncate:SF
4131           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4132   "TARGET_SSE2 && TARGET_SSE_MATH"
4133   "cvtsd2ss\t{%1, %0|%0, %1}"
4134   [(set_attr "type" "ssecvt")
4135    (set_attr "mode" "SF")])
4136
4137 (define_insn "*truncdfsf_fast_i387"
4138   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4139         (float_truncate:SF
4140           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4141   "TARGET_80387 && flag_unsafe_math_optimizations"
4142   "* return output_387_reg_move (insn, operands);"
4143   [(set_attr "type" "fmov")
4144    (set_attr "mode" "SF")])
4145
4146 (define_insn "*truncdfsf_mixed"
4147   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Yt")
4148         (float_truncate:SF
4149           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ytm")))
4150    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4151   "TARGET_MIX_SSE_I387"
4152 {
4153   switch (which_alternative)
4154     {
4155     case 0:
4156       return output_387_reg_move (insn, operands);
4157
4158     case 1:
4159       return "#";
4160     case 2:
4161       return "cvtsd2ss\t{%1, %0|%0, %1}";
4162     default:
4163       gcc_unreachable ();
4164     }
4165 }
4166   [(set_attr "type" "fmov,multi,ssecvt")
4167    (set_attr "unit" "*,i387,*")
4168    (set_attr "mode" "SF")])
4169
4170 (define_insn "*truncdfsf_i387"
4171   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4172         (float_truncate:SF
4173           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4174    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4175   "TARGET_80387"
4176 {
4177   switch (which_alternative)
4178     {
4179     case 0:
4180       return output_387_reg_move (insn, operands);
4181
4182     case 1:
4183       return "#";
4184     default:
4185       gcc_unreachable ();
4186     }
4187 }
4188   [(set_attr "type" "fmov,multi")
4189    (set_attr "unit" "*,i387")
4190    (set_attr "mode" "SF")])
4191
4192 (define_insn "*truncdfsf2_i387_1"
4193   [(set (match_operand:SF 0 "memory_operand" "=m")
4194         (float_truncate:SF
4195           (match_operand:DF 1 "register_operand" "f")))]
4196   "TARGET_80387
4197    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4198    && !TARGET_MIX_SSE_I387"
4199   "* return output_387_reg_move (insn, operands);"
4200   [(set_attr "type" "fmov")
4201    (set_attr "mode" "SF")])
4202
4203 (define_split
4204   [(set (match_operand:SF 0 "register_operand" "")
4205         (float_truncate:SF
4206          (match_operand:DF 1 "fp_register_operand" "")))
4207    (clobber (match_operand 2 "" ""))]
4208   "reload_completed"
4209   [(set (match_dup 2) (match_dup 1))
4210    (set (match_dup 0) (match_dup 2))]
4211 {
4212   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4213 })
4214
4215 ;; Conversion from XFmode to {SF,DF}mode
4216
4217 (define_expand "truncxf<mode>2"
4218   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4219                    (float_truncate:MODEF
4220                      (match_operand:XF 1 "register_operand" "")))
4221               (clobber (match_dup 2))])]
4222   "TARGET_80387"
4223 {
4224   if (flag_unsafe_math_optimizations)
4225     {
4226       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4227       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4228       if (reg != operands[0])
4229         emit_move_insn (operands[0], reg);
4230       DONE;
4231     }
4232   else
4233     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_VIRTUAL);
4234 })
4235
4236 (define_insn "*truncxfsf2_mixed"
4237   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4238         (float_truncate:SF
4239           (match_operand:XF 1 "register_operand" "f,f")))
4240    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4241   "TARGET_80387"
4242 {
4243   gcc_assert (!which_alternative);
4244   return output_387_reg_move (insn, operands);
4245 }
4246   [(set_attr "type" "fmov,multi")
4247    (set_attr "unit" "*,i387")
4248    (set_attr "mode" "SF")])
4249
4250 (define_insn "*truncxfdf2_mixed"
4251   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fYt*r")
4252         (float_truncate:DF
4253           (match_operand:XF 1 "register_operand" "f,f")))
4254    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4255   "TARGET_80387"
4256 {
4257   gcc_assert (!which_alternative);
4258   return output_387_reg_move (insn, operands);
4259 }
4260   [(set_attr "type" "fmov,multi")
4261    (set_attr "unit" "*,i387")
4262    (set_attr "mode" "DF")])
4263
4264 (define_insn "truncxf<mode>2_i387_noop"
4265   [(set (match_operand:MODEF 0 "register_operand" "=f")
4266         (float_truncate:MODEF
4267           (match_operand:XF 1 "register_operand" "f")))]
4268   "TARGET_80387 && flag_unsafe_math_optimizations"
4269   "* return output_387_reg_move (insn, operands);"
4270   [(set_attr "type" "fmov")
4271    (set_attr "mode" "<MODE>")])
4272
4273 (define_insn "*truncxf<mode>2_i387"
4274   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4275         (float_truncate:MODEF
4276           (match_operand:XF 1 "register_operand" "f")))]
4277   "TARGET_80387"
4278   "* return output_387_reg_move (insn, operands);"
4279   [(set_attr "type" "fmov")
4280    (set_attr "mode" "<MODE>")])
4281
4282 (define_split
4283   [(set (match_operand:MODEF 0 "register_operand" "")
4284         (float_truncate:MODEF
4285           (match_operand:XF 1 "register_operand" "")))
4286    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4287   "TARGET_80387 && reload_completed"
4288   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4289    (set (match_dup 0) (match_dup 2))]
4290   "")
4291
4292 (define_split
4293   [(set (match_operand:MODEF 0 "memory_operand" "")
4294         (float_truncate:MODEF
4295           (match_operand:XF 1 "register_operand" "")))
4296    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4297   "TARGET_80387"
4298   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4299   "")
4300 \f
4301 ;; Signed conversion to DImode.
4302
4303 (define_expand "fix_truncxfdi2"
4304   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4305                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4306               (clobber (reg:CC FLAGS_REG))])]
4307   "TARGET_80387"
4308 {
4309   if (TARGET_FISTTP)
4310    {
4311      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4312      DONE;
4313    }
4314 })
4315
4316 (define_expand "fix_trunc<mode>di2"
4317   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4318                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4319               (clobber (reg:CC FLAGS_REG))])]
4320   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4321 {
4322   if (TARGET_FISTTP
4323       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4324    {
4325      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4326      DONE;
4327    }
4328   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4329    {
4330      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4331      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4332      if (out != operands[0])
4333         emit_move_insn (operands[0], out);
4334      DONE;
4335    }
4336 })
4337
4338 ;; Signed conversion to SImode.
4339
4340 (define_expand "fix_truncxfsi2"
4341   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4342                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4343               (clobber (reg:CC FLAGS_REG))])]
4344   "TARGET_80387"
4345 {
4346   if (TARGET_FISTTP)
4347    {
4348      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4349      DONE;
4350    }
4351 })
4352
4353 (define_expand "fix_trunc<mode>si2"
4354   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4355                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4356               (clobber (reg:CC FLAGS_REG))])]
4357   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4358 {
4359   if (TARGET_FISTTP
4360       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4361    {
4362      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4363      DONE;
4364    }
4365   if (SSE_FLOAT_MODE_P (<MODE>mode))
4366    {
4367      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4368      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4369      if (out != operands[0])
4370         emit_move_insn (operands[0], out);
4371      DONE;
4372    }
4373 })
4374
4375 ;; Signed conversion to HImode.
4376
4377 (define_expand "fix_trunc<mode>hi2"
4378   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4379                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4380               (clobber (reg:CC FLAGS_REG))])]
4381   "TARGET_80387
4382    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4383 {
4384   if (TARGET_FISTTP)
4385    {
4386      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4387      DONE;
4388    }
4389 })
4390
4391 ;; Unsigned conversion to SImode.
4392
4393 (define_expand "fixuns_trunc<mode>si2"
4394   [(parallel
4395     [(set (match_operand:SI 0 "register_operand" "")
4396           (unsigned_fix:SI
4397             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4398      (use (match_dup 2))
4399      (clobber (match_scratch:<ssevecmode> 3 ""))
4400      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4401   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4402 {
4403   enum machine_mode mode = <MODE>mode;
4404   enum machine_mode vecmode = <ssevecmode>mode;
4405   REAL_VALUE_TYPE TWO31r;
4406   rtx two31;
4407
4408   real_ldexp (&TWO31r, &dconst1, 31);
4409   two31 = const_double_from_real_value (TWO31r, mode);
4410   two31 = ix86_build_const_vector (mode, true, two31);
4411   operands[2] = force_reg (vecmode, two31);
4412 })
4413
4414 (define_insn_and_split "*fixuns_trunc<mode>_1"
4415   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4416         (unsigned_fix:SI
4417           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4418    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4419    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4420    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4421   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4422   "#"
4423   "&& reload_completed"
4424   [(const_int 0)]
4425 {
4426   ix86_split_convert_uns_si_sse (operands);
4427   DONE;
4428 })
4429
4430 ;; Unsigned conversion to HImode.
4431 ;; Without these patterns, we'll try the unsigned SI conversion which
4432 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4433
4434 (define_expand "fixuns_trunc<mode>hi2"
4435   [(set (match_dup 2)
4436         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4437    (set (match_operand:HI 0 "nonimmediate_operand" "")
4438         (subreg:HI (match_dup 2) 0))]
4439   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4440   "operands[2] = gen_reg_rtx (SImode);")
4441
4442 ;; When SSE is available, it is always faster to use it!
4443 (define_insn "fix_trunc<mode>di_sse"
4444   [(set (match_operand:DI 0 "register_operand" "=r,r")
4445         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4446   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4447    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4448   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4449   [(set_attr "type" "sseicvt")
4450    (set_attr "mode" "<MODE>")
4451    (set_attr "athlon_decode" "double,vector")
4452    (set_attr "amdfam10_decode" "double,double")])
4453
4454 (define_insn "fix_trunc<mode>si_sse"
4455   [(set (match_operand:SI 0 "register_operand" "=r,r")
4456         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4457   "SSE_FLOAT_MODE_P (<MODE>mode)
4458    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4459   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4460   [(set_attr "type" "sseicvt")
4461    (set_attr "mode" "<MODE>")
4462    (set_attr "athlon_decode" "double,vector")
4463    (set_attr "amdfam10_decode" "double,double")])
4464
4465 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4466 (define_peephole2
4467   [(set (match_operand:MODEF 0 "register_operand" "")
4468         (match_operand:MODEF 1 "memory_operand" ""))
4469    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4470         (fix:SSEMODEI24 (match_dup 0)))]
4471   "TARGET_SHORTEN_X87_SSE
4472    && peep2_reg_dead_p (2, operands[0])"
4473   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4474   "")
4475
4476 ;; Avoid vector decoded forms of the instruction.
4477 (define_peephole2
4478   [(match_scratch:DF 2 "Yt")
4479    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4480         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4481   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4482   [(set (match_dup 2) (match_dup 1))
4483    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4484   "")
4485
4486 (define_peephole2
4487   [(match_scratch:SF 2 "x")
4488    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4489         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4490   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4491   [(set (match_dup 2) (match_dup 1))
4492    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4493   "")
4494
4495 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4496   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4497         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4498   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4499    && TARGET_FISTTP
4500    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4501          && (TARGET_64BIT || <MODE>mode != DImode))
4502         && TARGET_SSE_MATH)
4503    && !(reload_completed || reload_in_progress)"
4504   "#"
4505   "&& 1"
4506   [(const_int 0)]
4507 {
4508   if (memory_operand (operands[0], VOIDmode))
4509     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4510   else
4511     {
4512       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4513       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4514                                                             operands[1],
4515                                                             operands[2]));
4516     }
4517   DONE;
4518 }
4519   [(set_attr "type" "fisttp")
4520    (set_attr "mode" "<MODE>")])
4521
4522 (define_insn "fix_trunc<mode>_i387_fisttp"
4523   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4524         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4525    (clobber (match_scratch:XF 2 "=&1f"))]
4526   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4527    && TARGET_FISTTP
4528    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4529          && (TARGET_64BIT || <MODE>mode != DImode))
4530         && TARGET_SSE_MATH)"
4531   "* return output_fix_trunc (insn, operands, 1);"
4532   [(set_attr "type" "fisttp")
4533    (set_attr "mode" "<MODE>")])
4534
4535 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4536   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4537         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4538    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4539    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4540   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4541    && TARGET_FISTTP
4542    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4543         && (TARGET_64BIT || <MODE>mode != DImode))
4544         && TARGET_SSE_MATH)"
4545   "#"
4546   [(set_attr "type" "fisttp")
4547    (set_attr "mode" "<MODE>")])
4548
4549 (define_split
4550   [(set (match_operand:X87MODEI 0 "register_operand" "")
4551         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4552    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4553    (clobber (match_scratch 3 ""))]
4554   "reload_completed"
4555   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4556               (clobber (match_dup 3))])
4557    (set (match_dup 0) (match_dup 2))]
4558   "")
4559
4560 (define_split
4561   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4562         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4563    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4564    (clobber (match_scratch 3 ""))]
4565   "reload_completed"
4566   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4567               (clobber (match_dup 3))])]
4568   "")
4569
4570 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4571 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4572 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4573 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4574 ;; function in i386.c.
4575 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4576   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4577         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4578    (clobber (reg:CC FLAGS_REG))]
4579   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4580    && !TARGET_FISTTP
4581    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4582          && (TARGET_64BIT || <MODE>mode != DImode))
4583    && !(reload_completed || reload_in_progress)"
4584   "#"
4585   "&& 1"
4586   [(const_int 0)]
4587 {
4588   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4589
4590   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4591   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4592   if (memory_operand (operands[0], VOIDmode))
4593     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4594                                          operands[2], operands[3]));
4595   else
4596     {
4597       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4598       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4599                                                      operands[2], operands[3],
4600                                                      operands[4]));
4601     }
4602   DONE;
4603 }
4604   [(set_attr "type" "fistp")
4605    (set_attr "i387_cw" "trunc")
4606    (set_attr "mode" "<MODE>")])
4607
4608 (define_insn "fix_truncdi_i387"
4609   [(set (match_operand:DI 0 "memory_operand" "=m")
4610         (fix:DI (match_operand 1 "register_operand" "f")))
4611    (use (match_operand:HI 2 "memory_operand" "m"))
4612    (use (match_operand:HI 3 "memory_operand" "m"))
4613    (clobber (match_scratch:XF 4 "=&1f"))]
4614   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4615    && !TARGET_FISTTP
4616    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4617   "* return output_fix_trunc (insn, operands, 0);"
4618   [(set_attr "type" "fistp")
4619    (set_attr "i387_cw" "trunc")
4620    (set_attr "mode" "DI")])
4621
4622 (define_insn "fix_truncdi_i387_with_temp"
4623   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4624         (fix:DI (match_operand 1 "register_operand" "f,f")))
4625    (use (match_operand:HI 2 "memory_operand" "m,m"))
4626    (use (match_operand:HI 3 "memory_operand" "m,m"))
4627    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4628    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4629   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4630    && !TARGET_FISTTP
4631    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4632   "#"
4633   [(set_attr "type" "fistp")
4634    (set_attr "i387_cw" "trunc")
4635    (set_attr "mode" "DI")])
4636
4637 (define_split
4638   [(set (match_operand:DI 0 "register_operand" "")
4639         (fix:DI (match_operand 1 "register_operand" "")))
4640    (use (match_operand:HI 2 "memory_operand" ""))
4641    (use (match_operand:HI 3 "memory_operand" ""))
4642    (clobber (match_operand:DI 4 "memory_operand" ""))
4643    (clobber (match_scratch 5 ""))]
4644   "reload_completed"
4645   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4646               (use (match_dup 2))
4647               (use (match_dup 3))
4648               (clobber (match_dup 5))])
4649    (set (match_dup 0) (match_dup 4))]
4650   "")
4651
4652 (define_split
4653   [(set (match_operand:DI 0 "memory_operand" "")
4654         (fix:DI (match_operand 1 "register_operand" "")))
4655    (use (match_operand:HI 2 "memory_operand" ""))
4656    (use (match_operand:HI 3 "memory_operand" ""))
4657    (clobber (match_operand:DI 4 "memory_operand" ""))
4658    (clobber (match_scratch 5 ""))]
4659   "reload_completed"
4660   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4661               (use (match_dup 2))
4662               (use (match_dup 3))
4663               (clobber (match_dup 5))])]
4664   "")
4665
4666 (define_insn "fix_trunc<mode>_i387"
4667   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4668         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4669    (use (match_operand:HI 2 "memory_operand" "m"))
4670    (use (match_operand:HI 3 "memory_operand" "m"))]
4671   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4672    && !TARGET_FISTTP
4673    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4674   "* return output_fix_trunc (insn, operands, 0);"
4675   [(set_attr "type" "fistp")
4676    (set_attr "i387_cw" "trunc")
4677    (set_attr "mode" "<MODE>")])
4678
4679 (define_insn "fix_trunc<mode>_i387_with_temp"
4680   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4681         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4682    (use (match_operand:HI 2 "memory_operand" "m,m"))
4683    (use (match_operand:HI 3 "memory_operand" "m,m"))
4684    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4685   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4686    && !TARGET_FISTTP
4687    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4688   "#"
4689   [(set_attr "type" "fistp")
4690    (set_attr "i387_cw" "trunc")
4691    (set_attr "mode" "<MODE>")])
4692
4693 (define_split
4694   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4695         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4696    (use (match_operand:HI 2 "memory_operand" ""))
4697    (use (match_operand:HI 3 "memory_operand" ""))
4698    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4699   "reload_completed"
4700   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4701               (use (match_dup 2))
4702               (use (match_dup 3))])
4703    (set (match_dup 0) (match_dup 4))]
4704   "")
4705
4706 (define_split
4707   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4708         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4709    (use (match_operand:HI 2 "memory_operand" ""))
4710    (use (match_operand:HI 3 "memory_operand" ""))
4711    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4712   "reload_completed"
4713   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4714               (use (match_dup 2))
4715               (use (match_dup 3))])]
4716   "")
4717
4718 (define_insn "x86_fnstcw_1"
4719   [(set (match_operand:HI 0 "memory_operand" "=m")
4720         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4721   "TARGET_80387"
4722   "fnstcw\t%0"
4723   [(set_attr "length" "2")
4724    (set_attr "mode" "HI")
4725    (set_attr "unit" "i387")])
4726
4727 (define_insn "x86_fldcw_1"
4728   [(set (reg:HI FPCR_REG)
4729         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4730   "TARGET_80387"
4731   "fldcw\t%0"
4732   [(set_attr "length" "2")
4733    (set_attr "mode" "HI")
4734    (set_attr "unit" "i387")
4735    (set_attr "athlon_decode" "vector")
4736    (set_attr "amdfam10_decode" "vector")])   
4737 \f
4738 ;; Conversion between fixed point and floating point.
4739
4740 ;; Even though we only accept memory inputs, the backend _really_
4741 ;; wants to be able to do this between registers.
4742
4743 (define_expand "floathi<mode>2"
4744   [(set (match_operand:MODEF 0 "register_operand" "")
4745         (float:MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4746   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4747 {
4748   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4749     {
4750       emit_insn
4751         (gen_floatsi<mode>2 (operands[0],
4752                              convert_to_mode (SImode, operands[1], 0)));
4753       DONE;
4754     }
4755 })
4756
4757 (define_insn "*floathi<mode>2_i387"
4758   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4759         (float:MODEF
4760           (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4761   "TARGET_80387
4762    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4763        || TARGET_MIX_SSE_I387)"
4764   "@
4765    fild%z1\t%1
4766    #"
4767   [(set_attr "type" "fmov,multi")
4768    (set_attr "mode" "<MODE>")
4769    (set_attr "unit" "*,i387")
4770    (set_attr "fp_int_src" "true")])
4771
4772 (define_expand "floatsi<mode>2"
4773   [(set (match_operand:MODEF 0 "register_operand" "")
4774         (float:MODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4775   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4776   "
4777    /* When we use vector converts, we can't have input in memory.  */
4778    if (GET_MODE (operands[0]) == DFmode
4779        && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4780        && SSE_FLOAT_MODE_P (DFmode))
4781      operands[1] = force_reg (SImode, operands[1]);
4782    else if (GET_MODE (operands[0]) == SFmode
4783             && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4784             && SSE_FLOAT_MODE_P (SFmode))
4785      {
4786        /* When !flag_trapping_math, we handle SImode->SFmode vector
4787           conversions same way as SImode->DFmode.
4788
4789           For flat_trapping_math we can't safely use vector conversion without
4790           clearing upper half, otherwise precision exception might occur.
4791           However we can still generate the common sequence converting value
4792           from general register to XMM register as:
4793
4794             mov         reg32, mem32
4795             movd        mem32, xmm
4796             cvtdq2pd xmm,xmm
4797
4798           because we know that movd clears the upper half.
4799
4800           Sadly in this case we can't rely on reload moving the value to XMM
4801           register, since we need to know if upper half is OK, so we need
4802           to do reloading by hand.  We force operand to memory unless target
4803           supports inter unit moves.  */
4804        if (!flag_trapping_math)
4805          operands[1] = force_reg (SImode, operands[1]);
4806        else if (!MEM_P (operands[1]))
4807          {
4808            rtx tmp = assign_386_stack_local (SImode, SLOT_VIRTUAL);
4809            emit_move_insn (tmp, operands[1]);
4810            operands[1] = tmp;
4811          }
4812      }
4813    /* Offload operand of cvtsi2ss and cvtsi2sd into memory for
4814       !TARGET_INTER_UNIT_CONVERSIONS
4815       It is neccesary for the patterns to not accept nonemmory operands
4816       as we would optimize out later.  */
4817    else if (!TARGET_INTER_UNIT_CONVERSIONS
4818             && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
4819             && !optimize_size
4820             && !MEM_P (operands[1]))
4821      {
4822         rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), SLOT_VIRTUAL);
4823         emit_move_insn (tmp, operands[1]);
4824         operands[1] = tmp;
4825      }
4826   ")
4827
4828 (define_insn "*floatsisf2_mixed_vector"
4829   [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4830         (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4831   "TARGET_MIX_SSE_I387 && !flag_trapping_math 
4832    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4833   "@
4834    cvtdq2ps\t{%1, %0|%0, %1}
4835    fild%z1\t%1
4836    #"
4837   [(set_attr "type" "sseicvt,fmov,multi")
4838    (set_attr "mode" "SF")
4839    (set_attr "unit" "*,i387,*")
4840    (set_attr "athlon_decode" "double,*,*")
4841    (set_attr "amdfam10_decode" "double,*,*")
4842    (set_attr "fp_int_src" "false,true,true")])
4843
4844 (define_insn "*floatsisf2_mixed"
4845   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4846         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4847   "TARGET_MIX_SSE_I387
4848    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4849        || optimize_size)"
4850   "@
4851    fild%z1\t%1
4852    #
4853    cvtsi2ss\t{%1, %0|%0, %1}
4854    cvtsi2ss\t{%1, %0|%0, %1}"
4855   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4856    (set_attr "mode" "SF")
4857    (set_attr "unit" "*,i387,*,*")
4858    (set_attr "athlon_decode" "*,*,vector,double")
4859    (set_attr "amdfam10_decode" "*,*,vector,double")
4860    (set_attr "fp_int_src" "true")])
4861
4862 (define_insn "*floatsisf2_mixed_memory"
4863   [(set (match_operand:SF 0 "register_operand" "=f,x")
4864         (float:SF (match_operand:SI 1 "memory_operand" "m,m")))]
4865   "TARGET_MIX_SSE_I387
4866    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4867   "@
4868    fild%z1\t%1
4869    cvtsi2ss\t{%1, %0|%0, %1}"
4870   [(set_attr "type" "fmov,sseicvt")
4871    (set_attr "mode" "SF")
4872    (set_attr "athlon_decode" "*,double")
4873    (set_attr "amdfam10_decode" "*,double")
4874    (set_attr "fp_int_src" "true")])
4875
4876 (define_insn "*floatsisf2_sse_vector_nointernunit"
4877   [(set (match_operand:SF 0 "register_operand" "=x")
4878         (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4879   "TARGET_SSE_MATH && flag_trapping_math
4880    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4881    && !TARGET_INTER_UNIT_MOVES"
4882   "#"
4883   [(set_attr "type" "multi")])
4884
4885 (define_insn "*floatsisf2_sse_vector_internunit"
4886   [(set (match_operand:SF 0 "register_operand" "=x,x")
4887         (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4888   "TARGET_SSE_MATH && flag_trapping_math
4889    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4890    && TARGET_INTER_UNIT_MOVES"
4891   "#"
4892   [(set_attr "type" "multi")])
4893
4894 (define_split 
4895   [(set (match_operand:SF 0 "register_operand" "")
4896         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4897   "flag_trapping_math
4898    && TARGET_USE_VECTOR_CONVERTS && reload_completed
4899    && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4900    && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4901   [(set (match_dup 0)
4902         (float:V4SF (match_dup 2)))]
4903 {
4904   operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4905   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4906   emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4907 })
4908
4909 (define_split 
4910   [(set (match_operand:SF 0 "register_operand" "")
4911         (float:SF (match_operand:SI 1 "register_operand" "")))]
4912   "flag_trapping_math
4913    && TARGET_USE_VECTOR_CONVERTS && reload_completed
4914    && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4915   [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4916    (set (match_dup 0)
4917         (float:V4SF (match_dup 2)))]
4918 {
4919   operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4920   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4921 })
4922
4923 (define_insn "*floatsisf2_sse_vector"
4924   [(set (match_operand:SF 0 "register_operand" "=x")
4925         (float:SF (match_operand:SI 1 "register_operand" "x")))]
4926   "TARGET_SSE_MATH && !flag_trapping_math
4927    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4928    && !TARGET_INTER_UNIT_MOVES"
4929   "cvtdq2ps\t{%1, %0|%0, %1}"
4930   [(set_attr "type" "sseicvt")
4931    (set_attr "mode" "SF")
4932    (set_attr "athlon_decode" "double")
4933    (set_attr "amdfam10_decode" "double")
4934    (set_attr "fp_int_src" "true")])
4935
4936 (define_insn "*floatsisf2_sse"
4937   [(set (match_operand:SF 0 "register_operand" "=x,x")
4938         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4939   "TARGET_SSE_MATH
4940    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4941        || optimize_size)"
4942   "cvtsi2ss\t{%1, %0|%0, %1}"
4943   [(set_attr "type" "sseicvt")
4944    (set_attr "mode" "SF")
4945    (set_attr "athlon_decode" "vector,double")
4946    (set_attr "amdfam10_decode" "vector,double")
4947    (set_attr "fp_int_src" "true")])
4948
4949 (define_insn "*floatsisf2_sse_memory"
4950   [(set (match_operand:SF 0 "register_operand" "=x")
4951         (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4952   "TARGET_SSE_MATH
4953    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4954   "cvtsi2ss\t{%1, %0|%0, %1}"
4955   [(set_attr "type" "sseicvt")
4956    (set_attr "mode" "SF")
4957    (set_attr "athlon_decode" "double")
4958    (set_attr "amdfam10_decode" "double")
4959    (set_attr "fp_int_src" "true")])
4960
4961 (define_insn "*floatsidf2_mixed_vector"
4962   [(set (match_operand:DF 0 "register_operand" "=x,f,f")
4963         (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4964   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4965    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4966   "@
4967    cvtdq2pd\t{%1, %0|%0, %1}
4968    fild%z1\t%1
4969    #"
4970   [(set_attr "type" "sseicvt,fmov,multi")
4971    (set_attr "mode" "V2DF,DF,DF")
4972    (set_attr "unit" "*,*,i387")
4973    (set_attr "athlon_decode" "double,*,*")
4974    (set_attr "amdfam10_decode" "double,*,*")
4975    (set_attr "fp_int_src" "false,true,true")])
4976
4977 (define_insn "*floatsidf2_mixed"
4978   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
4979         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
4980   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4981    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4982        || optimize_size)"
4983   "@
4984    fild%z1\t%1
4985    #
4986    cvtsi2sd\t{%1, %0|%0, %1}
4987    cvtsi2sd\t{%1, %0|%0, %1}
4988    cvtdq2pd\t{%1, %0|%0, %1}"
4989   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4990    (set_attr "mode" "DF,DF,DF,DF,V2DF")
4991    (set_attr "unit" "*,i387,*,*,*")
4992    (set_attr "athlon_decode" "*,*,double,direct,double")
4993    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4994    (set_attr "fp_int_src" "true,true,true,true,false")])
4995
4996 (define_insn "*floatsidf2_mixed_memory"
4997   [(set (match_operand:DF 0 "register_operand" "=f,x")
4998         (float:DF (match_operand:SI 1 "memory_operand" "m,m")))]
4999   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5000    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5001   "@
5002    fild%z1\t%1
5003    cvtsi2sd\t{%1, %0|%0, %1}"
5004   [(set_attr "type" "fmov,sseicvt")
5005    (set_attr "mode" "DF")
5006    (set_attr "athlon_decode" "*,direct")
5007    (set_attr "amdfam10_decode" "*,double")
5008    (set_attr "fp_int_src" "true")])
5009
5010 (define_insn "*floatsidf2_sse_vector"
5011   [(set (match_operand:DF 0 "register_operand" "=x")
5012         (float:DF (match_operand:SI 1 "register_operand" "x")))]
5013   "TARGET_SSE2 && TARGET_SSE_MATH
5014    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5015   "cvtdq2pd\t{%1, %0|%0, %1}"
5016   [(set_attr "type" "sseicvt")
5017    (set_attr "mode" "V2DF")
5018    (set_attr "athlon_decode" "double")
5019    (set_attr "amdfam10_decode" "double")
5020    (set_attr "fp_int_src" "true")])
5021
5022 (define_split 
5023   [(set (match_operand:DF 0 "register_operand" "")
5024         (float:DF (match_operand:SI 1 "memory_operand" "")))]
5025   "TARGET_USE_VECTOR_CONVERTS && reload_completed
5026    && SSE_REG_P (operands[0])"
5027   [(set (match_dup 0)
5028         (float:V2DF
5029           (vec_select:V2SI
5030             (match_dup 2)
5031             (parallel [(const_int 0) (const_int 1)]))))]
5032 {
5033   operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
5034   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
5035   emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
5036 })
5037
5038 (define_insn "*floatsidf2_sse"
5039   [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
5040         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
5041   "TARGET_SSE2 && TARGET_SSE_MATH
5042    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5043        || optimize_size)"
5044   "@
5045    cvtsi2sd\t{%1, %0|%0, %1}
5046    cvtsi2sd\t{%1, %0|%0, %1}
5047    cvtdq2pd\t{%1, %0|%0, %1}"
5048   [(set_attr "type" "sseicvt")
5049    (set_attr "mode" "DF,DF,V2DF")
5050    (set_attr "athlon_decode" "double,direct,double")
5051    (set_attr "amdfam10_decode" "vector,double,double")
5052    (set_attr "fp_int_src" "true")])
5053
5054 (define_insn "*floatsidf2_memory"
5055   [(set (match_operand:DF 0 "register_operand" "=x")
5056         (float:DF (match_operand:SI 1 "memory_operand" "x")))]
5057   "TARGET_SSE2 && TARGET_SSE_MATH
5058    && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5059        || optimize_size)"
5060   "cvtsi2sd\t{%1, %0|%0, %1}"
5061   [(set_attr "type" "sseicvt")
5062    (set_attr "mode" "DF")
5063    (set_attr "athlon_decode" "direct")
5064    (set_attr "amdfam10_decode" "double")
5065    (set_attr "fp_int_src" "true")])
5066
5067 (define_insn "*floatsi<mode>2_i387"
5068   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5069         (float:MODEF
5070           (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5071   "TARGET_80387
5072    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5073   "@
5074    fild%z1\t%1
5075    #"
5076   [(set_attr "type" "fmov,multi")
5077    (set_attr "mode" "<MODE>")
5078    (set_attr "unit" "*,i387")
5079    (set_attr "fp_int_src" "true")])
5080
5081 (define_expand "floatdisf2"
5082   [(set (match_operand:SF 0 "register_operand" "")
5083         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5084   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5085 {
5086   if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5087       && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (SFmode)
5088       && !optimize_size
5089       && !MEM_P (operands[1]))
5090     {
5091         rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), SLOT_VIRTUAL);
5092         emit_move_insn (tmp, operands[1]);
5093         operands[1] = tmp;
5094     }
5095 })
5096
5097 (define_insn "*floatdisf2_mixed"
5098   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5099         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5100   "TARGET_64BIT && TARGET_MIX_SSE_I387
5101    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5102   "@
5103    fild%z1\t%1
5104    #
5105    cvtsi2ss{q}\t{%1, %0|%0, %1}
5106    cvtsi2ss{q}\t{%1, %0|%0, %1}"
5107   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5108    (set_attr "mode" "SF")
5109    (set_attr "unit" "*,i387,*,*")
5110    (set_attr "athlon_decode" "*,*,vector,double")
5111    (set_attr "amdfam10_decode" "*,*,vector,double")
5112    (set_attr "fp_int_src" "true")])
5113
5114 (define_insn "*floatdisf2_mixed"
5115   [(set (match_operand:SF 0 "register_operand" "=f,x")
5116         (float:SF (match_operand:DI 1 "memory_operand" "m,m")))]
5117   "TARGET_64BIT && TARGET_MIX_SSE_I387
5118    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5119   "@
5120    fild%z1\t%1
5121    cvtsi2ss{q}\t{%1, %0|%0, %1}"
5122   [(set_attr "type" "fmov,sseicvt")
5123    (set_attr "mode" "SF")
5124    (set_attr "athlon_decode" "*,double")
5125    (set_attr "amdfam10_decode" "*,double")
5126    (set_attr "fp_int_src" "true")])
5127
5128 (define_insn "*floatdisf2_sse"
5129   [(set (match_operand:SF 0 "register_operand" "=x,x")
5130         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5131   "TARGET_64BIT && TARGET_SSE_MATH
5132    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5133   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5134   [(set_attr "type" "sseicvt")
5135    (set_attr "mode" "SF")
5136    (set_attr "athlon_decode" "vector,double")
5137    (set_attr "amdfam10_decode" "vector,double")
5138    (set_attr "fp_int_src" "true")])
5139
5140 (define_insn "*floatdisf2_memory"
5141   [(set (match_operand:SF 0 "register_operand" "=x")
5142         (float:SF (match_operand:DI 1 "memory_operand" "m")))]
5143   "TARGET_64BIT && TARGET_SSE_MATH
5144    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5145   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5146   [(set_attr "type" "sseicvt")
5147    (set_attr "mode" "SF")
5148    (set_attr "athlon_decode" "double")
5149    (set_attr "amdfam10_decode" "double")
5150    (set_attr "fp_int_src" "true")])
5151
5152 (define_expand "floatdidf2"
5153   [(set (match_operand:DF 0 "register_operand" "")
5154         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5155   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5156 {
5157   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5158     {
5159       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5160       DONE;
5161     }
5162   if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5163       && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (DFmode)
5164       && !optimize_size
5165       && !MEM_P (operands[1]))
5166     {
5167         rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), SLOT_VIRTUAL);
5168         emit_move_insn (tmp, operands[1]);
5169         operands[1] = tmp;
5170     }
5171 })
5172
5173 (define_insn "*floatdidf2_mixed"
5174   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5175         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5176   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5177    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5178   "@
5179    fild%z1\t%1
5180    #
5181    cvtsi2sd{q}\t{%1, %0|%0, %1}
5182    cvtsi2sd{q}\t{%1, %0|%0, %1}"
5183   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5184    (set_attr "mode" "DF")
5185    (set_attr "unit" "*,i387,*,*")
5186    (set_attr "athlon_decode" "*,*,double,direct")
5187    (set_attr "amdfam10_decode" "*,*,vector,double")
5188    (set_attr "fp_int_src" "true")])
5189
5190 (define_insn "*floatdidf2_mixed_memory"
5191   [(set (match_operand:DF 0 "register_operand" "=f,x")
5192         (float:DF (match_operand:DI 1 "memory_operand" "m,m")))]
5193   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5194    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5195   "@
5196    fild%z1\t%1
5197    cvtsi2sd{q}\t{%1, %0|%0, %1}"
5198   [(set_attr "type" "fmov,sseicvt")
5199    (set_attr "mode" "DF")
5200    (set_attr "athlon_decode" "*,direct")
5201    (set_attr "amdfam10_decode" "*,double")
5202    (set_attr "fp_int_src" "true")])
5203
5204 (define_insn "*floatdidf2_sse"
5205   [(set (match_operand:DF 0 "register_operand" "=x,x")
5206         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5207   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5208    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5209   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5210   [(set_attr "type" "sseicvt")
5211    (set_attr "mode" "DF")
5212    (set_attr "athlon_decode" "double,direct")
5213    (set_attr "amdfam10_decode" "vector,double")
5214    (set_attr "fp_int_src" "true")])
5215
5216 (define_insn "*floatdidf2_sse_memory"
5217   [(set (match_operand:DF 0 "register_operand" "=x")
5218         (float:DF (match_operand:DI 1 "memory_operand" "m")))]
5219   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5220    && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5221   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5222   [(set_attr "type" "sseicvt")
5223    (set_attr "mode" "DF")
5224    (set_attr "athlon_decode" "direct")
5225    (set_attr "amdfam10_decode" "double")
5226    (set_attr "fp_int_src" "true")])
5227
5228 (define_insn "*floatdi<mode>2_i387"
5229   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5230         (float:MODEF
5231           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5232   "TARGET_80387
5233    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5234   "@
5235    fild%z1\t%1
5236    #"
5237   [(set_attr "type" "fmov,multi")
5238    (set_attr "mode" "<MODE>")
5239    (set_attr "unit" "*,i387")
5240    (set_attr "fp_int_src" "true")])
5241
5242 (define_insn "float<mode>xf2"
5243   [(set (match_operand:XF 0 "register_operand" "=f,f")
5244         (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5245   "TARGET_80387"
5246   "@
5247    fild%z1\t%1
5248    #"
5249   [(set_attr "type" "fmov,multi")
5250    (set_attr "mode" "XF")
5251    (set_attr "unit" "*,i387")
5252    (set_attr "fp_int_src" "true")])
5253
5254 ;; %%% Kill these when reload knows how to do it.
5255 (define_split
5256   [(set (match_operand 0 "fp_register_operand" "")
5257         (float (match_operand 1 "register_operand" "")))]
5258   "reload_completed
5259    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5260   [(const_int 0)]
5261 {
5262   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5263   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5264   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5265   ix86_free_from_memory (GET_MODE (operands[1]));
5266   DONE;
5267 })
5268
5269 (define_expand "floatunssisf2"
5270   [(use (match_operand:SF 0 "register_operand" ""))
5271    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5272   "!TARGET_64BIT"
5273 {
5274   if (TARGET_SSE_MATH && TARGET_SSE2)
5275     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5276   else
5277     x86_emit_floatuns (operands);
5278   DONE;
5279 })
5280
5281 (define_expand "floatunssidf2"
5282   [(use (match_operand:DF 0 "register_operand" ""))
5283    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5284   "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5285   "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5286
5287 (define_expand "floatunsdisf2"
5288   [(use (match_operand:SF 0 "register_operand" ""))
5289    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5290   "TARGET_64BIT && TARGET_SSE_MATH"
5291   "x86_emit_floatuns (operands); DONE;")
5292
5293 (define_expand "floatunsdidf2"
5294   [(use (match_operand:DF 0 "register_operand" ""))
5295    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5296   "TARGET_SSE_MATH && TARGET_SSE2
5297    && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5298 {
5299   if (TARGET_64BIT)
5300     x86_emit_floatuns (operands);
5301   else
5302     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5303   DONE;
5304 })
5305 \f
5306 ;; Add instructions
5307
5308 ;; %%% splits for addditi3
5309
5310 (define_expand "addti3"
5311   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5312         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5313                  (match_operand:TI 2 "x86_64_general_operand" "")))
5314    (clobber (reg:CC FLAGS_REG))]
5315   "TARGET_64BIT"
5316   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5317
5318 (define_insn "*addti3_1"
5319   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5320         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5321                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5322    (clobber (reg:CC FLAGS_REG))]
5323   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5324   "#")
5325
5326 (define_split
5327   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5328         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5329                  (match_operand:TI 2 "x86_64_general_operand" "")))
5330    (clobber (reg:CC FLAGS_REG))]
5331   "TARGET_64BIT && reload_completed"
5332   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5333                                           UNSPEC_ADD_CARRY))
5334               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5335    (parallel [(set (match_dup 3)
5336                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5337                                      (match_dup 4))
5338                             (match_dup 5)))
5339               (clobber (reg:CC FLAGS_REG))])]
5340   "split_ti (operands+0, 1, operands+0, operands+3);
5341    split_ti (operands+1, 1, operands+1, operands+4);
5342    split_ti (operands+2, 1, operands+2, operands+5);")
5343
5344 ;; %%% splits for addsidi3
5345 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5346 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5347 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5348
5349 (define_expand "adddi3"
5350   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5351         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5352                  (match_operand:DI 2 "x86_64_general_operand" "")))
5353    (clobber (reg:CC FLAGS_REG))]
5354   ""
5355   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5356
5357 (define_insn "*adddi3_1"
5358   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5359         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5360                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5361    (clobber (reg:CC FLAGS_REG))]
5362   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5363   "#")
5364
5365 (define_split
5366   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5367         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5368                  (match_operand:DI 2 "general_operand" "")))
5369    (clobber (reg:CC FLAGS_REG))]
5370   "!TARGET_64BIT && reload_completed"
5371   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5372                                           UNSPEC_ADD_CARRY))
5373               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5374    (parallel [(set (match_dup 3)
5375                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5376                                      (match_dup 4))
5377                             (match_dup 5)))
5378               (clobber (reg:CC FLAGS_REG))])]
5379   "split_di (operands+0, 1, operands+0, operands+3);
5380    split_di (operands+1, 1, operands+1, operands+4);
5381    split_di (operands+2, 1, operands+2, operands+5);")
5382
5383 (define_insn "adddi3_carry_rex64"
5384   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5385           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5386                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5387                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5388    (clobber (reg:CC FLAGS_REG))]
5389   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5390   "adc{q}\t{%2, %0|%0, %2}"
5391   [(set_attr "type" "alu")
5392    (set_attr "pent_pair" "pu")
5393    (set_attr "mode" "DI")])
5394
5395 (define_insn "*adddi3_cc_rex64"
5396   [(set (reg:CC FLAGS_REG)
5397         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5398                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5399                    UNSPEC_ADD_CARRY))
5400    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5401         (plus:DI (match_dup 1) (match_dup 2)))]
5402   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5403   "add{q}\t{%2, %0|%0, %2}"
5404   [(set_attr "type" "alu")
5405    (set_attr "mode" "DI")])
5406
5407 (define_insn "*<addsub><mode>3_cc_overflow"
5408   [(set (reg:CCC FLAGS_REG)
5409         (compare:CCC
5410             (plusminus:SWI
5411                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5412                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5413             (match_dup 1)))
5414    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5415         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5416   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5417   "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5418   [(set_attr "type" "alu")
5419    (set_attr "mode" "<MODE>")])
5420
5421 (define_insn "*add<mode>3_cconly_overflow"
5422   [(set (reg:CCC FLAGS_REG)
5423         (compare:CCC
5424                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5425                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5426                 (match_dup 1)))
5427    (clobber (match_scratch:SWI 0 "=<r>"))]
5428   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5429   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5430   [(set_attr "type" "alu")
5431    (set_attr "mode" "<MODE>")])
5432
5433 (define_insn "*sub<mode>3_cconly_overflow"
5434   [(set (reg:CCC FLAGS_REG)
5435         (compare:CCC
5436              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5437                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5438              (match_dup 0)))]
5439   ""
5440   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5441   [(set_attr "type" "icmp")
5442    (set_attr "mode" "<MODE>")])
5443
5444 (define_insn "*<addsub>si3_zext_cc_overflow"
5445   [(set (reg:CCC FLAGS_REG)
5446         (compare:CCC
5447             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5448                           (match_operand:SI 2 "general_operand" "g"))
5449             (match_dup 1)))
5450    (set (match_operand:DI 0 "register_operand" "=r")
5451         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5452   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5453   "<addsub>{l}\t{%2, %k0|%k0, %2}"
5454   [(set_attr "type" "alu")
5455    (set_attr "mode" "SI")])
5456
5457 (define_insn "addqi3_carry"
5458   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5459           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5460                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5461                    (match_operand:QI 2 "general_operand" "qi,qm")))
5462    (clobber (reg:CC FLAGS_REG))]
5463   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5464   "adc{b}\t{%2, %0|%0, %2}"
5465   [(set_attr "type" "alu")
5466    (set_attr "pent_pair" "pu")
5467    (set_attr "mode" "QI")])
5468
5469 (define_insn "addhi3_carry"
5470   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5471           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5472                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5473                    (match_operand:HI 2 "general_operand" "ri,rm")))
5474    (clobber (reg:CC FLAGS_REG))]
5475   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5476   "adc{w}\t{%2, %0|%0, %2}"
5477   [(set_attr "type" "alu")
5478    (set_attr "pent_pair" "pu")
5479    (set_attr "mode" "HI")])
5480
5481 (define_insn "addsi3_carry"
5482   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5483           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5484                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5485                    (match_operand:SI 2 "general_operand" "ri,rm")))
5486    (clobber (reg:CC FLAGS_REG))]
5487   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5488   "adc{l}\t{%2, %0|%0, %2}"
5489   [(set_attr "type" "alu")
5490    (set_attr "pent_pair" "pu")
5491    (set_attr "mode" "SI")])
5492
5493 (define_insn "*addsi3_carry_zext"
5494   [(set (match_operand:DI 0 "register_operand" "=r")
5495           (zero_extend:DI
5496             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5497                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5498                      (match_operand:SI 2 "general_operand" "g"))))
5499    (clobber (reg:CC FLAGS_REG))]
5500   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5501   "adc{l}\t{%2, %k0|%k0, %2}"
5502   [(set_attr "type" "alu")
5503    (set_attr "pent_pair" "pu")
5504    (set_attr "mode" "SI")])
5505
5506 (define_insn "*addsi3_cc"
5507   [(set (reg:CC FLAGS_REG)
5508         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5509                     (match_operand:SI 2 "general_operand" "ri,rm")]
5510                    UNSPEC_ADD_CARRY))
5511    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5512         (plus:SI (match_dup 1) (match_dup 2)))]
5513   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5514   "add{l}\t{%2, %0|%0, %2}"
5515   [(set_attr "type" "alu")
5516    (set_attr "mode" "SI")])
5517
5518 (define_insn "addqi3_cc"
5519   [(set (reg:CC FLAGS_REG)
5520         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5521                     (match_operand:QI 2 "general_operand" "qi,qm")]
5522                    UNSPEC_ADD_CARRY))
5523    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5524         (plus:QI (match_dup 1) (match_dup 2)))]
5525   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5526   "add{b}\t{%2, %0|%0, %2}"
5527   [(set_attr "type" "alu")
5528    (set_attr "mode" "QI")])
5529
5530 (define_expand "addsi3"
5531   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5532                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5533                             (match_operand:SI 2 "general_operand" "")))
5534               (clobber (reg:CC FLAGS_REG))])]
5535   ""
5536   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5537
5538 (define_insn "*lea_1"
5539   [(set (match_operand:SI 0 "register_operand" "=r")
5540         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5541   "!TARGET_64BIT"
5542   "lea{l}\t{%a1, %0|%0, %a1}"
5543   [(set_attr "type" "lea")
5544    (set_attr "mode" "SI")])
5545
5546 (define_insn "*lea_1_rex64"
5547   [(set (match_operand:SI 0 "register_operand" "=r")
5548         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5549   "TARGET_64BIT"
5550   "lea{l}\t{%a1, %0|%0, %a1}"
5551   [(set_attr "type" "lea")
5552    (set_attr "mode" "SI")])
5553
5554 (define_insn "*lea_1_zext"
5555   [(set (match_operand:DI 0 "register_operand" "=r")
5556         (zero_extend:DI
5557          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5558   "TARGET_64BIT"
5559   "lea{l}\t{%a1, %k0|%k0, %a1}"
5560   [(set_attr "type" "lea")
5561    (set_attr "mode" "SI")])
5562
5563 (define_insn "*lea_2_rex64"
5564   [(set (match_operand:DI 0 "register_operand" "=r")
5565         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5566   "TARGET_64BIT"
5567   "lea{q}\t{%a1, %0|%0, %a1}"
5568   [(set_attr "type" "lea")
5569    (set_attr "mode" "DI")])
5570
5571 ;; The lea patterns for non-Pmodes needs to be matched by several
5572 ;; insns converted to real lea by splitters.
5573
5574 (define_insn_and_split "*lea_general_1"
5575   [(set (match_operand 0 "register_operand" "=r")
5576         (plus (plus (match_operand 1 "index_register_operand" "l")
5577                     (match_operand 2 "register_operand" "r"))
5578               (match_operand 3 "immediate_operand" "i")))]
5579   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5580     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5581    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5582    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5583    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5584    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5585        || GET_MODE (operands[3]) == VOIDmode)"
5586   "#"
5587   "&& reload_completed"
5588   [(const_int 0)]
5589 {
5590   rtx pat;
5591   operands[0] = gen_lowpart (SImode, operands[0]);
5592   operands[1] = gen_lowpart (Pmode, operands[1]);
5593   operands[2] = gen_lowpart (Pmode, operands[2]);
5594   operands[3] = gen_lowpart (Pmode, operands[3]);
5595   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5596                       operands[3]);
5597   if (Pmode != SImode)
5598     pat = gen_rtx_SUBREG (SImode, pat, 0);
5599   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5600   DONE;
5601 }
5602   [(set_attr "type" "lea")
5603    (set_attr "mode" "SI")])
5604
5605 (define_insn_and_split "*lea_general_1_zext"
5606   [(set (match_operand:DI 0 "register_operand" "=r")
5607         (zero_extend:DI
5608           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5609                             (match_operand:SI 2 "register_operand" "r"))
5610                    (match_operand:SI 3 "immediate_operand" "i"))))]
5611   "TARGET_64BIT"
5612   "#"
5613   "&& reload_completed"
5614   [(set (match_dup 0)
5615         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5616                                                      (match_dup 2))
5617                                             (match_dup 3)) 0)))]
5618 {
5619   operands[1] = gen_lowpart (Pmode, operands[1]);
5620   operands[2] = gen_lowpart (Pmode, operands[2]);
5621   operands[3] = gen_lowpart (Pmode, operands[3]);
5622 }
5623   [(set_attr "type" "lea")
5624    (set_attr "mode" "SI")])
5625
5626 (define_insn_and_split "*lea_general_2"
5627   [(set (match_operand 0 "register_operand" "=r")
5628         (plus (mult (match_operand 1 "index_register_operand" "l")
5629                     (match_operand 2 "const248_operand" "i"))
5630               (match_operand 3 "nonmemory_operand" "ri")))]
5631   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5632     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5633    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5634    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5635    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5636        || GET_MODE (operands[3]) == VOIDmode)"
5637   "#"
5638   "&& reload_completed"
5639   [(const_int 0)]
5640 {
5641   rtx pat;
5642   operands[0] = gen_lowpart (SImode, operands[0]);
5643   operands[1] = gen_lowpart (Pmode, operands[1]);
5644   operands[3] = gen_lowpart (Pmode, operands[3]);
5645   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5646                       operands[3]);
5647   if (Pmode != SImode)
5648     pat = gen_rtx_SUBREG (SImode, pat, 0);
5649   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5650   DONE;
5651 }
5652   [(set_attr "type" "lea")
5653    (set_attr "mode" "SI")])
5654
5655 (define_insn_and_split "*lea_general_2_zext"
5656   [(set (match_operand:DI 0 "register_operand" "=r")
5657         (zero_extend:DI
5658           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5659                             (match_operand:SI 2 "const248_operand" "n"))
5660                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5661   "TARGET_64BIT"
5662   "#"
5663   "&& reload_completed"
5664   [(set (match_dup 0)
5665         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5666                                                      (match_dup 2))
5667                                             (match_dup 3)) 0)))]
5668 {
5669   operands[1] = gen_lowpart (Pmode, operands[1]);
5670   operands[3] = gen_lowpart (Pmode, operands[3]);
5671 }
5672   [(set_attr "type" "lea")
5673    (set_attr "mode" "SI")])
5674
5675 (define_insn_and_split "*lea_general_3"
5676   [(set (match_operand 0 "register_operand" "=r")
5677         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5678                           (match_operand 2 "const248_operand" "i"))
5679                     (match_operand 3 "register_operand" "r"))
5680               (match_operand 4 "immediate_operand" "i")))]
5681   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5682     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5683    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5684    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5685    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5686   "#"
5687   "&& reload_completed"
5688   [(const_int 0)]
5689 {
5690   rtx pat;
5691   operands[0] = gen_lowpart (SImode, operands[0]);
5692   operands[1] = gen_lowpart (Pmode, operands[1]);
5693   operands[3] = gen_lowpart (Pmode, operands[3]);
5694   operands[4] = gen_lowpart (Pmode, operands[4]);
5695   pat = gen_rtx_PLUS (Pmode,
5696                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5697                                                          operands[2]),
5698                                     operands[3]),
5699                       operands[4]);
5700   if (Pmode != SImode)
5701     pat = gen_rtx_SUBREG (SImode, pat, 0);
5702   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5703   DONE;
5704 }
5705   [(set_attr "type" "lea")
5706    (set_attr "mode" "SI")])
5707
5708 (define_insn_and_split "*lea_general_3_zext"
5709   [(set (match_operand:DI 0 "register_operand" "=r")
5710         (zero_extend:DI
5711           (plus:SI (plus:SI (mult:SI
5712                               (match_operand:SI 1 "index_register_operand" "l")
5713                               (match_operand:SI 2 "const248_operand" "n"))
5714                             (match_operand:SI 3 "register_operand" "r"))
5715                    (match_operand:SI 4 "immediate_operand" "i"))))]
5716   "TARGET_64BIT"
5717   "#"
5718   "&& reload_completed"
5719   [(set (match_dup 0)
5720         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5721                                                               (match_dup 2))
5722                                                      (match_dup 3))
5723                                             (match_dup 4)) 0)))]
5724 {
5725   operands[1] = gen_lowpart (Pmode, operands[1]);
5726   operands[3] = gen_lowpart (Pmode, operands[3]);
5727   operands[4] = gen_lowpart (Pmode, operands[4]);
5728 }
5729   [(set_attr "type" "lea")
5730    (set_attr "mode" "SI")])
5731
5732 (define_insn "*adddi_1_rex64"
5733   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5734         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5735                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5736    (clobber (reg:CC FLAGS_REG))]
5737   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5738 {
5739   switch (get_attr_type (insn))
5740     {
5741     case TYPE_LEA:
5742       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5743       return "lea{q}\t{%a2, %0|%0, %a2}";
5744
5745     case TYPE_INCDEC:
5746       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5747       if (operands[2] == const1_rtx)
5748         return "inc{q}\t%0";
5749       else
5750         {
5751           gcc_assert (operands[2] == constm1_rtx);
5752           return "dec{q}\t%0";
5753         }
5754
5755     default:
5756       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5757
5758       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5759          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5760       if (CONST_INT_P (operands[2])
5761           /* Avoid overflows.  */
5762           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5763           && (INTVAL (operands[2]) == 128
5764               || (INTVAL (operands[2]) < 0
5765                   && INTVAL (operands[2]) != -128)))
5766         {
5767           operands[2] = GEN_INT (-INTVAL (operands[2]));
5768           return "sub{q}\t{%2, %0|%0, %2}";
5769         }
5770       return "add{q}\t{%2, %0|%0, %2}";
5771     }
5772 }
5773   [(set (attr "type")
5774      (cond [(eq_attr "alternative" "2")
5775               (const_string "lea")
5776             ; Current assemblers are broken and do not allow @GOTOFF in
5777             ; ought but a memory context.
5778             (match_operand:DI 2 "pic_symbolic_operand" "")
5779               (const_string "lea")
5780             (match_operand:DI 2 "incdec_operand" "")
5781               (const_string "incdec")
5782            ]
5783            (const_string "alu")))
5784    (set_attr "mode" "DI")])
5785
5786 ;; Convert lea to the lea pattern to avoid flags dependency.
5787 (define_split
5788   [(set (match_operand:DI 0 "register_operand" "")
5789         (plus:DI (match_operand:DI 1 "register_operand" "")
5790                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5791    (clobber (reg:CC FLAGS_REG))]
5792   "TARGET_64BIT && reload_completed
5793    && true_regnum (operands[0]) != true_regnum (operands[1])"
5794   [(set (match_dup 0)
5795         (plus:DI (match_dup 1)
5796                  (match_dup 2)))]
5797   "")
5798
5799 (define_insn "*adddi_2_rex64"
5800   [(set (reg FLAGS_REG)
5801         (compare
5802           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5803                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5804           (const_int 0)))
5805    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5806         (plus:DI (match_dup 1) (match_dup 2)))]
5807   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5808    && ix86_binary_operator_ok (PLUS, DImode, operands)
5809    /* Current assemblers are broken and do not allow @GOTOFF in
5810       ought but a memory context.  */
5811    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5812 {
5813   switch (get_attr_type (insn))
5814     {
5815     case TYPE_INCDEC:
5816       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5817       if (operands[2] == const1_rtx)
5818         return "inc{q}\t%0";
5819       else
5820         {
5821           gcc_assert (operands[2] == constm1_rtx);
5822           return "dec{q}\t%0";
5823         }
5824
5825     default:
5826       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5827       /* ???? We ought to handle there the 32bit case too
5828          - do we need new constraint?  */
5829       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5830          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5831       if (CONST_INT_P (operands[2])
5832           /* Avoid overflows.  */
5833           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5834           && (INTVAL (operands[2]) == 128
5835               || (INTVAL (operands[2]) < 0
5836                   && INTVAL (operands[2]) != -128)))
5837         {
5838           operands[2] = GEN_INT (-INTVAL (operands[2]));
5839           return "sub{q}\t{%2, %0|%0, %2}";
5840         }
5841       return "add{q}\t{%2, %0|%0, %2}";
5842     }
5843 }
5844   [(set (attr "type")
5845      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5846         (const_string "incdec")
5847         (const_string "alu")))
5848    (set_attr "mode" "DI")])
5849
5850 (define_insn "*adddi_3_rex64"
5851   [(set (reg FLAGS_REG)
5852         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5853                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5854    (clobber (match_scratch:DI 0 "=r"))]
5855   "TARGET_64BIT
5856    && ix86_match_ccmode (insn, CCZmode)
5857    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5858    /* Current assemblers are broken and do not allow @GOTOFF in
5859       ought but a memory context.  */
5860    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5861 {
5862   switch (get_attr_type (insn))
5863     {
5864     case TYPE_INCDEC:
5865       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5866       if (operands[2] == const1_rtx)
5867         return "inc{q}\t%0";
5868       else
5869         {
5870           gcc_assert (operands[2] == constm1_rtx);
5871           return "dec{q}\t%0";
5872         }
5873
5874     default:
5875       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5876       /* ???? We ought to handle there the 32bit case too
5877          - do we need new constraint?  */
5878       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5879          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5880       if (CONST_INT_P (operands[2])
5881           /* Avoid overflows.  */
5882           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5883           && (INTVAL (operands[2]) == 128
5884               || (INTVAL (operands[2]) < 0
5885                   && INTVAL (operands[2]) != -128)))
5886         {
5887           operands[2] = GEN_INT (-INTVAL (operands[2]));
5888           return "sub{q}\t{%2, %0|%0, %2}";
5889         }
5890       return "add{q}\t{%2, %0|%0, %2}";
5891     }
5892 }
5893   [(set (attr "type")
5894      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5895         (const_string "incdec")
5896         (const_string "alu")))
5897    (set_attr "mode" "DI")])
5898
5899 ; For comparisons against 1, -1 and 128, we may generate better code
5900 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5901 ; is matched then.  We can't accept general immediate, because for
5902 ; case of overflows,  the result is messed up.
5903 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5904 ; when negated.
5905 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5906 ; only for comparisons not depending on it.
5907 (define_insn "*adddi_4_rex64"
5908   [(set (reg FLAGS_REG)
5909         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5910                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5911    (clobber (match_scratch:DI 0 "=rm"))]
5912   "TARGET_64BIT
5913    &&  ix86_match_ccmode (insn, CCGCmode)"
5914 {
5915   switch (get_attr_type (insn))
5916     {
5917     case TYPE_INCDEC:
5918       if (operands[2] == constm1_rtx)
5919         return "inc{q}\t%0";
5920       else
5921         {
5922           gcc_assert (operands[2] == const1_rtx);
5923           return "dec{q}\t%0";
5924         }
5925
5926     default:
5927       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5928       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5929          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5930       if ((INTVAL (operands[2]) == -128
5931            || (INTVAL (operands[2]) > 0
5932                && INTVAL (operands[2]) != 128))
5933           /* Avoid overflows.  */
5934           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5935         return "sub{q}\t{%2, %0|%0, %2}";
5936       operands[2] = GEN_INT (-INTVAL (operands[2]));
5937       return "add{q}\t{%2, %0|%0, %2}";
5938     }
5939 }
5940   [(set (attr "type")
5941      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5942         (const_string "incdec")
5943         (const_string "alu")))
5944    (set_attr "mode" "DI")])
5945
5946 (define_insn "*adddi_5_rex64"
5947   [(set (reg FLAGS_REG)
5948         (compare
5949           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5950                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5951           (const_int 0)))
5952    (clobber (match_scratch:DI 0 "=r"))]
5953   "TARGET_64BIT
5954    && ix86_match_ccmode (insn, CCGOCmode)
5955    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5956    /* Current assemblers are broken and do not allow @GOTOFF in
5957       ought but a memory context.  */
5958    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5959 {
5960   switch (get_attr_type (insn))
5961     {
5962     case TYPE_INCDEC:
5963       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5964       if (operands[2] == const1_rtx)
5965         return "inc{q}\t%0";
5966       else
5967         {
5968           gcc_assert (operands[2] == constm1_rtx);
5969           return "dec{q}\t%0";
5970         }
5971
5972     default:
5973       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5974       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5975          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5976       if (CONST_INT_P (operands[2])
5977           /* Avoid overflows.  */
5978           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5979           && (INTVAL (operands[2]) == 128
5980               || (INTVAL (operands[2]) < 0
5981                   && INTVAL (operands[2]) != -128)))
5982         {
5983           operands[2] = GEN_INT (-INTVAL (operands[2]));
5984           return "sub{q}\t{%2, %0|%0, %2}";
5985         }
5986       return "add{q}\t{%2, %0|%0, %2}";
5987     }
5988 }
5989   [(set (attr "type")
5990      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5991         (const_string "incdec")
5992         (const_string "alu")))
5993    (set_attr "mode" "DI")])
5994
5995
5996 (define_insn "*addsi_1"
5997   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5998         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5999                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6000    (clobber (reg:CC FLAGS_REG))]
6001   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6002 {
6003   switch (get_attr_type (insn))
6004     {
6005     case TYPE_LEA:
6006       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6007       return "lea{l}\t{%a2, %0|%0, %a2}";
6008
6009     case TYPE_INCDEC:
6010       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6011       if (operands[2] == const1_rtx)
6012         return "inc{l}\t%0";
6013       else
6014         {
6015           gcc_assert (operands[2] == constm1_rtx);
6016           return "dec{l}\t%0";
6017         }
6018
6019     default:
6020       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6021
6022       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6023          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6024       if (CONST_INT_P (operands[2])
6025           && (INTVAL (operands[2]) == 128
6026               || (INTVAL (operands[2]) < 0
6027                   && INTVAL (operands[2]) != -128)))
6028         {
6029           operands[2] = GEN_INT (-INTVAL (operands[2]));
6030           return "sub{l}\t{%2, %0|%0, %2}";
6031         }
6032       return "add{l}\t{%2, %0|%0, %2}";
6033     }
6034 }
6035   [(set (attr "type")
6036      (cond [(eq_attr "alternative" "2")
6037               (const_string "lea")
6038             ; Current assemblers are broken and do not allow @GOTOFF in
6039             ; ought but a memory context.
6040             (match_operand:SI 2 "pic_symbolic_operand" "")
6041               (const_string "lea")
6042             (match_operand:SI 2 "incdec_operand" "")
6043               (const_string "incdec")
6044            ]
6045            (const_string "alu")))
6046    (set_attr "mode" "SI")])
6047
6048 ;; Convert lea to the lea pattern to avoid flags dependency.
6049 (define_split
6050   [(set (match_operand 0 "register_operand" "")
6051         (plus (match_operand 1 "register_operand" "")
6052               (match_operand 2 "nonmemory_operand" "")))
6053    (clobber (reg:CC FLAGS_REG))]
6054   "reload_completed
6055    && true_regnum (operands[0]) != true_regnum (operands[1])"
6056   [(const_int 0)]
6057 {
6058   rtx pat;
6059   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6060      may confuse gen_lowpart.  */
6061   if (GET_MODE (operands[0]) != Pmode)
6062     {
6063       operands[1] = gen_lowpart (Pmode, operands[1]);
6064       operands[2] = gen_lowpart (Pmode, operands[2]);
6065     }
6066   operands[0] = gen_lowpart (SImode, operands[0]);
6067   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6068   if (Pmode != SImode)
6069     pat = gen_rtx_SUBREG (SImode, pat, 0);
6070   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6071   DONE;
6072 })
6073
6074 ;; It may seem that nonimmediate operand is proper one for operand 1.
6075 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6076 ;; we take care in ix86_binary_operator_ok to not allow two memory
6077 ;; operands so proper swapping will be done in reload.  This allow
6078 ;; patterns constructed from addsi_1 to match.
6079 (define_insn "addsi_1_zext"
6080   [(set (match_operand:DI 0 "register_operand" "=r,r")
6081         (zero_extend:DI
6082           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6083                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
6084    (clobber (reg:CC FLAGS_REG))]
6085   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6086 {
6087   switch (get_attr_type (insn))
6088     {
6089     case TYPE_LEA:
6090       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6091       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6092
6093     case TYPE_INCDEC:
6094       if (operands[2] == const1_rtx)
6095         return "inc{l}\t%k0";
6096       else
6097         {
6098           gcc_assert (operands[2] == constm1_rtx);
6099           return "dec{l}\t%k0";
6100         }
6101
6102     default:
6103       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6104          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6105       if (CONST_INT_P (operands[2])
6106           && (INTVAL (operands[2]) == 128
6107               || (INTVAL (operands[2]) < 0
6108                   && INTVAL (operands[2]) != -128)))
6109         {
6110           operands[2] = GEN_INT (-INTVAL (operands[2]));
6111           return "sub{l}\t{%2, %k0|%k0, %2}";
6112         }
6113       return "add{l}\t{%2, %k0|%k0, %2}";
6114     }
6115 }
6116   [(set (attr "type")
6117      (cond [(eq_attr "alternative" "1")
6118               (const_string "lea")
6119             ; Current assemblers are broken and do not allow @GOTOFF in
6120             ; ought but a memory context.
6121             (match_operand:SI 2 "pic_symbolic_operand" "")
6122               (const_string "lea")
6123             (match_operand:SI 2 "incdec_operand" "")
6124               (const_string "incdec")
6125            ]
6126            (const_string "alu")))
6127    (set_attr "mode" "SI")])
6128
6129 ;; Convert lea to the lea pattern to avoid flags dependency.
6130 (define_split
6131   [(set (match_operand:DI 0 "register_operand" "")
6132         (zero_extend:DI
6133           (plus:SI (match_operand:SI 1 "register_operand" "")
6134                    (match_operand:SI 2 "nonmemory_operand" ""))))
6135    (clobber (reg:CC FLAGS_REG))]
6136   "TARGET_64BIT && reload_completed
6137    && true_regnum (operands[0]) != true_regnum (operands[1])"
6138   [(set (match_dup 0)
6139         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6140 {
6141   operands[1] = gen_lowpart (Pmode, operands[1]);
6142   operands[2] = gen_lowpart (Pmode, operands[2]);
6143 })
6144
6145 (define_insn "*addsi_2"
6146   [(set (reg FLAGS_REG)
6147         (compare
6148           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6149                    (match_operand:SI 2 "general_operand" "rmni,rni"))
6150           (const_int 0)))
6151    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6152         (plus:SI (match_dup 1) (match_dup 2)))]
6153   "ix86_match_ccmode (insn, CCGOCmode)
6154    && ix86_binary_operator_ok (PLUS, SImode, operands)
6155    /* Current assemblers are broken and do not allow @GOTOFF in
6156       ought but a memory context.  */
6157    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6158 {
6159   switch (get_attr_type (insn))
6160     {
6161     case TYPE_INCDEC:
6162       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6163       if (operands[2] == const1_rtx)
6164         return "inc{l}\t%0";
6165       else
6166         {
6167           gcc_assert (operands[2] == constm1_rtx);
6168           return "dec{l}\t%0";
6169         }
6170
6171     default:
6172       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6173       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6174          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6175       if (CONST_INT_P (operands[2])
6176           && (INTVAL (operands[2]) == 128
6177               || (INTVAL (operands[2]) < 0
6178                   && INTVAL (operands[2]) != -128)))
6179         {
6180           operands[2] = GEN_INT (-INTVAL (operands[2]));
6181           return "sub{l}\t{%2, %0|%0, %2}";
6182         }
6183       return "add{l}\t{%2, %0|%0, %2}";
6184     }
6185 }
6186   [(set (attr "type")
6187      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6188         (const_string "incdec")
6189         (const_string "alu")))
6190    (set_attr "mode" "SI")])
6191
6192 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6193 (define_insn "*addsi_2_zext"
6194   [(set (reg FLAGS_REG)
6195         (compare
6196           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6197                    (match_operand:SI 2 "general_operand" "rmni"))
6198           (const_int 0)))
6199    (set (match_operand:DI 0 "register_operand" "=r")
6200         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6201   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6202    && ix86_binary_operator_ok (PLUS, SImode, operands)
6203    /* Current assemblers are broken and do not allow @GOTOFF in
6204       ought but a memory context.  */
6205    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6206 {
6207   switch (get_attr_type (insn))
6208     {
6209     case TYPE_INCDEC:
6210       if (operands[2] == const1_rtx)
6211         return "inc{l}\t%k0";
6212       else
6213         {
6214           gcc_assert (operands[2] == constm1_rtx);
6215           return "dec{l}\t%k0";
6216         }
6217
6218     default:
6219       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6220          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6221       if (CONST_INT_P (operands[2])
6222           && (INTVAL (operands[2]) == 128
6223               || (INTVAL (operands[2]) < 0
6224                   && INTVAL (operands[2]) != -128)))
6225         {
6226           operands[2] = GEN_INT (-INTVAL (operands[2]));
6227           return "sub{l}\t{%2, %k0|%k0, %2}";
6228         }
6229       return "add{l}\t{%2, %k0|%k0, %2}";
6230     }
6231 }
6232   [(set (attr "type")
6233      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6234         (const_string "incdec")
6235         (const_string "alu")))
6236    (set_attr "mode" "SI")])
6237
6238 (define_insn "*addsi_3"
6239   [(set (reg FLAGS_REG)
6240         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6241                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6242    (clobber (match_scratch:SI 0 "=r"))]
6243   "ix86_match_ccmode (insn, CCZmode)
6244    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6245    /* Current assemblers are broken and do not allow @GOTOFF in
6246       ought but a memory context.  */
6247    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6248 {
6249   switch (get_attr_type (insn))
6250     {
6251     case TYPE_INCDEC:
6252       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6253       if (operands[2] == const1_rtx)
6254         return "inc{l}\t%0";
6255       else
6256         {
6257           gcc_assert (operands[2] == constm1_rtx);
6258           return "dec{l}\t%0";
6259         }
6260
6261     default:
6262       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6263       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6264          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6265       if (CONST_INT_P (operands[2])
6266           && (INTVAL (operands[2]) == 128
6267               || (INTVAL (operands[2]) < 0
6268                   && INTVAL (operands[2]) != -128)))
6269         {
6270           operands[2] = GEN_INT (-INTVAL (operands[2]));
6271           return "sub{l}\t{%2, %0|%0, %2}";
6272         }
6273       return "add{l}\t{%2, %0|%0, %2}";
6274     }
6275 }
6276   [(set (attr "type")
6277      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6278         (const_string "incdec")
6279         (const_string "alu")))
6280    (set_attr "mode" "SI")])
6281
6282 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6283 (define_insn "*addsi_3_zext"
6284   [(set (reg FLAGS_REG)
6285         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6286                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6287    (set (match_operand:DI 0 "register_operand" "=r")
6288         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6289   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6290    && ix86_binary_operator_ok (PLUS, SImode, operands)
6291    /* Current assemblers are broken and do not allow @GOTOFF in
6292       ought but a memory context.  */
6293    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6294 {
6295   switch (get_attr_type (insn))
6296     {
6297     case TYPE_INCDEC:
6298       if (operands[2] == const1_rtx)
6299         return "inc{l}\t%k0";
6300       else
6301         {
6302           gcc_assert (operands[2] == constm1_rtx);
6303           return "dec{l}\t%k0";
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           return "sub{l}\t{%2, %k0|%k0, %2}";
6316         }
6317       return "add{l}\t{%2, %k0|%k0, %2}";
6318     }
6319 }
6320   [(set (attr "type")
6321      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6322         (const_string "incdec")
6323         (const_string "alu")))
6324    (set_attr "mode" "SI")])
6325
6326 ; For comparisons against 1, -1 and 128, we may generate better code
6327 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6328 ; is matched then.  We can't accept general immediate, because for
6329 ; case of overflows,  the result is messed up.
6330 ; This pattern also don't hold of 0x80000000, since the value overflows
6331 ; when negated.
6332 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6333 ; only for comparisons not depending on it.
6334 (define_insn "*addsi_4"
6335   [(set (reg FLAGS_REG)
6336         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6337                  (match_operand:SI 2 "const_int_operand" "n")))
6338    (clobber (match_scratch:SI 0 "=rm"))]
6339   "ix86_match_ccmode (insn, CCGCmode)
6340    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6341 {
6342   switch (get_attr_type (insn))
6343     {
6344     case TYPE_INCDEC:
6345       if (operands[2] == constm1_rtx)
6346         return "inc{l}\t%0";
6347       else
6348         {
6349           gcc_assert (operands[2] == const1_rtx);
6350           return "dec{l}\t%0";
6351         }
6352
6353     default:
6354       gcc_assert (rtx_equal_p (operands[0], operands[1]));
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 ((INTVAL (operands[2]) == -128
6358            || (INTVAL (operands[2]) > 0
6359                && INTVAL (operands[2]) != 128)))
6360         return "sub{l}\t{%2, %0|%0, %2}";
6361       operands[2] = GEN_INT (-INTVAL (operands[2]));
6362       return "add{l}\t{%2, %0|%0, %2}";
6363     }
6364 }
6365   [(set (attr "type")
6366      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6367         (const_string "incdec")
6368         (const_string "alu")))
6369    (set_attr "mode" "SI")])
6370
6371 (define_insn "*addsi_5"
6372   [(set (reg FLAGS_REG)
6373         (compare
6374           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6375                    (match_operand:SI 2 "general_operand" "rmni"))
6376           (const_int 0)))
6377    (clobber (match_scratch:SI 0 "=r"))]
6378   "ix86_match_ccmode (insn, CCGOCmode)
6379    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6380    /* Current assemblers are broken and do not allow @GOTOFF in
6381       ought but a memory context.  */
6382    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6383 {
6384   switch (get_attr_type (insn))
6385     {
6386     case TYPE_INCDEC:
6387       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6388       if (operands[2] == const1_rtx)
6389         return "inc{l}\t%0";
6390       else
6391         {
6392           gcc_assert (operands[2] == constm1_rtx);
6393           return "dec{l}\t%0";
6394         }
6395
6396     default:
6397       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6398       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6399          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6400       if (CONST_INT_P (operands[2])
6401           && (INTVAL (operands[2]) == 128
6402               || (INTVAL (operands[2]) < 0
6403                   && INTVAL (operands[2]) != -128)))
6404         {
6405           operands[2] = GEN_INT (-INTVAL (operands[2]));
6406           return "sub{l}\t{%2, %0|%0, %2}";
6407         }
6408       return "add{l}\t{%2, %0|%0, %2}";
6409     }
6410 }
6411   [(set (attr "type")
6412      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6413         (const_string "incdec")
6414         (const_string "alu")))
6415    (set_attr "mode" "SI")])
6416
6417 (define_expand "addhi3"
6418   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6419                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6420                             (match_operand:HI 2 "general_operand" "")))
6421               (clobber (reg:CC FLAGS_REG))])]
6422   "TARGET_HIMODE_MATH"
6423   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6424
6425 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6426 ;; type optimizations enabled by define-splits.  This is not important
6427 ;; for PII, and in fact harmful because of partial register stalls.
6428
6429 (define_insn "*addhi_1_lea"
6430   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6431         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6432                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6433    (clobber (reg:CC FLAGS_REG))]
6434   "!TARGET_PARTIAL_REG_STALL
6435    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6436 {
6437   switch (get_attr_type (insn))
6438     {
6439     case TYPE_LEA:
6440       return "#";
6441     case TYPE_INCDEC:
6442       if (operands[2] == const1_rtx)
6443         return "inc{w}\t%0";
6444       else
6445         {
6446           gcc_assert (operands[2] == constm1_rtx);
6447           return "dec{w}\t%0";
6448         }
6449
6450     default:
6451       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6452          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6453       if (CONST_INT_P (operands[2])
6454           && (INTVAL (operands[2]) == 128
6455               || (INTVAL (operands[2]) < 0
6456                   && INTVAL (operands[2]) != -128)))
6457         {
6458           operands[2] = GEN_INT (-INTVAL (operands[2]));
6459           return "sub{w}\t{%2, %0|%0, %2}";
6460         }
6461       return "add{w}\t{%2, %0|%0, %2}";
6462     }
6463 }
6464   [(set (attr "type")
6465      (if_then_else (eq_attr "alternative" "2")
6466         (const_string "lea")
6467         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6468            (const_string "incdec")
6469            (const_string "alu"))))
6470    (set_attr "mode" "HI,HI,SI")])
6471
6472 (define_insn "*addhi_1"
6473   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6474         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6475                  (match_operand:HI 2 "general_operand" "ri,rm")))
6476    (clobber (reg:CC FLAGS_REG))]
6477   "TARGET_PARTIAL_REG_STALL
6478    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6479 {
6480   switch (get_attr_type (insn))
6481     {
6482     case TYPE_INCDEC:
6483       if (operands[2] == const1_rtx)
6484         return "inc{w}\t%0";
6485       else
6486         {
6487           gcc_assert (operands[2] == constm1_rtx);
6488           return "dec{w}\t%0";
6489         }
6490
6491     default:
6492       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6493          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6494       if (CONST_INT_P (operands[2])
6495           && (INTVAL (operands[2]) == 128
6496               || (INTVAL (operands[2]) < 0
6497                   && INTVAL (operands[2]) != -128)))
6498         {
6499           operands[2] = GEN_INT (-INTVAL (operands[2]));
6500           return "sub{w}\t{%2, %0|%0, %2}";
6501         }
6502       return "add{w}\t{%2, %0|%0, %2}";
6503     }
6504 }
6505   [(set (attr "type")
6506      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6507         (const_string "incdec")
6508         (const_string "alu")))
6509    (set_attr "mode" "HI")])
6510
6511 (define_insn "*addhi_2"
6512   [(set (reg FLAGS_REG)
6513         (compare
6514           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6515                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6516           (const_int 0)))
6517    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6518         (plus:HI (match_dup 1) (match_dup 2)))]
6519   "ix86_match_ccmode (insn, CCGOCmode)
6520    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6521 {
6522   switch (get_attr_type (insn))
6523     {
6524     case TYPE_INCDEC:
6525       if (operands[2] == const1_rtx)
6526         return "inc{w}\t%0";
6527       else
6528         {
6529           gcc_assert (operands[2] == constm1_rtx);
6530           return "dec{w}\t%0";
6531         }
6532
6533     default:
6534       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6535          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6536       if (CONST_INT_P (operands[2])
6537           && (INTVAL (operands[2]) == 128
6538               || (INTVAL (operands[2]) < 0
6539                   && INTVAL (operands[2]) != -128)))
6540         {
6541           operands[2] = GEN_INT (-INTVAL (operands[2]));
6542           return "sub{w}\t{%2, %0|%0, %2}";
6543         }
6544       return "add{w}\t{%2, %0|%0, %2}";
6545     }
6546 }
6547   [(set (attr "type")
6548      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6549         (const_string "incdec")
6550         (const_string "alu")))
6551    (set_attr "mode" "HI")])
6552
6553 (define_insn "*addhi_3"
6554   [(set (reg FLAGS_REG)
6555         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6556                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6557    (clobber (match_scratch:HI 0 "=r"))]
6558   "ix86_match_ccmode (insn, CCZmode)
6559    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6560 {
6561   switch (get_attr_type (insn))
6562     {
6563     case TYPE_INCDEC:
6564       if (operands[2] == const1_rtx)
6565         return "inc{w}\t%0";
6566       else
6567         {
6568           gcc_assert (operands[2] == constm1_rtx);
6569           return "dec{w}\t%0";
6570         }
6571
6572     default:
6573       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6574          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6575       if (CONST_INT_P (operands[2])
6576           && (INTVAL (operands[2]) == 128
6577               || (INTVAL (operands[2]) < 0
6578                   && INTVAL (operands[2]) != -128)))
6579         {
6580           operands[2] = GEN_INT (-INTVAL (operands[2]));
6581           return "sub{w}\t{%2, %0|%0, %2}";
6582         }
6583       return "add{w}\t{%2, %0|%0, %2}";
6584     }
6585 }
6586   [(set (attr "type")
6587      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6588         (const_string "incdec")
6589         (const_string "alu")))
6590    (set_attr "mode" "HI")])
6591
6592 ; See comments above addsi_4 for details.
6593 (define_insn "*addhi_4"
6594   [(set (reg FLAGS_REG)
6595         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6596                  (match_operand:HI 2 "const_int_operand" "n")))
6597    (clobber (match_scratch:HI 0 "=rm"))]
6598   "ix86_match_ccmode (insn, CCGCmode)
6599    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6600 {
6601   switch (get_attr_type (insn))
6602     {
6603     case TYPE_INCDEC:
6604       if (operands[2] == constm1_rtx)
6605         return "inc{w}\t%0";
6606       else
6607         {
6608           gcc_assert (operands[2] == const1_rtx);
6609           return "dec{w}\t%0";
6610         }
6611
6612     default:
6613       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6614       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6615          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6616       if ((INTVAL (operands[2]) == -128
6617            || (INTVAL (operands[2]) > 0
6618                && INTVAL (operands[2]) != 128)))
6619         return "sub{w}\t{%2, %0|%0, %2}";
6620       operands[2] = GEN_INT (-INTVAL (operands[2]));
6621       return "add{w}\t{%2, %0|%0, %2}";
6622     }
6623 }
6624   [(set (attr "type")
6625      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6626         (const_string "incdec")
6627         (const_string "alu")))
6628    (set_attr "mode" "SI")])
6629
6630
6631 (define_insn "*addhi_5"
6632   [(set (reg FLAGS_REG)
6633         (compare
6634           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6635                    (match_operand:HI 2 "general_operand" "rmni"))
6636           (const_int 0)))
6637    (clobber (match_scratch:HI 0 "=r"))]
6638   "ix86_match_ccmode (insn, CCGOCmode)
6639    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6640 {
6641   switch (get_attr_type (insn))
6642     {
6643     case TYPE_INCDEC:
6644       if (operands[2] == const1_rtx)
6645         return "inc{w}\t%0";
6646       else
6647         {
6648           gcc_assert (operands[2] == constm1_rtx);
6649           return "dec{w}\t%0";
6650         }
6651
6652     default:
6653       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6654          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6655       if (CONST_INT_P (operands[2])
6656           && (INTVAL (operands[2]) == 128
6657               || (INTVAL (operands[2]) < 0
6658                   && INTVAL (operands[2]) != -128)))
6659         {
6660           operands[2] = GEN_INT (-INTVAL (operands[2]));
6661           return "sub{w}\t{%2, %0|%0, %2}";
6662         }
6663       return "add{w}\t{%2, %0|%0, %2}";
6664     }
6665 }
6666   [(set (attr "type")
6667      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6668         (const_string "incdec")
6669         (const_string "alu")))
6670    (set_attr "mode" "HI")])
6671
6672 (define_expand "addqi3"
6673   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6674                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6675                             (match_operand:QI 2 "general_operand" "")))
6676               (clobber (reg:CC FLAGS_REG))])]
6677   "TARGET_QIMODE_MATH"
6678   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6679
6680 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6681 (define_insn "*addqi_1_lea"
6682   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6683         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6684                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6685    (clobber (reg:CC FLAGS_REG))]
6686   "!TARGET_PARTIAL_REG_STALL
6687    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6688 {
6689   int widen = (which_alternative == 2);
6690   switch (get_attr_type (insn))
6691     {
6692     case TYPE_LEA:
6693       return "#";
6694     case TYPE_INCDEC:
6695       if (operands[2] == const1_rtx)
6696         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6697       else
6698         {
6699           gcc_assert (operands[2] == constm1_rtx);
6700           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6701         }
6702
6703     default:
6704       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6705          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6706       if (CONST_INT_P (operands[2])
6707           && (INTVAL (operands[2]) == 128
6708               || (INTVAL (operands[2]) < 0
6709                   && INTVAL (operands[2]) != -128)))
6710         {
6711           operands[2] = GEN_INT (-INTVAL (operands[2]));
6712           if (widen)
6713             return "sub{l}\t{%2, %k0|%k0, %2}";
6714           else
6715             return "sub{b}\t{%2, %0|%0, %2}";
6716         }
6717       if (widen)
6718         return "add{l}\t{%k2, %k0|%k0, %k2}";
6719       else
6720         return "add{b}\t{%2, %0|%0, %2}";
6721     }
6722 }
6723   [(set (attr "type")
6724      (if_then_else (eq_attr "alternative" "3")
6725         (const_string "lea")
6726         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6727            (const_string "incdec")
6728            (const_string "alu"))))
6729    (set_attr "mode" "QI,QI,SI,SI")])
6730
6731 (define_insn "*addqi_1"
6732   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6733         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6734                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6735    (clobber (reg:CC FLAGS_REG))]
6736   "TARGET_PARTIAL_REG_STALL
6737    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6738 {
6739   int widen = (which_alternative == 2);
6740   switch (get_attr_type (insn))
6741     {
6742     case TYPE_INCDEC:
6743       if (operands[2] == const1_rtx)
6744         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6745       else
6746         {
6747           gcc_assert (operands[2] == constm1_rtx);
6748           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6749         }
6750
6751     default:
6752       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6753          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6754       if (CONST_INT_P (operands[2])
6755           && (INTVAL (operands[2]) == 128
6756               || (INTVAL (operands[2]) < 0
6757                   && INTVAL (operands[2]) != -128)))
6758         {
6759           operands[2] = GEN_INT (-INTVAL (operands[2]));
6760           if (widen)
6761             return "sub{l}\t{%2, %k0|%k0, %2}";
6762           else
6763             return "sub{b}\t{%2, %0|%0, %2}";
6764         }
6765       if (widen)
6766         return "add{l}\t{%k2, %k0|%k0, %k2}";
6767       else
6768         return "add{b}\t{%2, %0|%0, %2}";
6769     }
6770 }
6771   [(set (attr "type")
6772      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6773         (const_string "incdec")
6774         (const_string "alu")))
6775    (set_attr "mode" "QI,QI,SI")])
6776
6777 (define_insn "*addqi_1_slp"
6778   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6779         (plus:QI (match_dup 0)
6780                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6781    (clobber (reg:CC FLAGS_REG))]
6782   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6783    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6784 {
6785   switch (get_attr_type (insn))
6786     {
6787     case TYPE_INCDEC:
6788       if (operands[1] == const1_rtx)
6789         return "inc{b}\t%0";
6790       else
6791         {
6792           gcc_assert (operands[1] == constm1_rtx);
6793           return "dec{b}\t%0";
6794         }
6795
6796     default:
6797       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6798       if (CONST_INT_P (operands[1])
6799           && INTVAL (operands[1]) < 0)
6800         {
6801           operands[1] = GEN_INT (-INTVAL (operands[1]));
6802           return "sub{b}\t{%1, %0|%0, %1}";
6803         }
6804       return "add{b}\t{%1, %0|%0, %1}";
6805     }
6806 }
6807   [(set (attr "type")
6808      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6809         (const_string "incdec")
6810         (const_string "alu1")))
6811    (set (attr "memory")
6812      (if_then_else (match_operand 1 "memory_operand" "")
6813         (const_string "load")
6814         (const_string "none")))
6815    (set_attr "mode" "QI")])
6816
6817 (define_insn "*addqi_2"
6818   [(set (reg FLAGS_REG)
6819         (compare
6820           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6821                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6822           (const_int 0)))
6823    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6824         (plus:QI (match_dup 1) (match_dup 2)))]
6825   "ix86_match_ccmode (insn, CCGOCmode)
6826    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6827 {
6828   switch (get_attr_type (insn))
6829     {
6830     case TYPE_INCDEC:
6831       if (operands[2] == const1_rtx)
6832         return "inc{b}\t%0";
6833       else
6834         {
6835           gcc_assert (operands[2] == constm1_rtx
6836                       || (CONST_INT_P (operands[2])
6837                           && INTVAL (operands[2]) == 255));
6838           return "dec{b}\t%0";
6839         }
6840
6841     default:
6842       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6843       if (CONST_INT_P (operands[2])
6844           && INTVAL (operands[2]) < 0)
6845         {
6846           operands[2] = GEN_INT (-INTVAL (operands[2]));
6847           return "sub{b}\t{%2, %0|%0, %2}";
6848         }
6849       return "add{b}\t{%2, %0|%0, %2}";
6850     }
6851 }
6852   [(set (attr "type")
6853      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6854         (const_string "incdec")
6855         (const_string "alu")))
6856    (set_attr "mode" "QI")])
6857
6858 (define_insn "*addqi_3"
6859   [(set (reg FLAGS_REG)
6860         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6861                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6862    (clobber (match_scratch:QI 0 "=q"))]
6863   "ix86_match_ccmode (insn, CCZmode)
6864    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6865 {
6866   switch (get_attr_type (insn))
6867     {
6868     case TYPE_INCDEC:
6869       if (operands[2] == const1_rtx)
6870         return "inc{b}\t%0";
6871       else
6872         {
6873           gcc_assert (operands[2] == constm1_rtx
6874                       || (CONST_INT_P (operands[2])
6875                           && INTVAL (operands[2]) == 255));
6876           return "dec{b}\t%0";
6877         }
6878
6879     default:
6880       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6881       if (CONST_INT_P (operands[2])
6882           && INTVAL (operands[2]) < 0)
6883         {
6884           operands[2] = GEN_INT (-INTVAL (operands[2]));
6885           return "sub{b}\t{%2, %0|%0, %2}";
6886         }
6887       return "add{b}\t{%2, %0|%0, %2}";
6888     }
6889 }
6890   [(set (attr "type")
6891      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6892         (const_string "incdec")
6893         (const_string "alu")))
6894    (set_attr "mode" "QI")])
6895
6896 ; See comments above addsi_4 for details.
6897 (define_insn "*addqi_4"
6898   [(set (reg FLAGS_REG)
6899         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6900                  (match_operand:QI 2 "const_int_operand" "n")))
6901    (clobber (match_scratch:QI 0 "=qm"))]
6902   "ix86_match_ccmode (insn, CCGCmode)
6903    && (INTVAL (operands[2]) & 0xff) != 0x80"
6904 {
6905   switch (get_attr_type (insn))
6906     {
6907     case TYPE_INCDEC:
6908       if (operands[2] == constm1_rtx
6909           || (CONST_INT_P (operands[2])
6910               && INTVAL (operands[2]) == 255))
6911         return "inc{b}\t%0";
6912       else
6913         {
6914           gcc_assert (operands[2] == const1_rtx);
6915           return "dec{b}\t%0";
6916         }
6917
6918     default:
6919       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6920       if (INTVAL (operands[2]) < 0)
6921         {
6922           operands[2] = GEN_INT (-INTVAL (operands[2]));
6923           return "add{b}\t{%2, %0|%0, %2}";
6924         }
6925       return "sub{b}\t{%2, %0|%0, %2}";
6926     }
6927 }
6928   [(set (attr "type")
6929      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6930         (const_string "incdec")
6931         (const_string "alu")))
6932    (set_attr "mode" "QI")])
6933
6934
6935 (define_insn "*addqi_5"
6936   [(set (reg FLAGS_REG)
6937         (compare
6938           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6939                    (match_operand:QI 2 "general_operand" "qmni"))
6940           (const_int 0)))
6941    (clobber (match_scratch:QI 0 "=q"))]
6942   "ix86_match_ccmode (insn, CCGOCmode)
6943    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6944 {
6945   switch (get_attr_type (insn))
6946     {
6947     case TYPE_INCDEC:
6948       if (operands[2] == const1_rtx)
6949         return "inc{b}\t%0";
6950       else
6951         {
6952           gcc_assert (operands[2] == constm1_rtx
6953                       || (CONST_INT_P (operands[2])
6954                           && INTVAL (operands[2]) == 255));
6955           return "dec{b}\t%0";
6956         }
6957
6958     default:
6959       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6960       if (CONST_INT_P (operands[2])
6961           && INTVAL (operands[2]) < 0)
6962         {
6963           operands[2] = GEN_INT (-INTVAL (operands[2]));
6964           return "sub{b}\t{%2, %0|%0, %2}";
6965         }
6966       return "add{b}\t{%2, %0|%0, %2}";
6967     }
6968 }
6969   [(set (attr "type")
6970      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6971         (const_string "incdec")
6972         (const_string "alu")))
6973    (set_attr "mode" "QI")])
6974
6975
6976 (define_insn "addqi_ext_1"
6977   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6978                          (const_int 8)
6979                          (const_int 8))
6980         (plus:SI
6981           (zero_extract:SI
6982             (match_operand 1 "ext_register_operand" "0")
6983             (const_int 8)
6984             (const_int 8))
6985           (match_operand:QI 2 "general_operand" "Qmn")))
6986    (clobber (reg:CC FLAGS_REG))]
6987   "!TARGET_64BIT"
6988 {
6989   switch (get_attr_type (insn))
6990     {
6991     case TYPE_INCDEC:
6992       if (operands[2] == const1_rtx)
6993         return "inc{b}\t%h0";
6994       else
6995         {
6996           gcc_assert (operands[2] == constm1_rtx
6997                       || (CONST_INT_P (operands[2])
6998                           && INTVAL (operands[2]) == 255));
6999           return "dec{b}\t%h0";
7000         }
7001
7002     default:
7003       return "add{b}\t{%2, %h0|%h0, %2}";
7004     }
7005 }
7006   [(set (attr "type")
7007      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7008         (const_string "incdec")
7009         (const_string "alu")))
7010    (set_attr "mode" "QI")])
7011
7012 (define_insn "*addqi_ext_1_rex64"
7013   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7014                          (const_int 8)
7015                          (const_int 8))
7016         (plus:SI
7017           (zero_extract:SI
7018             (match_operand 1 "ext_register_operand" "0")
7019             (const_int 8)
7020             (const_int 8))
7021           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7022    (clobber (reg:CC FLAGS_REG))]
7023   "TARGET_64BIT"
7024 {
7025   switch (get_attr_type (insn))
7026     {
7027     case TYPE_INCDEC:
7028       if (operands[2] == const1_rtx)
7029         return "inc{b}\t%h0";
7030       else
7031         {
7032           gcc_assert (operands[2] == constm1_rtx
7033                       || (CONST_INT_P (operands[2])
7034                           && INTVAL (operands[2]) == 255));
7035           return "dec{b}\t%h0";
7036         }
7037
7038     default:
7039       return "add{b}\t{%2, %h0|%h0, %2}";
7040     }
7041 }
7042   [(set (attr "type")
7043      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7044         (const_string "incdec")
7045         (const_string "alu")))
7046    (set_attr "mode" "QI")])
7047
7048 (define_insn "*addqi_ext_2"
7049   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7050                          (const_int 8)
7051                          (const_int 8))
7052         (plus:SI
7053           (zero_extract:SI
7054             (match_operand 1 "ext_register_operand" "%0")
7055             (const_int 8)
7056             (const_int 8))
7057           (zero_extract:SI
7058             (match_operand 2 "ext_register_operand" "Q")
7059             (const_int 8)
7060             (const_int 8))))
7061    (clobber (reg:CC FLAGS_REG))]
7062   ""
7063   "add{b}\t{%h2, %h0|%h0, %h2}"
7064   [(set_attr "type" "alu")
7065    (set_attr "mode" "QI")])
7066
7067 ;; The patterns that match these are at the end of this file.
7068
7069 (define_expand "addxf3"
7070   [(set (match_operand:XF 0 "register_operand" "")
7071         (plus:XF (match_operand:XF 1 "register_operand" "")
7072                  (match_operand:XF 2 "register_operand" "")))]
7073   "TARGET_80387"
7074   "")
7075
7076 (define_expand "add<mode>3"
7077   [(set (match_operand:MODEF 0 "register_operand" "")
7078         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7079                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7080   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7081   "")
7082 \f
7083 ;; Subtract instructions
7084
7085 ;; %%% splits for subditi3
7086
7087 (define_expand "subti3"
7088   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7089                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7090                              (match_operand:TI 2 "x86_64_general_operand" "")))
7091               (clobber (reg:CC FLAGS_REG))])]
7092   "TARGET_64BIT"
7093   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7094
7095 (define_insn "*subti3_1"
7096   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7097         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7098                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7099    (clobber (reg:CC FLAGS_REG))]
7100   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7101   "#")
7102
7103 (define_split
7104   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7105         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7106                   (match_operand:TI 2 "x86_64_general_operand" "")))
7107    (clobber (reg:CC FLAGS_REG))]
7108   "TARGET_64BIT && reload_completed"
7109   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7110               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7111    (parallel [(set (match_dup 3)
7112                    (minus:DI (match_dup 4)
7113                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7114                                       (match_dup 5))))
7115               (clobber (reg:CC FLAGS_REG))])]
7116   "split_ti (operands+0, 1, operands+0, operands+3);
7117    split_ti (operands+1, 1, operands+1, operands+4);
7118    split_ti (operands+2, 1, operands+2, operands+5);")
7119
7120 ;; %%% splits for subsidi3
7121
7122 (define_expand "subdi3"
7123   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7124                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7125                              (match_operand:DI 2 "x86_64_general_operand" "")))
7126               (clobber (reg:CC FLAGS_REG))])]
7127   ""
7128   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7129
7130 (define_insn "*subdi3_1"
7131   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7132         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7133                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7134    (clobber (reg:CC FLAGS_REG))]
7135   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7136   "#")
7137
7138 (define_split
7139   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7140         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7141                   (match_operand:DI 2 "general_operand" "")))
7142    (clobber (reg:CC FLAGS_REG))]
7143   "!TARGET_64BIT && reload_completed"
7144   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7145               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7146    (parallel [(set (match_dup 3)
7147                    (minus:SI (match_dup 4)
7148                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7149                                       (match_dup 5))))
7150               (clobber (reg:CC FLAGS_REG))])]
7151   "split_di (operands+0, 1, operands+0, operands+3);
7152    split_di (operands+1, 1, operands+1, operands+4);
7153    split_di (operands+2, 1, operands+2, operands+5);")
7154
7155 (define_insn "subdi3_carry_rex64"
7156   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7157           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7158             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7159                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7160    (clobber (reg:CC FLAGS_REG))]
7161   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7162   "sbb{q}\t{%2, %0|%0, %2}"
7163   [(set_attr "type" "alu")
7164    (set_attr "pent_pair" "pu")
7165    (set_attr "mode" "DI")])
7166
7167 (define_insn "*subdi_1_rex64"
7168   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7169         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7170                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7171    (clobber (reg:CC FLAGS_REG))]
7172   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7173   "sub{q}\t{%2, %0|%0, %2}"
7174   [(set_attr "type" "alu")
7175    (set_attr "mode" "DI")])
7176
7177 (define_insn "*subdi_2_rex64"
7178   [(set (reg FLAGS_REG)
7179         (compare
7180           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7181                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7182           (const_int 0)))
7183    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7184         (minus:DI (match_dup 1) (match_dup 2)))]
7185   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7186    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7187   "sub{q}\t{%2, %0|%0, %2}"
7188   [(set_attr "type" "alu")
7189    (set_attr "mode" "DI")])
7190
7191 (define_insn "*subdi_3_rex63"
7192   [(set (reg FLAGS_REG)
7193         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7194                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7195    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7196         (minus:DI (match_dup 1) (match_dup 2)))]
7197   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7198    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7199   "sub{q}\t{%2, %0|%0, %2}"
7200   [(set_attr "type" "alu")
7201    (set_attr "mode" "DI")])
7202
7203 (define_insn "subqi3_carry"
7204   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7205           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7206             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7207                (match_operand:QI 2 "general_operand" "qi,qm"))))
7208    (clobber (reg:CC FLAGS_REG))]
7209   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7210   "sbb{b}\t{%2, %0|%0, %2}"
7211   [(set_attr "type" "alu")
7212    (set_attr "pent_pair" "pu")
7213    (set_attr "mode" "QI")])
7214
7215 (define_insn "subhi3_carry"
7216   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7217           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7218             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7219                (match_operand:HI 2 "general_operand" "ri,rm"))))
7220    (clobber (reg:CC FLAGS_REG))]
7221   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7222   "sbb{w}\t{%2, %0|%0, %2}"
7223   [(set_attr "type" "alu")
7224    (set_attr "pent_pair" "pu")
7225    (set_attr "mode" "HI")])
7226
7227 (define_insn "subsi3_carry"
7228   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7229           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7230             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7231                (match_operand:SI 2 "general_operand" "ri,rm"))))
7232    (clobber (reg:CC FLAGS_REG))]
7233   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7234   "sbb{l}\t{%2, %0|%0, %2}"
7235   [(set_attr "type" "alu")
7236    (set_attr "pent_pair" "pu")
7237    (set_attr "mode" "SI")])
7238
7239 (define_insn "subsi3_carry_zext"
7240   [(set (match_operand:DI 0 "register_operand" "=r")
7241           (zero_extend:DI
7242             (minus:SI (match_operand:SI 1 "register_operand" "0")
7243               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7244                  (match_operand:SI 2 "general_operand" "g")))))
7245    (clobber (reg:CC FLAGS_REG))]
7246   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7247   "sbb{l}\t{%2, %k0|%k0, %2}"
7248   [(set_attr "type" "alu")
7249    (set_attr "pent_pair" "pu")
7250    (set_attr "mode" "SI")])
7251
7252 (define_expand "subsi3"
7253   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7254                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7255                              (match_operand:SI 2 "general_operand" "")))
7256               (clobber (reg:CC FLAGS_REG))])]
7257   ""
7258   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7259
7260 (define_insn "*subsi_1"
7261   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7262         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7263                   (match_operand:SI 2 "general_operand" "ri,rm")))
7264    (clobber (reg:CC FLAGS_REG))]
7265   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7266   "sub{l}\t{%2, %0|%0, %2}"
7267   [(set_attr "type" "alu")
7268    (set_attr "mode" "SI")])
7269
7270 (define_insn "*subsi_1_zext"
7271   [(set (match_operand:DI 0 "register_operand" "=r")
7272         (zero_extend:DI
7273           (minus:SI (match_operand:SI 1 "register_operand" "0")
7274                     (match_operand:SI 2 "general_operand" "g"))))
7275    (clobber (reg:CC FLAGS_REG))]
7276   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7277   "sub{l}\t{%2, %k0|%k0, %2}"
7278   [(set_attr "type" "alu")
7279    (set_attr "mode" "SI")])
7280
7281 (define_insn "*subsi_2"
7282   [(set (reg FLAGS_REG)
7283         (compare
7284           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7285                     (match_operand:SI 2 "general_operand" "ri,rm"))
7286           (const_int 0)))
7287    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7288         (minus:SI (match_dup 1) (match_dup 2)))]
7289   "ix86_match_ccmode (insn, CCGOCmode)
7290    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7291   "sub{l}\t{%2, %0|%0, %2}"
7292   [(set_attr "type" "alu")
7293    (set_attr "mode" "SI")])
7294
7295 (define_insn "*subsi_2_zext"
7296   [(set (reg FLAGS_REG)
7297         (compare
7298           (minus:SI (match_operand:SI 1 "register_operand" "0")
7299                     (match_operand:SI 2 "general_operand" "g"))
7300           (const_int 0)))
7301    (set (match_operand:DI 0 "register_operand" "=r")
7302         (zero_extend:DI
7303           (minus:SI (match_dup 1)
7304                     (match_dup 2))))]
7305   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7306    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7307   "sub{l}\t{%2, %k0|%k0, %2}"
7308   [(set_attr "type" "alu")
7309    (set_attr "mode" "SI")])
7310
7311 (define_insn "*subsi_3"
7312   [(set (reg FLAGS_REG)
7313         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7314                  (match_operand:SI 2 "general_operand" "ri,rm")))
7315    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7316         (minus:SI (match_dup 1) (match_dup 2)))]
7317   "ix86_match_ccmode (insn, CCmode)
7318    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7319   "sub{l}\t{%2, %0|%0, %2}"
7320   [(set_attr "type" "alu")
7321    (set_attr "mode" "SI")])
7322
7323 (define_insn "*subsi_3_zext"
7324   [(set (reg FLAGS_REG)
7325         (compare (match_operand:SI 1 "register_operand" "0")
7326                  (match_operand:SI 2 "general_operand" "g")))
7327    (set (match_operand:DI 0 "register_operand" "=r")
7328         (zero_extend:DI
7329           (minus:SI (match_dup 1)
7330                     (match_dup 2))))]
7331   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7332    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7333   "sub{l}\t{%2, %1|%1, %2}"
7334   [(set_attr "type" "alu")
7335    (set_attr "mode" "DI")])
7336
7337 (define_expand "subhi3"
7338   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7339                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7340                              (match_operand:HI 2 "general_operand" "")))
7341               (clobber (reg:CC FLAGS_REG))])]
7342   "TARGET_HIMODE_MATH"
7343   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7344
7345 (define_insn "*subhi_1"
7346   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7347         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7348                   (match_operand:HI 2 "general_operand" "ri,rm")))
7349    (clobber (reg:CC FLAGS_REG))]
7350   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7351   "sub{w}\t{%2, %0|%0, %2}"
7352   [(set_attr "type" "alu")
7353    (set_attr "mode" "HI")])
7354
7355 (define_insn "*subhi_2"
7356   [(set (reg FLAGS_REG)
7357         (compare
7358           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7359                     (match_operand:HI 2 "general_operand" "ri,rm"))
7360           (const_int 0)))
7361    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7362         (minus:HI (match_dup 1) (match_dup 2)))]
7363   "ix86_match_ccmode (insn, CCGOCmode)
7364    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7365   "sub{w}\t{%2, %0|%0, %2}"
7366   [(set_attr "type" "alu")
7367    (set_attr "mode" "HI")])
7368
7369 (define_insn "*subhi_3"
7370   [(set (reg FLAGS_REG)
7371         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7372                  (match_operand:HI 2 "general_operand" "ri,rm")))
7373    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7374         (minus:HI (match_dup 1) (match_dup 2)))]
7375   "ix86_match_ccmode (insn, CCmode)
7376    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7377   "sub{w}\t{%2, %0|%0, %2}"
7378   [(set_attr "type" "alu")
7379    (set_attr "mode" "HI")])
7380
7381 (define_expand "subqi3"
7382   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7383                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7384                              (match_operand:QI 2 "general_operand" "")))
7385               (clobber (reg:CC FLAGS_REG))])]
7386   "TARGET_QIMODE_MATH"
7387   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7388
7389 (define_insn "*subqi_1"
7390   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7391         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7392                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7393    (clobber (reg:CC FLAGS_REG))]
7394   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7395   "sub{b}\t{%2, %0|%0, %2}"
7396   [(set_attr "type" "alu")
7397    (set_attr "mode" "QI")])
7398
7399 (define_insn "*subqi_1_slp"
7400   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7401         (minus:QI (match_dup 0)
7402                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7403    (clobber (reg:CC FLAGS_REG))]
7404   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7405    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7406   "sub{b}\t{%1, %0|%0, %1}"
7407   [(set_attr "type" "alu1")
7408    (set_attr "mode" "QI")])
7409
7410 (define_insn "*subqi_2"
7411   [(set (reg FLAGS_REG)
7412         (compare
7413           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7414                     (match_operand:QI 2 "general_operand" "qi,qm"))
7415           (const_int 0)))
7416    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7417         (minus:HI (match_dup 1) (match_dup 2)))]
7418   "ix86_match_ccmode (insn, CCGOCmode)
7419    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7420   "sub{b}\t{%2, %0|%0, %2}"
7421   [(set_attr "type" "alu")
7422    (set_attr "mode" "QI")])
7423
7424 (define_insn "*subqi_3"
7425   [(set (reg FLAGS_REG)
7426         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7427                  (match_operand:QI 2 "general_operand" "qi,qm")))
7428    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7429         (minus:HI (match_dup 1) (match_dup 2)))]
7430   "ix86_match_ccmode (insn, CCmode)
7431    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7432   "sub{b}\t{%2, %0|%0, %2}"
7433   [(set_attr "type" "alu")
7434    (set_attr "mode" "QI")])
7435
7436 ;; The patterns that match these are at the end of this file.
7437
7438 (define_expand "subxf3"
7439   [(set (match_operand:XF 0 "register_operand" "")
7440         (minus:XF (match_operand:XF 1 "register_operand" "")
7441                   (match_operand:XF 2 "register_operand" "")))]
7442   "TARGET_80387"
7443   "")
7444
7445 (define_expand "sub<mode>3"
7446   [(set (match_operand:MODEF 0 "register_operand" "")
7447         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7448                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7449   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7450   "")
7451 \f
7452 ;; Multiply instructions
7453
7454 (define_expand "muldi3"
7455   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7456                    (mult:DI (match_operand:DI 1 "register_operand" "")
7457                             (match_operand:DI 2 "x86_64_general_operand" "")))
7458               (clobber (reg:CC FLAGS_REG))])]
7459   "TARGET_64BIT"
7460   "")
7461
7462 ;; On AMDFAM10 
7463 ;; IMUL reg64, reg64, imm8      Direct
7464 ;; IMUL reg64, mem64, imm8      VectorPath
7465 ;; IMUL reg64, reg64, imm32     Direct
7466 ;; IMUL reg64, mem64, imm32     VectorPath 
7467 ;; IMUL reg64, reg64            Direct
7468 ;; IMUL reg64, mem64            Direct
7469
7470 (define_insn "*muldi3_1_rex64"
7471   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7472         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7473                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7474    (clobber (reg:CC FLAGS_REG))]
7475   "TARGET_64BIT
7476    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7477   "@
7478    imul{q}\t{%2, %1, %0|%0, %1, %2}
7479    imul{q}\t{%2, %1, %0|%0, %1, %2}
7480    imul{q}\t{%2, %0|%0, %2}"
7481   [(set_attr "type" "imul")
7482    (set_attr "prefix_0f" "0,0,1")
7483    (set (attr "athlon_decode")
7484         (cond [(eq_attr "cpu" "athlon")
7485                   (const_string "vector")
7486                (eq_attr "alternative" "1")
7487                   (const_string "vector")
7488                (and (eq_attr "alternative" "2")
7489                     (match_operand 1 "memory_operand" ""))
7490                   (const_string "vector")]
7491               (const_string "direct")))
7492    (set (attr "amdfam10_decode")
7493         (cond [(and (eq_attr "alternative" "0,1")
7494                     (match_operand 1 "memory_operand" ""))
7495                   (const_string "vector")]
7496               (const_string "direct")))       
7497    (set_attr "mode" "DI")])
7498
7499 (define_expand "mulsi3"
7500   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7501                    (mult:SI (match_operand:SI 1 "register_operand" "")
7502                             (match_operand:SI 2 "general_operand" "")))
7503               (clobber (reg:CC FLAGS_REG))])]
7504   ""
7505   "")
7506
7507 ;; On AMDFAM10 
7508 ;; IMUL reg32, reg32, imm8      Direct
7509 ;; IMUL reg32, mem32, imm8      VectorPath
7510 ;; IMUL reg32, reg32, imm32     Direct
7511 ;; IMUL reg32, mem32, imm32     VectorPath
7512 ;; IMUL reg32, reg32            Direct
7513 ;; IMUL reg32, mem32            Direct
7514
7515 (define_insn "*mulsi3_1"
7516   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7517         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7518                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7519    (clobber (reg:CC FLAGS_REG))]
7520   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7521   "@
7522    imul{l}\t{%2, %1, %0|%0, %1, %2}
7523    imul{l}\t{%2, %1, %0|%0, %1, %2}
7524    imul{l}\t{%2, %0|%0, %2}"
7525   [(set_attr "type" "imul")
7526    (set_attr "prefix_0f" "0,0,1")
7527    (set (attr "athlon_decode")
7528         (cond [(eq_attr "cpu" "athlon")
7529                   (const_string "vector")
7530                (eq_attr "alternative" "1")
7531                   (const_string "vector")
7532                (and (eq_attr "alternative" "2")
7533                     (match_operand 1 "memory_operand" ""))
7534                   (const_string "vector")]
7535               (const_string "direct")))
7536    (set (attr "amdfam10_decode")
7537         (cond [(and (eq_attr "alternative" "0,1")
7538                     (match_operand 1 "memory_operand" ""))
7539                   (const_string "vector")]
7540               (const_string "direct")))       
7541    (set_attr "mode" "SI")])
7542
7543 (define_insn "*mulsi3_1_zext"
7544   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7545         (zero_extend:DI
7546           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7547                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7548    (clobber (reg:CC FLAGS_REG))]
7549   "TARGET_64BIT
7550    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7551   "@
7552    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7553    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7554    imul{l}\t{%2, %k0|%k0, %2}"
7555   [(set_attr "type" "imul")
7556    (set_attr "prefix_0f" "0,0,1")
7557    (set (attr "athlon_decode")
7558         (cond [(eq_attr "cpu" "athlon")
7559                   (const_string "vector")
7560                (eq_attr "alternative" "1")
7561                   (const_string "vector")
7562                (and (eq_attr "alternative" "2")
7563                     (match_operand 1 "memory_operand" ""))
7564                   (const_string "vector")]
7565               (const_string "direct")))
7566    (set (attr "amdfam10_decode")
7567         (cond [(and (eq_attr "alternative" "0,1")
7568                     (match_operand 1 "memory_operand" ""))
7569                   (const_string "vector")]
7570               (const_string "direct")))       
7571    (set_attr "mode" "SI")])
7572
7573 (define_expand "mulhi3"
7574   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7575                    (mult:HI (match_operand:HI 1 "register_operand" "")
7576                             (match_operand:HI 2 "general_operand" "")))
7577               (clobber (reg:CC FLAGS_REG))])]
7578   "TARGET_HIMODE_MATH"
7579   "")
7580
7581 ;; On AMDFAM10
7582 ;; IMUL reg16, reg16, imm8      VectorPath
7583 ;; IMUL reg16, mem16, imm8      VectorPath
7584 ;; IMUL reg16, reg16, imm16     VectorPath
7585 ;; IMUL reg16, mem16, imm16     VectorPath
7586 ;; IMUL reg16, reg16            Direct
7587 ;; IMUL reg16, mem16            Direct
7588 (define_insn "*mulhi3_1"
7589   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7590         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7591                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7592    (clobber (reg:CC FLAGS_REG))]
7593   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7594   "@
7595    imul{w}\t{%2, %1, %0|%0, %1, %2}
7596    imul{w}\t{%2, %1, %0|%0, %1, %2}
7597    imul{w}\t{%2, %0|%0, %2}"
7598   [(set_attr "type" "imul")
7599    (set_attr "prefix_0f" "0,0,1")
7600    (set (attr "athlon_decode")
7601         (cond [(eq_attr "cpu" "athlon")
7602                   (const_string "vector")
7603                (eq_attr "alternative" "1,2")
7604                   (const_string "vector")]
7605               (const_string "direct")))
7606    (set (attr "amdfam10_decode")
7607         (cond [(eq_attr "alternative" "0,1")
7608                   (const_string "vector")]
7609               (const_string "direct")))
7610    (set_attr "mode" "HI")])
7611
7612 (define_expand "mulqi3"
7613   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7614                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7615                             (match_operand:QI 2 "register_operand" "")))
7616               (clobber (reg:CC FLAGS_REG))])]
7617   "TARGET_QIMODE_MATH"
7618   "")
7619
7620 ;;On AMDFAM10
7621 ;; MUL reg8     Direct
7622 ;; MUL mem8     Direct
7623
7624 (define_insn "*mulqi3_1"
7625   [(set (match_operand:QI 0 "register_operand" "=a")
7626         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7627                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7628    (clobber (reg:CC FLAGS_REG))]
7629   "TARGET_QIMODE_MATH
7630    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7631   "mul{b}\t%2"
7632   [(set_attr "type" "imul")
7633    (set_attr "length_immediate" "0")
7634    (set (attr "athlon_decode")
7635      (if_then_else (eq_attr "cpu" "athlon")
7636         (const_string "vector")
7637         (const_string "direct")))
7638    (set_attr "amdfam10_decode" "direct")        
7639    (set_attr "mode" "QI")])
7640
7641 (define_expand "umulqihi3"
7642   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7643                    (mult:HI (zero_extend:HI
7644                               (match_operand:QI 1 "nonimmediate_operand" ""))
7645                             (zero_extend:HI
7646                               (match_operand:QI 2 "register_operand" ""))))
7647               (clobber (reg:CC FLAGS_REG))])]
7648   "TARGET_QIMODE_MATH"
7649   "")
7650
7651 (define_insn "*umulqihi3_1"
7652   [(set (match_operand:HI 0 "register_operand" "=a")
7653         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7654                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7655    (clobber (reg:CC FLAGS_REG))]
7656   "TARGET_QIMODE_MATH
7657    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7658   "mul{b}\t%2"
7659   [(set_attr "type" "imul")
7660    (set_attr "length_immediate" "0")
7661    (set (attr "athlon_decode")
7662      (if_then_else (eq_attr "cpu" "athlon")
7663         (const_string "vector")
7664         (const_string "direct")))
7665    (set_attr "amdfam10_decode" "direct")        
7666    (set_attr "mode" "QI")])
7667
7668 (define_expand "mulqihi3"
7669   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7670                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7671                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7672               (clobber (reg:CC FLAGS_REG))])]
7673   "TARGET_QIMODE_MATH"
7674   "")
7675
7676 (define_insn "*mulqihi3_insn"
7677   [(set (match_operand:HI 0 "register_operand" "=a")
7678         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7679                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7680    (clobber (reg:CC FLAGS_REG))]
7681   "TARGET_QIMODE_MATH
7682    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7683   "imul{b}\t%2"
7684   [(set_attr "type" "imul")
7685    (set_attr "length_immediate" "0")
7686    (set (attr "athlon_decode")
7687      (if_then_else (eq_attr "cpu" "athlon")
7688         (const_string "vector")
7689         (const_string "direct")))
7690    (set_attr "amdfam10_decode" "direct")        
7691    (set_attr "mode" "QI")])
7692
7693 (define_expand "umulditi3"
7694   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7695                    (mult:TI (zero_extend:TI
7696                               (match_operand:DI 1 "nonimmediate_operand" ""))
7697                             (zero_extend:TI
7698                               (match_operand:DI 2 "register_operand" ""))))
7699               (clobber (reg:CC FLAGS_REG))])]
7700   "TARGET_64BIT"
7701   "")
7702
7703 (define_insn "*umulditi3_insn"
7704   [(set (match_operand:TI 0 "register_operand" "=A")
7705         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7706                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7707    (clobber (reg:CC FLAGS_REG))]
7708   "TARGET_64BIT
7709    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7710   "mul{q}\t%2"
7711   [(set_attr "type" "imul")
7712    (set_attr "length_immediate" "0")
7713    (set (attr "athlon_decode")
7714      (if_then_else (eq_attr "cpu" "athlon")
7715         (const_string "vector")
7716         (const_string "double")))
7717    (set_attr "amdfam10_decode" "double")        
7718    (set_attr "mode" "DI")])
7719
7720 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7721 (define_expand "umulsidi3"
7722   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7723                    (mult:DI (zero_extend:DI
7724                               (match_operand:SI 1 "nonimmediate_operand" ""))
7725                             (zero_extend:DI
7726                               (match_operand:SI 2 "register_operand" ""))))
7727               (clobber (reg:CC FLAGS_REG))])]
7728   "!TARGET_64BIT"
7729   "")
7730
7731 (define_insn "*umulsidi3_insn"
7732   [(set (match_operand:DI 0 "register_operand" "=A")
7733         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7734                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7735    (clobber (reg:CC FLAGS_REG))]
7736   "!TARGET_64BIT
7737    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7738   "mul{l}\t%2"
7739   [(set_attr "type" "imul")
7740    (set_attr "length_immediate" "0")
7741    (set (attr "athlon_decode")
7742      (if_then_else (eq_attr "cpu" "athlon")
7743         (const_string "vector")
7744         (const_string "double")))
7745    (set_attr "amdfam10_decode" "double")        
7746    (set_attr "mode" "SI")])
7747
7748 (define_expand "mulditi3"
7749   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7750                    (mult:TI (sign_extend:TI
7751                               (match_operand:DI 1 "nonimmediate_operand" ""))
7752                             (sign_extend:TI
7753                               (match_operand:DI 2 "register_operand" ""))))
7754               (clobber (reg:CC FLAGS_REG))])]
7755   "TARGET_64BIT"
7756   "")
7757
7758 (define_insn "*mulditi3_insn"
7759   [(set (match_operand:TI 0 "register_operand" "=A")
7760         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7761                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7762    (clobber (reg:CC FLAGS_REG))]
7763   "TARGET_64BIT
7764    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7765   "imul{q}\t%2"
7766   [(set_attr "type" "imul")
7767    (set_attr "length_immediate" "0")
7768    (set (attr "athlon_decode")
7769      (if_then_else (eq_attr "cpu" "athlon")
7770         (const_string "vector")
7771         (const_string "double")))
7772    (set_attr "amdfam10_decode" "double")
7773    (set_attr "mode" "DI")])
7774
7775 (define_expand "mulsidi3"
7776   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7777                    (mult:DI (sign_extend:DI
7778                               (match_operand:SI 1 "nonimmediate_operand" ""))
7779                             (sign_extend:DI
7780                               (match_operand:SI 2 "register_operand" ""))))
7781               (clobber (reg:CC FLAGS_REG))])]
7782   "!TARGET_64BIT"
7783   "")
7784
7785 (define_insn "*mulsidi3_insn"
7786   [(set (match_operand:DI 0 "register_operand" "=A")
7787         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7788                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7789    (clobber (reg:CC FLAGS_REG))]
7790   "!TARGET_64BIT
7791    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7792   "imul{l}\t%2"
7793   [(set_attr "type" "imul")
7794    (set_attr "length_immediate" "0")
7795    (set (attr "athlon_decode")
7796      (if_then_else (eq_attr "cpu" "athlon")
7797         (const_string "vector")
7798         (const_string "double")))
7799    (set_attr "amdfam10_decode" "double")        
7800    (set_attr "mode" "SI")])
7801
7802 (define_expand "umuldi3_highpart"
7803   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7804                    (truncate:DI
7805                      (lshiftrt:TI
7806                        (mult:TI (zero_extend:TI
7807                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7808                                 (zero_extend:TI
7809                                   (match_operand:DI 2 "register_operand" "")))
7810                        (const_int 64))))
7811               (clobber (match_scratch:DI 3 ""))
7812               (clobber (reg:CC FLAGS_REG))])]
7813   "TARGET_64BIT"
7814   "")
7815
7816 (define_insn "*umuldi3_highpart_rex64"
7817   [(set (match_operand:DI 0 "register_operand" "=d")
7818         (truncate:DI
7819           (lshiftrt:TI
7820             (mult:TI (zero_extend:TI
7821                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7822                      (zero_extend:TI
7823                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7824             (const_int 64))))
7825    (clobber (match_scratch:DI 3 "=1"))
7826    (clobber (reg:CC FLAGS_REG))]
7827   "TARGET_64BIT
7828    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7829   "mul{q}\t%2"
7830   [(set_attr "type" "imul")
7831    (set_attr "length_immediate" "0")
7832    (set (attr "athlon_decode")
7833      (if_then_else (eq_attr "cpu" "athlon")
7834         (const_string "vector")
7835         (const_string "double")))
7836    (set_attr "amdfam10_decode" "double")        
7837    (set_attr "mode" "DI")])
7838
7839 (define_expand "umulsi3_highpart"
7840   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7841                    (truncate:SI
7842                      (lshiftrt:DI
7843                        (mult:DI (zero_extend:DI
7844                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7845                                 (zero_extend:DI
7846                                   (match_operand:SI 2 "register_operand" "")))
7847                        (const_int 32))))
7848               (clobber (match_scratch:SI 3 ""))
7849               (clobber (reg:CC FLAGS_REG))])]
7850   ""
7851   "")
7852
7853 (define_insn "*umulsi3_highpart_insn"
7854   [(set (match_operand:SI 0 "register_operand" "=d")
7855         (truncate:SI
7856           (lshiftrt:DI
7857             (mult:DI (zero_extend:DI
7858                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7859                      (zero_extend:DI
7860                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7861             (const_int 32))))
7862    (clobber (match_scratch:SI 3 "=1"))
7863    (clobber (reg:CC FLAGS_REG))]
7864   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7865   "mul{l}\t%2"
7866   [(set_attr "type" "imul")
7867    (set_attr "length_immediate" "0")
7868    (set (attr "athlon_decode")
7869      (if_then_else (eq_attr "cpu" "athlon")
7870         (const_string "vector")
7871         (const_string "double")))
7872    (set_attr "amdfam10_decode" "double")
7873    (set_attr "mode" "SI")])
7874
7875 (define_insn "*umulsi3_highpart_zext"
7876   [(set (match_operand:DI 0 "register_operand" "=d")
7877         (zero_extend:DI (truncate:SI
7878           (lshiftrt:DI
7879             (mult:DI (zero_extend:DI
7880                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7881                      (zero_extend:DI
7882                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7883             (const_int 32)))))
7884    (clobber (match_scratch:SI 3 "=1"))
7885    (clobber (reg:CC FLAGS_REG))]
7886   "TARGET_64BIT
7887    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7888   "mul{l}\t%2"
7889   [(set_attr "type" "imul")
7890    (set_attr "length_immediate" "0")
7891    (set (attr "athlon_decode")
7892      (if_then_else (eq_attr "cpu" "athlon")
7893         (const_string "vector")
7894         (const_string "double")))
7895    (set_attr "amdfam10_decode" "double")
7896    (set_attr "mode" "SI")])
7897
7898 (define_expand "smuldi3_highpart"
7899   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7900                    (truncate:DI
7901                      (lshiftrt:TI
7902                        (mult:TI (sign_extend:TI
7903                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7904                                 (sign_extend:TI
7905                                   (match_operand:DI 2 "register_operand" "")))
7906                        (const_int 64))))
7907               (clobber (match_scratch:DI 3 ""))
7908               (clobber (reg:CC FLAGS_REG))])]
7909   "TARGET_64BIT"
7910   "")
7911
7912 (define_insn "*smuldi3_highpart_rex64"
7913   [(set (match_operand:DI 0 "register_operand" "=d")
7914         (truncate:DI
7915           (lshiftrt:TI
7916             (mult:TI (sign_extend:TI
7917                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7918                      (sign_extend:TI
7919                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7920             (const_int 64))))
7921    (clobber (match_scratch:DI 3 "=1"))
7922    (clobber (reg:CC FLAGS_REG))]
7923   "TARGET_64BIT
7924    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7925   "imul{q}\t%2"
7926   [(set_attr "type" "imul")
7927    (set (attr "athlon_decode")
7928      (if_then_else (eq_attr "cpu" "athlon")
7929         (const_string "vector")
7930         (const_string "double")))
7931    (set_attr "amdfam10_decode" "double")
7932    (set_attr "mode" "DI")])
7933
7934 (define_expand "smulsi3_highpart"
7935   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7936                    (truncate:SI
7937                      (lshiftrt:DI
7938                        (mult:DI (sign_extend:DI
7939                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7940                                 (sign_extend:DI
7941                                   (match_operand:SI 2 "register_operand" "")))
7942                        (const_int 32))))
7943               (clobber (match_scratch:SI 3 ""))
7944               (clobber (reg:CC FLAGS_REG))])]
7945   ""
7946   "")
7947
7948 (define_insn "*smulsi3_highpart_insn"
7949   [(set (match_operand:SI 0 "register_operand" "=d")
7950         (truncate:SI
7951           (lshiftrt:DI
7952             (mult:DI (sign_extend:DI
7953                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7954                      (sign_extend:DI
7955                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7956             (const_int 32))))
7957    (clobber (match_scratch:SI 3 "=1"))
7958    (clobber (reg:CC FLAGS_REG))]
7959   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7960   "imul{l}\t%2"
7961   [(set_attr "type" "imul")
7962    (set (attr "athlon_decode")
7963      (if_then_else (eq_attr "cpu" "athlon")
7964         (const_string "vector")
7965         (const_string "double")))
7966    (set_attr "amdfam10_decode" "double")
7967    (set_attr "mode" "SI")])
7968
7969 (define_insn "*smulsi3_highpart_zext"
7970   [(set (match_operand:DI 0 "register_operand" "=d")
7971         (zero_extend:DI (truncate:SI
7972           (lshiftrt:DI
7973             (mult:DI (sign_extend:DI
7974                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7975                      (sign_extend:DI
7976                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7977             (const_int 32)))))
7978    (clobber (match_scratch:SI 3 "=1"))
7979    (clobber (reg:CC FLAGS_REG))]
7980   "TARGET_64BIT
7981    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7982   "imul{l}\t%2"
7983   [(set_attr "type" "imul")
7984    (set (attr "athlon_decode")
7985      (if_then_else (eq_attr "cpu" "athlon")
7986         (const_string "vector")
7987         (const_string "double")))
7988    (set_attr "amdfam10_decode" "double")
7989    (set_attr "mode" "SI")])
7990
7991 ;; The patterns that match these are at the end of this file.
7992
7993 (define_expand "mulxf3"
7994   [(set (match_operand:XF 0 "register_operand" "")
7995         (mult:XF (match_operand:XF 1 "register_operand" "")
7996                  (match_operand:XF 2 "register_operand" "")))]
7997   "TARGET_80387"
7998   "")
7999
8000 (define_expand "mul<mode>3"
8001   [(set (match_operand:MODEF 0 "register_operand" "")
8002         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8003                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8004   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8005   "")
8006 \f
8007 ;; Divide instructions
8008
8009 (define_insn "divqi3"
8010   [(set (match_operand:QI 0 "register_operand" "=a")
8011         (div:QI (match_operand:HI 1 "register_operand" "0")
8012                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8013    (clobber (reg:CC FLAGS_REG))]
8014   "TARGET_QIMODE_MATH"
8015   "idiv{b}\t%2"
8016   [(set_attr "type" "idiv")
8017    (set_attr "mode" "QI")])
8018
8019 (define_insn "udivqi3"
8020   [(set (match_operand:QI 0 "register_operand" "=a")
8021         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8022                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8023    (clobber (reg:CC FLAGS_REG))]
8024   "TARGET_QIMODE_MATH"
8025   "div{b}\t%2"
8026   [(set_attr "type" "idiv")
8027    (set_attr "mode" "QI")])
8028
8029 ;; The patterns that match these are at the end of this file.
8030
8031 (define_expand "divxf3"
8032   [(set (match_operand:XF 0 "register_operand" "")
8033         (div:XF (match_operand:XF 1 "register_operand" "")
8034                 (match_operand:XF 2 "register_operand" "")))]
8035   "TARGET_80387"
8036   "")
8037
8038 (define_expand "divdf3"
8039   [(set (match_operand:DF 0 "register_operand" "")
8040         (div:DF (match_operand:DF 1 "register_operand" "")
8041                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8042    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8043    "")
8044
8045 (define_expand "divsf3"
8046   [(set (match_operand:SF 0 "register_operand" "")
8047         (div:SF (match_operand:SF 1 "register_operand" "")
8048                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8049   "TARGET_80387 || TARGET_SSE_MATH"
8050 {
8051   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8052       && flag_finite_math_only && !flag_trapping_math
8053       && flag_unsafe_math_optimizations)
8054     {
8055       ix86_emit_swdivsf (operands[0], operands[1],
8056                          operands[2], SFmode);
8057       DONE;
8058     }
8059 })
8060 \f
8061 ;; Remainder instructions.
8062
8063 (define_expand "divmoddi4"
8064   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8065                    (div:DI (match_operand:DI 1 "register_operand" "")
8066                            (match_operand:DI 2 "nonimmediate_operand" "")))
8067               (set (match_operand:DI 3 "register_operand" "")
8068                    (mod:DI (match_dup 1) (match_dup 2)))
8069               (clobber (reg:CC FLAGS_REG))])]
8070   "TARGET_64BIT"
8071   "")
8072
8073 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8074 ;; Penalize eax case slightly because it results in worse scheduling
8075 ;; of code.
8076 (define_insn "*divmoddi4_nocltd_rex64"
8077   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8078         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8079                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8080    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8081         (mod:DI (match_dup 2) (match_dup 3)))
8082    (clobber (reg:CC FLAGS_REG))]
8083   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8084   "#"
8085   [(set_attr "type" "multi")])
8086
8087 (define_insn "*divmoddi4_cltd_rex64"
8088   [(set (match_operand:DI 0 "register_operand" "=a")
8089         (div:DI (match_operand:DI 2 "register_operand" "a")
8090                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8091    (set (match_operand:DI 1 "register_operand" "=&d")
8092         (mod:DI (match_dup 2) (match_dup 3)))
8093    (clobber (reg:CC FLAGS_REG))]
8094   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8095   "#"
8096   [(set_attr "type" "multi")])
8097
8098 (define_insn "*divmoddi_noext_rex64"
8099   [(set (match_operand:DI 0 "register_operand" "=a")
8100         (div:DI (match_operand:DI 1 "register_operand" "0")
8101                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8102    (set (match_operand:DI 3 "register_operand" "=d")
8103         (mod:DI (match_dup 1) (match_dup 2)))
8104    (use (match_operand:DI 4 "register_operand" "3"))
8105    (clobber (reg:CC FLAGS_REG))]
8106   "TARGET_64BIT"
8107   "idiv{q}\t%2"
8108   [(set_attr "type" "idiv")
8109    (set_attr "mode" "DI")])
8110
8111 (define_split
8112   [(set (match_operand:DI 0 "register_operand" "")
8113         (div:DI (match_operand:DI 1 "register_operand" "")
8114                 (match_operand:DI 2 "nonimmediate_operand" "")))
8115    (set (match_operand:DI 3 "register_operand" "")
8116         (mod:DI (match_dup 1) (match_dup 2)))
8117    (clobber (reg:CC FLAGS_REG))]
8118   "TARGET_64BIT && reload_completed"
8119   [(parallel [(set (match_dup 3)
8120                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8121               (clobber (reg:CC FLAGS_REG))])
8122    (parallel [(set (match_dup 0)
8123                    (div:DI (reg:DI 0) (match_dup 2)))
8124               (set (match_dup 3)
8125                    (mod:DI (reg:DI 0) (match_dup 2)))
8126               (use (match_dup 3))
8127               (clobber (reg:CC FLAGS_REG))])]
8128 {
8129   /* Avoid use of cltd in favor of a mov+shift.  */
8130   if (!TARGET_USE_CLTD && !optimize_size)
8131     {
8132       if (true_regnum (operands[1]))
8133         emit_move_insn (operands[0], operands[1]);
8134       else
8135         emit_move_insn (operands[3], operands[1]);
8136       operands[4] = operands[3];
8137     }
8138   else
8139     {
8140       gcc_assert (!true_regnum (operands[1]));
8141       operands[4] = operands[1];
8142     }
8143 })
8144
8145
8146 (define_expand "divmodsi4"
8147   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8148                    (div:SI (match_operand:SI 1 "register_operand" "")
8149                            (match_operand:SI 2 "nonimmediate_operand" "")))
8150               (set (match_operand:SI 3 "register_operand" "")
8151                    (mod:SI (match_dup 1) (match_dup 2)))
8152               (clobber (reg:CC FLAGS_REG))])]
8153   ""
8154   "")
8155
8156 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8157 ;; Penalize eax case slightly because it results in worse scheduling
8158 ;; of code.
8159 (define_insn "*divmodsi4_nocltd"
8160   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8161         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8162                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8163    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8164         (mod:SI (match_dup 2) (match_dup 3)))
8165    (clobber (reg:CC FLAGS_REG))]
8166   "!optimize_size && !TARGET_USE_CLTD"
8167   "#"
8168   [(set_attr "type" "multi")])
8169
8170 (define_insn "*divmodsi4_cltd"
8171   [(set (match_operand:SI 0 "register_operand" "=a")
8172         (div:SI (match_operand:SI 2 "register_operand" "a")
8173                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8174    (set (match_operand:SI 1 "register_operand" "=&d")
8175         (mod:SI (match_dup 2) (match_dup 3)))
8176    (clobber (reg:CC FLAGS_REG))]
8177   "optimize_size || TARGET_USE_CLTD"
8178   "#"
8179   [(set_attr "type" "multi")])
8180
8181 (define_insn "*divmodsi_noext"
8182   [(set (match_operand:SI 0 "register_operand" "=a")
8183         (div:SI (match_operand:SI 1 "register_operand" "0")
8184                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8185    (set (match_operand:SI 3 "register_operand" "=d")
8186         (mod:SI (match_dup 1) (match_dup 2)))
8187    (use (match_operand:SI 4 "register_operand" "3"))
8188    (clobber (reg:CC FLAGS_REG))]
8189   ""
8190   "idiv{l}\t%2"
8191   [(set_attr "type" "idiv")
8192    (set_attr "mode" "SI")])
8193
8194 (define_split
8195   [(set (match_operand:SI 0 "register_operand" "")
8196         (div:SI (match_operand:SI 1 "register_operand" "")
8197                 (match_operand:SI 2 "nonimmediate_operand" "")))
8198    (set (match_operand:SI 3 "register_operand" "")
8199         (mod:SI (match_dup 1) (match_dup 2)))
8200    (clobber (reg:CC FLAGS_REG))]
8201   "reload_completed"
8202   [(parallel [(set (match_dup 3)
8203                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8204               (clobber (reg:CC FLAGS_REG))])
8205    (parallel [(set (match_dup 0)
8206                    (div:SI (reg:SI 0) (match_dup 2)))
8207               (set (match_dup 3)
8208                    (mod:SI (reg:SI 0) (match_dup 2)))
8209               (use (match_dup 3))
8210               (clobber (reg:CC FLAGS_REG))])]
8211 {
8212   /* Avoid use of cltd in favor of a mov+shift.  */
8213   if (!TARGET_USE_CLTD && !optimize_size)
8214     {
8215       if (true_regnum (operands[1]))
8216         emit_move_insn (operands[0], operands[1]);
8217       else
8218         emit_move_insn (operands[3], operands[1]);
8219       operands[4] = operands[3];
8220     }
8221   else
8222     {
8223       gcc_assert (!true_regnum (operands[1]));
8224       operands[4] = operands[1];
8225     }
8226 })
8227 ;; %%% Split me.
8228 (define_insn "divmodhi4"
8229   [(set (match_operand:HI 0 "register_operand" "=a")
8230         (div:HI (match_operand:HI 1 "register_operand" "0")
8231                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8232    (set (match_operand:HI 3 "register_operand" "=&d")
8233         (mod:HI (match_dup 1) (match_dup 2)))
8234    (clobber (reg:CC FLAGS_REG))]
8235   "TARGET_HIMODE_MATH"
8236   "cwtd\;idiv{w}\t%2"
8237   [(set_attr "type" "multi")
8238    (set_attr "length_immediate" "0")
8239    (set_attr "mode" "SI")])
8240
8241 (define_insn "udivmoddi4"
8242   [(set (match_operand:DI 0 "register_operand" "=a")
8243         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8244                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8245    (set (match_operand:DI 3 "register_operand" "=&d")
8246         (umod:DI (match_dup 1) (match_dup 2)))
8247    (clobber (reg:CC FLAGS_REG))]
8248   "TARGET_64BIT"
8249   "xor{q}\t%3, %3\;div{q}\t%2"
8250   [(set_attr "type" "multi")
8251    (set_attr "length_immediate" "0")
8252    (set_attr "mode" "DI")])
8253
8254 (define_insn "*udivmoddi4_noext"
8255   [(set (match_operand:DI 0 "register_operand" "=a")
8256         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8257                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8258    (set (match_operand:DI 3 "register_operand" "=d")
8259         (umod:DI (match_dup 1) (match_dup 2)))
8260    (use (match_dup 3))
8261    (clobber (reg:CC FLAGS_REG))]
8262   "TARGET_64BIT"
8263   "div{q}\t%2"
8264   [(set_attr "type" "idiv")
8265    (set_attr "mode" "DI")])
8266
8267 (define_split
8268   [(set (match_operand:DI 0 "register_operand" "")
8269         (udiv:DI (match_operand:DI 1 "register_operand" "")
8270                  (match_operand:DI 2 "nonimmediate_operand" "")))
8271    (set (match_operand:DI 3 "register_operand" "")
8272         (umod:DI (match_dup 1) (match_dup 2)))
8273    (clobber (reg:CC FLAGS_REG))]
8274   "TARGET_64BIT && reload_completed"
8275   [(set (match_dup 3) (const_int 0))
8276    (parallel [(set (match_dup 0)
8277                    (udiv:DI (match_dup 1) (match_dup 2)))
8278               (set (match_dup 3)
8279                    (umod:DI (match_dup 1) (match_dup 2)))
8280               (use (match_dup 3))
8281               (clobber (reg:CC FLAGS_REG))])]
8282   "")
8283
8284 (define_insn "udivmodsi4"
8285   [(set (match_operand:SI 0 "register_operand" "=a")
8286         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8287                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8288    (set (match_operand:SI 3 "register_operand" "=&d")
8289         (umod:SI (match_dup 1) (match_dup 2)))
8290    (clobber (reg:CC FLAGS_REG))]
8291   ""
8292   "xor{l}\t%3, %3\;div{l}\t%2"
8293   [(set_attr "type" "multi")
8294    (set_attr "length_immediate" "0")
8295    (set_attr "mode" "SI")])
8296
8297 (define_insn "*udivmodsi4_noext"
8298   [(set (match_operand:SI 0 "register_operand" "=a")
8299         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8300                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8301    (set (match_operand:SI 3 "register_operand" "=d")
8302         (umod:SI (match_dup 1) (match_dup 2)))
8303    (use (match_dup 3))
8304    (clobber (reg:CC FLAGS_REG))]
8305   ""
8306   "div{l}\t%2"
8307   [(set_attr "type" "idiv")
8308    (set_attr "mode" "SI")])
8309
8310 (define_split
8311   [(set (match_operand:SI 0 "register_operand" "")
8312         (udiv:SI (match_operand:SI 1 "register_operand" "")
8313                  (match_operand:SI 2 "nonimmediate_operand" "")))
8314    (set (match_operand:SI 3 "register_operand" "")
8315         (umod:SI (match_dup 1) (match_dup 2)))
8316    (clobber (reg:CC FLAGS_REG))]
8317   "reload_completed"
8318   [(set (match_dup 3) (const_int 0))
8319    (parallel [(set (match_dup 0)
8320                    (udiv:SI (match_dup 1) (match_dup 2)))
8321               (set (match_dup 3)
8322                    (umod:SI (match_dup 1) (match_dup 2)))
8323               (use (match_dup 3))
8324               (clobber (reg:CC FLAGS_REG))])]
8325   "")
8326
8327 (define_expand "udivmodhi4"
8328   [(set (match_dup 4) (const_int 0))
8329    (parallel [(set (match_operand:HI 0 "register_operand" "")
8330                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8331                             (match_operand:HI 2 "nonimmediate_operand" "")))
8332               (set (match_operand:HI 3 "register_operand" "")
8333                    (umod:HI (match_dup 1) (match_dup 2)))
8334               (use (match_dup 4))
8335               (clobber (reg:CC FLAGS_REG))])]
8336   "TARGET_HIMODE_MATH"
8337   "operands[4] = gen_reg_rtx (HImode);")
8338
8339 (define_insn "*udivmodhi_noext"
8340   [(set (match_operand:HI 0 "register_operand" "=a")
8341         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8342                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8343    (set (match_operand:HI 3 "register_operand" "=d")
8344         (umod:HI (match_dup 1) (match_dup 2)))
8345    (use (match_operand:HI 4 "register_operand" "3"))
8346    (clobber (reg:CC FLAGS_REG))]
8347   ""
8348   "div{w}\t%2"
8349   [(set_attr "type" "idiv")
8350    (set_attr "mode" "HI")])
8351
8352 ;; We cannot use div/idiv for double division, because it causes
8353 ;; "division by zero" on the overflow and that's not what we expect
8354 ;; from truncate.  Because true (non truncating) double division is
8355 ;; never generated, we can't create this insn anyway.
8356 ;
8357 ;(define_insn ""
8358 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8359 ;       (truncate:SI
8360 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8361 ;                  (zero_extend:DI
8362 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8363 ;   (set (match_operand:SI 3 "register_operand" "=d")
8364 ;       (truncate:SI
8365 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8366 ;   (clobber (reg:CC FLAGS_REG))]
8367 ;  ""
8368 ;  "div{l}\t{%2, %0|%0, %2}"
8369 ;  [(set_attr "type" "idiv")])
8370 \f
8371 ;;- Logical AND instructions
8372
8373 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8374 ;; Note that this excludes ah.
8375
8376 (define_insn "*testdi_1_rex64"
8377   [(set (reg FLAGS_REG)
8378         (compare
8379           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8380                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8381           (const_int 0)))]
8382   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8383    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8384   "@
8385    test{l}\t{%k1, %k0|%k0, %k1}
8386    test{l}\t{%k1, %k0|%k0, %k1}
8387    test{q}\t{%1, %0|%0, %1}
8388    test{q}\t{%1, %0|%0, %1}
8389    test{q}\t{%1, %0|%0, %1}"
8390   [(set_attr "type" "test")
8391    (set_attr "modrm" "0,1,0,1,1")
8392    (set_attr "mode" "SI,SI,DI,DI,DI")
8393    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8394
8395 (define_insn "testsi_1"
8396   [(set (reg FLAGS_REG)
8397         (compare
8398           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8399                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8400           (const_int 0)))]
8401   "ix86_match_ccmode (insn, CCNOmode)
8402    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8403   "test{l}\t{%1, %0|%0, %1}"
8404   [(set_attr "type" "test")
8405    (set_attr "modrm" "0,1,1")
8406    (set_attr "mode" "SI")
8407    (set_attr "pent_pair" "uv,np,uv")])
8408
8409 (define_expand "testsi_ccno_1"
8410   [(set (reg:CCNO FLAGS_REG)
8411         (compare:CCNO
8412           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8413                   (match_operand:SI 1 "nonmemory_operand" ""))
8414           (const_int 0)))]
8415   ""
8416   "")
8417
8418 (define_insn "*testhi_1"
8419   [(set (reg FLAGS_REG)
8420         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8421                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8422                  (const_int 0)))]
8423   "ix86_match_ccmode (insn, CCNOmode)
8424    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8425   "test{w}\t{%1, %0|%0, %1}"
8426   [(set_attr "type" "test")
8427    (set_attr "modrm" "0,1,1")
8428    (set_attr "mode" "HI")
8429    (set_attr "pent_pair" "uv,np,uv")])
8430
8431 (define_expand "testqi_ccz_1"
8432   [(set (reg:CCZ FLAGS_REG)
8433         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8434                              (match_operand:QI 1 "nonmemory_operand" ""))
8435                  (const_int 0)))]
8436   ""
8437   "")
8438
8439 (define_insn "*testqi_1_maybe_si"
8440   [(set (reg FLAGS_REG)
8441         (compare
8442           (and:QI
8443             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8444             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8445           (const_int 0)))]
8446    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8447     && ix86_match_ccmode (insn,
8448                          CONST_INT_P (operands[1])
8449                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8450 {
8451   if (which_alternative == 3)
8452     {
8453       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8454         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8455       return "test{l}\t{%1, %k0|%k0, %1}";
8456     }
8457   return "test{b}\t{%1, %0|%0, %1}";
8458 }
8459   [(set_attr "type" "test")
8460    (set_attr "modrm" "0,1,1,1")
8461    (set_attr "mode" "QI,QI,QI,SI")
8462    (set_attr "pent_pair" "uv,np,uv,np")])
8463
8464 (define_insn "*testqi_1"
8465   [(set (reg FLAGS_REG)
8466         (compare
8467           (and:QI
8468             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8469             (match_operand:QI 1 "general_operand" "n,n,qn"))
8470           (const_int 0)))]
8471   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8472    && ix86_match_ccmode (insn, CCNOmode)"
8473   "test{b}\t{%1, %0|%0, %1}"
8474   [(set_attr "type" "test")
8475    (set_attr "modrm" "0,1,1")
8476    (set_attr "mode" "QI")
8477    (set_attr "pent_pair" "uv,np,uv")])
8478
8479 (define_expand "testqi_ext_ccno_0"
8480   [(set (reg:CCNO FLAGS_REG)
8481         (compare:CCNO
8482           (and:SI
8483             (zero_extract:SI
8484               (match_operand 0 "ext_register_operand" "")
8485               (const_int 8)
8486               (const_int 8))
8487             (match_operand 1 "const_int_operand" ""))
8488           (const_int 0)))]
8489   ""
8490   "")
8491
8492 (define_insn "*testqi_ext_0"
8493   [(set (reg FLAGS_REG)
8494         (compare
8495           (and:SI
8496             (zero_extract:SI
8497               (match_operand 0 "ext_register_operand" "Q")
8498               (const_int 8)
8499               (const_int 8))
8500             (match_operand 1 "const_int_operand" "n"))
8501           (const_int 0)))]
8502   "ix86_match_ccmode (insn, CCNOmode)"
8503   "test{b}\t{%1, %h0|%h0, %1}"
8504   [(set_attr "type" "test")
8505    (set_attr "mode" "QI")
8506    (set_attr "length_immediate" "1")
8507    (set_attr "pent_pair" "np")])
8508
8509 (define_insn "*testqi_ext_1"
8510   [(set (reg FLAGS_REG)
8511         (compare
8512           (and:SI
8513             (zero_extract:SI
8514               (match_operand 0 "ext_register_operand" "Q")
8515               (const_int 8)
8516               (const_int 8))
8517             (zero_extend:SI
8518               (match_operand:QI 1 "general_operand" "Qm")))
8519           (const_int 0)))]
8520   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8521    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8522   "test{b}\t{%1, %h0|%h0, %1}"
8523   [(set_attr "type" "test")
8524    (set_attr "mode" "QI")])
8525
8526 (define_insn "*testqi_ext_1_rex64"
8527   [(set (reg FLAGS_REG)
8528         (compare
8529           (and:SI
8530             (zero_extract:SI
8531               (match_operand 0 "ext_register_operand" "Q")
8532               (const_int 8)
8533               (const_int 8))
8534             (zero_extend:SI
8535               (match_operand:QI 1 "register_operand" "Q")))
8536           (const_int 0)))]
8537   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8538   "test{b}\t{%1, %h0|%h0, %1}"
8539   [(set_attr "type" "test")
8540    (set_attr "mode" "QI")])
8541
8542 (define_insn "*testqi_ext_2"
8543   [(set (reg FLAGS_REG)
8544         (compare
8545           (and:SI
8546             (zero_extract:SI
8547               (match_operand 0 "ext_register_operand" "Q")
8548               (const_int 8)
8549               (const_int 8))
8550             (zero_extract:SI
8551               (match_operand 1 "ext_register_operand" "Q")
8552               (const_int 8)
8553               (const_int 8)))
8554           (const_int 0)))]
8555   "ix86_match_ccmode (insn, CCNOmode)"
8556   "test{b}\t{%h1, %h0|%h0, %h1}"
8557   [(set_attr "type" "test")
8558    (set_attr "mode" "QI")])
8559
8560 ;; Combine likes to form bit extractions for some tests.  Humor it.
8561 (define_insn "*testqi_ext_3"
8562   [(set (reg FLAGS_REG)
8563         (compare (zero_extract:SI
8564                    (match_operand 0 "nonimmediate_operand" "rm")
8565                    (match_operand:SI 1 "const_int_operand" "")
8566                    (match_operand:SI 2 "const_int_operand" ""))
8567                  (const_int 0)))]
8568   "ix86_match_ccmode (insn, CCNOmode)
8569    && INTVAL (operands[1]) > 0
8570    && INTVAL (operands[2]) >= 0
8571    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8572    && (GET_MODE (operands[0]) == SImode
8573        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8574        || GET_MODE (operands[0]) == HImode
8575        || GET_MODE (operands[0]) == QImode)"
8576   "#")
8577
8578 (define_insn "*testqi_ext_3_rex64"
8579   [(set (reg FLAGS_REG)
8580         (compare (zero_extract:DI
8581                    (match_operand 0 "nonimmediate_operand" "rm")
8582                    (match_operand:DI 1 "const_int_operand" "")
8583                    (match_operand:DI 2 "const_int_operand" ""))
8584                  (const_int 0)))]
8585   "TARGET_64BIT
8586    && ix86_match_ccmode (insn, CCNOmode)
8587    && INTVAL (operands[1]) > 0
8588    && INTVAL (operands[2]) >= 0
8589    /* Ensure that resulting mask is zero or sign extended operand.  */
8590    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8591        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8592            && INTVAL (operands[1]) > 32))
8593    && (GET_MODE (operands[0]) == SImode
8594        || GET_MODE (operands[0]) == DImode
8595        || GET_MODE (operands[0]) == HImode
8596        || GET_MODE (operands[0]) == QImode)"
8597   "#")
8598
8599 (define_split
8600   [(set (match_operand 0 "flags_reg_operand" "")
8601         (match_operator 1 "compare_operator"
8602           [(zero_extract
8603              (match_operand 2 "nonimmediate_operand" "")
8604              (match_operand 3 "const_int_operand" "")
8605              (match_operand 4 "const_int_operand" ""))
8606            (const_int 0)]))]
8607   "ix86_match_ccmode (insn, CCNOmode)"
8608   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8609 {
8610   rtx val = operands[2];
8611   HOST_WIDE_INT len = INTVAL (operands[3]);
8612   HOST_WIDE_INT pos = INTVAL (operands[4]);
8613   HOST_WIDE_INT mask;
8614   enum machine_mode mode, submode;
8615
8616   mode = GET_MODE (val);
8617   if (MEM_P (val))
8618     {
8619       /* ??? Combine likes to put non-volatile mem extractions in QImode
8620          no matter the size of the test.  So find a mode that works.  */
8621       if (! MEM_VOLATILE_P (val))
8622         {
8623           mode = smallest_mode_for_size (pos + len, MODE_INT);
8624           val = adjust_address (val, mode, 0);
8625         }
8626     }
8627   else if (GET_CODE (val) == SUBREG
8628            && (submode = GET_MODE (SUBREG_REG (val)),
8629                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8630            && pos + len <= GET_MODE_BITSIZE (submode))
8631     {
8632       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8633       mode = submode;
8634       val = SUBREG_REG (val);
8635     }
8636   else if (mode == HImode && pos + len <= 8)
8637     {
8638       /* Small HImode tests can be converted to QImode.  */
8639       mode = QImode;
8640       val = gen_lowpart (QImode, val);
8641     }
8642
8643   if (len == HOST_BITS_PER_WIDE_INT)
8644     mask = -1;
8645   else
8646     mask = ((HOST_WIDE_INT)1 << len) - 1;
8647   mask <<= pos;
8648
8649   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8650 })
8651
8652 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8653 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8654 ;; this is relatively important trick.
8655 ;; Do the conversion only post-reload to avoid limiting of the register class
8656 ;; to QI regs.
8657 (define_split
8658   [(set (match_operand 0 "flags_reg_operand" "")
8659         (match_operator 1 "compare_operator"
8660           [(and (match_operand 2 "register_operand" "")
8661                 (match_operand 3 "const_int_operand" ""))
8662            (const_int 0)]))]
8663    "reload_completed
8664     && QI_REG_P (operands[2])
8665     && GET_MODE (operands[2]) != QImode
8666     && ((ix86_match_ccmode (insn, CCZmode)
8667          && !(INTVAL (operands[3]) & ~(255 << 8)))
8668         || (ix86_match_ccmode (insn, CCNOmode)
8669             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8670   [(set (match_dup 0)
8671         (match_op_dup 1
8672           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8673                    (match_dup 3))
8674            (const_int 0)]))]
8675   "operands[2] = gen_lowpart (SImode, operands[2]);
8676    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8677
8678 (define_split
8679   [(set (match_operand 0 "flags_reg_operand" "")
8680         (match_operator 1 "compare_operator"
8681           [(and (match_operand 2 "nonimmediate_operand" "")
8682                 (match_operand 3 "const_int_operand" ""))
8683            (const_int 0)]))]
8684    "reload_completed
8685     && GET_MODE (operands[2]) != QImode
8686     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8687     && ((ix86_match_ccmode (insn, CCZmode)
8688          && !(INTVAL (operands[3]) & ~255))
8689         || (ix86_match_ccmode (insn, CCNOmode)
8690             && !(INTVAL (operands[3]) & ~127)))"
8691   [(set (match_dup 0)
8692         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8693                          (const_int 0)]))]
8694   "operands[2] = gen_lowpart (QImode, operands[2]);
8695    operands[3] = gen_lowpart (QImode, operands[3]);")
8696
8697
8698 ;; %%% This used to optimize known byte-wide and operations to memory,
8699 ;; and sometimes to QImode registers.  If this is considered useful,
8700 ;; it should be done with splitters.
8701
8702 (define_expand "anddi3"
8703   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8704         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8705                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8706    (clobber (reg:CC FLAGS_REG))]
8707   "TARGET_64BIT"
8708   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8709
8710 (define_insn "*anddi_1_rex64"
8711   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8712         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8713                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8714    (clobber (reg:CC FLAGS_REG))]
8715   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8716 {
8717   switch (get_attr_type (insn))
8718     {
8719     case TYPE_IMOVX:
8720       {
8721         enum machine_mode mode;
8722
8723         gcc_assert (CONST_INT_P (operands[2]));
8724         if (INTVAL (operands[2]) == 0xff)
8725           mode = QImode;
8726         else
8727           {
8728             gcc_assert (INTVAL (operands[2]) == 0xffff);
8729             mode = HImode;
8730           }
8731
8732         operands[1] = gen_lowpart (mode, operands[1]);
8733         if (mode == QImode)
8734           return "movz{bq|x}\t{%1,%0|%0, %1}";
8735         else
8736           return "movz{wq|x}\t{%1,%0|%0, %1}";
8737       }
8738
8739     default:
8740       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8741       if (get_attr_mode (insn) == MODE_SI)
8742         return "and{l}\t{%k2, %k0|%k0, %k2}";
8743       else
8744         return "and{q}\t{%2, %0|%0, %2}";
8745     }
8746 }
8747   [(set_attr "type" "alu,alu,alu,imovx")
8748    (set_attr "length_immediate" "*,*,*,0")
8749    (set_attr "mode" "SI,DI,DI,DI")])
8750
8751 (define_insn "*anddi_2"
8752   [(set (reg FLAGS_REG)
8753         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8754                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8755                  (const_int 0)))
8756    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8757         (and:DI (match_dup 1) (match_dup 2)))]
8758   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8759    && ix86_binary_operator_ok (AND, DImode, operands)"
8760   "@
8761    and{l}\t{%k2, %k0|%k0, %k2}
8762    and{q}\t{%2, %0|%0, %2}
8763    and{q}\t{%2, %0|%0, %2}"
8764   [(set_attr "type" "alu")
8765    (set_attr "mode" "SI,DI,DI")])
8766
8767 (define_expand "andsi3"
8768   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8769         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8770                 (match_operand:SI 2 "general_operand" "")))
8771    (clobber (reg:CC FLAGS_REG))]
8772   ""
8773   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8774
8775 (define_insn "*andsi_1"
8776   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8777         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8778                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8779    (clobber (reg:CC FLAGS_REG))]
8780   "ix86_binary_operator_ok (AND, SImode, operands)"
8781 {
8782   switch (get_attr_type (insn))
8783     {
8784     case TYPE_IMOVX:
8785       {
8786         enum machine_mode mode;
8787
8788         gcc_assert (CONST_INT_P (operands[2]));
8789         if (INTVAL (operands[2]) == 0xff)
8790           mode = QImode;
8791         else
8792           {
8793             gcc_assert (INTVAL (operands[2]) == 0xffff);
8794             mode = HImode;
8795           }
8796
8797         operands[1] = gen_lowpart (mode, operands[1]);
8798         if (mode == QImode)
8799           return "movz{bl|x}\t{%1,%0|%0, %1}";
8800         else
8801           return "movz{wl|x}\t{%1,%0|%0, %1}";
8802       }
8803
8804     default:
8805       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8806       return "and{l}\t{%2, %0|%0, %2}";
8807     }
8808 }
8809   [(set_attr "type" "alu,alu,imovx")
8810    (set_attr "length_immediate" "*,*,0")
8811    (set_attr "mode" "SI")])
8812
8813 (define_split
8814   [(set (match_operand 0 "register_operand" "")
8815         (and (match_dup 0)
8816              (const_int -65536)))
8817    (clobber (reg:CC FLAGS_REG))]
8818   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8819   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8820   "operands[1] = gen_lowpart (HImode, operands[0]);")
8821
8822 (define_split
8823   [(set (match_operand 0 "ext_register_operand" "")
8824         (and (match_dup 0)
8825              (const_int -256)))
8826    (clobber (reg:CC FLAGS_REG))]
8827   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8828   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8829   "operands[1] = gen_lowpart (QImode, operands[0]);")
8830
8831 (define_split
8832   [(set (match_operand 0 "ext_register_operand" "")
8833         (and (match_dup 0)
8834              (const_int -65281)))
8835    (clobber (reg:CC FLAGS_REG))]
8836   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8837   [(parallel [(set (zero_extract:SI (match_dup 0)
8838                                     (const_int 8)
8839                                     (const_int 8))
8840                    (xor:SI
8841                      (zero_extract:SI (match_dup 0)
8842                                       (const_int 8)
8843                                       (const_int 8))
8844                      (zero_extract:SI (match_dup 0)
8845                                       (const_int 8)
8846                                       (const_int 8))))
8847               (clobber (reg:CC FLAGS_REG))])]
8848   "operands[0] = gen_lowpart (SImode, operands[0]);")
8849
8850 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8851 (define_insn "*andsi_1_zext"
8852   [(set (match_operand:DI 0 "register_operand" "=r")
8853         (zero_extend:DI
8854           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8855                   (match_operand:SI 2 "general_operand" "g"))))
8856    (clobber (reg:CC FLAGS_REG))]
8857   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8858   "and{l}\t{%2, %k0|%k0, %2}"
8859   [(set_attr "type" "alu")
8860    (set_attr "mode" "SI")])
8861
8862 (define_insn "*andsi_2"
8863   [(set (reg FLAGS_REG)
8864         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8865                          (match_operand:SI 2 "general_operand" "g,ri"))
8866                  (const_int 0)))
8867    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8868         (and:SI (match_dup 1) (match_dup 2)))]
8869   "ix86_match_ccmode (insn, CCNOmode)
8870    && ix86_binary_operator_ok (AND, SImode, operands)"
8871   "and{l}\t{%2, %0|%0, %2}"
8872   [(set_attr "type" "alu")
8873    (set_attr "mode" "SI")])
8874
8875 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8876 (define_insn "*andsi_2_zext"
8877   [(set (reg FLAGS_REG)
8878         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8879                          (match_operand:SI 2 "general_operand" "g"))
8880                  (const_int 0)))
8881    (set (match_operand:DI 0 "register_operand" "=r")
8882         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8883   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8884    && ix86_binary_operator_ok (AND, SImode, operands)"
8885   "and{l}\t{%2, %k0|%k0, %2}"
8886   [(set_attr "type" "alu")
8887    (set_attr "mode" "SI")])
8888
8889 (define_expand "andhi3"
8890   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8891         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8892                 (match_operand:HI 2 "general_operand" "")))
8893    (clobber (reg:CC FLAGS_REG))]
8894   "TARGET_HIMODE_MATH"
8895   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8896
8897 (define_insn "*andhi_1"
8898   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8899         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8900                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8901    (clobber (reg:CC FLAGS_REG))]
8902   "ix86_binary_operator_ok (AND, HImode, operands)"
8903 {
8904   switch (get_attr_type (insn))
8905     {
8906     case TYPE_IMOVX:
8907       gcc_assert (CONST_INT_P (operands[2]));
8908       gcc_assert (INTVAL (operands[2]) == 0xff);
8909       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8910
8911     default:
8912       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8913
8914       return "and{w}\t{%2, %0|%0, %2}";
8915     }
8916 }
8917   [(set_attr "type" "alu,alu,imovx")
8918    (set_attr "length_immediate" "*,*,0")
8919    (set_attr "mode" "HI,HI,SI")])
8920
8921 (define_insn "*andhi_2"
8922   [(set (reg FLAGS_REG)
8923         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8924                          (match_operand:HI 2 "general_operand" "g,ri"))
8925                  (const_int 0)))
8926    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8927         (and:HI (match_dup 1) (match_dup 2)))]
8928   "ix86_match_ccmode (insn, CCNOmode)
8929    && ix86_binary_operator_ok (AND, HImode, operands)"
8930   "and{w}\t{%2, %0|%0, %2}"
8931   [(set_attr "type" "alu")
8932    (set_attr "mode" "HI")])
8933
8934 (define_expand "andqi3"
8935   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8936         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8937                 (match_operand:QI 2 "general_operand" "")))
8938    (clobber (reg:CC FLAGS_REG))]
8939   "TARGET_QIMODE_MATH"
8940   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8941
8942 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8943 (define_insn "*andqi_1"
8944   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8945         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8946                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8947    (clobber (reg:CC FLAGS_REG))]
8948   "ix86_binary_operator_ok (AND, QImode, operands)"
8949   "@
8950    and{b}\t{%2, %0|%0, %2}
8951    and{b}\t{%2, %0|%0, %2}
8952    and{l}\t{%k2, %k0|%k0, %k2}"
8953   [(set_attr "type" "alu")
8954    (set_attr "mode" "QI,QI,SI")])
8955
8956 (define_insn "*andqi_1_slp"
8957   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8958         (and:QI (match_dup 0)
8959                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8960    (clobber (reg:CC FLAGS_REG))]
8961   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8962    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8963   "and{b}\t{%1, %0|%0, %1}"
8964   [(set_attr "type" "alu1")
8965    (set_attr "mode" "QI")])
8966
8967 (define_insn "*andqi_2_maybe_si"
8968   [(set (reg FLAGS_REG)
8969         (compare (and:QI
8970                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8971                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8972                  (const_int 0)))
8973    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8974         (and:QI (match_dup 1) (match_dup 2)))]
8975   "ix86_binary_operator_ok (AND, QImode, operands)
8976    && ix86_match_ccmode (insn,
8977                          CONST_INT_P (operands[2])
8978                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8979 {
8980   if (which_alternative == 2)
8981     {
8982       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8983         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8984       return "and{l}\t{%2, %k0|%k0, %2}";
8985     }
8986   return "and{b}\t{%2, %0|%0, %2}";
8987 }
8988   [(set_attr "type" "alu")
8989    (set_attr "mode" "QI,QI,SI")])
8990
8991 (define_insn "*andqi_2"
8992   [(set (reg FLAGS_REG)
8993         (compare (and:QI
8994                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8995                    (match_operand:QI 2 "general_operand" "qim,qi"))
8996                  (const_int 0)))
8997    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8998         (and:QI (match_dup 1) (match_dup 2)))]
8999   "ix86_match_ccmode (insn, CCNOmode)
9000    && ix86_binary_operator_ok (AND, QImode, operands)"
9001   "and{b}\t{%2, %0|%0, %2}"
9002   [(set_attr "type" "alu")
9003    (set_attr "mode" "QI")])
9004
9005 (define_insn "*andqi_2_slp"
9006   [(set (reg FLAGS_REG)
9007         (compare (and:QI
9008                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9009                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9010                  (const_int 0)))
9011    (set (strict_low_part (match_dup 0))
9012         (and:QI (match_dup 0) (match_dup 1)))]
9013   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9014    && ix86_match_ccmode (insn, CCNOmode)
9015    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9016   "and{b}\t{%1, %0|%0, %1}"
9017   [(set_attr "type" "alu1")
9018    (set_attr "mode" "QI")])
9019
9020 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9021 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9022 ;; for a QImode operand, which of course failed.
9023
9024 (define_insn "andqi_ext_0"
9025   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9026                          (const_int 8)
9027                          (const_int 8))
9028         (and:SI
9029           (zero_extract:SI
9030             (match_operand 1 "ext_register_operand" "0")
9031             (const_int 8)
9032             (const_int 8))
9033           (match_operand 2 "const_int_operand" "n")))
9034    (clobber (reg:CC FLAGS_REG))]
9035   ""
9036   "and{b}\t{%2, %h0|%h0, %2}"
9037   [(set_attr "type" "alu")
9038    (set_attr "length_immediate" "1")
9039    (set_attr "mode" "QI")])
9040
9041 ;; Generated by peephole translating test to and.  This shows up
9042 ;; often in fp comparisons.
9043
9044 (define_insn "*andqi_ext_0_cc"
9045   [(set (reg FLAGS_REG)
9046         (compare
9047           (and:SI
9048             (zero_extract:SI
9049               (match_operand 1 "ext_register_operand" "0")
9050               (const_int 8)
9051               (const_int 8))
9052             (match_operand 2 "const_int_operand" "n"))
9053           (const_int 0)))
9054    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9055                          (const_int 8)
9056                          (const_int 8))
9057         (and:SI
9058           (zero_extract:SI
9059             (match_dup 1)
9060             (const_int 8)
9061             (const_int 8))
9062           (match_dup 2)))]
9063   "ix86_match_ccmode (insn, CCNOmode)"
9064   "and{b}\t{%2, %h0|%h0, %2}"
9065   [(set_attr "type" "alu")
9066    (set_attr "length_immediate" "1")
9067    (set_attr "mode" "QI")])
9068
9069 (define_insn "*andqi_ext_1"
9070   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9071                          (const_int 8)
9072                          (const_int 8))
9073         (and:SI
9074           (zero_extract:SI
9075             (match_operand 1 "ext_register_operand" "0")
9076             (const_int 8)
9077             (const_int 8))
9078           (zero_extend:SI
9079             (match_operand:QI 2 "general_operand" "Qm"))))
9080    (clobber (reg:CC FLAGS_REG))]
9081   "!TARGET_64BIT"
9082   "and{b}\t{%2, %h0|%h0, %2}"
9083   [(set_attr "type" "alu")
9084    (set_attr "length_immediate" "0")
9085    (set_attr "mode" "QI")])
9086
9087 (define_insn "*andqi_ext_1_rex64"
9088   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9089                          (const_int 8)
9090                          (const_int 8))
9091         (and:SI
9092           (zero_extract:SI
9093             (match_operand 1 "ext_register_operand" "0")
9094             (const_int 8)
9095             (const_int 8))
9096           (zero_extend:SI
9097             (match_operand 2 "ext_register_operand" "Q"))))
9098    (clobber (reg:CC FLAGS_REG))]
9099   "TARGET_64BIT"
9100   "and{b}\t{%2, %h0|%h0, %2}"
9101   [(set_attr "type" "alu")
9102    (set_attr "length_immediate" "0")
9103    (set_attr "mode" "QI")])
9104
9105 (define_insn "*andqi_ext_2"
9106   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9107                          (const_int 8)
9108                          (const_int 8))
9109         (and:SI
9110           (zero_extract:SI
9111             (match_operand 1 "ext_register_operand" "%0")
9112             (const_int 8)
9113             (const_int 8))
9114           (zero_extract:SI
9115             (match_operand 2 "ext_register_operand" "Q")
9116             (const_int 8)
9117             (const_int 8))))
9118    (clobber (reg:CC FLAGS_REG))]
9119   ""
9120   "and{b}\t{%h2, %h0|%h0, %h2}"
9121   [(set_attr "type" "alu")
9122    (set_attr "length_immediate" "0")
9123    (set_attr "mode" "QI")])
9124
9125 ;; Convert wide AND instructions with immediate operand to shorter QImode
9126 ;; equivalents when possible.
9127 ;; Don't do the splitting with memory operands, since it introduces risk
9128 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9129 ;; for size, but that can (should?) be handled by generic code instead.
9130 (define_split
9131   [(set (match_operand 0 "register_operand" "")
9132         (and (match_operand 1 "register_operand" "")
9133              (match_operand 2 "const_int_operand" "")))
9134    (clobber (reg:CC FLAGS_REG))]
9135    "reload_completed
9136     && QI_REG_P (operands[0])
9137     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9138     && !(~INTVAL (operands[2]) & ~(255 << 8))
9139     && GET_MODE (operands[0]) != QImode"
9140   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9141                    (and:SI (zero_extract:SI (match_dup 1)
9142                                             (const_int 8) (const_int 8))
9143                            (match_dup 2)))
9144               (clobber (reg:CC FLAGS_REG))])]
9145   "operands[0] = gen_lowpart (SImode, operands[0]);
9146    operands[1] = gen_lowpart (SImode, operands[1]);
9147    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9148
9149 ;; Since AND can be encoded with sign extended immediate, this is only
9150 ;; profitable when 7th bit is not set.
9151 (define_split
9152   [(set (match_operand 0 "register_operand" "")
9153         (and (match_operand 1 "general_operand" "")
9154              (match_operand 2 "const_int_operand" "")))
9155    (clobber (reg:CC FLAGS_REG))]
9156    "reload_completed
9157     && ANY_QI_REG_P (operands[0])
9158     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9159     && !(~INTVAL (operands[2]) & ~255)
9160     && !(INTVAL (operands[2]) & 128)
9161     && GET_MODE (operands[0]) != QImode"
9162   [(parallel [(set (strict_low_part (match_dup 0))
9163                    (and:QI (match_dup 1)
9164                            (match_dup 2)))
9165               (clobber (reg:CC FLAGS_REG))])]
9166   "operands[0] = gen_lowpart (QImode, operands[0]);
9167    operands[1] = gen_lowpart (QImode, operands[1]);
9168    operands[2] = gen_lowpart (QImode, operands[2]);")
9169 \f
9170 ;; Logical inclusive OR instructions
9171
9172 ;; %%% This used to optimize known byte-wide and operations to memory.
9173 ;; If this is considered useful, it should be done with splitters.
9174
9175 (define_expand "iordi3"
9176   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9177         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9178                 (match_operand:DI 2 "x86_64_general_operand" "")))
9179    (clobber (reg:CC FLAGS_REG))]
9180   "TARGET_64BIT"
9181   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9182
9183 (define_insn "*iordi_1_rex64"
9184   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9185         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9186                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9187    (clobber (reg:CC FLAGS_REG))]
9188   "TARGET_64BIT
9189    && ix86_binary_operator_ok (IOR, DImode, operands)"
9190   "or{q}\t{%2, %0|%0, %2}"
9191   [(set_attr "type" "alu")
9192    (set_attr "mode" "DI")])
9193
9194 (define_insn "*iordi_2_rex64"
9195   [(set (reg FLAGS_REG)
9196         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9197                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9198                  (const_int 0)))
9199    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9200         (ior:DI (match_dup 1) (match_dup 2)))]
9201   "TARGET_64BIT
9202    && ix86_match_ccmode (insn, CCNOmode)
9203    && ix86_binary_operator_ok (IOR, DImode, operands)"
9204   "or{q}\t{%2, %0|%0, %2}"
9205   [(set_attr "type" "alu")
9206    (set_attr "mode" "DI")])
9207
9208 (define_insn "*iordi_3_rex64"
9209   [(set (reg FLAGS_REG)
9210         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9211                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9212                  (const_int 0)))
9213    (clobber (match_scratch:DI 0 "=r"))]
9214   "TARGET_64BIT
9215    && ix86_match_ccmode (insn, CCNOmode)
9216    && ix86_binary_operator_ok (IOR, DImode, operands)"
9217   "or{q}\t{%2, %0|%0, %2}"
9218   [(set_attr "type" "alu")
9219    (set_attr "mode" "DI")])
9220
9221
9222 (define_expand "iorsi3"
9223   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9224         (ior: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 (IOR, SImode, operands); DONE;")
9229
9230 (define_insn "*iorsi_1"
9231   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9232         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9233                 (match_operand:SI 2 "general_operand" "ri,g")))
9234    (clobber (reg:CC FLAGS_REG))]
9235   "ix86_binary_operator_ok (IOR, SImode, operands)"
9236   "or{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 (define_insn "*iorsi_1_zext"
9242   [(set (match_operand:DI 0 "register_operand" "=r")
9243         (zero_extend:DI
9244           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9245                   (match_operand:SI 2 "general_operand" "g"))))
9246    (clobber (reg:CC FLAGS_REG))]
9247   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9248   "or{l}\t{%2, %k0|%k0, %2}"
9249   [(set_attr "type" "alu")
9250    (set_attr "mode" "SI")])
9251
9252 (define_insn "*iorsi_1_zext_imm"
9253   [(set (match_operand:DI 0 "register_operand" "=r")
9254         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9255                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9256    (clobber (reg:CC FLAGS_REG))]
9257   "TARGET_64BIT"
9258   "or{l}\t{%2, %k0|%k0, %2}"
9259   [(set_attr "type" "alu")
9260    (set_attr "mode" "SI")])
9261
9262 (define_insn "*iorsi_2"
9263   [(set (reg FLAGS_REG)
9264         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9265                          (match_operand:SI 2 "general_operand" "g,ri"))
9266                  (const_int 0)))
9267    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9268         (ior:SI (match_dup 1) (match_dup 2)))]
9269   "ix86_match_ccmode (insn, CCNOmode)
9270    && ix86_binary_operator_ok (IOR, SImode, operands)"
9271   "or{l}\t{%2, %0|%0, %2}"
9272   [(set_attr "type" "alu")
9273    (set_attr "mode" "SI")])
9274
9275 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9276 ;; ??? Special case for immediate operand is missing - it is tricky.
9277 (define_insn "*iorsi_2_zext"
9278   [(set (reg FLAGS_REG)
9279         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9280                          (match_operand:SI 2 "general_operand" "g"))
9281                  (const_int 0)))
9282    (set (match_operand:DI 0 "register_operand" "=r")
9283         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9284   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9285    && ix86_binary_operator_ok (IOR, SImode, operands)"
9286   "or{l}\t{%2, %k0|%k0, %2}"
9287   [(set_attr "type" "alu")
9288    (set_attr "mode" "SI")])
9289
9290 (define_insn "*iorsi_2_zext_imm"
9291   [(set (reg FLAGS_REG)
9292         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9293                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9294                  (const_int 0)))
9295    (set (match_operand:DI 0 "register_operand" "=r")
9296         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9297   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9298    && ix86_binary_operator_ok (IOR, SImode, operands)"
9299   "or{l}\t{%2, %k0|%k0, %2}"
9300   [(set_attr "type" "alu")
9301    (set_attr "mode" "SI")])
9302
9303 (define_insn "*iorsi_3"
9304   [(set (reg FLAGS_REG)
9305         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9306                          (match_operand:SI 2 "general_operand" "g"))
9307                  (const_int 0)))
9308    (clobber (match_scratch:SI 0 "=r"))]
9309   "ix86_match_ccmode (insn, CCNOmode)
9310    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9311   "or{l}\t{%2, %0|%0, %2}"
9312   [(set_attr "type" "alu")
9313    (set_attr "mode" "SI")])
9314
9315 (define_expand "iorhi3"
9316   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9317         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9318                 (match_operand:HI 2 "general_operand" "")))
9319    (clobber (reg:CC FLAGS_REG))]
9320   "TARGET_HIMODE_MATH"
9321   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9322
9323 (define_insn "*iorhi_1"
9324   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9325         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9326                 (match_operand:HI 2 "general_operand" "g,ri")))
9327    (clobber (reg:CC FLAGS_REG))]
9328   "ix86_binary_operator_ok (IOR, HImode, operands)"
9329   "or{w}\t{%2, %0|%0, %2}"
9330   [(set_attr "type" "alu")
9331    (set_attr "mode" "HI")])
9332
9333 (define_insn "*iorhi_2"
9334   [(set (reg FLAGS_REG)
9335         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9336                          (match_operand:HI 2 "general_operand" "g,ri"))
9337                  (const_int 0)))
9338    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9339         (ior:HI (match_dup 1) (match_dup 2)))]
9340   "ix86_match_ccmode (insn, CCNOmode)
9341    && ix86_binary_operator_ok (IOR, HImode, operands)"
9342   "or{w}\t{%2, %0|%0, %2}"
9343   [(set_attr "type" "alu")
9344    (set_attr "mode" "HI")])
9345
9346 (define_insn "*iorhi_3"
9347   [(set (reg FLAGS_REG)
9348         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9349                          (match_operand:HI 2 "general_operand" "g"))
9350                  (const_int 0)))
9351    (clobber (match_scratch:HI 0 "=r"))]
9352   "ix86_match_ccmode (insn, CCNOmode)
9353    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9354   "or{w}\t{%2, %0|%0, %2}"
9355   [(set_attr "type" "alu")
9356    (set_attr "mode" "HI")])
9357
9358 (define_expand "iorqi3"
9359   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9360         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9361                 (match_operand:QI 2 "general_operand" "")))
9362    (clobber (reg:CC FLAGS_REG))]
9363   "TARGET_QIMODE_MATH"
9364   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9365
9366 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9367 (define_insn "*iorqi_1"
9368   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9369         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9370                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9371    (clobber (reg:CC FLAGS_REG))]
9372   "ix86_binary_operator_ok (IOR, QImode, operands)"
9373   "@
9374    or{b}\t{%2, %0|%0, %2}
9375    or{b}\t{%2, %0|%0, %2}
9376    or{l}\t{%k2, %k0|%k0, %k2}"
9377   [(set_attr "type" "alu")
9378    (set_attr "mode" "QI,QI,SI")])
9379
9380 (define_insn "*iorqi_1_slp"
9381   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9382         (ior:QI (match_dup 0)
9383                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9384    (clobber (reg:CC FLAGS_REG))]
9385   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9386    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9387   "or{b}\t{%1, %0|%0, %1}"
9388   [(set_attr "type" "alu1")
9389    (set_attr "mode" "QI")])
9390
9391 (define_insn "*iorqi_2"
9392   [(set (reg FLAGS_REG)
9393         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9394                          (match_operand:QI 2 "general_operand" "qim,qi"))
9395                  (const_int 0)))
9396    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9397         (ior:QI (match_dup 1) (match_dup 2)))]
9398   "ix86_match_ccmode (insn, CCNOmode)
9399    && ix86_binary_operator_ok (IOR, QImode, operands)"
9400   "or{b}\t{%2, %0|%0, %2}"
9401   [(set_attr "type" "alu")
9402    (set_attr "mode" "QI")])
9403
9404 (define_insn "*iorqi_2_slp"
9405   [(set (reg FLAGS_REG)
9406         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9407                          (match_operand:QI 1 "general_operand" "qim,qi"))
9408                  (const_int 0)))
9409    (set (strict_low_part (match_dup 0))
9410         (ior:QI (match_dup 0) (match_dup 1)))]
9411   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9412    && ix86_match_ccmode (insn, CCNOmode)
9413    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9414   "or{b}\t{%1, %0|%0, %1}"
9415   [(set_attr "type" "alu1")
9416    (set_attr "mode" "QI")])
9417
9418 (define_insn "*iorqi_3"
9419   [(set (reg FLAGS_REG)
9420         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9421                          (match_operand:QI 2 "general_operand" "qim"))
9422                  (const_int 0)))
9423    (clobber (match_scratch:QI 0 "=q"))]
9424   "ix86_match_ccmode (insn, CCNOmode)
9425    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9426   "or{b}\t{%2, %0|%0, %2}"
9427   [(set_attr "type" "alu")
9428    (set_attr "mode" "QI")])
9429
9430 (define_insn "iorqi_ext_0"
9431   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9432                          (const_int 8)
9433                          (const_int 8))
9434         (ior:SI
9435           (zero_extract:SI
9436             (match_operand 1 "ext_register_operand" "0")
9437             (const_int 8)
9438             (const_int 8))
9439           (match_operand 2 "const_int_operand" "n")))
9440    (clobber (reg:CC FLAGS_REG))]
9441   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9442   "or{b}\t{%2, %h0|%h0, %2}"
9443   [(set_attr "type" "alu")
9444    (set_attr "length_immediate" "1")
9445    (set_attr "mode" "QI")])
9446
9447 (define_insn "*iorqi_ext_1"
9448   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9449                          (const_int 8)
9450                          (const_int 8))
9451         (ior:SI
9452           (zero_extract:SI
9453             (match_operand 1 "ext_register_operand" "0")
9454             (const_int 8)
9455             (const_int 8))
9456           (zero_extend:SI
9457             (match_operand:QI 2 "general_operand" "Qm"))))
9458    (clobber (reg:CC FLAGS_REG))]
9459   "!TARGET_64BIT
9460    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9461   "or{b}\t{%2, %h0|%h0, %2}"
9462   [(set_attr "type" "alu")
9463    (set_attr "length_immediate" "0")
9464    (set_attr "mode" "QI")])
9465
9466 (define_insn "*iorqi_ext_1_rex64"
9467   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9468                          (const_int 8)
9469                          (const_int 8))
9470         (ior:SI
9471           (zero_extract:SI
9472             (match_operand 1 "ext_register_operand" "0")
9473             (const_int 8)
9474             (const_int 8))
9475           (zero_extend:SI
9476             (match_operand 2 "ext_register_operand" "Q"))))
9477    (clobber (reg:CC FLAGS_REG))]
9478   "TARGET_64BIT
9479    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9480   "or{b}\t{%2, %h0|%h0, %2}"
9481   [(set_attr "type" "alu")
9482    (set_attr "length_immediate" "0")
9483    (set_attr "mode" "QI")])
9484
9485 (define_insn "*iorqi_ext_2"
9486   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9487                          (const_int 8)
9488                          (const_int 8))
9489         (ior:SI
9490           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9491                            (const_int 8)
9492                            (const_int 8))
9493           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9494                            (const_int 8)
9495                            (const_int 8))))
9496    (clobber (reg:CC FLAGS_REG))]
9497   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9498   "ior{b}\t{%h2, %h0|%h0, %h2}"
9499   [(set_attr "type" "alu")
9500    (set_attr "length_immediate" "0")
9501    (set_attr "mode" "QI")])
9502
9503 (define_split
9504   [(set (match_operand 0 "register_operand" "")
9505         (ior (match_operand 1 "register_operand" "")
9506              (match_operand 2 "const_int_operand" "")))
9507    (clobber (reg:CC FLAGS_REG))]
9508    "reload_completed
9509     && QI_REG_P (operands[0])
9510     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9511     && !(INTVAL (operands[2]) & ~(255 << 8))
9512     && GET_MODE (operands[0]) != QImode"
9513   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9514                    (ior:SI (zero_extract:SI (match_dup 1)
9515                                             (const_int 8) (const_int 8))
9516                            (match_dup 2)))
9517               (clobber (reg:CC FLAGS_REG))])]
9518   "operands[0] = gen_lowpart (SImode, operands[0]);
9519    operands[1] = gen_lowpart (SImode, operands[1]);
9520    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9521
9522 ;; Since OR can be encoded with sign extended immediate, this is only
9523 ;; profitable when 7th bit is set.
9524 (define_split
9525   [(set (match_operand 0 "register_operand" "")
9526         (ior (match_operand 1 "general_operand" "")
9527              (match_operand 2 "const_int_operand" "")))
9528    (clobber (reg:CC FLAGS_REG))]
9529    "reload_completed
9530     && ANY_QI_REG_P (operands[0])
9531     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9532     && !(INTVAL (operands[2]) & ~255)
9533     && (INTVAL (operands[2]) & 128)
9534     && GET_MODE (operands[0]) != QImode"
9535   [(parallel [(set (strict_low_part (match_dup 0))
9536                    (ior:QI (match_dup 1)
9537                            (match_dup 2)))
9538               (clobber (reg:CC FLAGS_REG))])]
9539   "operands[0] = gen_lowpart (QImode, operands[0]);
9540    operands[1] = gen_lowpart (QImode, operands[1]);
9541    operands[2] = gen_lowpart (QImode, operands[2]);")
9542 \f
9543 ;; Logical XOR instructions
9544
9545 ;; %%% This used to optimize known byte-wide and operations to memory.
9546 ;; If this is considered useful, it should be done with splitters.
9547
9548 (define_expand "xordi3"
9549   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9550         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9551                 (match_operand:DI 2 "x86_64_general_operand" "")))
9552    (clobber (reg:CC FLAGS_REG))]
9553   "TARGET_64BIT"
9554   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9555
9556 (define_insn "*xordi_1_rex64"
9557   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9558         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9559                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9560    (clobber (reg:CC FLAGS_REG))]
9561   "TARGET_64BIT
9562    && ix86_binary_operator_ok (XOR, DImode, operands)"
9563   "@
9564    xor{q}\t{%2, %0|%0, %2}
9565    xor{q}\t{%2, %0|%0, %2}"
9566   [(set_attr "type" "alu")
9567    (set_attr "mode" "DI,DI")])
9568
9569 (define_insn "*xordi_2_rex64"
9570   [(set (reg FLAGS_REG)
9571         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9572                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9573                  (const_int 0)))
9574    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9575         (xor:DI (match_dup 1) (match_dup 2)))]
9576   "TARGET_64BIT
9577    && ix86_match_ccmode (insn, CCNOmode)
9578    && ix86_binary_operator_ok (XOR, DImode, operands)"
9579   "@
9580    xor{q}\t{%2, %0|%0, %2}
9581    xor{q}\t{%2, %0|%0, %2}"
9582   [(set_attr "type" "alu")
9583    (set_attr "mode" "DI,DI")])
9584
9585 (define_insn "*xordi_3_rex64"
9586   [(set (reg FLAGS_REG)
9587         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9588                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9589                  (const_int 0)))
9590    (clobber (match_scratch:DI 0 "=r"))]
9591   "TARGET_64BIT
9592    && ix86_match_ccmode (insn, CCNOmode)
9593    && ix86_binary_operator_ok (XOR, DImode, operands)"
9594   "xor{q}\t{%2, %0|%0, %2}"
9595   [(set_attr "type" "alu")
9596    (set_attr "mode" "DI")])
9597
9598 (define_expand "xorsi3"
9599   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9600         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9601                 (match_operand:SI 2 "general_operand" "")))
9602    (clobber (reg:CC FLAGS_REG))]
9603   ""
9604   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9605
9606 (define_insn "*xorsi_1"
9607   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9608         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9609                 (match_operand:SI 2 "general_operand" "ri,rm")))
9610    (clobber (reg:CC FLAGS_REG))]
9611   "ix86_binary_operator_ok (XOR, SImode, operands)"
9612   "xor{l}\t{%2, %0|%0, %2}"
9613   [(set_attr "type" "alu")
9614    (set_attr "mode" "SI")])
9615
9616 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9617 ;; Add speccase for immediates
9618 (define_insn "*xorsi_1_zext"
9619   [(set (match_operand:DI 0 "register_operand" "=r")
9620         (zero_extend:DI
9621           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9622                   (match_operand:SI 2 "general_operand" "g"))))
9623    (clobber (reg:CC FLAGS_REG))]
9624   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9625   "xor{l}\t{%2, %k0|%k0, %2}"
9626   [(set_attr "type" "alu")
9627    (set_attr "mode" "SI")])
9628
9629 (define_insn "*xorsi_1_zext_imm"
9630   [(set (match_operand:DI 0 "register_operand" "=r")
9631         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9632                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9633    (clobber (reg:CC FLAGS_REG))]
9634   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9635   "xor{l}\t{%2, %k0|%k0, %2}"
9636   [(set_attr "type" "alu")
9637    (set_attr "mode" "SI")])
9638
9639 (define_insn "*xorsi_2"
9640   [(set (reg FLAGS_REG)
9641         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9642                          (match_operand:SI 2 "general_operand" "g,ri"))
9643                  (const_int 0)))
9644    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9645         (xor:SI (match_dup 1) (match_dup 2)))]
9646   "ix86_match_ccmode (insn, CCNOmode)
9647    && ix86_binary_operator_ok (XOR, SImode, operands)"
9648   "xor{l}\t{%2, %0|%0, %2}"
9649   [(set_attr "type" "alu")
9650    (set_attr "mode" "SI")])
9651
9652 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9653 ;; ??? Special case for immediate operand is missing - it is tricky.
9654 (define_insn "*xorsi_2_zext"
9655   [(set (reg FLAGS_REG)
9656         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9657                          (match_operand:SI 2 "general_operand" "g"))
9658                  (const_int 0)))
9659    (set (match_operand:DI 0 "register_operand" "=r")
9660         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9661   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9662    && ix86_binary_operator_ok (XOR, SImode, operands)"
9663   "xor{l}\t{%2, %k0|%k0, %2}"
9664   [(set_attr "type" "alu")
9665    (set_attr "mode" "SI")])
9666
9667 (define_insn "*xorsi_2_zext_imm"
9668   [(set (reg FLAGS_REG)
9669         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9670                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9671                  (const_int 0)))
9672    (set (match_operand:DI 0 "register_operand" "=r")
9673         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9674   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9675    && ix86_binary_operator_ok (XOR, SImode, operands)"
9676   "xor{l}\t{%2, %k0|%k0, %2}"
9677   [(set_attr "type" "alu")
9678    (set_attr "mode" "SI")])
9679
9680 (define_insn "*xorsi_3"
9681   [(set (reg FLAGS_REG)
9682         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9683                          (match_operand:SI 2 "general_operand" "g"))
9684                  (const_int 0)))
9685    (clobber (match_scratch:SI 0 "=r"))]
9686   "ix86_match_ccmode (insn, CCNOmode)
9687    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9688   "xor{l}\t{%2, %0|%0, %2}"
9689   [(set_attr "type" "alu")
9690    (set_attr "mode" "SI")])
9691
9692 (define_expand "xorhi3"
9693   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9694         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9695                 (match_operand:HI 2 "general_operand" "")))
9696    (clobber (reg:CC FLAGS_REG))]
9697   "TARGET_HIMODE_MATH"
9698   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9699
9700 (define_insn "*xorhi_1"
9701   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9702         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9703                 (match_operand:HI 2 "general_operand" "g,ri")))
9704    (clobber (reg:CC FLAGS_REG))]
9705   "ix86_binary_operator_ok (XOR, HImode, operands)"
9706   "xor{w}\t{%2, %0|%0, %2}"
9707   [(set_attr "type" "alu")
9708    (set_attr "mode" "HI")])
9709
9710 (define_insn "*xorhi_2"
9711   [(set (reg FLAGS_REG)
9712         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9713                          (match_operand:HI 2 "general_operand" "g,ri"))
9714                  (const_int 0)))
9715    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9716         (xor:HI (match_dup 1) (match_dup 2)))]
9717   "ix86_match_ccmode (insn, CCNOmode)
9718    && ix86_binary_operator_ok (XOR, HImode, operands)"
9719   "xor{w}\t{%2, %0|%0, %2}"
9720   [(set_attr "type" "alu")
9721    (set_attr "mode" "HI")])
9722
9723 (define_insn "*xorhi_3"
9724   [(set (reg FLAGS_REG)
9725         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9726                          (match_operand:HI 2 "general_operand" "g"))
9727                  (const_int 0)))
9728    (clobber (match_scratch:HI 0 "=r"))]
9729   "ix86_match_ccmode (insn, CCNOmode)
9730    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9731   "xor{w}\t{%2, %0|%0, %2}"
9732   [(set_attr "type" "alu")
9733    (set_attr "mode" "HI")])
9734
9735 (define_expand "xorqi3"
9736   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9737         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9738                 (match_operand:QI 2 "general_operand" "")))
9739    (clobber (reg:CC FLAGS_REG))]
9740   "TARGET_QIMODE_MATH"
9741   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9742
9743 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9744 (define_insn "*xorqi_1"
9745   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9746         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9747                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9748    (clobber (reg:CC FLAGS_REG))]
9749   "ix86_binary_operator_ok (XOR, QImode, operands)"
9750   "@
9751    xor{b}\t{%2, %0|%0, %2}
9752    xor{b}\t{%2, %0|%0, %2}
9753    xor{l}\t{%k2, %k0|%k0, %k2}"
9754   [(set_attr "type" "alu")
9755    (set_attr "mode" "QI,QI,SI")])
9756
9757 (define_insn "*xorqi_1_slp"
9758   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9759         (xor:QI (match_dup 0)
9760                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9761    (clobber (reg:CC FLAGS_REG))]
9762   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9763    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9764   "xor{b}\t{%1, %0|%0, %1}"
9765   [(set_attr "type" "alu1")
9766    (set_attr "mode" "QI")])
9767
9768 (define_insn "xorqi_ext_0"
9769   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9770                          (const_int 8)
9771                          (const_int 8))
9772         (xor:SI
9773           (zero_extract:SI
9774             (match_operand 1 "ext_register_operand" "0")
9775             (const_int 8)
9776             (const_int 8))
9777           (match_operand 2 "const_int_operand" "n")))
9778    (clobber (reg:CC FLAGS_REG))]
9779   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9780   "xor{b}\t{%2, %h0|%h0, %2}"
9781   [(set_attr "type" "alu")
9782    (set_attr "length_immediate" "1")
9783    (set_attr "mode" "QI")])
9784
9785 (define_insn "*xorqi_ext_1"
9786   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9787                          (const_int 8)
9788                          (const_int 8))
9789         (xor:SI
9790           (zero_extract:SI
9791             (match_operand 1 "ext_register_operand" "0")
9792             (const_int 8)
9793             (const_int 8))
9794           (zero_extend:SI
9795             (match_operand:QI 2 "general_operand" "Qm"))))
9796    (clobber (reg:CC FLAGS_REG))]
9797   "!TARGET_64BIT
9798    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9799   "xor{b}\t{%2, %h0|%h0, %2}"
9800   [(set_attr "type" "alu")
9801    (set_attr "length_immediate" "0")
9802    (set_attr "mode" "QI")])
9803
9804 (define_insn "*xorqi_ext_1_rex64"
9805   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9806                          (const_int 8)
9807                          (const_int 8))
9808         (xor:SI
9809           (zero_extract:SI
9810             (match_operand 1 "ext_register_operand" "0")
9811             (const_int 8)
9812             (const_int 8))
9813           (zero_extend:SI
9814             (match_operand 2 "ext_register_operand" "Q"))))
9815    (clobber (reg:CC FLAGS_REG))]
9816   "TARGET_64BIT
9817    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9818   "xor{b}\t{%2, %h0|%h0, %2}"
9819   [(set_attr "type" "alu")
9820    (set_attr "length_immediate" "0")
9821    (set_attr "mode" "QI")])
9822
9823 (define_insn "*xorqi_ext_2"
9824   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9825                          (const_int 8)
9826                          (const_int 8))
9827         (xor:SI
9828           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9829                            (const_int 8)
9830                            (const_int 8))
9831           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9832                            (const_int 8)
9833                            (const_int 8))))
9834    (clobber (reg:CC FLAGS_REG))]
9835   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9836   "xor{b}\t{%h2, %h0|%h0, %h2}"
9837   [(set_attr "type" "alu")
9838    (set_attr "length_immediate" "0")
9839    (set_attr "mode" "QI")])
9840
9841 (define_insn "*xorqi_cc_1"
9842   [(set (reg FLAGS_REG)
9843         (compare
9844           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9845                   (match_operand:QI 2 "general_operand" "qim,qi"))
9846           (const_int 0)))
9847    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9848         (xor:QI (match_dup 1) (match_dup 2)))]
9849   "ix86_match_ccmode (insn, CCNOmode)
9850    && ix86_binary_operator_ok (XOR, QImode, operands)"
9851   "xor{b}\t{%2, %0|%0, %2}"
9852   [(set_attr "type" "alu")
9853    (set_attr "mode" "QI")])
9854
9855 (define_insn "*xorqi_2_slp"
9856   [(set (reg FLAGS_REG)
9857         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9858                          (match_operand:QI 1 "general_operand" "qim,qi"))
9859                  (const_int 0)))
9860    (set (strict_low_part (match_dup 0))
9861         (xor:QI (match_dup 0) (match_dup 1)))]
9862   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9863    && ix86_match_ccmode (insn, CCNOmode)
9864    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9865   "xor{b}\t{%1, %0|%0, %1}"
9866   [(set_attr "type" "alu1")
9867    (set_attr "mode" "QI")])
9868
9869 (define_insn "*xorqi_cc_2"
9870   [(set (reg FLAGS_REG)
9871         (compare
9872           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9873                   (match_operand:QI 2 "general_operand" "qim"))
9874           (const_int 0)))
9875    (clobber (match_scratch:QI 0 "=q"))]
9876   "ix86_match_ccmode (insn, CCNOmode)
9877    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9878   "xor{b}\t{%2, %0|%0, %2}"
9879   [(set_attr "type" "alu")
9880    (set_attr "mode" "QI")])
9881
9882 (define_insn "*xorqi_cc_ext_1"
9883   [(set (reg FLAGS_REG)
9884         (compare
9885           (xor:SI
9886             (zero_extract:SI
9887               (match_operand 1 "ext_register_operand" "0")
9888               (const_int 8)
9889               (const_int 8))
9890             (match_operand:QI 2 "general_operand" "qmn"))
9891           (const_int 0)))
9892    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9893                          (const_int 8)
9894                          (const_int 8))
9895         (xor:SI
9896           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9897           (match_dup 2)))]
9898   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9899   "xor{b}\t{%2, %h0|%h0, %2}"
9900   [(set_attr "type" "alu")
9901    (set_attr "mode" "QI")])
9902
9903 (define_insn "*xorqi_cc_ext_1_rex64"
9904   [(set (reg FLAGS_REG)
9905         (compare
9906           (xor:SI
9907             (zero_extract:SI
9908               (match_operand 1 "ext_register_operand" "0")
9909               (const_int 8)
9910               (const_int 8))
9911             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9912           (const_int 0)))
9913    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9914                          (const_int 8)
9915                          (const_int 8))
9916         (xor:SI
9917           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9918           (match_dup 2)))]
9919   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9920   "xor{b}\t{%2, %h0|%h0, %2}"
9921   [(set_attr "type" "alu")
9922    (set_attr "mode" "QI")])
9923
9924 (define_expand "xorqi_cc_ext_1"
9925   [(parallel [
9926      (set (reg:CCNO FLAGS_REG)
9927           (compare:CCNO
9928             (xor:SI
9929               (zero_extract:SI
9930                 (match_operand 1 "ext_register_operand" "")
9931                 (const_int 8)
9932                 (const_int 8))
9933               (match_operand:QI 2 "general_operand" ""))
9934             (const_int 0)))
9935      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9936                            (const_int 8)
9937                            (const_int 8))
9938           (xor:SI
9939             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9940             (match_dup 2)))])]
9941   ""
9942   "")
9943
9944 (define_split
9945   [(set (match_operand 0 "register_operand" "")
9946         (xor (match_operand 1 "register_operand" "")
9947              (match_operand 2 "const_int_operand" "")))
9948    (clobber (reg:CC FLAGS_REG))]
9949    "reload_completed
9950     && QI_REG_P (operands[0])
9951     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9952     && !(INTVAL (operands[2]) & ~(255 << 8))
9953     && GET_MODE (operands[0]) != QImode"
9954   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9955                    (xor:SI (zero_extract:SI (match_dup 1)
9956                                             (const_int 8) (const_int 8))
9957                            (match_dup 2)))
9958               (clobber (reg:CC FLAGS_REG))])]
9959   "operands[0] = gen_lowpart (SImode, operands[0]);
9960    operands[1] = gen_lowpart (SImode, operands[1]);
9961    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9962
9963 ;; Since XOR can be encoded with sign extended immediate, this is only
9964 ;; profitable when 7th bit is set.
9965 (define_split
9966   [(set (match_operand 0 "register_operand" "")
9967         (xor (match_operand 1 "general_operand" "")
9968              (match_operand 2 "const_int_operand" "")))
9969    (clobber (reg:CC FLAGS_REG))]
9970    "reload_completed
9971     && ANY_QI_REG_P (operands[0])
9972     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9973     && !(INTVAL (operands[2]) & ~255)
9974     && (INTVAL (operands[2]) & 128)
9975     && GET_MODE (operands[0]) != QImode"
9976   [(parallel [(set (strict_low_part (match_dup 0))
9977                    (xor:QI (match_dup 1)
9978                            (match_dup 2)))
9979               (clobber (reg:CC FLAGS_REG))])]
9980   "operands[0] = gen_lowpart (QImode, operands[0]);
9981    operands[1] = gen_lowpart (QImode, operands[1]);
9982    operands[2] = gen_lowpart (QImode, operands[2]);")
9983 \f
9984 ;; Negation instructions
9985
9986 (define_expand "negti2"
9987   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9988                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9989               (clobber (reg:CC FLAGS_REG))])]
9990   "TARGET_64BIT"
9991   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9992
9993 (define_insn "*negti2_1"
9994   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9995         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9996    (clobber (reg:CC FLAGS_REG))]
9997   "TARGET_64BIT
9998    && ix86_unary_operator_ok (NEG, TImode, operands)"
9999   "#")
10000
10001 (define_split
10002   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10003         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10004    (clobber (reg:CC FLAGS_REG))]
10005   "TARGET_64BIT && reload_completed"
10006   [(parallel
10007     [(set (reg:CCZ FLAGS_REG)
10008           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10009      (set (match_dup 0) (neg:DI (match_dup 2)))])
10010    (parallel
10011     [(set (match_dup 1)
10012           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10013                             (match_dup 3))
10014                    (const_int 0)))
10015      (clobber (reg:CC FLAGS_REG))])
10016    (parallel
10017     [(set (match_dup 1)
10018           (neg:DI (match_dup 1)))
10019      (clobber (reg:CC FLAGS_REG))])]
10020   "split_ti (operands+1, 1, operands+2, operands+3);
10021    split_ti (operands+0, 1, operands+0, operands+1);")
10022
10023 (define_expand "negdi2"
10024   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10025                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10026               (clobber (reg:CC FLAGS_REG))])]
10027   ""
10028   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10029
10030 (define_insn "*negdi2_1"
10031   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10032         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10033    (clobber (reg:CC FLAGS_REG))]
10034   "!TARGET_64BIT
10035    && ix86_unary_operator_ok (NEG, DImode, operands)"
10036   "#")
10037
10038 (define_split
10039   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10040         (neg:DI (match_operand:DI 1 "general_operand" "")))
10041    (clobber (reg:CC FLAGS_REG))]
10042   "!TARGET_64BIT && reload_completed"
10043   [(parallel
10044     [(set (reg:CCZ FLAGS_REG)
10045           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10046      (set (match_dup 0) (neg:SI (match_dup 2)))])
10047    (parallel
10048     [(set (match_dup 1)
10049           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10050                             (match_dup 3))
10051                    (const_int 0)))
10052      (clobber (reg:CC FLAGS_REG))])
10053    (parallel
10054     [(set (match_dup 1)
10055           (neg:SI (match_dup 1)))
10056      (clobber (reg:CC FLAGS_REG))])]
10057   "split_di (operands+1, 1, operands+2, operands+3);
10058    split_di (operands+0, 1, operands+0, operands+1);")
10059
10060 (define_insn "*negdi2_1_rex64"
10061   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10062         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10063    (clobber (reg:CC FLAGS_REG))]
10064   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10065   "neg{q}\t%0"
10066   [(set_attr "type" "negnot")
10067    (set_attr "mode" "DI")])
10068
10069 ;; The problem with neg is that it does not perform (compare x 0),
10070 ;; it really performs (compare 0 x), which leaves us with the zero
10071 ;; flag being the only useful item.
10072
10073 (define_insn "*negdi2_cmpz_rex64"
10074   [(set (reg:CCZ FLAGS_REG)
10075         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10076                      (const_int 0)))
10077    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10078         (neg:DI (match_dup 1)))]
10079   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10080   "neg{q}\t%0"
10081   [(set_attr "type" "negnot")
10082    (set_attr "mode" "DI")])
10083
10084
10085 (define_expand "negsi2"
10086   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10087                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10088               (clobber (reg:CC FLAGS_REG))])]
10089   ""
10090   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10091
10092 (define_insn "*negsi2_1"
10093   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10094         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10095    (clobber (reg:CC FLAGS_REG))]
10096   "ix86_unary_operator_ok (NEG, SImode, operands)"
10097   "neg{l}\t%0"
10098   [(set_attr "type" "negnot")
10099    (set_attr "mode" "SI")])
10100
10101 ;; Combine is quite creative about this pattern.
10102 (define_insn "*negsi2_1_zext"
10103   [(set (match_operand:DI 0 "register_operand" "=r")
10104         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10105                                         (const_int 32)))
10106                      (const_int 32)))
10107    (clobber (reg:CC FLAGS_REG))]
10108   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10109   "neg{l}\t%k0"
10110   [(set_attr "type" "negnot")
10111    (set_attr "mode" "SI")])
10112
10113 ;; The problem with neg is that it does not perform (compare x 0),
10114 ;; it really performs (compare 0 x), which leaves us with the zero
10115 ;; flag being the only useful item.
10116
10117 (define_insn "*negsi2_cmpz"
10118   [(set (reg:CCZ FLAGS_REG)
10119         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10120                      (const_int 0)))
10121    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10122         (neg:SI (match_dup 1)))]
10123   "ix86_unary_operator_ok (NEG, SImode, operands)"
10124   "neg{l}\t%0"
10125   [(set_attr "type" "negnot")
10126    (set_attr "mode" "SI")])
10127
10128 (define_insn "*negsi2_cmpz_zext"
10129   [(set (reg:CCZ FLAGS_REG)
10130         (compare:CCZ (lshiftrt:DI
10131                        (neg:DI (ashift:DI
10132                                  (match_operand:DI 1 "register_operand" "0")
10133                                  (const_int 32)))
10134                        (const_int 32))
10135                      (const_int 0)))
10136    (set (match_operand:DI 0 "register_operand" "=r")
10137         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10138                                         (const_int 32)))
10139                      (const_int 32)))]
10140   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10141   "neg{l}\t%k0"
10142   [(set_attr "type" "negnot")
10143    (set_attr "mode" "SI")])
10144
10145 (define_expand "neghi2"
10146   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10147                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10148               (clobber (reg:CC FLAGS_REG))])]
10149   "TARGET_HIMODE_MATH"
10150   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10151
10152 (define_insn "*neghi2_1"
10153   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10154         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10155    (clobber (reg:CC FLAGS_REG))]
10156   "ix86_unary_operator_ok (NEG, HImode, operands)"
10157   "neg{w}\t%0"
10158   [(set_attr "type" "negnot")
10159    (set_attr "mode" "HI")])
10160
10161 (define_insn "*neghi2_cmpz"
10162   [(set (reg:CCZ FLAGS_REG)
10163         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10164                      (const_int 0)))
10165    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10166         (neg:HI (match_dup 1)))]
10167   "ix86_unary_operator_ok (NEG, HImode, operands)"
10168   "neg{w}\t%0"
10169   [(set_attr "type" "negnot")
10170    (set_attr "mode" "HI")])
10171
10172 (define_expand "negqi2"
10173   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10174                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10175               (clobber (reg:CC FLAGS_REG))])]
10176   "TARGET_QIMODE_MATH"
10177   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10178
10179 (define_insn "*negqi2_1"
10180   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10181         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10182    (clobber (reg:CC FLAGS_REG))]
10183   "ix86_unary_operator_ok (NEG, QImode, operands)"
10184   "neg{b}\t%0"
10185   [(set_attr "type" "negnot")
10186    (set_attr "mode" "QI")])
10187
10188 (define_insn "*negqi2_cmpz"
10189   [(set (reg:CCZ FLAGS_REG)
10190         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10191                      (const_int 0)))
10192    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10193         (neg:QI (match_dup 1)))]
10194   "ix86_unary_operator_ok (NEG, QImode, operands)"
10195   "neg{b}\t%0"
10196   [(set_attr "type" "negnot")
10197    (set_attr "mode" "QI")])
10198
10199 ;; Changing of sign for FP values is doable using integer unit too.
10200
10201 (define_expand "negsf2"
10202   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10203         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10204   "TARGET_80387 || TARGET_SSE_MATH"
10205   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
10206
10207 (define_expand "abssf2"
10208   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10209         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10210   "TARGET_80387 || TARGET_SSE_MATH"
10211   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
10212
10213 (define_insn "*absnegsf2_mixed"
10214   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
10215         (match_operator:SF 3 "absneg_operator"
10216           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
10217    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
10218    (clobber (reg:CC FLAGS_REG))]
10219   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10220    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10221   "#")
10222
10223 (define_insn "*absnegsf2_sse"
10224   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
10225         (match_operator:SF 3 "absneg_operator"
10226           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
10227    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
10228    (clobber (reg:CC FLAGS_REG))]
10229   "TARGET_SSE_MATH
10230    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10231   "#")
10232
10233 (define_insn "*absnegsf2_i387"
10234   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
10235         (match_operator:SF 3 "absneg_operator"
10236           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
10237    (use (match_operand 2 "" ""))
10238    (clobber (reg:CC FLAGS_REG))]
10239   "TARGET_80387 && !TARGET_SSE_MATH
10240    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10241   "#")
10242
10243 (define_expand "negdf2"
10244   [(set (match_operand:DF 0 "nonimmediate_operand" "")
10245         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10246   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10247   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
10248
10249 (define_expand "absdf2"
10250   [(set (match_operand:DF 0 "nonimmediate_operand" "")
10251         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10252   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10253   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
10254
10255 (define_insn "*absnegdf2_mixed"
10256   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
10257         (match_operator:DF 3 "absneg_operator"
10258           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
10259    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
10260    (clobber (reg:CC FLAGS_REG))]
10261   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10262    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10263   "#")
10264
10265 (define_insn "*absnegdf2_sse"
10266   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
10267         (match_operator:DF 3 "absneg_operator"
10268           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10269    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
10270    (clobber (reg:CC FLAGS_REG))]
10271   "TARGET_SSE2 && TARGET_SSE_MATH
10272    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10273   "#")
10274
10275 (define_insn "*absnegdf2_i387"
10276   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10277         (match_operator:DF 3 "absneg_operator"
10278           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10279    (use (match_operand 2 "" ""))
10280    (clobber (reg:CC FLAGS_REG))]
10281   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10282    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10283   "#")
10284
10285 (define_expand "negxf2"
10286   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10287         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10288   "TARGET_80387"
10289   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10290
10291 (define_expand "absxf2"
10292   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10293         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10294   "TARGET_80387"
10295   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10296
10297 (define_insn "*absnegxf2_i387"
10298   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10299         (match_operator:XF 3 "absneg_operator"
10300           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10301    (use (match_operand 2 "" ""))
10302    (clobber (reg:CC FLAGS_REG))]
10303   "TARGET_80387
10304    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10305   "#")
10306
10307 (define_expand "negtf2"
10308   [(set (match_operand:TF 0 "nonimmediate_operand" "")
10309         (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
10310   "TARGET_64BIT"
10311   "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10312
10313 (define_expand "abstf2"
10314   [(set (match_operand:TF 0 "nonimmediate_operand" "")
10315         (abs:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
10316   "TARGET_64BIT"
10317   "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10318
10319 (define_insn "*absnegtf2_sse"
10320   [(set (match_operand:TF 0 "nonimmediate_operand"    "=x,x,m")
10321         (match_operator:TF 3 "absneg_operator"
10322           [(match_operand:TF 1 "nonimmediate_operand" "0, x,0")]))
10323    (use (match_operand:TF 2 "nonimmediate_operand"    "xm,0,X"))
10324    (clobber (reg:CC FLAGS_REG))]
10325   "TARGET_64BIT
10326    && ix86_unary_operator_ok (GET_CODE (operands[3]), TFmode, operands)"
10327   "#")
10328
10329 ;; Splitters for fp abs and neg.
10330
10331 (define_split
10332   [(set (match_operand 0 "fp_register_operand" "")
10333         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10334    (use (match_operand 2 "" ""))
10335    (clobber (reg:CC FLAGS_REG))]
10336   "reload_completed"
10337   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10338
10339 (define_split
10340   [(set (match_operand 0 "register_operand" "")
10341         (match_operator 3 "absneg_operator"
10342           [(match_operand 1 "register_operand" "")]))
10343    (use (match_operand 2 "nonimmediate_operand" ""))
10344    (clobber (reg:CC FLAGS_REG))]
10345   "reload_completed && SSE_REG_P (operands[0])"
10346   [(set (match_dup 0) (match_dup 3))]
10347 {
10348   enum machine_mode mode = GET_MODE (operands[0]);
10349   enum machine_mode vmode = GET_MODE (operands[2]);
10350   rtx tmp;
10351
10352   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10353   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10354   if (operands_match_p (operands[0], operands[2]))
10355     {
10356       tmp = operands[1];
10357       operands[1] = operands[2];
10358       operands[2] = tmp;
10359     }
10360   if (GET_CODE (operands[3]) == ABS)
10361     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10362   else
10363     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10364   operands[3] = tmp;
10365 })
10366
10367 (define_split
10368   [(set (match_operand:SF 0 "register_operand" "")
10369         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10370    (use (match_operand:V4SF 2 "" ""))
10371    (clobber (reg:CC FLAGS_REG))]
10372   "reload_completed"
10373   [(parallel [(set (match_dup 0) (match_dup 1))
10374               (clobber (reg:CC FLAGS_REG))])]
10375 {
10376   rtx tmp;
10377   operands[0] = gen_lowpart (SImode, operands[0]);
10378   if (GET_CODE (operands[1]) == ABS)
10379     {
10380       tmp = gen_int_mode (0x7fffffff, SImode);
10381       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10382     }
10383   else
10384     {
10385       tmp = gen_int_mode (0x80000000, SImode);
10386       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10387     }
10388   operands[1] = tmp;
10389 })
10390
10391 (define_split
10392   [(set (match_operand:DF 0 "register_operand" "")
10393         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10394    (use (match_operand 2 "" ""))
10395    (clobber (reg:CC FLAGS_REG))]
10396   "reload_completed"
10397   [(parallel [(set (match_dup 0) (match_dup 1))
10398               (clobber (reg:CC FLAGS_REG))])]
10399 {
10400   rtx tmp;
10401   if (TARGET_64BIT)
10402     {
10403       tmp = gen_lowpart (DImode, operands[0]);
10404       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10405       operands[0] = tmp;
10406
10407       if (GET_CODE (operands[1]) == ABS)
10408         tmp = const0_rtx;
10409       else
10410         tmp = gen_rtx_NOT (DImode, tmp);
10411     }
10412   else
10413     {
10414       operands[0] = gen_highpart (SImode, operands[0]);
10415       if (GET_CODE (operands[1]) == ABS)
10416         {
10417           tmp = gen_int_mode (0x7fffffff, SImode);
10418           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10419         }
10420       else
10421         {
10422           tmp = gen_int_mode (0x80000000, SImode);
10423           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10424         }
10425     }
10426   operands[1] = tmp;
10427 })
10428
10429 (define_split
10430   [(set (match_operand:XF 0 "register_operand" "")
10431         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10432    (use (match_operand 2 "" ""))
10433    (clobber (reg:CC FLAGS_REG))]
10434   "reload_completed"
10435   [(parallel [(set (match_dup 0) (match_dup 1))
10436               (clobber (reg:CC FLAGS_REG))])]
10437 {
10438   rtx tmp;
10439   operands[0] = gen_rtx_REG (SImode,
10440                              true_regnum (operands[0])
10441                              + (TARGET_64BIT ? 1 : 2));
10442   if (GET_CODE (operands[1]) == ABS)
10443     {
10444       tmp = GEN_INT (0x7fff);
10445       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10446     }
10447   else
10448     {
10449       tmp = GEN_INT (0x8000);
10450       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10451     }
10452   operands[1] = tmp;
10453 })
10454
10455 (define_split
10456   [(set (match_operand 0 "memory_operand" "")
10457         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10458    (use (match_operand 2 "" ""))
10459    (clobber (reg:CC FLAGS_REG))]
10460   "reload_completed"
10461   [(parallel [(set (match_dup 0) (match_dup 1))
10462               (clobber (reg:CC FLAGS_REG))])]
10463 {
10464   enum machine_mode mode = GET_MODE (operands[0]);
10465   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10466   rtx tmp;
10467
10468   operands[0] = adjust_address (operands[0], QImode, size - 1);
10469   if (GET_CODE (operands[1]) == ABS)
10470     {
10471       tmp = gen_int_mode (0x7f, QImode);
10472       tmp = gen_rtx_AND (QImode, operands[0], tmp);
10473     }
10474   else
10475     {
10476       tmp = gen_int_mode (0x80, QImode);
10477       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10478     }
10479   operands[1] = tmp;
10480 })
10481
10482 ;; Conditionalize these after reload. If they match before reload, we
10483 ;; lose the clobber and ability to use integer instructions.
10484
10485 (define_insn "*negsf2_1"
10486   [(set (match_operand:SF 0 "register_operand" "=f")
10487         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10488   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10489   "fchs"
10490   [(set_attr "type" "fsgn")
10491    (set_attr "mode" "SF")])
10492
10493 (define_insn "*negdf2_1"
10494   [(set (match_operand:DF 0 "register_operand" "=f")
10495         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10496   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10497   "fchs"
10498   [(set_attr "type" "fsgn")
10499    (set_attr "mode" "DF")])
10500
10501 (define_insn "*negxf2_1"
10502   [(set (match_operand:XF 0 "register_operand" "=f")
10503         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10504   "TARGET_80387"
10505   "fchs"
10506   [(set_attr "type" "fsgn")
10507    (set_attr "mode" "XF")])
10508
10509 (define_insn "*abssf2_1"
10510   [(set (match_operand:SF 0 "register_operand" "=f")
10511         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10512   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10513   "fabs"
10514   [(set_attr "type" "fsgn")
10515    (set_attr "mode" "SF")])
10516
10517 (define_insn "*absdf2_1"
10518   [(set (match_operand:DF 0 "register_operand" "=f")
10519         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10520   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10521   "fabs"
10522   [(set_attr "type" "fsgn")
10523    (set_attr "mode" "DF")])
10524
10525 (define_insn "*absxf2_1"
10526   [(set (match_operand:XF 0 "register_operand" "=f")
10527         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10528   "TARGET_80387"
10529   "fabs"
10530   [(set_attr "type" "fsgn")
10531    (set_attr "mode" "DF")])
10532
10533 (define_insn "*negextendsfdf2"
10534   [(set (match_operand:DF 0 "register_operand" "=f")
10535         (neg:DF (float_extend:DF
10536                   (match_operand:SF 1 "register_operand" "0"))))]
10537   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10538   "fchs"
10539   [(set_attr "type" "fsgn")
10540    (set_attr "mode" "DF")])
10541
10542 (define_insn "*negextenddfxf2"
10543   [(set (match_operand:XF 0 "register_operand" "=f")
10544         (neg:XF (float_extend:XF
10545                   (match_operand:DF 1 "register_operand" "0"))))]
10546   "TARGET_80387"
10547   "fchs"
10548   [(set_attr "type" "fsgn")
10549    (set_attr "mode" "XF")])
10550
10551 (define_insn "*negextendsfxf2"
10552   [(set (match_operand:XF 0 "register_operand" "=f")
10553         (neg:XF (float_extend:XF
10554                   (match_operand:SF 1 "register_operand" "0"))))]
10555   "TARGET_80387"
10556   "fchs"
10557   [(set_attr "type" "fsgn")
10558    (set_attr "mode" "XF")])
10559
10560 (define_insn "*absextendsfdf2"
10561   [(set (match_operand:DF 0 "register_operand" "=f")
10562         (abs:DF (float_extend:DF
10563                   (match_operand:SF 1 "register_operand" "0"))))]
10564   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10565   "fabs"
10566   [(set_attr "type" "fsgn")
10567    (set_attr "mode" "DF")])
10568
10569 (define_insn "*absextenddfxf2"
10570   [(set (match_operand:XF 0 "register_operand" "=f")
10571         (abs:XF (float_extend:XF
10572           (match_operand:DF 1 "register_operand" "0"))))]
10573   "TARGET_80387"
10574   "fabs"
10575   [(set_attr "type" "fsgn")
10576    (set_attr "mode" "XF")])
10577
10578 (define_insn "*absextendsfxf2"
10579   [(set (match_operand:XF 0 "register_operand" "=f")
10580         (abs:XF (float_extend:XF
10581           (match_operand:SF 1 "register_operand" "0"))))]
10582   "TARGET_80387"
10583   "fabs"
10584   [(set_attr "type" "fsgn")
10585    (set_attr "mode" "XF")])
10586
10587 ;; Copysign instructions
10588
10589 (define_mode_iterator CSGNMODE [SF DF TF])
10590 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10591
10592 (define_expand "copysign<mode>3"
10593   [(match_operand:CSGNMODE 0 "register_operand" "")
10594    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10595    (match_operand:CSGNMODE 2 "register_operand" "")]
10596   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10597    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10598 {
10599   ix86_expand_copysign (operands);
10600   DONE;
10601 })
10602
10603 (define_insn_and_split "copysign<mode>3_const"
10604   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10605         (unspec:CSGNMODE
10606           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10607            (match_operand:CSGNMODE 2 "register_operand" "0")
10608            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10609           UNSPEC_COPYSIGN))]
10610   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10611    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10612   "#"
10613   "&& reload_completed"
10614   [(const_int 0)]
10615 {
10616   ix86_split_copysign_const (operands);
10617   DONE;
10618 })
10619
10620 (define_insn "copysign<mode>3_var"
10621   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10622         (unspec:CSGNMODE
10623           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10624            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10625            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10626            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10627           UNSPEC_COPYSIGN))
10628    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10629   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10630    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10631   "#")
10632
10633 (define_split
10634   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10635         (unspec:CSGNMODE
10636           [(match_operand:CSGNMODE 2 "register_operand" "")
10637            (match_operand:CSGNMODE 3 "register_operand" "")
10638            (match_operand:<CSGNVMODE> 4 "" "")
10639            (match_operand:<CSGNVMODE> 5 "" "")]
10640           UNSPEC_COPYSIGN))
10641    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10642   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10643     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10644    && reload_completed"
10645   [(const_int 0)]
10646 {
10647   ix86_split_copysign_var (operands);
10648   DONE;
10649 })
10650 \f
10651 ;; One complement instructions
10652
10653 (define_expand "one_cmpldi2"
10654   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10655         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10656   "TARGET_64BIT"
10657   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10658
10659 (define_insn "*one_cmpldi2_1_rex64"
10660   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10661         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10662   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10663   "not{q}\t%0"
10664   [(set_attr "type" "negnot")
10665    (set_attr "mode" "DI")])
10666
10667 (define_insn "*one_cmpldi2_2_rex64"
10668   [(set (reg FLAGS_REG)
10669         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10670                  (const_int 0)))
10671    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10672         (not:DI (match_dup 1)))]
10673   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10674    && ix86_unary_operator_ok (NOT, DImode, operands)"
10675   "#"
10676   [(set_attr "type" "alu1")
10677    (set_attr "mode" "DI")])
10678
10679 (define_split
10680   [(set (match_operand 0 "flags_reg_operand" "")
10681         (match_operator 2 "compare_operator"
10682           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10683            (const_int 0)]))
10684    (set (match_operand:DI 1 "nonimmediate_operand" "")
10685         (not:DI (match_dup 3)))]
10686   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10687   [(parallel [(set (match_dup 0)
10688                    (match_op_dup 2
10689                      [(xor:DI (match_dup 3) (const_int -1))
10690                       (const_int 0)]))
10691               (set (match_dup 1)
10692                    (xor:DI (match_dup 3) (const_int -1)))])]
10693   "")
10694
10695 (define_expand "one_cmplsi2"
10696   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10697         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10698   ""
10699   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10700
10701 (define_insn "*one_cmplsi2_1"
10702   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10703         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10704   "ix86_unary_operator_ok (NOT, SImode, operands)"
10705   "not{l}\t%0"
10706   [(set_attr "type" "negnot")
10707    (set_attr "mode" "SI")])
10708
10709 ;; ??? Currently never generated - xor is used instead.
10710 (define_insn "*one_cmplsi2_1_zext"
10711   [(set (match_operand:DI 0 "register_operand" "=r")
10712         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10713   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10714   "not{l}\t%k0"
10715   [(set_attr "type" "negnot")
10716    (set_attr "mode" "SI")])
10717
10718 (define_insn "*one_cmplsi2_2"
10719   [(set (reg FLAGS_REG)
10720         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10721                  (const_int 0)))
10722    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10723         (not:SI (match_dup 1)))]
10724   "ix86_match_ccmode (insn, CCNOmode)
10725    && ix86_unary_operator_ok (NOT, SImode, operands)"
10726   "#"
10727   [(set_attr "type" "alu1")
10728    (set_attr "mode" "SI")])
10729
10730 (define_split
10731   [(set (match_operand 0 "flags_reg_operand" "")
10732         (match_operator 2 "compare_operator"
10733           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10734            (const_int 0)]))
10735    (set (match_operand:SI 1 "nonimmediate_operand" "")
10736         (not:SI (match_dup 3)))]
10737   "ix86_match_ccmode (insn, CCNOmode)"
10738   [(parallel [(set (match_dup 0)
10739                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10740                                     (const_int 0)]))
10741               (set (match_dup 1)
10742                    (xor:SI (match_dup 3) (const_int -1)))])]
10743   "")
10744
10745 ;; ??? Currently never generated - xor is used instead.
10746 (define_insn "*one_cmplsi2_2_zext"
10747   [(set (reg FLAGS_REG)
10748         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10749                  (const_int 0)))
10750    (set (match_operand:DI 0 "register_operand" "=r")
10751         (zero_extend:DI (not:SI (match_dup 1))))]
10752   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10753    && ix86_unary_operator_ok (NOT, SImode, operands)"
10754   "#"
10755   [(set_attr "type" "alu1")
10756    (set_attr "mode" "SI")])
10757
10758 (define_split
10759   [(set (match_operand 0 "flags_reg_operand" "")
10760         (match_operator 2 "compare_operator"
10761           [(not:SI (match_operand:SI 3 "register_operand" ""))
10762            (const_int 0)]))
10763    (set (match_operand:DI 1 "register_operand" "")
10764         (zero_extend:DI (not:SI (match_dup 3))))]
10765   "ix86_match_ccmode (insn, CCNOmode)"
10766   [(parallel [(set (match_dup 0)
10767                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10768                                     (const_int 0)]))
10769               (set (match_dup 1)
10770                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10771   "")
10772
10773 (define_expand "one_cmplhi2"
10774   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10775         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10776   "TARGET_HIMODE_MATH"
10777   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10778
10779 (define_insn "*one_cmplhi2_1"
10780   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10781         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10782   "ix86_unary_operator_ok (NOT, HImode, operands)"
10783   "not{w}\t%0"
10784   [(set_attr "type" "negnot")
10785    (set_attr "mode" "HI")])
10786
10787 (define_insn "*one_cmplhi2_2"
10788   [(set (reg FLAGS_REG)
10789         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10790                  (const_int 0)))
10791    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10792         (not:HI (match_dup 1)))]
10793   "ix86_match_ccmode (insn, CCNOmode)
10794    && ix86_unary_operator_ok (NEG, HImode, operands)"
10795   "#"
10796   [(set_attr "type" "alu1")
10797    (set_attr "mode" "HI")])
10798
10799 (define_split
10800   [(set (match_operand 0 "flags_reg_operand" "")
10801         (match_operator 2 "compare_operator"
10802           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10803            (const_int 0)]))
10804    (set (match_operand:HI 1 "nonimmediate_operand" "")
10805         (not:HI (match_dup 3)))]
10806   "ix86_match_ccmode (insn, CCNOmode)"
10807   [(parallel [(set (match_dup 0)
10808                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10809                                     (const_int 0)]))
10810               (set (match_dup 1)
10811                    (xor:HI (match_dup 3) (const_int -1)))])]
10812   "")
10813
10814 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10815 (define_expand "one_cmplqi2"
10816   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10817         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10818   "TARGET_QIMODE_MATH"
10819   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10820
10821 (define_insn "*one_cmplqi2_1"
10822   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10823         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10824   "ix86_unary_operator_ok (NOT, QImode, operands)"
10825   "@
10826    not{b}\t%0
10827    not{l}\t%k0"
10828   [(set_attr "type" "negnot")
10829    (set_attr "mode" "QI,SI")])
10830
10831 (define_insn "*one_cmplqi2_2"
10832   [(set (reg FLAGS_REG)
10833         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10834                  (const_int 0)))
10835    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10836         (not:QI (match_dup 1)))]
10837   "ix86_match_ccmode (insn, CCNOmode)
10838    && ix86_unary_operator_ok (NOT, QImode, operands)"
10839   "#"
10840   [(set_attr "type" "alu1")
10841    (set_attr "mode" "QI")])
10842
10843 (define_split
10844   [(set (match_operand 0 "flags_reg_operand" "")
10845         (match_operator 2 "compare_operator"
10846           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10847            (const_int 0)]))
10848    (set (match_operand:QI 1 "nonimmediate_operand" "")
10849         (not:QI (match_dup 3)))]
10850   "ix86_match_ccmode (insn, CCNOmode)"
10851   [(parallel [(set (match_dup 0)
10852                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10853                                     (const_int 0)]))
10854               (set (match_dup 1)
10855                    (xor:QI (match_dup 3) (const_int -1)))])]
10856   "")
10857 \f
10858 ;; Arithmetic shift instructions
10859
10860 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10861 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10862 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10863 ;; from the assembler input.
10864 ;;
10865 ;; This instruction shifts the target reg/mem as usual, but instead of
10866 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10867 ;; is a left shift double, bits are taken from the high order bits of
10868 ;; reg, else if the insn is a shift right double, bits are taken from the
10869 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10870 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10871 ;;
10872 ;; Since sh[lr]d does not change the `reg' operand, that is done
10873 ;; separately, making all shifts emit pairs of shift double and normal
10874 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10875 ;; support a 63 bit shift, each shift where the count is in a reg expands
10876 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10877 ;;
10878 ;; If the shift count is a constant, we need never emit more than one
10879 ;; shift pair, instead using moves and sign extension for counts greater
10880 ;; than 31.
10881
10882 (define_expand "ashlti3"
10883   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10884                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10885                               (match_operand:QI 2 "nonmemory_operand" "")))
10886               (clobber (reg:CC FLAGS_REG))])]
10887   "TARGET_64BIT"
10888 {
10889   if (! immediate_operand (operands[2], QImode))
10890     {
10891       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10892       DONE;
10893     }
10894   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10895   DONE;
10896 })
10897
10898 (define_insn "ashlti3_1"
10899   [(set (match_operand:TI 0 "register_operand" "=r")
10900         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10901                    (match_operand:QI 2 "register_operand" "c")))
10902    (clobber (match_scratch:DI 3 "=&r"))
10903    (clobber (reg:CC FLAGS_REG))]
10904   "TARGET_64BIT"
10905   "#"
10906   [(set_attr "type" "multi")])
10907
10908 ;; This pattern must be defined before *ashlti3_2 to prevent
10909 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10910
10911 (define_insn "sse2_ashlti3"
10912   [(set (match_operand:TI 0 "register_operand" "=x")
10913         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10914                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10915   "TARGET_SSE2"
10916 {
10917   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10918   return "pslldq\t{%2, %0|%0, %2}";
10919 }
10920   [(set_attr "type" "sseishft")
10921    (set_attr "prefix_data16" "1")
10922    (set_attr "mode" "TI")])
10923
10924 (define_insn "*ashlti3_2"
10925   [(set (match_operand:TI 0 "register_operand" "=r")
10926         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10927                    (match_operand:QI 2 "immediate_operand" "O")))
10928    (clobber (reg:CC FLAGS_REG))]
10929   "TARGET_64BIT"
10930   "#"
10931   [(set_attr "type" "multi")])
10932
10933 (define_split
10934   [(set (match_operand:TI 0 "register_operand" "")
10935         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10936                    (match_operand:QI 2 "register_operand" "")))
10937    (clobber (match_scratch:DI 3 ""))
10938    (clobber (reg:CC FLAGS_REG))]
10939   "TARGET_64BIT && reload_completed"
10940   [(const_int 0)]
10941   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10942
10943 (define_split
10944   [(set (match_operand:TI 0 "register_operand" "")
10945         (ashift:TI (match_operand:TI 1 "register_operand" "")
10946                    (match_operand:QI 2 "immediate_operand" "")))
10947    (clobber (reg:CC FLAGS_REG))]
10948   "TARGET_64BIT && reload_completed"
10949   [(const_int 0)]
10950   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10951
10952 (define_insn "x86_64_shld"
10953   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10954         (ior:DI (ashift:DI (match_dup 0)
10955                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10956                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10957                   (minus:QI (const_int 64) (match_dup 2)))))
10958    (clobber (reg:CC FLAGS_REG))]
10959   "TARGET_64BIT"
10960   "@
10961    shld{q}\t{%2, %1, %0|%0, %1, %2}
10962    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10963   [(set_attr "type" "ishift")
10964    (set_attr "prefix_0f" "1")
10965    (set_attr "mode" "DI")
10966    (set_attr "athlon_decode" "vector")
10967    (set_attr "amdfam10_decode" "vector")])   
10968
10969 (define_expand "x86_64_shift_adj"
10970   [(set (reg:CCZ FLAGS_REG)
10971         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10972                              (const_int 64))
10973                      (const_int 0)))
10974    (set (match_operand:DI 0 "register_operand" "")
10975         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10976                          (match_operand:DI 1 "register_operand" "")
10977                          (match_dup 0)))
10978    (set (match_dup 1)
10979         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10980                          (match_operand:DI 3 "register_operand" "r")
10981                          (match_dup 1)))]
10982   "TARGET_64BIT"
10983   "")
10984
10985 (define_expand "ashldi3"
10986   [(set (match_operand:DI 0 "shiftdi_operand" "")
10987         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10988                    (match_operand:QI 2 "nonmemory_operand" "")))]
10989   ""
10990   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10991
10992 (define_insn "*ashldi3_1_rex64"
10993   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10994         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10995                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10996    (clobber (reg:CC FLAGS_REG))]
10997   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10998 {
10999   switch (get_attr_type (insn))
11000     {
11001     case TYPE_ALU:
11002       gcc_assert (operands[2] == const1_rtx);
11003       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11004       return "add{q}\t%0, %0";
11005
11006     case TYPE_LEA:
11007       gcc_assert (CONST_INT_P (operands[2]));
11008       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11009       operands[1] = gen_rtx_MULT (DImode, operands[1],
11010                                   GEN_INT (1 << INTVAL (operands[2])));
11011       return "lea{q}\t{%a1, %0|%0, %a1}";
11012
11013     default:
11014       if (REG_P (operands[2]))
11015         return "sal{q}\t{%b2, %0|%0, %b2}";
11016       else if (operands[2] == const1_rtx
11017                && (TARGET_SHIFT1 || optimize_size))
11018         return "sal{q}\t%0";
11019       else
11020         return "sal{q}\t{%2, %0|%0, %2}";
11021     }
11022 }
11023   [(set (attr "type")
11024      (cond [(eq_attr "alternative" "1")
11025               (const_string "lea")
11026             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11027                           (const_int 0))
11028                       (match_operand 0 "register_operand" ""))
11029                  (match_operand 2 "const1_operand" ""))
11030               (const_string "alu")
11031            ]
11032            (const_string "ishift")))
11033    (set_attr "mode" "DI")])
11034
11035 ;; Convert lea to the lea pattern to avoid flags dependency.
11036 (define_split
11037   [(set (match_operand:DI 0 "register_operand" "")
11038         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11039                    (match_operand:QI 2 "immediate_operand" "")))
11040    (clobber (reg:CC FLAGS_REG))]
11041   "TARGET_64BIT && reload_completed
11042    && true_regnum (operands[0]) != true_regnum (operands[1])"
11043   [(set (match_dup 0)
11044         (mult:DI (match_dup 1)
11045                  (match_dup 2)))]
11046   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11047
11048 ;; This pattern can't accept a variable shift count, since shifts by
11049 ;; zero don't affect the flags.  We assume that shifts by constant
11050 ;; zero are optimized away.
11051 (define_insn "*ashldi3_cmp_rex64"
11052   [(set (reg FLAGS_REG)
11053         (compare
11054           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11055                      (match_operand:QI 2 "immediate_operand" "e"))
11056           (const_int 0)))
11057    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11058         (ashift:DI (match_dup 1) (match_dup 2)))]
11059   "TARGET_64BIT
11060    && (optimize_size
11061        || !TARGET_PARTIAL_FLAG_REG_STALL
11062        || (operands[2] == const1_rtx
11063            && (TARGET_SHIFT1
11064                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11065    && ix86_match_ccmode (insn, CCGOCmode)
11066    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11067 {
11068   switch (get_attr_type (insn))
11069     {
11070     case TYPE_ALU:
11071       gcc_assert (operands[2] == const1_rtx);
11072       return "add{q}\t%0, %0";
11073
11074     default:
11075       if (REG_P (operands[2]))
11076         return "sal{q}\t{%b2, %0|%0, %b2}";
11077       else if (operands[2] == const1_rtx
11078                && (TARGET_SHIFT1 || optimize_size))
11079         return "sal{q}\t%0";
11080       else
11081         return "sal{q}\t{%2, %0|%0, %2}";
11082     }
11083 }
11084   [(set (attr "type")
11085      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11086                           (const_int 0))
11087                       (match_operand 0 "register_operand" ""))
11088                  (match_operand 2 "const1_operand" ""))
11089               (const_string "alu")
11090            ]
11091            (const_string "ishift")))
11092    (set_attr "mode" "DI")])
11093
11094 (define_insn "*ashldi3_cconly_rex64"
11095   [(set (reg FLAGS_REG)
11096         (compare
11097           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11098                      (match_operand:QI 2 "immediate_operand" "e"))
11099           (const_int 0)))
11100    (clobber (match_scratch:DI 0 "=r"))]
11101   "TARGET_64BIT
11102    && (optimize_size
11103        || !TARGET_PARTIAL_FLAG_REG_STALL
11104        || (operands[2] == const1_rtx
11105            && (TARGET_SHIFT1
11106                || TARGET_DOUBLE_WITH_ADD)))
11107    && ix86_match_ccmode (insn, CCGOCmode)
11108    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11109 {
11110   switch (get_attr_type (insn))
11111     {
11112     case TYPE_ALU:
11113       gcc_assert (operands[2] == const1_rtx);
11114       return "add{q}\t%0, %0";
11115
11116     default:
11117       if (REG_P (operands[2]))
11118         return "sal{q}\t{%b2, %0|%0, %b2}";
11119       else if (operands[2] == const1_rtx
11120                && (TARGET_SHIFT1 || optimize_size))
11121         return "sal{q}\t%0";
11122       else
11123         return "sal{q}\t{%2, %0|%0, %2}";
11124     }
11125 }
11126   [(set (attr "type")
11127      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11128                           (const_int 0))
11129                       (match_operand 0 "register_operand" ""))
11130                  (match_operand 2 "const1_operand" ""))
11131               (const_string "alu")
11132            ]
11133            (const_string "ishift")))
11134    (set_attr "mode" "DI")])
11135
11136 (define_insn "*ashldi3_1"
11137   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11138         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11139                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11140    (clobber (reg:CC FLAGS_REG))]
11141   "!TARGET_64BIT"
11142   "#"
11143   [(set_attr "type" "multi")])
11144
11145 ;; By default we don't ask for a scratch register, because when DImode
11146 ;; values are manipulated, registers are already at a premium.  But if
11147 ;; we have one handy, we won't turn it away.
11148 (define_peephole2
11149   [(match_scratch:SI 3 "r")
11150    (parallel [(set (match_operand:DI 0 "register_operand" "")
11151                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11152                               (match_operand:QI 2 "nonmemory_operand" "")))
11153               (clobber (reg:CC FLAGS_REG))])
11154    (match_dup 3)]
11155   "!TARGET_64BIT && TARGET_CMOVE"
11156   [(const_int 0)]
11157   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11158
11159 (define_split
11160   [(set (match_operand:DI 0 "register_operand" "")
11161         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11162                    (match_operand:QI 2 "nonmemory_operand" "")))
11163    (clobber (reg:CC FLAGS_REG))]
11164   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11165                      ? epilogue_completed : reload_completed)"
11166   [(const_int 0)]
11167   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11168
11169 (define_insn "x86_shld_1"
11170   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11171         (ior:SI (ashift:SI (match_dup 0)
11172                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11173                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11174                   (minus:QI (const_int 32) (match_dup 2)))))
11175    (clobber (reg:CC FLAGS_REG))]
11176   ""
11177   "@
11178    shld{l}\t{%2, %1, %0|%0, %1, %2}
11179    shld{l}\t{%s2%1, %0|%0, %1, %2}"
11180   [(set_attr "type" "ishift")
11181    (set_attr "prefix_0f" "1")
11182    (set_attr "mode" "SI")
11183    (set_attr "pent_pair" "np")
11184    (set_attr "athlon_decode" "vector")
11185    (set_attr "amdfam10_decode" "vector")])   
11186
11187 (define_expand "x86_shift_adj_1"
11188   [(set (reg:CCZ FLAGS_REG)
11189         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11190                              (const_int 32))
11191                      (const_int 0)))
11192    (set (match_operand:SI 0 "register_operand" "")
11193         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11194                          (match_operand:SI 1 "register_operand" "")
11195                          (match_dup 0)))
11196    (set (match_dup 1)
11197         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11198                          (match_operand:SI 3 "register_operand" "r")
11199                          (match_dup 1)))]
11200   "TARGET_CMOVE"
11201   "")
11202
11203 (define_expand "x86_shift_adj_2"
11204   [(use (match_operand:SI 0 "register_operand" ""))
11205    (use (match_operand:SI 1 "register_operand" ""))
11206    (use (match_operand:QI 2 "register_operand" ""))]
11207   ""
11208 {
11209   rtx label = gen_label_rtx ();
11210   rtx tmp;
11211
11212   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11213
11214   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11215   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11216   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11217                               gen_rtx_LABEL_REF (VOIDmode, label),
11218                               pc_rtx);
11219   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11220   JUMP_LABEL (tmp) = label;
11221
11222   emit_move_insn (operands[0], operands[1]);
11223   ix86_expand_clear (operands[1]);
11224
11225   emit_label (label);
11226   LABEL_NUSES (label) = 1;
11227
11228   DONE;
11229 })
11230
11231 (define_expand "ashlsi3"
11232   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11233         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11234                    (match_operand:QI 2 "nonmemory_operand" "")))
11235    (clobber (reg:CC FLAGS_REG))]
11236   ""
11237   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11238
11239 (define_insn "*ashlsi3_1"
11240   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11241         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11242                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11243    (clobber (reg:CC FLAGS_REG))]
11244   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11245 {
11246   switch (get_attr_type (insn))
11247     {
11248     case TYPE_ALU:
11249       gcc_assert (operands[2] == const1_rtx);
11250       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11251       return "add{l}\t%0, %0";
11252
11253     case TYPE_LEA:
11254       return "#";
11255
11256     default:
11257       if (REG_P (operands[2]))
11258         return "sal{l}\t{%b2, %0|%0, %b2}";
11259       else if (operands[2] == const1_rtx
11260                && (TARGET_SHIFT1 || optimize_size))
11261         return "sal{l}\t%0";
11262       else
11263         return "sal{l}\t{%2, %0|%0, %2}";
11264     }
11265 }
11266   [(set (attr "type")
11267      (cond [(eq_attr "alternative" "1")
11268               (const_string "lea")
11269             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11270                           (const_int 0))
11271                       (match_operand 0 "register_operand" ""))
11272                  (match_operand 2 "const1_operand" ""))
11273               (const_string "alu")
11274            ]
11275            (const_string "ishift")))
11276    (set_attr "mode" "SI")])
11277
11278 ;; Convert lea to the lea pattern to avoid flags dependency.
11279 (define_split
11280   [(set (match_operand 0 "register_operand" "")
11281         (ashift (match_operand 1 "index_register_operand" "")
11282                 (match_operand:QI 2 "const_int_operand" "")))
11283    (clobber (reg:CC FLAGS_REG))]
11284   "reload_completed
11285    && true_regnum (operands[0]) != true_regnum (operands[1])
11286    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11287   [(const_int 0)]
11288 {
11289   rtx pat;
11290   enum machine_mode mode = GET_MODE (operands[0]);
11291
11292   if (GET_MODE_SIZE (mode) < 4)
11293     operands[0] = gen_lowpart (SImode, operands[0]);
11294   if (mode != Pmode)
11295     operands[1] = gen_lowpart (Pmode, operands[1]);
11296   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11297
11298   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11299   if (Pmode != SImode)
11300     pat = gen_rtx_SUBREG (SImode, pat, 0);
11301   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11302   DONE;
11303 })
11304
11305 ;; Rare case of shifting RSP is handled by generating move and shift
11306 (define_split
11307   [(set (match_operand 0 "register_operand" "")
11308         (ashift (match_operand 1 "register_operand" "")
11309                 (match_operand:QI 2 "const_int_operand" "")))
11310    (clobber (reg:CC FLAGS_REG))]
11311   "reload_completed
11312    && true_regnum (operands[0]) != true_regnum (operands[1])"
11313   [(const_int 0)]
11314 {
11315   rtx pat, clob;
11316   emit_move_insn (operands[0], operands[1]);
11317   pat = gen_rtx_SET (VOIDmode, operands[0],
11318                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11319                                      operands[0], operands[2]));
11320   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11321   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11322   DONE;
11323 })
11324
11325 (define_insn "*ashlsi3_1_zext"
11326   [(set (match_operand:DI 0 "register_operand" "=r,r")
11327         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11328                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11329    (clobber (reg:CC FLAGS_REG))]
11330   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11331 {
11332   switch (get_attr_type (insn))
11333     {
11334     case TYPE_ALU:
11335       gcc_assert (operands[2] == const1_rtx);
11336       return "add{l}\t%k0, %k0";
11337
11338     case TYPE_LEA:
11339       return "#";
11340
11341     default:
11342       if (REG_P (operands[2]))
11343         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11344       else if (operands[2] == const1_rtx
11345                && (TARGET_SHIFT1 || optimize_size))
11346         return "sal{l}\t%k0";
11347       else
11348         return "sal{l}\t{%2, %k0|%k0, %2}";
11349     }
11350 }
11351   [(set (attr "type")
11352      (cond [(eq_attr "alternative" "1")
11353               (const_string "lea")
11354             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11355                      (const_int 0))
11356                  (match_operand 2 "const1_operand" ""))
11357               (const_string "alu")
11358            ]
11359            (const_string "ishift")))
11360    (set_attr "mode" "SI")])
11361
11362 ;; Convert lea to the lea pattern to avoid flags dependency.
11363 (define_split
11364   [(set (match_operand:DI 0 "register_operand" "")
11365         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11366                                 (match_operand:QI 2 "const_int_operand" ""))))
11367    (clobber (reg:CC FLAGS_REG))]
11368   "TARGET_64BIT && reload_completed
11369    && true_regnum (operands[0]) != true_regnum (operands[1])"
11370   [(set (match_dup 0) (zero_extend:DI
11371                         (subreg:SI (mult:SI (match_dup 1)
11372                                             (match_dup 2)) 0)))]
11373 {
11374   operands[1] = gen_lowpart (Pmode, operands[1]);
11375   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11376 })
11377
11378 ;; This pattern can't accept a variable shift count, since shifts by
11379 ;; zero don't affect the flags.  We assume that shifts by constant
11380 ;; zero are optimized away.
11381 (define_insn "*ashlsi3_cmp"
11382   [(set (reg FLAGS_REG)
11383         (compare
11384           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11385                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11386           (const_int 0)))
11387    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11388         (ashift:SI (match_dup 1) (match_dup 2)))]
11389    "(optimize_size
11390      || !TARGET_PARTIAL_FLAG_REG_STALL
11391      || (operands[2] == const1_rtx
11392          && (TARGET_SHIFT1
11393              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11394    && ix86_match_ccmode (insn, CCGOCmode)
11395    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11396 {
11397   switch (get_attr_type (insn))
11398     {
11399     case TYPE_ALU:
11400       gcc_assert (operands[2] == const1_rtx);
11401       return "add{l}\t%0, %0";
11402
11403     default:
11404       if (REG_P (operands[2]))
11405         return "sal{l}\t{%b2, %0|%0, %b2}";
11406       else if (operands[2] == const1_rtx
11407                && (TARGET_SHIFT1 || optimize_size))
11408         return "sal{l}\t%0";
11409       else
11410         return "sal{l}\t{%2, %0|%0, %2}";
11411     }
11412 }
11413   [(set (attr "type")
11414      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11415                           (const_int 0))
11416                       (match_operand 0 "register_operand" ""))
11417                  (match_operand 2 "const1_operand" ""))
11418               (const_string "alu")
11419            ]
11420            (const_string "ishift")))
11421    (set_attr "mode" "SI")])
11422
11423 (define_insn "*ashlsi3_cconly"
11424   [(set (reg FLAGS_REG)
11425         (compare
11426           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11427                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11428           (const_int 0)))
11429    (clobber (match_scratch:SI 0 "=r"))]
11430   "(optimize_size
11431     || !TARGET_PARTIAL_FLAG_REG_STALL
11432     || (operands[2] == const1_rtx
11433         && (TARGET_SHIFT1
11434             || TARGET_DOUBLE_WITH_ADD)))
11435    && ix86_match_ccmode (insn, CCGOCmode)
11436    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11437 {
11438   switch (get_attr_type (insn))
11439     {
11440     case TYPE_ALU:
11441       gcc_assert (operands[2] == const1_rtx);
11442       return "add{l}\t%0, %0";
11443
11444     default:
11445       if (REG_P (operands[2]))
11446         return "sal{l}\t{%b2, %0|%0, %b2}";
11447       else if (operands[2] == const1_rtx
11448                && (TARGET_SHIFT1 || optimize_size))
11449         return "sal{l}\t%0";
11450       else
11451         return "sal{l}\t{%2, %0|%0, %2}";
11452     }
11453 }
11454   [(set (attr "type")
11455      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11456                           (const_int 0))
11457                       (match_operand 0 "register_operand" ""))
11458                  (match_operand 2 "const1_operand" ""))
11459               (const_string "alu")
11460            ]
11461            (const_string "ishift")))
11462    (set_attr "mode" "SI")])
11463
11464 (define_insn "*ashlsi3_cmp_zext"
11465   [(set (reg FLAGS_REG)
11466         (compare
11467           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11468                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11469           (const_int 0)))
11470    (set (match_operand:DI 0 "register_operand" "=r")
11471         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11472   "TARGET_64BIT
11473    && (optimize_size
11474        || !TARGET_PARTIAL_FLAG_REG_STALL
11475        || (operands[2] == const1_rtx
11476            && (TARGET_SHIFT1
11477                || TARGET_DOUBLE_WITH_ADD)))
11478    && ix86_match_ccmode (insn, CCGOCmode)
11479    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11480 {
11481   switch (get_attr_type (insn))
11482     {
11483     case TYPE_ALU:
11484       gcc_assert (operands[2] == const1_rtx);
11485       return "add{l}\t%k0, %k0";
11486
11487     default:
11488       if (REG_P (operands[2]))
11489         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11490       else if (operands[2] == const1_rtx
11491                && (TARGET_SHIFT1 || optimize_size))
11492         return "sal{l}\t%k0";
11493       else
11494         return "sal{l}\t{%2, %k0|%k0, %2}";
11495     }
11496 }
11497   [(set (attr "type")
11498      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11499                      (const_int 0))
11500                  (match_operand 2 "const1_operand" ""))
11501               (const_string "alu")
11502            ]
11503            (const_string "ishift")))
11504    (set_attr "mode" "SI")])
11505
11506 (define_expand "ashlhi3"
11507   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11508         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11509                    (match_operand:QI 2 "nonmemory_operand" "")))
11510    (clobber (reg:CC FLAGS_REG))]
11511   "TARGET_HIMODE_MATH"
11512   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11513
11514 (define_insn "*ashlhi3_1_lea"
11515   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11516         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11517                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11518    (clobber (reg:CC FLAGS_REG))]
11519   "!TARGET_PARTIAL_REG_STALL
11520    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11521 {
11522   switch (get_attr_type (insn))
11523     {
11524     case TYPE_LEA:
11525       return "#";
11526     case TYPE_ALU:
11527       gcc_assert (operands[2] == const1_rtx);
11528       return "add{w}\t%0, %0";
11529
11530     default:
11531       if (REG_P (operands[2]))
11532         return "sal{w}\t{%b2, %0|%0, %b2}";
11533       else if (operands[2] == const1_rtx
11534                && (TARGET_SHIFT1 || optimize_size))
11535         return "sal{w}\t%0";
11536       else
11537         return "sal{w}\t{%2, %0|%0, %2}";
11538     }
11539 }
11540   [(set (attr "type")
11541      (cond [(eq_attr "alternative" "1")
11542               (const_string "lea")
11543             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11544                           (const_int 0))
11545                       (match_operand 0 "register_operand" ""))
11546                  (match_operand 2 "const1_operand" ""))
11547               (const_string "alu")
11548            ]
11549            (const_string "ishift")))
11550    (set_attr "mode" "HI,SI")])
11551
11552 (define_insn "*ashlhi3_1"
11553   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11554         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11555                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11556    (clobber (reg:CC FLAGS_REG))]
11557   "TARGET_PARTIAL_REG_STALL
11558    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11559 {
11560   switch (get_attr_type (insn))
11561     {
11562     case TYPE_ALU:
11563       gcc_assert (operands[2] == const1_rtx);
11564       return "add{w}\t%0, %0";
11565
11566     default:
11567       if (REG_P (operands[2]))
11568         return "sal{w}\t{%b2, %0|%0, %b2}";
11569       else if (operands[2] == const1_rtx
11570                && (TARGET_SHIFT1 || optimize_size))
11571         return "sal{w}\t%0";
11572       else
11573         return "sal{w}\t{%2, %0|%0, %2}";
11574     }
11575 }
11576   [(set (attr "type")
11577      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11578                           (const_int 0))
11579                       (match_operand 0 "register_operand" ""))
11580                  (match_operand 2 "const1_operand" ""))
11581               (const_string "alu")
11582            ]
11583            (const_string "ishift")))
11584    (set_attr "mode" "HI")])
11585
11586 ;; This pattern can't accept a variable shift count, since shifts by
11587 ;; zero don't affect the flags.  We assume that shifts by constant
11588 ;; zero are optimized away.
11589 (define_insn "*ashlhi3_cmp"
11590   [(set (reg FLAGS_REG)
11591         (compare
11592           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11593                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11594           (const_int 0)))
11595    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11596         (ashift:HI (match_dup 1) (match_dup 2)))]
11597   "(optimize_size
11598     || !TARGET_PARTIAL_FLAG_REG_STALL
11599     || (operands[2] == const1_rtx
11600         && (TARGET_SHIFT1
11601             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11602    && ix86_match_ccmode (insn, CCGOCmode)
11603    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11604 {
11605   switch (get_attr_type (insn))
11606     {
11607     case TYPE_ALU:
11608       gcc_assert (operands[2] == const1_rtx);
11609       return "add{w}\t%0, %0";
11610
11611     default:
11612       if (REG_P (operands[2]))
11613         return "sal{w}\t{%b2, %0|%0, %b2}";
11614       else if (operands[2] == const1_rtx
11615                && (TARGET_SHIFT1 || optimize_size))
11616         return "sal{w}\t%0";
11617       else
11618         return "sal{w}\t{%2, %0|%0, %2}";
11619     }
11620 }
11621   [(set (attr "type")
11622      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11623                           (const_int 0))
11624                       (match_operand 0 "register_operand" ""))
11625                  (match_operand 2 "const1_operand" ""))
11626               (const_string "alu")
11627            ]
11628            (const_string "ishift")))
11629    (set_attr "mode" "HI")])
11630
11631 (define_insn "*ashlhi3_cconly"
11632   [(set (reg FLAGS_REG)
11633         (compare
11634           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11635                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11636           (const_int 0)))
11637    (clobber (match_scratch:HI 0 "=r"))]
11638   "(optimize_size
11639     || !TARGET_PARTIAL_FLAG_REG_STALL
11640     || (operands[2] == const1_rtx
11641         && (TARGET_SHIFT1
11642             || TARGET_DOUBLE_WITH_ADD)))
11643    && ix86_match_ccmode (insn, CCGOCmode)
11644    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11645 {
11646   switch (get_attr_type (insn))
11647     {
11648     case TYPE_ALU:
11649       gcc_assert (operands[2] == const1_rtx);
11650       return "add{w}\t%0, %0";
11651
11652     default:
11653       if (REG_P (operands[2]))
11654         return "sal{w}\t{%b2, %0|%0, %b2}";
11655       else if (operands[2] == const1_rtx
11656                && (TARGET_SHIFT1 || optimize_size))
11657         return "sal{w}\t%0";
11658       else
11659         return "sal{w}\t{%2, %0|%0, %2}";
11660     }
11661 }
11662   [(set (attr "type")
11663      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11664                           (const_int 0))
11665                       (match_operand 0 "register_operand" ""))
11666                  (match_operand 2 "const1_operand" ""))
11667               (const_string "alu")
11668            ]
11669            (const_string "ishift")))
11670    (set_attr "mode" "HI")])
11671
11672 (define_expand "ashlqi3"
11673   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11674         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11675                    (match_operand:QI 2 "nonmemory_operand" "")))
11676    (clobber (reg:CC FLAGS_REG))]
11677   "TARGET_QIMODE_MATH"
11678   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11679
11680 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11681
11682 (define_insn "*ashlqi3_1_lea"
11683   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11684         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11685                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11686    (clobber (reg:CC FLAGS_REG))]
11687   "!TARGET_PARTIAL_REG_STALL
11688    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11689 {
11690   switch (get_attr_type (insn))
11691     {
11692     case TYPE_LEA:
11693       return "#";
11694     case TYPE_ALU:
11695       gcc_assert (operands[2] == const1_rtx);
11696       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11697         return "add{l}\t%k0, %k0";
11698       else
11699         return "add{b}\t%0, %0";
11700
11701     default:
11702       if (REG_P (operands[2]))
11703         {
11704           if (get_attr_mode (insn) == MODE_SI)
11705             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11706           else
11707             return "sal{b}\t{%b2, %0|%0, %b2}";
11708         }
11709       else if (operands[2] == const1_rtx
11710                && (TARGET_SHIFT1 || optimize_size))
11711         {
11712           if (get_attr_mode (insn) == MODE_SI)
11713             return "sal{l}\t%0";
11714           else
11715             return "sal{b}\t%0";
11716         }
11717       else
11718         {
11719           if (get_attr_mode (insn) == MODE_SI)
11720             return "sal{l}\t{%2, %k0|%k0, %2}";
11721           else
11722             return "sal{b}\t{%2, %0|%0, %2}";
11723         }
11724     }
11725 }
11726   [(set (attr "type")
11727      (cond [(eq_attr "alternative" "2")
11728               (const_string "lea")
11729             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11730                           (const_int 0))
11731                       (match_operand 0 "register_operand" ""))
11732                  (match_operand 2 "const1_operand" ""))
11733               (const_string "alu")
11734            ]
11735            (const_string "ishift")))
11736    (set_attr "mode" "QI,SI,SI")])
11737
11738 (define_insn "*ashlqi3_1"
11739   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11740         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11741                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11742    (clobber (reg:CC FLAGS_REG))]
11743   "TARGET_PARTIAL_REG_STALL
11744    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11745 {
11746   switch (get_attr_type (insn))
11747     {
11748     case TYPE_ALU:
11749       gcc_assert (operands[2] == const1_rtx);
11750       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11751         return "add{l}\t%k0, %k0";
11752       else
11753         return "add{b}\t%0, %0";
11754
11755     default:
11756       if (REG_P (operands[2]))
11757         {
11758           if (get_attr_mode (insn) == MODE_SI)
11759             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11760           else
11761             return "sal{b}\t{%b2, %0|%0, %b2}";
11762         }
11763       else if (operands[2] == const1_rtx
11764                && (TARGET_SHIFT1 || optimize_size))
11765         {
11766           if (get_attr_mode (insn) == MODE_SI)
11767             return "sal{l}\t%0";
11768           else
11769             return "sal{b}\t%0";
11770         }
11771       else
11772         {
11773           if (get_attr_mode (insn) == MODE_SI)
11774             return "sal{l}\t{%2, %k0|%k0, %2}";
11775           else
11776             return "sal{b}\t{%2, %0|%0, %2}";
11777         }
11778     }
11779 }
11780   [(set (attr "type")
11781      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11782                           (const_int 0))
11783                       (match_operand 0 "register_operand" ""))
11784                  (match_operand 2 "const1_operand" ""))
11785               (const_string "alu")
11786            ]
11787            (const_string "ishift")))
11788    (set_attr "mode" "QI,SI")])
11789
11790 ;; This pattern can't accept a variable shift count, since shifts by
11791 ;; zero don't affect the flags.  We assume that shifts by constant
11792 ;; zero are optimized away.
11793 (define_insn "*ashlqi3_cmp"
11794   [(set (reg FLAGS_REG)
11795         (compare
11796           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11797                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11798           (const_int 0)))
11799    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11800         (ashift:QI (match_dup 1) (match_dup 2)))]
11801   "(optimize_size
11802     || !TARGET_PARTIAL_FLAG_REG_STALL
11803     || (operands[2] == const1_rtx
11804         && (TARGET_SHIFT1
11805             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11806    && ix86_match_ccmode (insn, CCGOCmode)
11807    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11808 {
11809   switch (get_attr_type (insn))
11810     {
11811     case TYPE_ALU:
11812       gcc_assert (operands[2] == const1_rtx);
11813       return "add{b}\t%0, %0";
11814
11815     default:
11816       if (REG_P (operands[2]))
11817         return "sal{b}\t{%b2, %0|%0, %b2}";
11818       else if (operands[2] == const1_rtx
11819                && (TARGET_SHIFT1 || optimize_size))
11820         return "sal{b}\t%0";
11821       else
11822         return "sal{b}\t{%2, %0|%0, %2}";
11823     }
11824 }
11825   [(set (attr "type")
11826      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11827                           (const_int 0))
11828                       (match_operand 0 "register_operand" ""))
11829                  (match_operand 2 "const1_operand" ""))
11830               (const_string "alu")
11831            ]
11832            (const_string "ishift")))
11833    (set_attr "mode" "QI")])
11834
11835 (define_insn "*ashlqi3_cconly"
11836   [(set (reg FLAGS_REG)
11837         (compare
11838           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11839                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11840           (const_int 0)))
11841    (clobber (match_scratch:QI 0 "=q"))]
11842   "(optimize_size
11843     || !TARGET_PARTIAL_FLAG_REG_STALL
11844     || (operands[2] == const1_rtx
11845         && (TARGET_SHIFT1
11846             || TARGET_DOUBLE_WITH_ADD)))
11847    && ix86_match_ccmode (insn, CCGOCmode)
11848    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11849 {
11850   switch (get_attr_type (insn))
11851     {
11852     case TYPE_ALU:
11853       gcc_assert (operands[2] == const1_rtx);
11854       return "add{b}\t%0, %0";
11855
11856     default:
11857       if (REG_P (operands[2]))
11858         return "sal{b}\t{%b2, %0|%0, %b2}";
11859       else if (operands[2] == const1_rtx
11860                && (TARGET_SHIFT1 || optimize_size))
11861         return "sal{b}\t%0";
11862       else
11863         return "sal{b}\t{%2, %0|%0, %2}";
11864     }
11865 }
11866   [(set (attr "type")
11867      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11868                           (const_int 0))
11869                       (match_operand 0 "register_operand" ""))
11870                  (match_operand 2 "const1_operand" ""))
11871               (const_string "alu")
11872            ]
11873            (const_string "ishift")))
11874    (set_attr "mode" "QI")])
11875
11876 ;; See comment above `ashldi3' about how this works.
11877
11878 (define_expand "ashrti3"
11879   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11880                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11881                                 (match_operand:QI 2 "nonmemory_operand" "")))
11882               (clobber (reg:CC FLAGS_REG))])]
11883   "TARGET_64BIT"
11884 {
11885   if (! immediate_operand (operands[2], QImode))
11886     {
11887       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11888       DONE;
11889     }
11890   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11891   DONE;
11892 })
11893
11894 (define_insn "ashrti3_1"
11895   [(set (match_operand:TI 0 "register_operand" "=r")
11896         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11897                      (match_operand:QI 2 "register_operand" "c")))
11898    (clobber (match_scratch:DI 3 "=&r"))
11899    (clobber (reg:CC FLAGS_REG))]
11900   "TARGET_64BIT"
11901   "#"
11902   [(set_attr "type" "multi")])
11903
11904 (define_insn "*ashrti3_2"
11905   [(set (match_operand:TI 0 "register_operand" "=r")
11906         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11907                      (match_operand:QI 2 "immediate_operand" "O")))
11908    (clobber (reg:CC FLAGS_REG))]
11909   "TARGET_64BIT"
11910   "#"
11911   [(set_attr "type" "multi")])
11912
11913 (define_split
11914   [(set (match_operand:TI 0 "register_operand" "")
11915         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11916                      (match_operand:QI 2 "register_operand" "")))
11917    (clobber (match_scratch:DI 3 ""))
11918    (clobber (reg:CC FLAGS_REG))]
11919   "TARGET_64BIT && reload_completed"
11920   [(const_int 0)]
11921   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11922
11923 (define_split
11924   [(set (match_operand:TI 0 "register_operand" "")
11925         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11926                      (match_operand:QI 2 "immediate_operand" "")))
11927    (clobber (reg:CC FLAGS_REG))]
11928   "TARGET_64BIT && reload_completed"
11929   [(const_int 0)]
11930   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11931
11932 (define_insn "x86_64_shrd"
11933   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11934         (ior:DI (ashiftrt:DI (match_dup 0)
11935                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11936                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11937                   (minus:QI (const_int 64) (match_dup 2)))))
11938    (clobber (reg:CC FLAGS_REG))]
11939   "TARGET_64BIT"
11940   "@
11941    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11942    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11943   [(set_attr "type" "ishift")
11944    (set_attr "prefix_0f" "1")
11945    (set_attr "mode" "DI")
11946    (set_attr "athlon_decode" "vector")
11947    (set_attr "amdfam10_decode" "vector")])   
11948
11949 (define_expand "ashrdi3"
11950   [(set (match_operand:DI 0 "shiftdi_operand" "")
11951         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11952                      (match_operand:QI 2 "nonmemory_operand" "")))]
11953   ""
11954   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11955
11956 (define_insn "*ashrdi3_63_rex64"
11957   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11958         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11959                      (match_operand:DI 2 "const_int_operand" "i,i")))
11960    (clobber (reg:CC FLAGS_REG))]
11961   "TARGET_64BIT && INTVAL (operands[2]) == 63
11962    && (TARGET_USE_CLTD || optimize_size)
11963    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11964   "@
11965    {cqto|cqo}
11966    sar{q}\t{%2, %0|%0, %2}"
11967   [(set_attr "type" "imovx,ishift")
11968    (set_attr "prefix_0f" "0,*")
11969    (set_attr "length_immediate" "0,*")
11970    (set_attr "modrm" "0,1")
11971    (set_attr "mode" "DI")])
11972
11973 (define_insn "*ashrdi3_1_one_bit_rex64"
11974   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11975         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11976                      (match_operand:QI 2 "const1_operand" "")))
11977    (clobber (reg:CC FLAGS_REG))]
11978   "TARGET_64BIT
11979    && (TARGET_SHIFT1 || optimize_size)
11980    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11981   "sar{q}\t%0"
11982   [(set_attr "type" "ishift")
11983    (set (attr "length")
11984      (if_then_else (match_operand:DI 0 "register_operand" "")
11985         (const_string "2")
11986         (const_string "*")))])
11987
11988 (define_insn "*ashrdi3_1_rex64"
11989   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11990         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11991                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11992    (clobber (reg:CC FLAGS_REG))]
11993   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11994   "@
11995    sar{q}\t{%2, %0|%0, %2}
11996    sar{q}\t{%b2, %0|%0, %b2}"
11997   [(set_attr "type" "ishift")
11998    (set_attr "mode" "DI")])
11999
12000 ;; This pattern can't accept a variable shift count, since shifts by
12001 ;; zero don't affect the flags.  We assume that shifts by constant
12002 ;; zero are optimized away.
12003 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12004   [(set (reg FLAGS_REG)
12005         (compare
12006           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12007                        (match_operand:QI 2 "const1_operand" ""))
12008           (const_int 0)))
12009    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12010         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12011   "TARGET_64BIT
12012    && (TARGET_SHIFT1 || optimize_size)
12013    && ix86_match_ccmode (insn, CCGOCmode)
12014    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12015   "sar{q}\t%0"
12016   [(set_attr "type" "ishift")
12017    (set (attr "length")
12018      (if_then_else (match_operand:DI 0 "register_operand" "")
12019         (const_string "2")
12020         (const_string "*")))])
12021
12022 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12023   [(set (reg FLAGS_REG)
12024         (compare
12025           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12026                        (match_operand:QI 2 "const1_operand" ""))
12027           (const_int 0)))
12028    (clobber (match_scratch:DI 0 "=r"))]
12029   "TARGET_64BIT
12030    && (TARGET_SHIFT1 || optimize_size)
12031    && ix86_match_ccmode (insn, CCGOCmode)
12032    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12033   "sar{q}\t%0"
12034   [(set_attr "type" "ishift")
12035    (set_attr "length" "2")])
12036
12037 ;; This pattern can't accept a variable shift count, since shifts by
12038 ;; zero don't affect the flags.  We assume that shifts by constant
12039 ;; zero are optimized away.
12040 (define_insn "*ashrdi3_cmp_rex64"
12041   [(set (reg FLAGS_REG)
12042         (compare
12043           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12044                        (match_operand:QI 2 "const_int_operand" "n"))
12045           (const_int 0)))
12046    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12047         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12048   "TARGET_64BIT
12049    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12050    && ix86_match_ccmode (insn, CCGOCmode)
12051    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12052   "sar{q}\t{%2, %0|%0, %2}"
12053   [(set_attr "type" "ishift")
12054    (set_attr "mode" "DI")])
12055
12056 (define_insn "*ashrdi3_cconly_rex64"
12057   [(set (reg FLAGS_REG)
12058         (compare
12059           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12060                        (match_operand:QI 2 "const_int_operand" "n"))
12061           (const_int 0)))
12062    (clobber (match_scratch:DI 0 "=r"))]
12063   "TARGET_64BIT
12064    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12065    && ix86_match_ccmode (insn, CCGOCmode)
12066    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12067   "sar{q}\t{%2, %0|%0, %2}"
12068   [(set_attr "type" "ishift")
12069    (set_attr "mode" "DI")])
12070
12071 (define_insn "*ashrdi3_1"
12072   [(set (match_operand:DI 0 "register_operand" "=r")
12073         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12074                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12075    (clobber (reg:CC FLAGS_REG))]
12076   "!TARGET_64BIT"
12077   "#"
12078   [(set_attr "type" "multi")])
12079
12080 ;; By default we don't ask for a scratch register, because when DImode
12081 ;; values are manipulated, registers are already at a premium.  But if
12082 ;; we have one handy, we won't turn it away.
12083 (define_peephole2
12084   [(match_scratch:SI 3 "r")
12085    (parallel [(set (match_operand:DI 0 "register_operand" "")
12086                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12087                                 (match_operand:QI 2 "nonmemory_operand" "")))
12088               (clobber (reg:CC FLAGS_REG))])
12089    (match_dup 3)]
12090   "!TARGET_64BIT && TARGET_CMOVE"
12091   [(const_int 0)]
12092   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12093
12094 (define_split
12095   [(set (match_operand:DI 0 "register_operand" "")
12096         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12097                      (match_operand:QI 2 "nonmemory_operand" "")))
12098    (clobber (reg:CC FLAGS_REG))]
12099   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12100                      ? epilogue_completed : reload_completed)"
12101   [(const_int 0)]
12102   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12103
12104 (define_insn "x86_shrd_1"
12105   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12106         (ior:SI (ashiftrt:SI (match_dup 0)
12107                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
12108                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12109                   (minus:QI (const_int 32) (match_dup 2)))))
12110    (clobber (reg:CC FLAGS_REG))]
12111   ""
12112   "@
12113    shrd{l}\t{%2, %1, %0|%0, %1, %2}
12114    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12115   [(set_attr "type" "ishift")
12116    (set_attr "prefix_0f" "1")
12117    (set_attr "pent_pair" "np")
12118    (set_attr "mode" "SI")])
12119
12120 (define_expand "x86_shift_adj_3"
12121   [(use (match_operand:SI 0 "register_operand" ""))
12122    (use (match_operand:SI 1 "register_operand" ""))
12123    (use (match_operand:QI 2 "register_operand" ""))]
12124   ""
12125 {
12126   rtx label = gen_label_rtx ();
12127   rtx tmp;
12128
12129   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12130
12131   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12132   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12133   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12134                               gen_rtx_LABEL_REF (VOIDmode, label),
12135                               pc_rtx);
12136   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12137   JUMP_LABEL (tmp) = label;
12138
12139   emit_move_insn (operands[0], operands[1]);
12140   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12141
12142   emit_label (label);
12143   LABEL_NUSES (label) = 1;
12144
12145   DONE;
12146 })
12147
12148 (define_insn "ashrsi3_31"
12149   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12150         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12151                      (match_operand:SI 2 "const_int_operand" "i,i")))
12152    (clobber (reg:CC FLAGS_REG))]
12153   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12154    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12155   "@
12156    {cltd|cdq}
12157    sar{l}\t{%2, %0|%0, %2}"
12158   [(set_attr "type" "imovx,ishift")
12159    (set_attr "prefix_0f" "0,*")
12160    (set_attr "length_immediate" "0,*")
12161    (set_attr "modrm" "0,1")
12162    (set_attr "mode" "SI")])
12163
12164 (define_insn "*ashrsi3_31_zext"
12165   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12166         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12167                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12168    (clobber (reg:CC FLAGS_REG))]
12169   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12170    && INTVAL (operands[2]) == 31
12171    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12172   "@
12173    {cltd|cdq}
12174    sar{l}\t{%2, %k0|%k0, %2}"
12175   [(set_attr "type" "imovx,ishift")
12176    (set_attr "prefix_0f" "0,*")
12177    (set_attr "length_immediate" "0,*")
12178    (set_attr "modrm" "0,1")
12179    (set_attr "mode" "SI")])
12180
12181 (define_expand "ashrsi3"
12182   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12183         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12184                      (match_operand:QI 2 "nonmemory_operand" "")))
12185    (clobber (reg:CC FLAGS_REG))]
12186   ""
12187   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12188
12189 (define_insn "*ashrsi3_1_one_bit"
12190   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12191         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12192                      (match_operand:QI 2 "const1_operand" "")))
12193    (clobber (reg:CC FLAGS_REG))]
12194   "(TARGET_SHIFT1 || optimize_size)
12195    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12196   "sar{l}\t%0"
12197   [(set_attr "type" "ishift")
12198    (set (attr "length")
12199      (if_then_else (match_operand:SI 0 "register_operand" "")
12200         (const_string "2")
12201         (const_string "*")))])
12202
12203 (define_insn "*ashrsi3_1_one_bit_zext"
12204   [(set (match_operand:DI 0 "register_operand" "=r")
12205         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12206                                      (match_operand:QI 2 "const1_operand" ""))))
12207    (clobber (reg:CC FLAGS_REG))]
12208   "TARGET_64BIT
12209    && (TARGET_SHIFT1 || optimize_size)
12210    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12211   "sar{l}\t%k0"
12212   [(set_attr "type" "ishift")
12213    (set_attr "length" "2")])
12214
12215 (define_insn "*ashrsi3_1"
12216   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12217         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12218                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12219    (clobber (reg:CC FLAGS_REG))]
12220   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12221   "@
12222    sar{l}\t{%2, %0|%0, %2}
12223    sar{l}\t{%b2, %0|%0, %b2}"
12224   [(set_attr "type" "ishift")
12225    (set_attr "mode" "SI")])
12226
12227 (define_insn "*ashrsi3_1_zext"
12228   [(set (match_operand:DI 0 "register_operand" "=r,r")
12229         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12230                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12231    (clobber (reg:CC FLAGS_REG))]
12232   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12233   "@
12234    sar{l}\t{%2, %k0|%k0, %2}
12235    sar{l}\t{%b2, %k0|%k0, %b2}"
12236   [(set_attr "type" "ishift")
12237    (set_attr "mode" "SI")])
12238
12239 ;; This pattern can't accept a variable shift count, since shifts by
12240 ;; zero don't affect the flags.  We assume that shifts by constant
12241 ;; zero are optimized away.
12242 (define_insn "*ashrsi3_one_bit_cmp"
12243   [(set (reg FLAGS_REG)
12244         (compare
12245           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12246                        (match_operand:QI 2 "const1_operand" ""))
12247           (const_int 0)))
12248    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12249         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12250   "(TARGET_SHIFT1 || optimize_size)
12251    && ix86_match_ccmode (insn, CCGOCmode)
12252    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12253   "sar{l}\t%0"
12254   [(set_attr "type" "ishift")
12255    (set (attr "length")
12256      (if_then_else (match_operand:SI 0 "register_operand" "")
12257         (const_string "2")
12258         (const_string "*")))])
12259
12260 (define_insn "*ashrsi3_one_bit_cconly"
12261   [(set (reg FLAGS_REG)
12262         (compare
12263           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12264                        (match_operand:QI 2 "const1_operand" ""))
12265           (const_int 0)))
12266    (clobber (match_scratch:SI 0 "=r"))]
12267   "(TARGET_SHIFT1 || optimize_size)
12268    && ix86_match_ccmode (insn, CCGOCmode)
12269    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12270   "sar{l}\t%0"
12271   [(set_attr "type" "ishift")
12272    (set_attr "length" "2")])
12273
12274 (define_insn "*ashrsi3_one_bit_cmp_zext"
12275   [(set (reg FLAGS_REG)
12276         (compare
12277           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12278                        (match_operand:QI 2 "const1_operand" ""))
12279           (const_int 0)))
12280    (set (match_operand:DI 0 "register_operand" "=r")
12281         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12282   "TARGET_64BIT
12283    && (TARGET_SHIFT1 || optimize_size)
12284    && ix86_match_ccmode (insn, CCmode)
12285    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12286   "sar{l}\t%k0"
12287   [(set_attr "type" "ishift")
12288    (set_attr "length" "2")])
12289
12290 ;; This pattern can't accept a variable shift count, since shifts by
12291 ;; zero don't affect the flags.  We assume that shifts by constant
12292 ;; zero are optimized away.
12293 (define_insn "*ashrsi3_cmp"
12294   [(set (reg FLAGS_REG)
12295         (compare
12296           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12297                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12298           (const_int 0)))
12299    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12300         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12301   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12302    && ix86_match_ccmode (insn, CCGOCmode)
12303    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12304   "sar{l}\t{%2, %0|%0, %2}"
12305   [(set_attr "type" "ishift")
12306    (set_attr "mode" "SI")])
12307
12308 (define_insn "*ashrsi3_cconly"
12309   [(set (reg FLAGS_REG)
12310         (compare
12311           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12312                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12313           (const_int 0)))
12314    (clobber (match_scratch:SI 0 "=r"))]
12315   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12316    && ix86_match_ccmode (insn, CCGOCmode)
12317    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12318   "sar{l}\t{%2, %0|%0, %2}"
12319   [(set_attr "type" "ishift")
12320    (set_attr "mode" "SI")])
12321
12322 (define_insn "*ashrsi3_cmp_zext"
12323   [(set (reg FLAGS_REG)
12324         (compare
12325           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12326                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12327           (const_int 0)))
12328    (set (match_operand:DI 0 "register_operand" "=r")
12329         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12330   "TARGET_64BIT
12331    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12332    && ix86_match_ccmode (insn, CCGOCmode)
12333    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12334   "sar{l}\t{%2, %k0|%k0, %2}"
12335   [(set_attr "type" "ishift")
12336    (set_attr "mode" "SI")])
12337
12338 (define_expand "ashrhi3"
12339   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12340         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12341                      (match_operand:QI 2 "nonmemory_operand" "")))
12342    (clobber (reg:CC FLAGS_REG))]
12343   "TARGET_HIMODE_MATH"
12344   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12345
12346 (define_insn "*ashrhi3_1_one_bit"
12347   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12348         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12349                      (match_operand:QI 2 "const1_operand" "")))
12350    (clobber (reg:CC FLAGS_REG))]
12351   "(TARGET_SHIFT1 || optimize_size)
12352    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12353   "sar{w}\t%0"
12354   [(set_attr "type" "ishift")
12355    (set (attr "length")
12356      (if_then_else (match_operand 0 "register_operand" "")
12357         (const_string "2")
12358         (const_string "*")))])
12359
12360 (define_insn "*ashrhi3_1"
12361   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12362         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12363                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12364    (clobber (reg:CC FLAGS_REG))]
12365   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12366   "@
12367    sar{w}\t{%2, %0|%0, %2}
12368    sar{w}\t{%b2, %0|%0, %b2}"
12369   [(set_attr "type" "ishift")
12370    (set_attr "mode" "HI")])
12371
12372 ;; This pattern can't accept a variable shift count, since shifts by
12373 ;; zero don't affect the flags.  We assume that shifts by constant
12374 ;; zero are optimized away.
12375 (define_insn "*ashrhi3_one_bit_cmp"
12376   [(set (reg FLAGS_REG)
12377         (compare
12378           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12379                        (match_operand:QI 2 "const1_operand" ""))
12380           (const_int 0)))
12381    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12382         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12383   "(TARGET_SHIFT1 || optimize_size)
12384    && ix86_match_ccmode (insn, CCGOCmode)
12385    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12386   "sar{w}\t%0"
12387   [(set_attr "type" "ishift")
12388    (set (attr "length")
12389      (if_then_else (match_operand 0 "register_operand" "")
12390         (const_string "2")
12391         (const_string "*")))])
12392
12393 (define_insn "*ashrhi3_one_bit_cconly"
12394   [(set (reg FLAGS_REG)
12395         (compare
12396           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12397                        (match_operand:QI 2 "const1_operand" ""))
12398           (const_int 0)))
12399    (clobber (match_scratch:HI 0 "=r"))]
12400   "(TARGET_SHIFT1 || optimize_size)
12401    && ix86_match_ccmode (insn, CCGOCmode)
12402    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12403   "sar{w}\t%0"
12404   [(set_attr "type" "ishift")
12405    (set_attr "length" "2")])
12406
12407 ;; This pattern can't accept a variable shift count, since shifts by
12408 ;; zero don't affect the flags.  We assume that shifts by constant
12409 ;; zero are optimized away.
12410 (define_insn "*ashrhi3_cmp"
12411   [(set (reg FLAGS_REG)
12412         (compare
12413           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12414                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12415           (const_int 0)))
12416    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12417         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12418   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12419    && ix86_match_ccmode (insn, CCGOCmode)
12420    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12421   "sar{w}\t{%2, %0|%0, %2}"
12422   [(set_attr "type" "ishift")
12423    (set_attr "mode" "HI")])
12424
12425 (define_insn "*ashrhi3_cconly"
12426   [(set (reg FLAGS_REG)
12427         (compare
12428           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12429                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12430           (const_int 0)))
12431    (clobber (match_scratch:HI 0 "=r"))]
12432   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12433    && ix86_match_ccmode (insn, CCGOCmode)
12434    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12435   "sar{w}\t{%2, %0|%0, %2}"
12436   [(set_attr "type" "ishift")
12437    (set_attr "mode" "HI")])
12438
12439 (define_expand "ashrqi3"
12440   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12441         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12442                      (match_operand:QI 2 "nonmemory_operand" "")))
12443    (clobber (reg:CC FLAGS_REG))]
12444   "TARGET_QIMODE_MATH"
12445   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12446
12447 (define_insn "*ashrqi3_1_one_bit"
12448   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12449         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12450                      (match_operand:QI 2 "const1_operand" "")))
12451    (clobber (reg:CC FLAGS_REG))]
12452   "(TARGET_SHIFT1 || optimize_size)
12453    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12454   "sar{b}\t%0"
12455   [(set_attr "type" "ishift")
12456    (set (attr "length")
12457      (if_then_else (match_operand 0 "register_operand" "")
12458         (const_string "2")
12459         (const_string "*")))])
12460
12461 (define_insn "*ashrqi3_1_one_bit_slp"
12462   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12463         (ashiftrt:QI (match_dup 0)
12464                      (match_operand:QI 1 "const1_operand" "")))
12465    (clobber (reg:CC FLAGS_REG))]
12466   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12467    && (TARGET_SHIFT1 || optimize_size)
12468    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12469   "sar{b}\t%0"
12470   [(set_attr "type" "ishift1")
12471    (set (attr "length")
12472      (if_then_else (match_operand 0 "register_operand" "")
12473         (const_string "2")
12474         (const_string "*")))])
12475
12476 (define_insn "*ashrqi3_1"
12477   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12478         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12479                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12480    (clobber (reg:CC FLAGS_REG))]
12481   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12482   "@
12483    sar{b}\t{%2, %0|%0, %2}
12484    sar{b}\t{%b2, %0|%0, %b2}"
12485   [(set_attr "type" "ishift")
12486    (set_attr "mode" "QI")])
12487
12488 (define_insn "*ashrqi3_1_slp"
12489   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12490         (ashiftrt:QI (match_dup 0)
12491                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12492    (clobber (reg:CC FLAGS_REG))]
12493   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12494    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12495   "@
12496    sar{b}\t{%1, %0|%0, %1}
12497    sar{b}\t{%b1, %0|%0, %b1}"
12498   [(set_attr "type" "ishift1")
12499    (set_attr "mode" "QI")])
12500
12501 ;; This pattern can't accept a variable shift count, since shifts by
12502 ;; zero don't affect the flags.  We assume that shifts by constant
12503 ;; zero are optimized away.
12504 (define_insn "*ashrqi3_one_bit_cmp"
12505   [(set (reg FLAGS_REG)
12506         (compare
12507           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12508                        (match_operand:QI 2 "const1_operand" "I"))
12509           (const_int 0)))
12510    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12511         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12512   "(TARGET_SHIFT1 || optimize_size)
12513    && ix86_match_ccmode (insn, CCGOCmode)
12514    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12515   "sar{b}\t%0"
12516   [(set_attr "type" "ishift")
12517    (set (attr "length")
12518      (if_then_else (match_operand 0 "register_operand" "")
12519         (const_string "2")
12520         (const_string "*")))])
12521
12522 (define_insn "*ashrqi3_one_bit_cconly"
12523   [(set (reg FLAGS_REG)
12524         (compare
12525           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12526                        (match_operand:QI 2 "const1_operand" "I"))
12527           (const_int 0)))
12528    (clobber (match_scratch:QI 0 "=q"))]
12529   "(TARGET_SHIFT1 || optimize_size)
12530    && ix86_match_ccmode (insn, CCGOCmode)
12531    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12532   "sar{b}\t%0"
12533   [(set_attr "type" "ishift")
12534    (set_attr "length" "2")])
12535
12536 ;; This pattern can't accept a variable shift count, since shifts by
12537 ;; zero don't affect the flags.  We assume that shifts by constant
12538 ;; zero are optimized away.
12539 (define_insn "*ashrqi3_cmp"
12540   [(set (reg FLAGS_REG)
12541         (compare
12542           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12543                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12544           (const_int 0)))
12545    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12546         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12547   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12548    && ix86_match_ccmode (insn, CCGOCmode)
12549    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12550   "sar{b}\t{%2, %0|%0, %2}"
12551   [(set_attr "type" "ishift")
12552    (set_attr "mode" "QI")])
12553
12554 (define_insn "*ashrqi3_cconly"
12555   [(set (reg FLAGS_REG)
12556         (compare
12557           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12558                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12559           (const_int 0)))
12560    (clobber (match_scratch:QI 0 "=q"))]
12561   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12562    && ix86_match_ccmode (insn, CCGOCmode)
12563    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12564   "sar{b}\t{%2, %0|%0, %2}"
12565   [(set_attr "type" "ishift")
12566    (set_attr "mode" "QI")])
12567
12568 \f
12569 ;; Logical shift instructions
12570
12571 ;; See comment above `ashldi3' about how this works.
12572
12573 (define_expand "lshrti3"
12574   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12575                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12576                                 (match_operand:QI 2 "nonmemory_operand" "")))
12577               (clobber (reg:CC FLAGS_REG))])]
12578   "TARGET_64BIT"
12579 {
12580   if (! immediate_operand (operands[2], QImode))
12581     {
12582       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12583       DONE;
12584     }
12585   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12586   DONE;
12587 })
12588
12589 (define_insn "lshrti3_1"
12590   [(set (match_operand:TI 0 "register_operand" "=r")
12591         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12592                      (match_operand:QI 2 "register_operand" "c")))
12593    (clobber (match_scratch:DI 3 "=&r"))
12594    (clobber (reg:CC FLAGS_REG))]
12595   "TARGET_64BIT"
12596   "#"
12597   [(set_attr "type" "multi")])
12598
12599 ;; This pattern must be defined before *lshrti3_2 to prevent
12600 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12601
12602 (define_insn "sse2_lshrti3"
12603   [(set (match_operand:TI 0 "register_operand" "=x")
12604         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12605                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12606   "TARGET_SSE2"
12607 {
12608   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12609   return "psrldq\t{%2, %0|%0, %2}";
12610 }
12611   [(set_attr "type" "sseishft")
12612    (set_attr "prefix_data16" "1")
12613    (set_attr "mode" "TI")])
12614
12615 (define_insn "*lshrti3_2"
12616   [(set (match_operand:TI 0 "register_operand" "=r")
12617         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12618                      (match_operand:QI 2 "immediate_operand" "O")))
12619    (clobber (reg:CC FLAGS_REG))]
12620   "TARGET_64BIT"
12621   "#"
12622   [(set_attr "type" "multi")])
12623
12624 (define_split
12625   [(set (match_operand:TI 0 "register_operand" "")
12626         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12627                      (match_operand:QI 2 "register_operand" "")))
12628    (clobber (match_scratch:DI 3 ""))
12629    (clobber (reg:CC FLAGS_REG))]
12630   "TARGET_64BIT && reload_completed"
12631   [(const_int 0)]
12632   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12633
12634 (define_split
12635   [(set (match_operand:TI 0 "register_operand" "")
12636         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12637                      (match_operand:QI 2 "immediate_operand" "")))
12638    (clobber (reg:CC FLAGS_REG))]
12639   "TARGET_64BIT && reload_completed"
12640   [(const_int 0)]
12641   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12642
12643 (define_expand "lshrdi3"
12644   [(set (match_operand:DI 0 "shiftdi_operand" "")
12645         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12646                      (match_operand:QI 2 "nonmemory_operand" "")))]
12647   ""
12648   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12649
12650 (define_insn "*lshrdi3_1_one_bit_rex64"
12651   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12652         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12653                      (match_operand:QI 2 "const1_operand" "")))
12654    (clobber (reg:CC FLAGS_REG))]
12655   "TARGET_64BIT
12656    && (TARGET_SHIFT1 || optimize_size)
12657    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12658   "shr{q}\t%0"
12659   [(set_attr "type" "ishift")
12660    (set (attr "length")
12661      (if_then_else (match_operand:DI 0 "register_operand" "")
12662         (const_string "2")
12663         (const_string "*")))])
12664
12665 (define_insn "*lshrdi3_1_rex64"
12666   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12667         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12668                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12669    (clobber (reg:CC FLAGS_REG))]
12670   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12671   "@
12672    shr{q}\t{%2, %0|%0, %2}
12673    shr{q}\t{%b2, %0|%0, %b2}"
12674   [(set_attr "type" "ishift")
12675    (set_attr "mode" "DI")])
12676
12677 ;; This pattern can't accept a variable shift count, since shifts by
12678 ;; zero don't affect the flags.  We assume that shifts by constant
12679 ;; zero are optimized away.
12680 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12681   [(set (reg FLAGS_REG)
12682         (compare
12683           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12684                        (match_operand:QI 2 "const1_operand" ""))
12685           (const_int 0)))
12686    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12687         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12688   "TARGET_64BIT
12689    && (TARGET_SHIFT1 || optimize_size)
12690    && ix86_match_ccmode (insn, CCGOCmode)
12691    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12692   "shr{q}\t%0"
12693   [(set_attr "type" "ishift")
12694    (set (attr "length")
12695      (if_then_else (match_operand:DI 0 "register_operand" "")
12696         (const_string "2")
12697         (const_string "*")))])
12698
12699 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12700   [(set (reg FLAGS_REG)
12701         (compare
12702           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12703                        (match_operand:QI 2 "const1_operand" ""))
12704           (const_int 0)))
12705    (clobber (match_scratch:DI 0 "=r"))]
12706   "TARGET_64BIT
12707    && (TARGET_SHIFT1 || optimize_size)
12708    && ix86_match_ccmode (insn, CCGOCmode)
12709    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12710   "shr{q}\t%0"
12711   [(set_attr "type" "ishift")
12712    (set_attr "length" "2")])
12713
12714 ;; This pattern can't accept a variable shift count, since shifts by
12715 ;; zero don't affect the flags.  We assume that shifts by constant
12716 ;; zero are optimized away.
12717 (define_insn "*lshrdi3_cmp_rex64"
12718   [(set (reg FLAGS_REG)
12719         (compare
12720           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12721                        (match_operand:QI 2 "const_int_operand" "e"))
12722           (const_int 0)))
12723    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12724         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12725   "TARGET_64BIT
12726    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12727    && ix86_match_ccmode (insn, CCGOCmode)
12728    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12729   "shr{q}\t{%2, %0|%0, %2}"
12730   [(set_attr "type" "ishift")
12731    (set_attr "mode" "DI")])
12732
12733 (define_insn "*lshrdi3_cconly_rex64"
12734   [(set (reg FLAGS_REG)
12735         (compare
12736           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12737                        (match_operand:QI 2 "const_int_operand" "e"))
12738           (const_int 0)))
12739    (clobber (match_scratch:DI 0 "=r"))]
12740   "TARGET_64BIT
12741    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12742    && ix86_match_ccmode (insn, CCGOCmode)
12743    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12744   "shr{q}\t{%2, %0|%0, %2}"
12745   [(set_attr "type" "ishift")
12746    (set_attr "mode" "DI")])
12747
12748 (define_insn "*lshrdi3_1"
12749   [(set (match_operand:DI 0 "register_operand" "=r")
12750         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12751                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12752    (clobber (reg:CC FLAGS_REG))]
12753   "!TARGET_64BIT"
12754   "#"
12755   [(set_attr "type" "multi")])
12756
12757 ;; By default we don't ask for a scratch register, because when DImode
12758 ;; values are manipulated, registers are already at a premium.  But if
12759 ;; we have one handy, we won't turn it away.
12760 (define_peephole2
12761   [(match_scratch:SI 3 "r")
12762    (parallel [(set (match_operand:DI 0 "register_operand" "")
12763                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12764                                 (match_operand:QI 2 "nonmemory_operand" "")))
12765               (clobber (reg:CC FLAGS_REG))])
12766    (match_dup 3)]
12767   "!TARGET_64BIT && TARGET_CMOVE"
12768   [(const_int 0)]
12769   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12770
12771 (define_split
12772   [(set (match_operand:DI 0 "register_operand" "")
12773         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12774                      (match_operand:QI 2 "nonmemory_operand" "")))
12775    (clobber (reg:CC FLAGS_REG))]
12776   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12777                      ? epilogue_completed : reload_completed)"
12778   [(const_int 0)]
12779   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12780
12781 (define_expand "lshrsi3"
12782   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12783         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12784                      (match_operand:QI 2 "nonmemory_operand" "")))
12785    (clobber (reg:CC FLAGS_REG))]
12786   ""
12787   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12788
12789 (define_insn "*lshrsi3_1_one_bit"
12790   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12791         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12792                      (match_operand:QI 2 "const1_operand" "")))
12793    (clobber (reg:CC FLAGS_REG))]
12794   "(TARGET_SHIFT1 || optimize_size)
12795    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12796   "shr{l}\t%0"
12797   [(set_attr "type" "ishift")
12798    (set (attr "length")
12799      (if_then_else (match_operand:SI 0 "register_operand" "")
12800         (const_string "2")
12801         (const_string "*")))])
12802
12803 (define_insn "*lshrsi3_1_one_bit_zext"
12804   [(set (match_operand:DI 0 "register_operand" "=r")
12805         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12806                      (match_operand:QI 2 "const1_operand" "")))
12807    (clobber (reg:CC FLAGS_REG))]
12808   "TARGET_64BIT
12809    && (TARGET_SHIFT1 || optimize_size)
12810    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12811   "shr{l}\t%k0"
12812   [(set_attr "type" "ishift")
12813    (set_attr "length" "2")])
12814
12815 (define_insn "*lshrsi3_1"
12816   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12817         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12818                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12819    (clobber (reg:CC FLAGS_REG))]
12820   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12821   "@
12822    shr{l}\t{%2, %0|%0, %2}
12823    shr{l}\t{%b2, %0|%0, %b2}"
12824   [(set_attr "type" "ishift")
12825    (set_attr "mode" "SI")])
12826
12827 (define_insn "*lshrsi3_1_zext"
12828   [(set (match_operand:DI 0 "register_operand" "=r,r")
12829         (zero_extend:DI
12830           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12831                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12832    (clobber (reg:CC FLAGS_REG))]
12833   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12834   "@
12835    shr{l}\t{%2, %k0|%k0, %2}
12836    shr{l}\t{%b2, %k0|%k0, %b2}"
12837   [(set_attr "type" "ishift")
12838    (set_attr "mode" "SI")])
12839
12840 ;; This pattern can't accept a variable shift count, since shifts by
12841 ;; zero don't affect the flags.  We assume that shifts by constant
12842 ;; zero are optimized away.
12843 (define_insn "*lshrsi3_one_bit_cmp"
12844   [(set (reg FLAGS_REG)
12845         (compare
12846           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12847                        (match_operand:QI 2 "const1_operand" ""))
12848           (const_int 0)))
12849    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12850         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12851   "(TARGET_SHIFT1 || optimize_size)
12852    && ix86_match_ccmode (insn, CCGOCmode)
12853    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12854   "shr{l}\t%0"
12855   [(set_attr "type" "ishift")
12856    (set (attr "length")
12857      (if_then_else (match_operand:SI 0 "register_operand" "")
12858         (const_string "2")
12859         (const_string "*")))])
12860
12861 (define_insn "*lshrsi3_one_bit_cconly"
12862   [(set (reg FLAGS_REG)
12863         (compare
12864           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12865                        (match_operand:QI 2 "const1_operand" ""))
12866           (const_int 0)))
12867    (clobber (match_scratch:SI 0 "=r"))]
12868   "(TARGET_SHIFT1 || optimize_size)
12869    && ix86_match_ccmode (insn, CCGOCmode)
12870    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12871   "shr{l}\t%0"
12872   [(set_attr "type" "ishift")
12873    (set_attr "length" "2")])
12874
12875 (define_insn "*lshrsi3_cmp_one_bit_zext"
12876   [(set (reg FLAGS_REG)
12877         (compare
12878           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12879                        (match_operand:QI 2 "const1_operand" ""))
12880           (const_int 0)))
12881    (set (match_operand:DI 0 "register_operand" "=r")
12882         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12883   "TARGET_64BIT
12884    && (TARGET_SHIFT1 || optimize_size)
12885    && ix86_match_ccmode (insn, CCGOCmode)
12886    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12887   "shr{l}\t%k0"
12888   [(set_attr "type" "ishift")
12889    (set_attr "length" "2")])
12890
12891 ;; This pattern can't accept a variable shift count, since shifts by
12892 ;; zero don't affect the flags.  We assume that shifts by constant
12893 ;; zero are optimized away.
12894 (define_insn "*lshrsi3_cmp"
12895   [(set (reg FLAGS_REG)
12896         (compare
12897           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12898                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12899           (const_int 0)))
12900    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12901         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12902   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12903    && ix86_match_ccmode (insn, CCGOCmode)
12904    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12905   "shr{l}\t{%2, %0|%0, %2}"
12906   [(set_attr "type" "ishift")
12907    (set_attr "mode" "SI")])
12908
12909 (define_insn "*lshrsi3_cconly"
12910   [(set (reg FLAGS_REG)
12911       (compare
12912         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12913                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12914         (const_int 0)))
12915    (clobber (match_scratch:SI 0 "=r"))]
12916   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12917    && ix86_match_ccmode (insn, CCGOCmode)
12918    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12919   "shr{l}\t{%2, %0|%0, %2}"
12920   [(set_attr "type" "ishift")
12921    (set_attr "mode" "SI")])
12922
12923 (define_insn "*lshrsi3_cmp_zext"
12924   [(set (reg FLAGS_REG)
12925         (compare
12926           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12927                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12928           (const_int 0)))
12929    (set (match_operand:DI 0 "register_operand" "=r")
12930         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12931   "TARGET_64BIT
12932    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12933    && ix86_match_ccmode (insn, CCGOCmode)
12934    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12935   "shr{l}\t{%2, %k0|%k0, %2}"
12936   [(set_attr "type" "ishift")
12937    (set_attr "mode" "SI")])
12938
12939 (define_expand "lshrhi3"
12940   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12941         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12942                      (match_operand:QI 2 "nonmemory_operand" "")))
12943    (clobber (reg:CC FLAGS_REG))]
12944   "TARGET_HIMODE_MATH"
12945   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12946
12947 (define_insn "*lshrhi3_1_one_bit"
12948   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12949         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12950                      (match_operand:QI 2 "const1_operand" "")))
12951    (clobber (reg:CC FLAGS_REG))]
12952   "(TARGET_SHIFT1 || optimize_size)
12953    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12954   "shr{w}\t%0"
12955   [(set_attr "type" "ishift")
12956    (set (attr "length")
12957      (if_then_else (match_operand 0 "register_operand" "")
12958         (const_string "2")
12959         (const_string "*")))])
12960
12961 (define_insn "*lshrhi3_1"
12962   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12963         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12964                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12965    (clobber (reg:CC FLAGS_REG))]
12966   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12967   "@
12968    shr{w}\t{%2, %0|%0, %2}
12969    shr{w}\t{%b2, %0|%0, %b2}"
12970   [(set_attr "type" "ishift")
12971    (set_attr "mode" "HI")])
12972
12973 ;; This pattern can't accept a variable shift count, since shifts by
12974 ;; zero don't affect the flags.  We assume that shifts by constant
12975 ;; zero are optimized away.
12976 (define_insn "*lshrhi3_one_bit_cmp"
12977   [(set (reg FLAGS_REG)
12978         (compare
12979           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12980                        (match_operand:QI 2 "const1_operand" ""))
12981           (const_int 0)))
12982    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12983         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12984   "(TARGET_SHIFT1 || optimize_size)
12985    && ix86_match_ccmode (insn, CCGOCmode)
12986    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12987   "shr{w}\t%0"
12988   [(set_attr "type" "ishift")
12989    (set (attr "length")
12990      (if_then_else (match_operand:SI 0 "register_operand" "")
12991         (const_string "2")
12992         (const_string "*")))])
12993
12994 (define_insn "*lshrhi3_one_bit_cconly"
12995   [(set (reg FLAGS_REG)
12996         (compare
12997           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12998                        (match_operand:QI 2 "const1_operand" ""))
12999           (const_int 0)))
13000    (clobber (match_scratch:HI 0 "=r"))]
13001   "(TARGET_SHIFT1 || optimize_size)
13002    && ix86_match_ccmode (insn, CCGOCmode)
13003    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13004   "shr{w}\t%0"
13005   [(set_attr "type" "ishift")
13006    (set_attr "length" "2")])
13007
13008 ;; This pattern can't accept a variable shift count, since shifts by
13009 ;; zero don't affect the flags.  We assume that shifts by constant
13010 ;; zero are optimized away.
13011 (define_insn "*lshrhi3_cmp"
13012   [(set (reg FLAGS_REG)
13013         (compare
13014           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13015                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13016           (const_int 0)))
13017    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13018         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13019   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13020    && ix86_match_ccmode (insn, CCGOCmode)
13021    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13022   "shr{w}\t{%2, %0|%0, %2}"
13023   [(set_attr "type" "ishift")
13024    (set_attr "mode" "HI")])
13025
13026 (define_insn "*lshrhi3_cconly"
13027   [(set (reg FLAGS_REG)
13028         (compare
13029           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13030                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13031           (const_int 0)))
13032    (clobber (match_scratch:HI 0 "=r"))]
13033   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13034    && ix86_match_ccmode (insn, CCGOCmode)
13035    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13036   "shr{w}\t{%2, %0|%0, %2}"
13037   [(set_attr "type" "ishift")
13038    (set_attr "mode" "HI")])
13039
13040 (define_expand "lshrqi3"
13041   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13042         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13043                      (match_operand:QI 2 "nonmemory_operand" "")))
13044    (clobber (reg:CC FLAGS_REG))]
13045   "TARGET_QIMODE_MATH"
13046   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13047
13048 (define_insn "*lshrqi3_1_one_bit"
13049   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13050         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13051                      (match_operand:QI 2 "const1_operand" "")))
13052    (clobber (reg:CC FLAGS_REG))]
13053   "(TARGET_SHIFT1 || optimize_size)
13054    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13055   "shr{b}\t%0"
13056   [(set_attr "type" "ishift")
13057    (set (attr "length")
13058      (if_then_else (match_operand 0 "register_operand" "")
13059         (const_string "2")
13060         (const_string "*")))])
13061
13062 (define_insn "*lshrqi3_1_one_bit_slp"
13063   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13064         (lshiftrt:QI (match_dup 0)
13065                      (match_operand:QI 1 "const1_operand" "")))
13066    (clobber (reg:CC FLAGS_REG))]
13067   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13068    && (TARGET_SHIFT1 || optimize_size)"
13069   "shr{b}\t%0"
13070   [(set_attr "type" "ishift1")
13071    (set (attr "length")
13072      (if_then_else (match_operand 0 "register_operand" "")
13073         (const_string "2")
13074         (const_string "*")))])
13075
13076 (define_insn "*lshrqi3_1"
13077   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13078         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13079                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13080    (clobber (reg:CC FLAGS_REG))]
13081   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13082   "@
13083    shr{b}\t{%2, %0|%0, %2}
13084    shr{b}\t{%b2, %0|%0, %b2}"
13085   [(set_attr "type" "ishift")
13086    (set_attr "mode" "QI")])
13087
13088 (define_insn "*lshrqi3_1_slp"
13089   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13090         (lshiftrt:QI (match_dup 0)
13091                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13092    (clobber (reg:CC FLAGS_REG))]
13093   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13094    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13095   "@
13096    shr{b}\t{%1, %0|%0, %1}
13097    shr{b}\t{%b1, %0|%0, %b1}"
13098   [(set_attr "type" "ishift1")
13099    (set_attr "mode" "QI")])
13100
13101 ;; This pattern can't accept a variable shift count, since shifts by
13102 ;; zero don't affect the flags.  We assume that shifts by constant
13103 ;; zero are optimized away.
13104 (define_insn "*lshrqi2_one_bit_cmp"
13105   [(set (reg FLAGS_REG)
13106         (compare
13107           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13108                        (match_operand:QI 2 "const1_operand" ""))
13109           (const_int 0)))
13110    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13111         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13112   "(TARGET_SHIFT1 || optimize_size)
13113    && ix86_match_ccmode (insn, CCGOCmode)
13114    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13115   "shr{b}\t%0"
13116   [(set_attr "type" "ishift")
13117    (set (attr "length")
13118      (if_then_else (match_operand:SI 0 "register_operand" "")
13119         (const_string "2")
13120         (const_string "*")))])
13121
13122 (define_insn "*lshrqi2_one_bit_cconly"
13123   [(set (reg FLAGS_REG)
13124         (compare
13125           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13126                        (match_operand:QI 2 "const1_operand" ""))
13127           (const_int 0)))
13128    (clobber (match_scratch:QI 0 "=q"))]
13129   "(TARGET_SHIFT1 || optimize_size)
13130    && ix86_match_ccmode (insn, CCGOCmode)
13131    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13132   "shr{b}\t%0"
13133   [(set_attr "type" "ishift")
13134    (set_attr "length" "2")])
13135
13136 ;; This pattern can't accept a variable shift count, since shifts by
13137 ;; zero don't affect the flags.  We assume that shifts by constant
13138 ;; zero are optimized away.
13139 (define_insn "*lshrqi2_cmp"
13140   [(set (reg FLAGS_REG)
13141         (compare
13142           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13143                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13144           (const_int 0)))
13145    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13146         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13147   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13148    && ix86_match_ccmode (insn, CCGOCmode)
13149    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13150   "shr{b}\t{%2, %0|%0, %2}"
13151   [(set_attr "type" "ishift")
13152    (set_attr "mode" "QI")])
13153
13154 (define_insn "*lshrqi2_cconly"
13155   [(set (reg FLAGS_REG)
13156         (compare
13157           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13158                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13159           (const_int 0)))
13160    (clobber (match_scratch:QI 0 "=q"))]
13161   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13162    && ix86_match_ccmode (insn, CCGOCmode)
13163    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13164   "shr{b}\t{%2, %0|%0, %2}"
13165   [(set_attr "type" "ishift")
13166    (set_attr "mode" "QI")])
13167 \f
13168 ;; Rotate instructions
13169
13170 (define_expand "rotldi3"
13171   [(set (match_operand:DI 0 "shiftdi_operand" "")
13172         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13173                    (match_operand:QI 2 "nonmemory_operand" "")))
13174    (clobber (reg:CC FLAGS_REG))]
13175  ""
13176 {
13177   if (TARGET_64BIT)
13178     {
13179       ix86_expand_binary_operator (ROTATE, DImode, operands);
13180       DONE;
13181     }
13182   if (!const_1_to_31_operand (operands[2], VOIDmode))
13183     FAIL;
13184   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13185   DONE;
13186 })
13187
13188 ;; Implement rotation using two double-precision shift instructions
13189 ;; and a scratch register.
13190 (define_insn_and_split "ix86_rotldi3"
13191  [(set (match_operand:DI 0 "register_operand" "=r")
13192        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13193                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13194   (clobber (reg:CC FLAGS_REG))
13195   (clobber (match_scratch:SI 3 "=&r"))]
13196  "!TARGET_64BIT"
13197  ""
13198  "&& reload_completed"
13199  [(set (match_dup 3) (match_dup 4))
13200   (parallel
13201    [(set (match_dup 4)
13202          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13203                  (lshiftrt:SI (match_dup 5)
13204                               (minus:QI (const_int 32) (match_dup 2)))))
13205     (clobber (reg:CC FLAGS_REG))])
13206   (parallel
13207    [(set (match_dup 5)
13208          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13209                  (lshiftrt:SI (match_dup 3)
13210                               (minus:QI (const_int 32) (match_dup 2)))))
13211     (clobber (reg:CC FLAGS_REG))])]
13212  "split_di (operands, 1, operands + 4, operands + 5);")
13213
13214 (define_insn "*rotlsi3_1_one_bit_rex64"
13215   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13216         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13217                    (match_operand:QI 2 "const1_operand" "")))
13218    (clobber (reg:CC FLAGS_REG))]
13219   "TARGET_64BIT
13220    && (TARGET_SHIFT1 || optimize_size)
13221    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13222   "rol{q}\t%0"
13223   [(set_attr "type" "rotate")
13224    (set (attr "length")
13225      (if_then_else (match_operand:DI 0 "register_operand" "")
13226         (const_string "2")
13227         (const_string "*")))])
13228
13229 (define_insn "*rotldi3_1_rex64"
13230   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13231         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13232                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13233    (clobber (reg:CC FLAGS_REG))]
13234   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13235   "@
13236    rol{q}\t{%2, %0|%0, %2}
13237    rol{q}\t{%b2, %0|%0, %b2}"
13238   [(set_attr "type" "rotate")
13239    (set_attr "mode" "DI")])
13240
13241 (define_expand "rotlsi3"
13242   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13243         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13244                    (match_operand:QI 2 "nonmemory_operand" "")))
13245    (clobber (reg:CC FLAGS_REG))]
13246   ""
13247   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13248
13249 (define_insn "*rotlsi3_1_one_bit"
13250   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13251         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13252                    (match_operand:QI 2 "const1_operand" "")))
13253    (clobber (reg:CC FLAGS_REG))]
13254   "(TARGET_SHIFT1 || optimize_size)
13255    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13256   "rol{l}\t%0"
13257   [(set_attr "type" "rotate")
13258    (set (attr "length")
13259      (if_then_else (match_operand:SI 0 "register_operand" "")
13260         (const_string "2")
13261         (const_string "*")))])
13262
13263 (define_insn "*rotlsi3_1_one_bit_zext"
13264   [(set (match_operand:DI 0 "register_operand" "=r")
13265         (zero_extend:DI
13266           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13267                      (match_operand:QI 2 "const1_operand" ""))))
13268    (clobber (reg:CC FLAGS_REG))]
13269   "TARGET_64BIT
13270    && (TARGET_SHIFT1 || optimize_size)
13271    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13272   "rol{l}\t%k0"
13273   [(set_attr "type" "rotate")
13274    (set_attr "length" "2")])
13275
13276 (define_insn "*rotlsi3_1"
13277   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13278         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13279                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13280    (clobber (reg:CC FLAGS_REG))]
13281   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13282   "@
13283    rol{l}\t{%2, %0|%0, %2}
13284    rol{l}\t{%b2, %0|%0, %b2}"
13285   [(set_attr "type" "rotate")
13286    (set_attr "mode" "SI")])
13287
13288 (define_insn "*rotlsi3_1_zext"
13289   [(set (match_operand:DI 0 "register_operand" "=r,r")
13290         (zero_extend:DI
13291           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13292                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13293    (clobber (reg:CC FLAGS_REG))]
13294   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13295   "@
13296    rol{l}\t{%2, %k0|%k0, %2}
13297    rol{l}\t{%b2, %k0|%k0, %b2}"
13298   [(set_attr "type" "rotate")
13299    (set_attr "mode" "SI")])
13300
13301 (define_expand "rotlhi3"
13302   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13303         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13304                    (match_operand:QI 2 "nonmemory_operand" "")))
13305    (clobber (reg:CC FLAGS_REG))]
13306   "TARGET_HIMODE_MATH"
13307   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13308
13309 (define_insn "*rotlhi3_1_one_bit"
13310   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13311         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13312                    (match_operand:QI 2 "const1_operand" "")))
13313    (clobber (reg:CC FLAGS_REG))]
13314   "(TARGET_SHIFT1 || optimize_size)
13315    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13316   "rol{w}\t%0"
13317   [(set_attr "type" "rotate")
13318    (set (attr "length")
13319      (if_then_else (match_operand 0 "register_operand" "")
13320         (const_string "2")
13321         (const_string "*")))])
13322
13323 (define_insn "*rotlhi3_1"
13324   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13325         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13326                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13327    (clobber (reg:CC FLAGS_REG))]
13328   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13329   "@
13330    rol{w}\t{%2, %0|%0, %2}
13331    rol{w}\t{%b2, %0|%0, %b2}"
13332   [(set_attr "type" "rotate")
13333    (set_attr "mode" "HI")])
13334
13335 (define_split
13336  [(set (match_operand:HI 0 "register_operand" "")
13337        (rotate:HI (match_dup 0) (const_int 8)))
13338   (clobber (reg:CC FLAGS_REG))]
13339  "reload_completed"
13340  [(parallel [(set (strict_low_part (match_dup 0))
13341                   (bswap:HI (match_dup 0)))
13342              (clobber (reg:CC FLAGS_REG))])]
13343  "")
13344
13345 (define_expand "rotlqi3"
13346   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13347         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13348                    (match_operand:QI 2 "nonmemory_operand" "")))
13349    (clobber (reg:CC FLAGS_REG))]
13350   "TARGET_QIMODE_MATH"
13351   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13352
13353 (define_insn "*rotlqi3_1_one_bit_slp"
13354   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13355         (rotate:QI (match_dup 0)
13356                    (match_operand:QI 1 "const1_operand" "")))
13357    (clobber (reg:CC FLAGS_REG))]
13358   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13359    && (TARGET_SHIFT1 || optimize_size)"
13360   "rol{b}\t%0"
13361   [(set_attr "type" "rotate1")
13362    (set (attr "length")
13363      (if_then_else (match_operand 0 "register_operand" "")
13364         (const_string "2")
13365         (const_string "*")))])
13366
13367 (define_insn "*rotlqi3_1_one_bit"
13368   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13369         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13370                    (match_operand:QI 2 "const1_operand" "")))
13371    (clobber (reg:CC FLAGS_REG))]
13372   "(TARGET_SHIFT1 || optimize_size)
13373    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13374   "rol{b}\t%0"
13375   [(set_attr "type" "rotate")
13376    (set (attr "length")
13377      (if_then_else (match_operand 0 "register_operand" "")
13378         (const_string "2")
13379         (const_string "*")))])
13380
13381 (define_insn "*rotlqi3_1_slp"
13382   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13383         (rotate:QI (match_dup 0)
13384                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13385    (clobber (reg:CC FLAGS_REG))]
13386   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13387    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13388   "@
13389    rol{b}\t{%1, %0|%0, %1}
13390    rol{b}\t{%b1, %0|%0, %b1}"
13391   [(set_attr "type" "rotate1")
13392    (set_attr "mode" "QI")])
13393
13394 (define_insn "*rotlqi3_1"
13395   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13396         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13397                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13398    (clobber (reg:CC FLAGS_REG))]
13399   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13400   "@
13401    rol{b}\t{%2, %0|%0, %2}
13402    rol{b}\t{%b2, %0|%0, %b2}"
13403   [(set_attr "type" "rotate")
13404    (set_attr "mode" "QI")])
13405
13406 (define_expand "rotrdi3"
13407   [(set (match_operand:DI 0 "shiftdi_operand" "")
13408         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13409                    (match_operand:QI 2 "nonmemory_operand" "")))
13410    (clobber (reg:CC FLAGS_REG))]
13411  ""
13412 {
13413   if (TARGET_64BIT)
13414     {
13415       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13416       DONE;
13417     }
13418   if (!const_1_to_31_operand (operands[2], VOIDmode))
13419     FAIL;
13420   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13421   DONE;
13422 })
13423
13424 ;; Implement rotation using two double-precision shift instructions
13425 ;; and a scratch register.
13426 (define_insn_and_split "ix86_rotrdi3"
13427  [(set (match_operand:DI 0 "register_operand" "=r")
13428        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13429                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13430   (clobber (reg:CC FLAGS_REG))
13431   (clobber (match_scratch:SI 3 "=&r"))]
13432  "!TARGET_64BIT"
13433  ""
13434  "&& reload_completed"
13435  [(set (match_dup 3) (match_dup 4))
13436   (parallel
13437    [(set (match_dup 4)
13438          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13439                  (ashift:SI (match_dup 5)
13440                             (minus:QI (const_int 32) (match_dup 2)))))
13441     (clobber (reg:CC FLAGS_REG))])
13442   (parallel
13443    [(set (match_dup 5)
13444          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13445                  (ashift:SI (match_dup 3)
13446                             (minus:QI (const_int 32) (match_dup 2)))))
13447     (clobber (reg:CC FLAGS_REG))])]
13448  "split_di (operands, 1, operands + 4, operands + 5);")
13449
13450 (define_insn "*rotrdi3_1_one_bit_rex64"
13451   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13452         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13453                      (match_operand:QI 2 "const1_operand" "")))
13454    (clobber (reg:CC FLAGS_REG))]
13455   "TARGET_64BIT
13456    && (TARGET_SHIFT1 || optimize_size)
13457    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13458   "ror{q}\t%0"
13459   [(set_attr "type" "rotate")
13460    (set (attr "length")
13461      (if_then_else (match_operand:DI 0 "register_operand" "")
13462         (const_string "2")
13463         (const_string "*")))])
13464
13465 (define_insn "*rotrdi3_1_rex64"
13466   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13467         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13468                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13469    (clobber (reg:CC FLAGS_REG))]
13470   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13471   "@
13472    ror{q}\t{%2, %0|%0, %2}
13473    ror{q}\t{%b2, %0|%0, %b2}"
13474   [(set_attr "type" "rotate")
13475    (set_attr "mode" "DI")])
13476
13477 (define_expand "rotrsi3"
13478   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13479         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13480                      (match_operand:QI 2 "nonmemory_operand" "")))
13481    (clobber (reg:CC FLAGS_REG))]
13482   ""
13483   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13484
13485 (define_insn "*rotrsi3_1_one_bit"
13486   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13487         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13488                      (match_operand:QI 2 "const1_operand" "")))
13489    (clobber (reg:CC FLAGS_REG))]
13490   "(TARGET_SHIFT1 || optimize_size)
13491    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13492   "ror{l}\t%0"
13493   [(set_attr "type" "rotate")
13494    (set (attr "length")
13495      (if_then_else (match_operand:SI 0 "register_operand" "")
13496         (const_string "2")
13497         (const_string "*")))])
13498
13499 (define_insn "*rotrsi3_1_one_bit_zext"
13500   [(set (match_operand:DI 0 "register_operand" "=r")
13501         (zero_extend:DI
13502           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13503                        (match_operand:QI 2 "const1_operand" ""))))
13504    (clobber (reg:CC FLAGS_REG))]
13505   "TARGET_64BIT
13506    && (TARGET_SHIFT1 || optimize_size)
13507    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13508   "ror{l}\t%k0"
13509   [(set_attr "type" "rotate")
13510    (set (attr "length")
13511      (if_then_else (match_operand:SI 0 "register_operand" "")
13512         (const_string "2")
13513         (const_string "*")))])
13514
13515 (define_insn "*rotrsi3_1"
13516   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13517         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13518                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13519    (clobber (reg:CC FLAGS_REG))]
13520   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13521   "@
13522    ror{l}\t{%2, %0|%0, %2}
13523    ror{l}\t{%b2, %0|%0, %b2}"
13524   [(set_attr "type" "rotate")
13525    (set_attr "mode" "SI")])
13526
13527 (define_insn "*rotrsi3_1_zext"
13528   [(set (match_operand:DI 0 "register_operand" "=r,r")
13529         (zero_extend:DI
13530           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13531                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13532    (clobber (reg:CC FLAGS_REG))]
13533   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13534   "@
13535    ror{l}\t{%2, %k0|%k0, %2}
13536    ror{l}\t{%b2, %k0|%k0, %b2}"
13537   [(set_attr "type" "rotate")
13538    (set_attr "mode" "SI")])
13539
13540 (define_expand "rotrhi3"
13541   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13542         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13543                      (match_operand:QI 2 "nonmemory_operand" "")))
13544    (clobber (reg:CC FLAGS_REG))]
13545   "TARGET_HIMODE_MATH"
13546   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13547
13548 (define_insn "*rotrhi3_one_bit"
13549   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13550         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13551                      (match_operand:QI 2 "const1_operand" "")))
13552    (clobber (reg:CC FLAGS_REG))]
13553   "(TARGET_SHIFT1 || optimize_size)
13554    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13555   "ror{w}\t%0"
13556   [(set_attr "type" "rotate")
13557    (set (attr "length")
13558      (if_then_else (match_operand 0 "register_operand" "")
13559         (const_string "2")
13560         (const_string "*")))])
13561
13562 (define_insn "*rotrhi3_1"
13563   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13564         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13565                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13566    (clobber (reg:CC FLAGS_REG))]
13567   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13568   "@
13569    ror{w}\t{%2, %0|%0, %2}
13570    ror{w}\t{%b2, %0|%0, %b2}"
13571   [(set_attr "type" "rotate")
13572    (set_attr "mode" "HI")])
13573
13574 (define_split
13575  [(set (match_operand:HI 0 "register_operand" "")
13576        (rotatert:HI (match_dup 0) (const_int 8)))
13577   (clobber (reg:CC FLAGS_REG))]
13578  "reload_completed"
13579  [(parallel [(set (strict_low_part (match_dup 0))
13580                   (bswap:HI (match_dup 0)))
13581              (clobber (reg:CC FLAGS_REG))])]
13582  "")
13583
13584 (define_expand "rotrqi3"
13585   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13586         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13587                      (match_operand:QI 2 "nonmemory_operand" "")))
13588    (clobber (reg:CC FLAGS_REG))]
13589   "TARGET_QIMODE_MATH"
13590   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13591
13592 (define_insn "*rotrqi3_1_one_bit"
13593   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13594         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13595                      (match_operand:QI 2 "const1_operand" "")))
13596    (clobber (reg:CC FLAGS_REG))]
13597   "(TARGET_SHIFT1 || optimize_size)
13598    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13599   "ror{b}\t%0"
13600   [(set_attr "type" "rotate")
13601    (set (attr "length")
13602      (if_then_else (match_operand 0 "register_operand" "")
13603         (const_string "2")
13604         (const_string "*")))])
13605
13606 (define_insn "*rotrqi3_1_one_bit_slp"
13607   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13608         (rotatert:QI (match_dup 0)
13609                      (match_operand:QI 1 "const1_operand" "")))
13610    (clobber (reg:CC FLAGS_REG))]
13611   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13612    && (TARGET_SHIFT1 || optimize_size)"
13613   "ror{b}\t%0"
13614   [(set_attr "type" "rotate1")
13615    (set (attr "length")
13616      (if_then_else (match_operand 0 "register_operand" "")
13617         (const_string "2")
13618         (const_string "*")))])
13619
13620 (define_insn "*rotrqi3_1"
13621   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13622         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13623                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13624    (clobber (reg:CC FLAGS_REG))]
13625   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13626   "@
13627    ror{b}\t{%2, %0|%0, %2}
13628    ror{b}\t{%b2, %0|%0, %b2}"
13629   [(set_attr "type" "rotate")
13630    (set_attr "mode" "QI")])
13631
13632 (define_insn "*rotrqi3_1_slp"
13633   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13634         (rotatert:QI (match_dup 0)
13635                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13636    (clobber (reg:CC FLAGS_REG))]
13637   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13638    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13639   "@
13640    ror{b}\t{%1, %0|%0, %1}
13641    ror{b}\t{%b1, %0|%0, %b1}"
13642   [(set_attr "type" "rotate1")
13643    (set_attr "mode" "QI")])
13644 \f
13645 ;; Bit set / bit test instructions
13646
13647 (define_expand "extv"
13648   [(set (match_operand:SI 0 "register_operand" "")
13649         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13650                          (match_operand:SI 2 "const8_operand" "")
13651                          (match_operand:SI 3 "const8_operand" "")))]
13652   ""
13653 {
13654   /* Handle extractions from %ah et al.  */
13655   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13656     FAIL;
13657
13658   /* From mips.md: extract_bit_field doesn't verify that our source
13659      matches the predicate, so check it again here.  */
13660   if (! ext_register_operand (operands[1], VOIDmode))
13661     FAIL;
13662 })
13663
13664 (define_expand "extzv"
13665   [(set (match_operand:SI 0 "register_operand" "")
13666         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13667                          (match_operand:SI 2 "const8_operand" "")
13668                          (match_operand:SI 3 "const8_operand" "")))]
13669   ""
13670 {
13671   /* Handle extractions from %ah et al.  */
13672   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13673     FAIL;
13674
13675   /* From mips.md: extract_bit_field doesn't verify that our source
13676      matches the predicate, so check it again here.  */
13677   if (! ext_register_operand (operands[1], VOIDmode))
13678     FAIL;
13679 })
13680
13681 (define_expand "insv"
13682   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13683                       (match_operand 1 "const8_operand" "")
13684                       (match_operand 2 "const8_operand" ""))
13685         (match_operand 3 "register_operand" ""))]
13686   ""
13687 {
13688   /* Handle insertions to %ah et al.  */
13689   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13690     FAIL;
13691
13692   /* From mips.md: insert_bit_field doesn't verify that our source
13693      matches the predicate, so check it again here.  */
13694   if (! ext_register_operand (operands[0], VOIDmode))
13695     FAIL;
13696
13697   if (TARGET_64BIT)
13698     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13699   else
13700     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13701
13702   DONE;
13703 })
13704
13705 ;; %%% bts, btr, btc, bt.
13706 ;; In general these instructions are *slow* when applied to memory,
13707 ;; since they enforce atomic operation.  When applied to registers,
13708 ;; it depends on the cpu implementation.  They're never faster than
13709 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13710 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13711 ;; within the instruction itself, so operating on bits in the high
13712 ;; 32-bits of a register becomes easier.
13713 ;;
13714 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13715 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13716 ;; negdf respectively, so they can never be disabled entirely.
13717
13718 (define_insn "*btsq"
13719   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13720                          (const_int 1)
13721                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13722         (const_int 1))
13723    (clobber (reg:CC FLAGS_REG))]
13724   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13725   "bts{q} %1,%0"
13726   [(set_attr "type" "alu1")])
13727
13728 (define_insn "*btrq"
13729   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13730                          (const_int 1)
13731                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13732         (const_int 0))
13733    (clobber (reg:CC FLAGS_REG))]
13734   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13735   "btr{q} %1,%0"
13736   [(set_attr "type" "alu1")])
13737
13738 (define_insn "*btcq"
13739   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13740                          (const_int 1)
13741                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13742         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13743    (clobber (reg:CC FLAGS_REG))]
13744   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13745   "btc{q} %1,%0"
13746   [(set_attr "type" "alu1")])
13747
13748 ;; Allow Nocona to avoid these instructions if a register is available.
13749
13750 (define_peephole2
13751   [(match_scratch:DI 2 "r")
13752    (parallel [(set (zero_extract:DI
13753                      (match_operand:DI 0 "register_operand" "")
13754                      (const_int 1)
13755                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13756                    (const_int 1))
13757               (clobber (reg:CC FLAGS_REG))])]
13758   "TARGET_64BIT && !TARGET_USE_BT"
13759   [(const_int 0)]
13760 {
13761   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13762   rtx op1;
13763
13764   if (HOST_BITS_PER_WIDE_INT >= 64)
13765     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13766   else if (i < HOST_BITS_PER_WIDE_INT)
13767     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13768   else
13769     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13770
13771   op1 = immed_double_const (lo, hi, DImode);
13772   if (i >= 31)
13773     {
13774       emit_move_insn (operands[2], op1);
13775       op1 = operands[2];
13776     }
13777
13778   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13779   DONE;
13780 })
13781
13782 (define_peephole2
13783   [(match_scratch:DI 2 "r")
13784    (parallel [(set (zero_extract:DI
13785                      (match_operand:DI 0 "register_operand" "")
13786                      (const_int 1)
13787                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13788                    (const_int 0))
13789               (clobber (reg:CC FLAGS_REG))])]
13790   "TARGET_64BIT && !TARGET_USE_BT"
13791   [(const_int 0)]
13792 {
13793   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13794   rtx op1;
13795
13796   if (HOST_BITS_PER_WIDE_INT >= 64)
13797     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13798   else if (i < HOST_BITS_PER_WIDE_INT)
13799     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13800   else
13801     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13802
13803   op1 = immed_double_const (~lo, ~hi, DImode);
13804   if (i >= 32)
13805     {
13806       emit_move_insn (operands[2], op1);
13807       op1 = operands[2];
13808     }
13809
13810   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13811   DONE;
13812 })
13813
13814 (define_peephole2
13815   [(match_scratch:DI 2 "r")
13816    (parallel [(set (zero_extract:DI
13817                      (match_operand:DI 0 "register_operand" "")
13818                      (const_int 1)
13819                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13820               (not:DI (zero_extract:DI
13821                         (match_dup 0) (const_int 1) (match_dup 1))))
13822               (clobber (reg:CC FLAGS_REG))])]
13823   "TARGET_64BIT && !TARGET_USE_BT"
13824   [(const_int 0)]
13825 {
13826   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13827   rtx op1;
13828
13829   if (HOST_BITS_PER_WIDE_INT >= 64)
13830     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13831   else if (i < HOST_BITS_PER_WIDE_INT)
13832     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13833   else
13834     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13835
13836   op1 = immed_double_const (lo, hi, DImode);
13837   if (i >= 31)
13838     {
13839       emit_move_insn (operands[2], op1);
13840       op1 = operands[2];
13841     }
13842
13843   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13844   DONE;
13845 })
13846 \f
13847 ;; Store-flag instructions.
13848
13849 ;; For all sCOND expanders, also expand the compare or test insn that
13850 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13851
13852 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13853 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13854 ;; way, which can later delete the movzx if only QImode is needed.
13855
13856 (define_expand "seq"
13857   [(set (match_operand:QI 0 "register_operand" "")
13858         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13859   ""
13860   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13861
13862 (define_expand "sne"
13863   [(set (match_operand:QI 0 "register_operand" "")
13864         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13865   ""
13866   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13867
13868 (define_expand "sgt"
13869   [(set (match_operand:QI 0 "register_operand" "")
13870         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13871   ""
13872   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13873
13874 (define_expand "sgtu"
13875   [(set (match_operand:QI 0 "register_operand" "")
13876         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13877   ""
13878   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13879
13880 (define_expand "slt"
13881   [(set (match_operand:QI 0 "register_operand" "")
13882         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13883   ""
13884   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13885
13886 (define_expand "sltu"
13887   [(set (match_operand:QI 0 "register_operand" "")
13888         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13889   ""
13890   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13891
13892 (define_expand "sge"
13893   [(set (match_operand:QI 0 "register_operand" "")
13894         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13895   ""
13896   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13897
13898 (define_expand "sgeu"
13899   [(set (match_operand:QI 0 "register_operand" "")
13900         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13901   ""
13902   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13903
13904 (define_expand "sle"
13905   [(set (match_operand:QI 0 "register_operand" "")
13906         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13907   ""
13908   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13909
13910 (define_expand "sleu"
13911   [(set (match_operand:QI 0 "register_operand" "")
13912         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13913   ""
13914   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13915
13916 (define_expand "sunordered"
13917   [(set (match_operand:QI 0 "register_operand" "")
13918         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13919   "TARGET_80387 || TARGET_SSE"
13920   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13921
13922 (define_expand "sordered"
13923   [(set (match_operand:QI 0 "register_operand" "")
13924         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13925   "TARGET_80387"
13926   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13927
13928 (define_expand "suneq"
13929   [(set (match_operand:QI 0 "register_operand" "")
13930         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13931   "TARGET_80387 || TARGET_SSE"
13932   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13933
13934 (define_expand "sunge"
13935   [(set (match_operand:QI 0 "register_operand" "")
13936         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13937   "TARGET_80387 || TARGET_SSE"
13938   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13939
13940 (define_expand "sungt"
13941   [(set (match_operand:QI 0 "register_operand" "")
13942         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13943   "TARGET_80387 || TARGET_SSE"
13944   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13945
13946 (define_expand "sunle"
13947   [(set (match_operand:QI 0 "register_operand" "")
13948         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13949   "TARGET_80387 || TARGET_SSE"
13950   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13951
13952 (define_expand "sunlt"
13953   [(set (match_operand:QI 0 "register_operand" "")
13954         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13955   "TARGET_80387 || TARGET_SSE"
13956   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13957
13958 (define_expand "sltgt"
13959   [(set (match_operand:QI 0 "register_operand" "")
13960         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13961   "TARGET_80387 || TARGET_SSE"
13962   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13963
13964 (define_insn "*setcc_1"
13965   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13966         (match_operator:QI 1 "ix86_comparison_operator"
13967           [(reg FLAGS_REG) (const_int 0)]))]
13968   ""
13969   "set%C1\t%0"
13970   [(set_attr "type" "setcc")
13971    (set_attr "mode" "QI")])
13972
13973 (define_insn "*setcc_2"
13974   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13975         (match_operator:QI 1 "ix86_comparison_operator"
13976           [(reg FLAGS_REG) (const_int 0)]))]
13977   ""
13978   "set%C1\t%0"
13979   [(set_attr "type" "setcc")
13980    (set_attr "mode" "QI")])
13981
13982 ;; In general it is not safe to assume too much about CCmode registers,
13983 ;; so simplify-rtx stops when it sees a second one.  Under certain
13984 ;; conditions this is safe on x86, so help combine not create
13985 ;;
13986 ;;      seta    %al
13987 ;;      testb   %al, %al
13988 ;;      sete    %al
13989
13990 (define_split
13991   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13992         (ne:QI (match_operator 1 "ix86_comparison_operator"
13993                  [(reg FLAGS_REG) (const_int 0)])
13994             (const_int 0)))]
13995   ""
13996   [(set (match_dup 0) (match_dup 1))]
13997 {
13998   PUT_MODE (operands[1], QImode);
13999 })
14000
14001 (define_split
14002   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14003         (ne:QI (match_operator 1 "ix86_comparison_operator"
14004                  [(reg FLAGS_REG) (const_int 0)])
14005             (const_int 0)))]
14006   ""
14007   [(set (match_dup 0) (match_dup 1))]
14008 {
14009   PUT_MODE (operands[1], QImode);
14010 })
14011
14012 (define_split
14013   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14014         (eq:QI (match_operator 1 "ix86_comparison_operator"
14015                  [(reg FLAGS_REG) (const_int 0)])
14016             (const_int 0)))]
14017   ""
14018   [(set (match_dup 0) (match_dup 1))]
14019 {
14020   rtx new_op1 = copy_rtx (operands[1]);
14021   operands[1] = new_op1;
14022   PUT_MODE (new_op1, QImode);
14023   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14024                                              GET_MODE (XEXP (new_op1, 0))));
14025
14026   /* Make sure that (a) the CCmode we have for the flags is strong
14027      enough for the reversed compare or (b) we have a valid FP compare.  */
14028   if (! ix86_comparison_operator (new_op1, VOIDmode))
14029     FAIL;
14030 })
14031
14032 (define_split
14033   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14034         (eq:QI (match_operator 1 "ix86_comparison_operator"
14035                  [(reg FLAGS_REG) (const_int 0)])
14036             (const_int 0)))]
14037   ""
14038   [(set (match_dup 0) (match_dup 1))]
14039 {
14040   rtx new_op1 = copy_rtx (operands[1]);
14041   operands[1] = new_op1;
14042   PUT_MODE (new_op1, QImode);
14043   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14044                                              GET_MODE (XEXP (new_op1, 0))));
14045
14046   /* Make sure that (a) the CCmode we have for the flags is strong
14047      enough for the reversed compare or (b) we have a valid FP compare.  */
14048   if (! ix86_comparison_operator (new_op1, VOIDmode))
14049     FAIL;
14050 })
14051
14052 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14053 ;; subsequent logical operations are used to imitate conditional moves.
14054 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14055 ;; it directly.
14056
14057 (define_insn "*sse_setccsf"
14058   [(set (match_operand:SF 0 "register_operand" "=x")
14059         (match_operator:SF 1 "sse_comparison_operator"
14060           [(match_operand:SF 2 "register_operand" "0")
14061            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
14062   "TARGET_SSE"
14063   "cmp%D1ss\t{%3, %0|%0, %3}"
14064   [(set_attr "type" "ssecmp")
14065    (set_attr "mode" "SF")])
14066
14067 (define_insn "*sse_setccdf"
14068   [(set (match_operand:DF 0 "register_operand" "=x")
14069         (match_operator:DF 1 "sse_comparison_operator"
14070           [(match_operand:DF 2 "register_operand" "0")
14071            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
14072   "TARGET_SSE2"
14073   "cmp%D1sd\t{%3, %0|%0, %3}"
14074   [(set_attr "type" "ssecmp")
14075    (set_attr "mode" "DF")])
14076 \f
14077 ;; Basic conditional jump instructions.
14078 ;; We ignore the overflow flag for signed branch instructions.
14079
14080 ;; For all bCOND expanders, also expand the compare or test insn that
14081 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
14082
14083 (define_expand "beq"
14084   [(set (pc)
14085         (if_then_else (match_dup 1)
14086                       (label_ref (match_operand 0 "" ""))
14087                       (pc)))]
14088   ""
14089   "ix86_expand_branch (EQ, operands[0]); DONE;")
14090
14091 (define_expand "bne"
14092   [(set (pc)
14093         (if_then_else (match_dup 1)
14094                       (label_ref (match_operand 0 "" ""))
14095                       (pc)))]
14096   ""
14097   "ix86_expand_branch (NE, operands[0]); DONE;")
14098
14099 (define_expand "bgt"
14100   [(set (pc)
14101         (if_then_else (match_dup 1)
14102                       (label_ref (match_operand 0 "" ""))
14103                       (pc)))]
14104   ""
14105   "ix86_expand_branch (GT, operands[0]); DONE;")
14106
14107 (define_expand "bgtu"
14108   [(set (pc)
14109         (if_then_else (match_dup 1)
14110                       (label_ref (match_operand 0 "" ""))
14111                       (pc)))]
14112   ""
14113   "ix86_expand_branch (GTU, operands[0]); DONE;")
14114
14115 (define_expand "blt"
14116   [(set (pc)
14117         (if_then_else (match_dup 1)
14118                       (label_ref (match_operand 0 "" ""))
14119                       (pc)))]
14120   ""
14121   "ix86_expand_branch (LT, operands[0]); DONE;")
14122
14123 (define_expand "bltu"
14124   [(set (pc)
14125         (if_then_else (match_dup 1)
14126                       (label_ref (match_operand 0 "" ""))
14127                       (pc)))]
14128   ""
14129   "ix86_expand_branch (LTU, operands[0]); DONE;")
14130
14131 (define_expand "bge"
14132   [(set (pc)
14133         (if_then_else (match_dup 1)
14134                       (label_ref (match_operand 0 "" ""))
14135                       (pc)))]
14136   ""
14137   "ix86_expand_branch (GE, operands[0]); DONE;")
14138
14139 (define_expand "bgeu"
14140   [(set (pc)
14141         (if_then_else (match_dup 1)
14142                       (label_ref (match_operand 0 "" ""))
14143                       (pc)))]
14144   ""
14145   "ix86_expand_branch (GEU, operands[0]); DONE;")
14146
14147 (define_expand "ble"
14148   [(set (pc)
14149         (if_then_else (match_dup 1)
14150                       (label_ref (match_operand 0 "" ""))
14151                       (pc)))]
14152   ""
14153   "ix86_expand_branch (LE, operands[0]); DONE;")
14154
14155 (define_expand "bleu"
14156   [(set (pc)
14157         (if_then_else (match_dup 1)
14158                       (label_ref (match_operand 0 "" ""))
14159                       (pc)))]
14160   ""
14161   "ix86_expand_branch (LEU, operands[0]); DONE;")
14162
14163 (define_expand "bunordered"
14164   [(set (pc)
14165         (if_then_else (match_dup 1)
14166                       (label_ref (match_operand 0 "" ""))
14167                       (pc)))]
14168   "TARGET_80387 || TARGET_SSE_MATH"
14169   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
14170
14171 (define_expand "bordered"
14172   [(set (pc)
14173         (if_then_else (match_dup 1)
14174                       (label_ref (match_operand 0 "" ""))
14175                       (pc)))]
14176   "TARGET_80387 || TARGET_SSE_MATH"
14177   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
14178
14179 (define_expand "buneq"
14180   [(set (pc)
14181         (if_then_else (match_dup 1)
14182                       (label_ref (match_operand 0 "" ""))
14183                       (pc)))]
14184   "TARGET_80387 || TARGET_SSE_MATH"
14185   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
14186
14187 (define_expand "bunge"
14188   [(set (pc)
14189         (if_then_else (match_dup 1)
14190                       (label_ref (match_operand 0 "" ""))
14191                       (pc)))]
14192   "TARGET_80387 || TARGET_SSE_MATH"
14193   "ix86_expand_branch (UNGE, operands[0]); DONE;")
14194
14195 (define_expand "bungt"
14196   [(set (pc)
14197         (if_then_else (match_dup 1)
14198                       (label_ref (match_operand 0 "" ""))
14199                       (pc)))]
14200   "TARGET_80387 || TARGET_SSE_MATH"
14201   "ix86_expand_branch (UNGT, operands[0]); DONE;")
14202
14203 (define_expand "bunle"
14204   [(set (pc)
14205         (if_then_else (match_dup 1)
14206                       (label_ref (match_operand 0 "" ""))
14207                       (pc)))]
14208   "TARGET_80387 || TARGET_SSE_MATH"
14209   "ix86_expand_branch (UNLE, operands[0]); DONE;")
14210
14211 (define_expand "bunlt"
14212   [(set (pc)
14213         (if_then_else (match_dup 1)
14214                       (label_ref (match_operand 0 "" ""))
14215                       (pc)))]
14216   "TARGET_80387 || TARGET_SSE_MATH"
14217   "ix86_expand_branch (UNLT, operands[0]); DONE;")
14218
14219 (define_expand "bltgt"
14220   [(set (pc)
14221         (if_then_else (match_dup 1)
14222                       (label_ref (match_operand 0 "" ""))
14223                       (pc)))]
14224   "TARGET_80387 || TARGET_SSE_MATH"
14225   "ix86_expand_branch (LTGT, operands[0]); DONE;")
14226
14227 (define_insn "*jcc_1"
14228   [(set (pc)
14229         (if_then_else (match_operator 1 "ix86_comparison_operator"
14230                                       [(reg FLAGS_REG) (const_int 0)])
14231                       (label_ref (match_operand 0 "" ""))
14232                       (pc)))]
14233   ""
14234   "%+j%C1\t%l0"
14235   [(set_attr "type" "ibr")
14236    (set_attr "modrm" "0")
14237    (set (attr "length")
14238            (if_then_else (and (ge (minus (match_dup 0) (pc))
14239                                   (const_int -126))
14240                               (lt (minus (match_dup 0) (pc))
14241                                   (const_int 128)))
14242              (const_int 2)
14243              (const_int 6)))])
14244
14245 (define_insn "*jcc_2"
14246   [(set (pc)
14247         (if_then_else (match_operator 1 "ix86_comparison_operator"
14248                                       [(reg FLAGS_REG) (const_int 0)])
14249                       (pc)
14250                       (label_ref (match_operand 0 "" ""))))]
14251   ""
14252   "%+j%c1\t%l0"
14253   [(set_attr "type" "ibr")
14254    (set_attr "modrm" "0")
14255    (set (attr "length")
14256            (if_then_else (and (ge (minus (match_dup 0) (pc))
14257                                   (const_int -126))
14258                               (lt (minus (match_dup 0) (pc))
14259                                   (const_int 128)))
14260              (const_int 2)
14261              (const_int 6)))])
14262
14263 ;; In general it is not safe to assume too much about CCmode registers,
14264 ;; so simplify-rtx stops when it sees a second one.  Under certain
14265 ;; conditions this is safe on x86, so help combine not create
14266 ;;
14267 ;;      seta    %al
14268 ;;      testb   %al, %al
14269 ;;      je      Lfoo
14270
14271 (define_split
14272   [(set (pc)
14273         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14274                                       [(reg FLAGS_REG) (const_int 0)])
14275                           (const_int 0))
14276                       (label_ref (match_operand 1 "" ""))
14277                       (pc)))]
14278   ""
14279   [(set (pc)
14280         (if_then_else (match_dup 0)
14281                       (label_ref (match_dup 1))
14282                       (pc)))]
14283 {
14284   PUT_MODE (operands[0], VOIDmode);
14285 })
14286
14287 (define_split
14288   [(set (pc)
14289         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14290                                       [(reg FLAGS_REG) (const_int 0)])
14291                           (const_int 0))
14292                       (label_ref (match_operand 1 "" ""))
14293                       (pc)))]
14294   ""
14295   [(set (pc)
14296         (if_then_else (match_dup 0)
14297                       (label_ref (match_dup 1))
14298                       (pc)))]
14299 {
14300   rtx new_op0 = copy_rtx (operands[0]);
14301   operands[0] = new_op0;
14302   PUT_MODE (new_op0, VOIDmode);
14303   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14304                                              GET_MODE (XEXP (new_op0, 0))));
14305
14306   /* Make sure that (a) the CCmode we have for the flags is strong
14307      enough for the reversed compare or (b) we have a valid FP compare.  */
14308   if (! ix86_comparison_operator (new_op0, VOIDmode))
14309     FAIL;
14310 })
14311
14312 ;; Define combination compare-and-branch fp compare instructions to use
14313 ;; during early optimization.  Splitting the operation apart early makes
14314 ;; for bad code when we want to reverse the operation.
14315
14316 (define_insn "*fp_jcc_1_mixed"
14317   [(set (pc)
14318         (if_then_else (match_operator 0 "comparison_operator"
14319                         [(match_operand 1 "register_operand" "f,x")
14320                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14321           (label_ref (match_operand 3 "" ""))
14322           (pc)))
14323    (clobber (reg:CCFP FPSR_REG))
14324    (clobber (reg:CCFP FLAGS_REG))]
14325   "TARGET_MIX_SSE_I387
14326    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14327    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14328    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14329   "#")
14330
14331 (define_insn "*fp_jcc_1_sse"
14332   [(set (pc)
14333         (if_then_else (match_operator 0 "comparison_operator"
14334                         [(match_operand 1 "register_operand" "x")
14335                          (match_operand 2 "nonimmediate_operand" "xm")])
14336           (label_ref (match_operand 3 "" ""))
14337           (pc)))
14338    (clobber (reg:CCFP FPSR_REG))
14339    (clobber (reg:CCFP FLAGS_REG))]
14340   "TARGET_SSE_MATH
14341    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14342    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14343    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14344   "#")
14345
14346 (define_insn "*fp_jcc_1_387"
14347   [(set (pc)
14348         (if_then_else (match_operator 0 "comparison_operator"
14349                         [(match_operand 1 "register_operand" "f")
14350                          (match_operand 2 "register_operand" "f")])
14351           (label_ref (match_operand 3 "" ""))
14352           (pc)))
14353    (clobber (reg:CCFP FPSR_REG))
14354    (clobber (reg:CCFP FLAGS_REG))]
14355   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14356    && TARGET_CMOVE
14357    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14358    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14359   "#")
14360
14361 (define_insn "*fp_jcc_2_mixed"
14362   [(set (pc)
14363         (if_then_else (match_operator 0 "comparison_operator"
14364                         [(match_operand 1 "register_operand" "f,x")
14365                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14366           (pc)
14367           (label_ref (match_operand 3 "" ""))))
14368    (clobber (reg:CCFP FPSR_REG))
14369    (clobber (reg:CCFP FLAGS_REG))]
14370   "TARGET_MIX_SSE_I387
14371    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14372    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14373    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14374   "#")
14375
14376 (define_insn "*fp_jcc_2_sse"
14377   [(set (pc)
14378         (if_then_else (match_operator 0 "comparison_operator"
14379                         [(match_operand 1 "register_operand" "x")
14380                          (match_operand 2 "nonimmediate_operand" "xm")])
14381           (pc)
14382           (label_ref (match_operand 3 "" ""))))
14383    (clobber (reg:CCFP FPSR_REG))
14384    (clobber (reg:CCFP FLAGS_REG))]
14385   "TARGET_SSE_MATH
14386    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14387    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14388    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14389   "#")
14390
14391 (define_insn "*fp_jcc_2_387"
14392   [(set (pc)
14393         (if_then_else (match_operator 0 "comparison_operator"
14394                         [(match_operand 1 "register_operand" "f")
14395                          (match_operand 2 "register_operand" "f")])
14396           (pc)
14397           (label_ref (match_operand 3 "" ""))))
14398    (clobber (reg:CCFP FPSR_REG))
14399    (clobber (reg:CCFP FLAGS_REG))]
14400   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14401    && TARGET_CMOVE
14402    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14403    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14404   "#")
14405
14406 (define_insn "*fp_jcc_3_387"
14407   [(set (pc)
14408         (if_then_else (match_operator 0 "comparison_operator"
14409                         [(match_operand 1 "register_operand" "f")
14410                          (match_operand 2 "nonimmediate_operand" "fm")])
14411           (label_ref (match_operand 3 "" ""))
14412           (pc)))
14413    (clobber (reg:CCFP FPSR_REG))
14414    (clobber (reg:CCFP FLAGS_REG))
14415    (clobber (match_scratch:HI 4 "=a"))]
14416   "TARGET_80387
14417    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14418    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14419    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14420    && SELECT_CC_MODE (GET_CODE (operands[0]),
14421                       operands[1], operands[2]) == CCFPmode
14422    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14423   "#")
14424
14425 (define_insn "*fp_jcc_4_387"
14426   [(set (pc)
14427         (if_then_else (match_operator 0 "comparison_operator"
14428                         [(match_operand 1 "register_operand" "f")
14429                          (match_operand 2 "nonimmediate_operand" "fm")])
14430           (pc)
14431           (label_ref (match_operand 3 "" ""))))
14432    (clobber (reg:CCFP FPSR_REG))
14433    (clobber (reg:CCFP FLAGS_REG))
14434    (clobber (match_scratch:HI 4 "=a"))]
14435   "TARGET_80387
14436    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14437    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14438    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14439    && SELECT_CC_MODE (GET_CODE (operands[0]),
14440                       operands[1], operands[2]) == CCFPmode
14441    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14442   "#")
14443
14444 (define_insn "*fp_jcc_5_387"
14445   [(set (pc)
14446         (if_then_else (match_operator 0 "comparison_operator"
14447                         [(match_operand 1 "register_operand" "f")
14448                          (match_operand 2 "register_operand" "f")])
14449           (label_ref (match_operand 3 "" ""))
14450           (pc)))
14451    (clobber (reg:CCFP FPSR_REG))
14452    (clobber (reg:CCFP FLAGS_REG))
14453    (clobber (match_scratch:HI 4 "=a"))]
14454   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14455    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14456    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14457   "#")
14458
14459 (define_insn "*fp_jcc_6_387"
14460   [(set (pc)
14461         (if_then_else (match_operator 0 "comparison_operator"
14462                         [(match_operand 1 "register_operand" "f")
14463                          (match_operand 2 "register_operand" "f")])
14464           (pc)
14465           (label_ref (match_operand 3 "" ""))))
14466    (clobber (reg:CCFP FPSR_REG))
14467    (clobber (reg:CCFP FLAGS_REG))
14468    (clobber (match_scratch:HI 4 "=a"))]
14469   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14470    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14471    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14472   "#")
14473
14474 (define_insn "*fp_jcc_7_387"
14475   [(set (pc)
14476         (if_then_else (match_operator 0 "comparison_operator"
14477                         [(match_operand 1 "register_operand" "f")
14478                          (match_operand 2 "const0_operand" "X")])
14479           (label_ref (match_operand 3 "" ""))
14480           (pc)))
14481    (clobber (reg:CCFP FPSR_REG))
14482    (clobber (reg:CCFP FLAGS_REG))
14483    (clobber (match_scratch:HI 4 "=a"))]
14484   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14485    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14486    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14487    && SELECT_CC_MODE (GET_CODE (operands[0]),
14488                       operands[1], operands[2]) == CCFPmode
14489    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14490   "#")
14491
14492 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14493 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14494 ;; with a precedence over other operators and is always put in the first
14495 ;; place. Swap condition and operands to match ficom instruction.
14496
14497 (define_insn "*fp_jcc_8<mode>_387"
14498   [(set (pc)
14499         (if_then_else (match_operator 0 "comparison_operator"
14500                         [(match_operator 1 "float_operator"
14501                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14502                            (match_operand 3 "register_operand" "f,f")])
14503           (label_ref (match_operand 4 "" ""))
14504           (pc)))
14505    (clobber (reg:CCFP FPSR_REG))
14506    (clobber (reg:CCFP FLAGS_REG))
14507    (clobber (match_scratch:HI 5 "=a,a"))]
14508   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14509    && TARGET_USE_<MODE>MODE_FIOP
14510    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14511    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14512    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14513    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14514   "#")
14515
14516 (define_split
14517   [(set (pc)
14518         (if_then_else (match_operator 0 "comparison_operator"
14519                         [(match_operand 1 "register_operand" "")
14520                          (match_operand 2 "nonimmediate_operand" "")])
14521           (match_operand 3 "" "")
14522           (match_operand 4 "" "")))
14523    (clobber (reg:CCFP FPSR_REG))
14524    (clobber (reg:CCFP FLAGS_REG))]
14525   "reload_completed"
14526   [(const_int 0)]
14527 {
14528   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14529                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14530   DONE;
14531 })
14532
14533 (define_split
14534   [(set (pc)
14535         (if_then_else (match_operator 0 "comparison_operator"
14536                         [(match_operand 1 "register_operand" "")
14537                          (match_operand 2 "general_operand" "")])
14538           (match_operand 3 "" "")
14539           (match_operand 4 "" "")))
14540    (clobber (reg:CCFP FPSR_REG))
14541    (clobber (reg:CCFP FLAGS_REG))
14542    (clobber (match_scratch:HI 5 "=a"))]
14543   "reload_completed"
14544   [(const_int 0)]
14545 {
14546   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14547                         operands[3], operands[4], operands[5], NULL_RTX);
14548   DONE;
14549 })
14550
14551 (define_split
14552   [(set (pc)
14553         (if_then_else (match_operator 0 "comparison_operator"
14554                         [(match_operator 1 "float_operator"
14555                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14556                            (match_operand 3 "register_operand" "")])
14557           (match_operand 4 "" "")
14558           (match_operand 5 "" "")))
14559    (clobber (reg:CCFP FPSR_REG))
14560    (clobber (reg:CCFP FLAGS_REG))
14561    (clobber (match_scratch:HI 6 "=a"))]
14562   "reload_completed"
14563   [(const_int 0)]
14564 {
14565   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14566   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14567                         operands[3], operands[7],
14568                         operands[4], operands[5], operands[6], NULL_RTX);
14569   DONE;
14570 })
14571
14572 ;; %%% Kill this when reload knows how to do it.
14573 (define_split
14574   [(set (pc)
14575         (if_then_else (match_operator 0 "comparison_operator"
14576                         [(match_operator 1 "float_operator"
14577                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14578                            (match_operand 3 "register_operand" "")])
14579           (match_operand 4 "" "")
14580           (match_operand 5 "" "")))
14581    (clobber (reg:CCFP FPSR_REG))
14582    (clobber (reg:CCFP FLAGS_REG))
14583    (clobber (match_scratch:HI 6 "=a"))]
14584   "reload_completed"
14585   [(const_int 0)]
14586 {
14587   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14588   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14589   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14590                         operands[3], operands[7],
14591                         operands[4], operands[5], operands[6], operands[2]);
14592   DONE;
14593 })
14594 \f
14595 ;; Unconditional and other jump instructions
14596
14597 (define_insn "jump"
14598   [(set (pc)
14599         (label_ref (match_operand 0 "" "")))]
14600   ""
14601   "jmp\t%l0"
14602   [(set_attr "type" "ibr")
14603    (set (attr "length")
14604            (if_then_else (and (ge (minus (match_dup 0) (pc))
14605                                   (const_int -126))
14606                               (lt (minus (match_dup 0) (pc))
14607                                   (const_int 128)))
14608              (const_int 2)
14609              (const_int 5)))
14610    (set_attr "modrm" "0")])
14611
14612 (define_expand "indirect_jump"
14613   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14614   ""
14615   "")
14616
14617 (define_insn "*indirect_jump"
14618   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14619   "!TARGET_64BIT"
14620   "jmp\t%A0"
14621   [(set_attr "type" "ibr")
14622    (set_attr "length_immediate" "0")])
14623
14624 (define_insn "*indirect_jump_rtx64"
14625   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14626   "TARGET_64BIT"
14627   "jmp\t%A0"
14628   [(set_attr "type" "ibr")
14629    (set_attr "length_immediate" "0")])
14630
14631 (define_expand "tablejump"
14632   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14633               (use (label_ref (match_operand 1 "" "")))])]
14634   ""
14635 {
14636   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14637      relative.  Convert the relative address to an absolute address.  */
14638   if (flag_pic)
14639     {
14640       rtx op0, op1;
14641       enum rtx_code code;
14642
14643       /* We can't use @GOTOFF for text labels on VxWorks;
14644          see gotoff_operand.  */
14645       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14646         {
14647           code = PLUS;
14648           op0 = operands[0];
14649           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14650         }
14651       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14652         {
14653           code = PLUS;
14654           op0 = operands[0];
14655           op1 = pic_offset_table_rtx;
14656         }
14657       else
14658         {
14659           code = MINUS;
14660           op0 = pic_offset_table_rtx;
14661           op1 = operands[0];
14662         }
14663
14664       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14665                                          OPTAB_DIRECT);
14666     }
14667 })
14668
14669 (define_insn "*tablejump_1"
14670   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14671    (use (label_ref (match_operand 1 "" "")))]
14672   "!TARGET_64BIT"
14673   "jmp\t%A0"
14674   [(set_attr "type" "ibr")
14675    (set_attr "length_immediate" "0")])
14676
14677 (define_insn "*tablejump_1_rtx64"
14678   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14679    (use (label_ref (match_operand 1 "" "")))]
14680   "TARGET_64BIT"
14681   "jmp\t%A0"
14682   [(set_attr "type" "ibr")
14683    (set_attr "length_immediate" "0")])
14684 \f
14685 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14686
14687 (define_peephole2
14688   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14689    (set (match_operand:QI 1 "register_operand" "")
14690         (match_operator:QI 2 "ix86_comparison_operator"
14691           [(reg FLAGS_REG) (const_int 0)]))
14692    (set (match_operand 3 "q_regs_operand" "")
14693         (zero_extend (match_dup 1)))]
14694   "(peep2_reg_dead_p (3, operands[1])
14695     || operands_match_p (operands[1], operands[3]))
14696    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14697   [(set (match_dup 4) (match_dup 0))
14698    (set (strict_low_part (match_dup 5))
14699         (match_dup 2))]
14700 {
14701   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14702   operands[5] = gen_lowpart (QImode, operands[3]);
14703   ix86_expand_clear (operands[3]);
14704 })
14705
14706 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14707
14708 (define_peephole2
14709   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14710    (set (match_operand:QI 1 "register_operand" "")
14711         (match_operator:QI 2 "ix86_comparison_operator"
14712           [(reg FLAGS_REG) (const_int 0)]))
14713    (parallel [(set (match_operand 3 "q_regs_operand" "")
14714                    (zero_extend (match_dup 1)))
14715               (clobber (reg:CC FLAGS_REG))])]
14716   "(peep2_reg_dead_p (3, operands[1])
14717     || operands_match_p (operands[1], operands[3]))
14718    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14719   [(set (match_dup 4) (match_dup 0))
14720    (set (strict_low_part (match_dup 5))
14721         (match_dup 2))]
14722 {
14723   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14724   operands[5] = gen_lowpart (QImode, operands[3]);
14725   ix86_expand_clear (operands[3]);
14726 })
14727 \f
14728 ;; Call instructions.
14729
14730 ;; The predicates normally associated with named expanders are not properly
14731 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14732 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14733
14734 ;; Call subroutine returning no value.
14735
14736 (define_expand "call_pop"
14737   [(parallel [(call (match_operand:QI 0 "" "")
14738                     (match_operand:SI 1 "" ""))
14739               (set (reg:SI SP_REG)
14740                    (plus:SI (reg:SI SP_REG)
14741                             (match_operand:SI 3 "" "")))])]
14742   "!TARGET_64BIT"
14743 {
14744   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14745   DONE;
14746 })
14747
14748 (define_insn "*call_pop_0"
14749   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14750          (match_operand:SI 1 "" ""))
14751    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14752                             (match_operand:SI 2 "immediate_operand" "")))]
14753   "!TARGET_64BIT"
14754 {
14755   if (SIBLING_CALL_P (insn))
14756     return "jmp\t%P0";
14757   else
14758     return "call\t%P0";
14759 }
14760   [(set_attr "type" "call")])
14761
14762 (define_insn "*call_pop_1"
14763   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14764          (match_operand:SI 1 "" ""))
14765    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14766                             (match_operand:SI 2 "immediate_operand" "i")))]
14767   "!TARGET_64BIT"
14768 {
14769   if (constant_call_address_operand (operands[0], Pmode))
14770     {
14771       if (SIBLING_CALL_P (insn))
14772         return "jmp\t%P0";
14773       else
14774         return "call\t%P0";
14775     }
14776   if (SIBLING_CALL_P (insn))
14777     return "jmp\t%A0";
14778   else
14779     return "call\t%A0";
14780 }
14781   [(set_attr "type" "call")])
14782
14783 (define_expand "call"
14784   [(call (match_operand:QI 0 "" "")
14785          (match_operand 1 "" ""))
14786    (use (match_operand 2 "" ""))]
14787   ""
14788 {
14789   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14790   DONE;
14791 })
14792
14793 (define_expand "sibcall"
14794   [(call (match_operand:QI 0 "" "")
14795          (match_operand 1 "" ""))
14796    (use (match_operand 2 "" ""))]
14797   ""
14798 {
14799   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14800   DONE;
14801 })
14802
14803 (define_insn "*call_0"
14804   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14805          (match_operand 1 "" ""))]
14806   ""
14807 {
14808   if (SIBLING_CALL_P (insn))
14809     return "jmp\t%P0";
14810   else
14811     return "call\t%P0";
14812 }
14813   [(set_attr "type" "call")])
14814
14815 (define_insn "*call_1"
14816   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14817          (match_operand 1 "" ""))]
14818   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14819 {
14820   if (constant_call_address_operand (operands[0], Pmode))
14821     return "call\t%P0";
14822   return "call\t%A0";
14823 }
14824   [(set_attr "type" "call")])
14825
14826 (define_insn "*sibcall_1"
14827   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14828          (match_operand 1 "" ""))]
14829   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14830 {
14831   if (constant_call_address_operand (operands[0], Pmode))
14832     return "jmp\t%P0";
14833   return "jmp\t%A0";
14834 }
14835   [(set_attr "type" "call")])
14836
14837 (define_insn "*call_1_rex64"
14838   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14839          (match_operand 1 "" ""))]
14840   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14841    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14842 {
14843   if (constant_call_address_operand (operands[0], Pmode))
14844     return "call\t%P0";
14845   return "call\t%A0";
14846 }
14847   [(set_attr "type" "call")])
14848
14849 (define_insn "*call_1_rex64_large"
14850   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14851          (match_operand 1 "" ""))]
14852   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14853   "call\t%A0"
14854   [(set_attr "type" "call")])
14855
14856 (define_insn "*sibcall_1_rex64"
14857   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14858          (match_operand 1 "" ""))]
14859   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14860   "jmp\t%P0"
14861   [(set_attr "type" "call")])
14862
14863 (define_insn "*sibcall_1_rex64_v"
14864   [(call (mem:QI (reg:DI R11_REG))
14865          (match_operand 0 "" ""))]
14866   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14867   "jmp\t*%%r11"
14868   [(set_attr "type" "call")])
14869
14870
14871 ;; Call subroutine, returning value in operand 0
14872
14873 (define_expand "call_value_pop"
14874   [(parallel [(set (match_operand 0 "" "")
14875                    (call (match_operand:QI 1 "" "")
14876                          (match_operand:SI 2 "" "")))
14877               (set (reg:SI SP_REG)
14878                    (plus:SI (reg:SI SP_REG)
14879                             (match_operand:SI 4 "" "")))])]
14880   "!TARGET_64BIT"
14881 {
14882   ix86_expand_call (operands[0], operands[1], operands[2],
14883                     operands[3], operands[4], 0);
14884   DONE;
14885 })
14886
14887 (define_expand "call_value"
14888   [(set (match_operand 0 "" "")
14889         (call (match_operand:QI 1 "" "")
14890               (match_operand:SI 2 "" "")))
14891    (use (match_operand:SI 3 "" ""))]
14892   ;; Operand 2 not used on the i386.
14893   ""
14894 {
14895   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14896   DONE;
14897 })
14898
14899 (define_expand "sibcall_value"
14900   [(set (match_operand 0 "" "")
14901         (call (match_operand:QI 1 "" "")
14902               (match_operand:SI 2 "" "")))
14903    (use (match_operand:SI 3 "" ""))]
14904   ;; Operand 2 not used on the i386.
14905   ""
14906 {
14907   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14908   DONE;
14909 })
14910
14911 ;; Call subroutine returning any type.
14912
14913 (define_expand "untyped_call"
14914   [(parallel [(call (match_operand 0 "" "")
14915                     (const_int 0))
14916               (match_operand 1 "" "")
14917               (match_operand 2 "" "")])]
14918   ""
14919 {
14920   int i;
14921
14922   /* In order to give reg-stack an easier job in validating two
14923      coprocessor registers as containing a possible return value,
14924      simply pretend the untyped call returns a complex long double
14925      value.  */
14926
14927   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14928                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14929                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14930                     NULL, 0);
14931
14932   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14933     {
14934       rtx set = XVECEXP (operands[2], 0, i);
14935       emit_move_insn (SET_DEST (set), SET_SRC (set));
14936     }
14937
14938   /* The optimizer does not know that the call sets the function value
14939      registers we stored in the result block.  We avoid problems by
14940      claiming that all hard registers are used and clobbered at this
14941      point.  */
14942   emit_insn (gen_blockage ());
14943
14944   DONE;
14945 })
14946 \f
14947 ;; Prologue and epilogue instructions
14948
14949 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14950 ;; all of memory.  This blocks insns from being moved across this point.
14951
14952 (define_insn "blockage"
14953   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14954   ""
14955   ""
14956   [(set_attr "length" "0")])
14957
14958 ;; As USE insns aren't meaningful after reload, this is used instead
14959 ;; to prevent deleting instructions setting registers for PIC code
14960 (define_insn "prologue_use"
14961   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14962   ""
14963   ""
14964   [(set_attr "length" "0")])
14965
14966 ;; Insn emitted into the body of a function to return from a function.
14967 ;; This is only done if the function's epilogue is known to be simple.
14968 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14969
14970 (define_expand "return"
14971   [(return)]
14972   "ix86_can_use_return_insn_p ()"
14973 {
14974   if (current_function_pops_args)
14975     {
14976       rtx popc = GEN_INT (current_function_pops_args);
14977       emit_jump_insn (gen_return_pop_internal (popc));
14978       DONE;
14979     }
14980 })
14981
14982 (define_insn "return_internal"
14983   [(return)]
14984   "reload_completed"
14985   "ret"
14986   [(set_attr "length" "1")
14987    (set_attr "length_immediate" "0")
14988    (set_attr "modrm" "0")])
14989
14990 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14991 ;; instruction Athlon and K8 have.
14992
14993 (define_insn "return_internal_long"
14994   [(return)
14995    (unspec [(const_int 0)] UNSPEC_REP)]
14996   "reload_completed"
14997   "rep{\;| }ret"
14998   [(set_attr "length" "1")
14999    (set_attr "length_immediate" "0")
15000    (set_attr "prefix_rep" "1")
15001    (set_attr "modrm" "0")])
15002
15003 (define_insn "return_pop_internal"
15004   [(return)
15005    (use (match_operand:SI 0 "const_int_operand" ""))]
15006   "reload_completed"
15007   "ret\t%0"
15008   [(set_attr "length" "3")
15009    (set_attr "length_immediate" "2")
15010    (set_attr "modrm" "0")])
15011
15012 (define_insn "return_indirect_internal"
15013   [(return)
15014    (use (match_operand:SI 0 "register_operand" "r"))]
15015   "reload_completed"
15016   "jmp\t%A0"
15017   [(set_attr "type" "ibr")
15018    (set_attr "length_immediate" "0")])
15019
15020 (define_insn "nop"
15021   [(const_int 0)]
15022   ""
15023   "nop"
15024   [(set_attr "length" "1")
15025    (set_attr "length_immediate" "0")
15026    (set_attr "modrm" "0")])
15027
15028 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
15029 ;; branch prediction penalty for the third jump in a 16-byte
15030 ;; block on K8.
15031
15032 (define_insn "align"
15033   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15034   ""
15035 {
15036 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15037   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15038 #else
15039   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15040      The align insn is used to avoid 3 jump instructions in the row to improve
15041      branch prediction and the benefits hardly outweigh the cost of extra 8
15042      nops on the average inserted by full alignment pseudo operation.  */
15043 #endif
15044   return "";
15045 }
15046   [(set_attr "length" "16")])
15047
15048 (define_expand "prologue"
15049   [(const_int 0)]
15050   ""
15051   "ix86_expand_prologue (); DONE;")
15052
15053 (define_insn "set_got"
15054   [(set (match_operand:SI 0 "register_operand" "=r")
15055         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15056    (clobber (reg:CC FLAGS_REG))]
15057   "!TARGET_64BIT"
15058   { return output_set_got (operands[0], NULL_RTX); }
15059   [(set_attr "type" "multi")
15060    (set_attr "length" "12")])
15061
15062 (define_insn "set_got_labelled"
15063   [(set (match_operand:SI 0 "register_operand" "=r")
15064         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15065          UNSPEC_SET_GOT))
15066    (clobber (reg:CC FLAGS_REG))]
15067   "!TARGET_64BIT"
15068   { return output_set_got (operands[0], operands[1]); }
15069   [(set_attr "type" "multi")
15070    (set_attr "length" "12")])
15071
15072 (define_insn "set_got_rex64"
15073   [(set (match_operand:DI 0 "register_operand" "=r")
15074         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15075   "TARGET_64BIT"
15076   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
15077   [(set_attr "type" "lea")
15078    (set_attr "length" "6")])
15079
15080 (define_insn "set_rip_rex64"
15081   [(set (match_operand:DI 0 "register_operand" "=r")
15082         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15083   "TARGET_64BIT"
15084   "lea{q}\t%l1(%%rip), %0"
15085   [(set_attr "type" "lea")
15086    (set_attr "length" "6")])
15087
15088 (define_insn "set_got_offset_rex64"
15089   [(set (match_operand:DI 0 "register_operand" "=r")
15090         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15091   "TARGET_64BIT"
15092   "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
15093   [(set_attr "type" "imov")
15094    (set_attr "length" "11")])
15095
15096 (define_expand "epilogue"
15097   [(const_int 0)]
15098   ""
15099   "ix86_expand_epilogue (1); DONE;")
15100
15101 (define_expand "sibcall_epilogue"
15102   [(const_int 0)]
15103   ""
15104   "ix86_expand_epilogue (0); DONE;")
15105
15106 (define_expand "eh_return"
15107   [(use (match_operand 0 "register_operand" ""))]
15108   ""
15109 {
15110   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15111
15112   /* Tricky bit: we write the address of the handler to which we will
15113      be returning into someone else's stack frame, one word below the
15114      stack address we wish to restore.  */
15115   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15116   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15117   tmp = gen_rtx_MEM (Pmode, tmp);
15118   emit_move_insn (tmp, ra);
15119
15120   if (Pmode == SImode)
15121     emit_jump_insn (gen_eh_return_si (sa));
15122   else
15123     emit_jump_insn (gen_eh_return_di (sa));
15124   emit_barrier ();
15125   DONE;
15126 })
15127
15128 (define_insn_and_split "eh_return_si"
15129   [(set (pc)
15130         (unspec [(match_operand:SI 0 "register_operand" "c")]
15131                  UNSPEC_EH_RETURN))]
15132   "!TARGET_64BIT"
15133   "#"
15134   "reload_completed"
15135   [(const_int 0)]
15136   "ix86_expand_epilogue (2); DONE;")
15137
15138 (define_insn_and_split "eh_return_di"
15139   [(set (pc)
15140         (unspec [(match_operand:DI 0 "register_operand" "c")]
15141                  UNSPEC_EH_RETURN))]
15142   "TARGET_64BIT"
15143   "#"
15144   "reload_completed"
15145   [(const_int 0)]
15146   "ix86_expand_epilogue (2); DONE;")
15147
15148 (define_insn "leave"
15149   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15150    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15151    (clobber (mem:BLK (scratch)))]
15152   "!TARGET_64BIT"
15153   "leave"
15154   [(set_attr "type" "leave")])
15155
15156 (define_insn "leave_rex64"
15157   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15158    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15159    (clobber (mem:BLK (scratch)))]
15160   "TARGET_64BIT"
15161   "leave"
15162   [(set_attr "type" "leave")])
15163 \f
15164 (define_expand "ffssi2"
15165   [(parallel
15166      [(set (match_operand:SI 0 "register_operand" "")
15167            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15168       (clobber (match_scratch:SI 2 ""))
15169       (clobber (reg:CC FLAGS_REG))])]
15170   ""
15171 {
15172   if (TARGET_CMOVE)
15173     {
15174       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15175       DONE;
15176     }
15177 })
15178
15179 (define_expand "ffs_cmove"
15180   [(set (match_dup 2) (const_int -1))
15181    (parallel [(set (reg:CCZ FLAGS_REG)
15182                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
15183                                 (const_int 0)))
15184               (set (match_operand:SI 0 "nonimmediate_operand" "")
15185                    (ctz:SI (match_dup 1)))])
15186    (set (match_dup 0) (if_then_else:SI
15187                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15188                         (match_dup 2)
15189                         (match_dup 0)))
15190    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15191               (clobber (reg:CC FLAGS_REG))])]
15192   "TARGET_CMOVE"
15193   "operands[2] = gen_reg_rtx (SImode);")
15194
15195 (define_insn_and_split "*ffs_no_cmove"
15196   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15197         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15198    (clobber (match_scratch:SI 2 "=&q"))
15199    (clobber (reg:CC FLAGS_REG))]
15200   "!TARGET_CMOVE"
15201   "#"
15202   "&& reload_completed"
15203   [(parallel [(set (reg:CCZ FLAGS_REG)
15204                    (compare:CCZ (match_dup 1) (const_int 0)))
15205               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15206    (set (strict_low_part (match_dup 3))
15207         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15208    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15209               (clobber (reg:CC FLAGS_REG))])
15210    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15211               (clobber (reg:CC FLAGS_REG))])
15212    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15213               (clobber (reg:CC FLAGS_REG))])]
15214 {
15215   operands[3] = gen_lowpart (QImode, operands[2]);
15216   ix86_expand_clear (operands[2]);
15217 })
15218
15219 (define_insn "*ffssi_1"
15220   [(set (reg:CCZ FLAGS_REG)
15221         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15222                      (const_int 0)))
15223    (set (match_operand:SI 0 "register_operand" "=r")
15224         (ctz:SI (match_dup 1)))]
15225   ""
15226   "bsf{l}\t{%1, %0|%0, %1}"
15227   [(set_attr "prefix_0f" "1")])
15228
15229 (define_expand "ffsdi2"
15230   [(set (match_dup 2) (const_int -1))
15231    (parallel [(set (reg:CCZ FLAGS_REG)
15232                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
15233                                 (const_int 0)))
15234               (set (match_operand:DI 0 "nonimmediate_operand" "")
15235                    (ctz:DI (match_dup 1)))])
15236    (set (match_dup 0) (if_then_else:DI
15237                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15238                         (match_dup 2)
15239                         (match_dup 0)))
15240    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15241               (clobber (reg:CC FLAGS_REG))])]
15242   "TARGET_64BIT"
15243   "operands[2] = gen_reg_rtx (DImode);")
15244
15245 (define_insn "*ffsdi_1"
15246   [(set (reg:CCZ FLAGS_REG)
15247         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15248                      (const_int 0)))
15249    (set (match_operand:DI 0 "register_operand" "=r")
15250         (ctz:DI (match_dup 1)))]
15251   "TARGET_64BIT"
15252   "bsf{q}\t{%1, %0|%0, %1}"
15253   [(set_attr "prefix_0f" "1")])
15254
15255 (define_insn "ctzsi2"
15256   [(set (match_operand:SI 0 "register_operand" "=r")
15257         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15258    (clobber (reg:CC FLAGS_REG))]
15259   ""
15260   "bsf{l}\t{%1, %0|%0, %1}"
15261   [(set_attr "prefix_0f" "1")])
15262
15263 (define_insn "ctzdi2"
15264   [(set (match_operand:DI 0 "register_operand" "=r")
15265         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15266    (clobber (reg:CC FLAGS_REG))]
15267   "TARGET_64BIT"
15268   "bsf{q}\t{%1, %0|%0, %1}"
15269   [(set_attr "prefix_0f" "1")])
15270
15271 (define_expand "clzsi2"
15272   [(parallel
15273      [(set (match_operand:SI 0 "register_operand" "")
15274            (minus:SI (const_int 31)
15275                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15276       (clobber (reg:CC FLAGS_REG))])
15277    (parallel
15278      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15279       (clobber (reg:CC FLAGS_REG))])]
15280   ""
15281 {
15282   if (TARGET_ABM)
15283     {
15284       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15285       DONE;
15286     }
15287 })
15288
15289 (define_insn "clzsi2_abm"
15290   [(set (match_operand:SI 0 "register_operand" "=r")
15291         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15292    (clobber (reg:CC FLAGS_REG))]
15293   "TARGET_ABM"
15294   "lzcnt{l}\t{%1, %0|%0, %1}"
15295   [(set_attr "prefix_rep" "1")
15296    (set_attr "type" "bitmanip")
15297    (set_attr "mode" "SI")])
15298
15299 (define_insn "*bsr"
15300   [(set (match_operand:SI 0 "register_operand" "=r")
15301         (minus:SI (const_int 31)
15302                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15303    (clobber (reg:CC FLAGS_REG))]
15304   ""
15305   "bsr{l}\t{%1, %0|%0, %1}"
15306   [(set_attr "prefix_0f" "1")
15307    (set_attr "mode" "SI")])
15308
15309 (define_insn "popcountsi2"
15310   [(set (match_operand:SI 0 "register_operand" "=r")
15311         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15312    (clobber (reg:CC FLAGS_REG))]
15313   "TARGET_POPCNT"
15314   "popcnt{l}\t{%1, %0|%0, %1}"
15315   [(set_attr "prefix_rep" "1")
15316    (set_attr "type" "bitmanip")
15317    (set_attr "mode" "SI")])
15318
15319 (define_insn "*popcountsi2_cmp"
15320   [(set (reg FLAGS_REG)
15321         (compare
15322           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15323           (const_int 0)))
15324    (set (match_operand:SI 0 "register_operand" "=r")
15325         (popcount:SI (match_dup 1)))]
15326   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15327   "popcnt{l}\t{%1, %0|%0, %1}"
15328   [(set_attr "prefix_rep" "1")
15329    (set_attr "type" "bitmanip")
15330    (set_attr "mode" "SI")])
15331
15332 (define_insn "*popcountsi2_cmp_zext"
15333   [(set (reg FLAGS_REG)
15334         (compare
15335           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15336           (const_int 0)))
15337    (set (match_operand:DI 0 "register_operand" "=r")
15338         (zero_extend:DI(popcount:SI (match_dup 1))))]
15339   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15340   "popcnt{l}\t{%1, %0|%0, %1}"
15341   [(set_attr "prefix_rep" "1")
15342    (set_attr "type" "bitmanip")
15343    (set_attr "mode" "SI")])
15344
15345 (define_expand "bswapsi2"
15346   [(set (match_operand:SI 0 "register_operand" "")
15347         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15348   ""
15349 {
15350   if (!TARGET_BSWAP)
15351     {
15352       rtx x = operands[0];
15353
15354       emit_move_insn (x, operands[1]);
15355       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15356       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15357       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15358       DONE;
15359     }
15360 })
15361
15362 (define_insn "*bswapsi_1"
15363   [(set (match_operand:SI 0 "register_operand" "=r")
15364         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15365   "TARGET_BSWAP"
15366   "bswap\t%0"
15367   [(set_attr "prefix_0f" "1")
15368    (set_attr "length" "2")])
15369
15370 (define_insn "*bswaphi_lowpart_1"
15371   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15372         (bswap:HI (match_dup 0)))
15373    (clobber (reg:CC FLAGS_REG))]
15374   "TARGET_USE_XCHGB || optimize_size"
15375   "@
15376     xchg{b}\t{%h0, %b0|%b0, %h0}
15377     rol{w}\t{$8, %0|%0, 8}"
15378   [(set_attr "length" "2,4")
15379    (set_attr "mode" "QI,HI")])
15380
15381 (define_insn "bswaphi_lowpart"
15382   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15383         (bswap:HI (match_dup 0)))
15384    (clobber (reg:CC FLAGS_REG))]
15385   ""
15386   "rol{w}\t{$8, %0|%0, 8}"
15387   [(set_attr "length" "4")
15388    (set_attr "mode" "HI")])
15389
15390 (define_insn "bswapdi2"
15391   [(set (match_operand:DI 0 "register_operand" "=r")
15392         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15393   "TARGET_64BIT"
15394   "bswap\t%0"
15395   [(set_attr "prefix_0f" "1")
15396    (set_attr "length" "3")])
15397
15398 (define_expand "clzdi2"
15399   [(parallel
15400      [(set (match_operand:DI 0 "register_operand" "")
15401            (minus:DI (const_int 63)
15402                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15403       (clobber (reg:CC FLAGS_REG))])
15404    (parallel
15405      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15406       (clobber (reg:CC FLAGS_REG))])]
15407   "TARGET_64BIT"
15408 {
15409   if (TARGET_ABM)
15410     {
15411       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15412       DONE;
15413     }
15414 })
15415
15416 (define_insn "clzdi2_abm"
15417   [(set (match_operand:DI 0 "register_operand" "=r")
15418         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15419    (clobber (reg:CC FLAGS_REG))]
15420   "TARGET_64BIT && TARGET_ABM"
15421   "lzcnt{q}\t{%1, %0|%0, %1}"
15422   [(set_attr "prefix_rep" "1")
15423    (set_attr "type" "bitmanip")
15424    (set_attr "mode" "DI")])
15425
15426 (define_insn "*bsr_rex64"
15427   [(set (match_operand:DI 0 "register_operand" "=r")
15428         (minus:DI (const_int 63)
15429                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15430    (clobber (reg:CC FLAGS_REG))]
15431   "TARGET_64BIT"
15432   "bsr{q}\t{%1, %0|%0, %1}"
15433   [(set_attr "prefix_0f" "1")
15434    (set_attr "mode" "DI")])
15435
15436 (define_insn "popcountdi2"
15437   [(set (match_operand:DI 0 "register_operand" "=r")
15438         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15439    (clobber (reg:CC FLAGS_REG))]
15440   "TARGET_64BIT && TARGET_POPCNT"
15441   "popcnt{q}\t{%1, %0|%0, %1}"
15442   [(set_attr "prefix_rep" "1")
15443    (set_attr "type" "bitmanip")
15444    (set_attr "mode" "DI")])
15445
15446 (define_insn "*popcountdi2_cmp"
15447   [(set (reg FLAGS_REG)
15448         (compare
15449           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15450           (const_int 0)))
15451    (set (match_operand:DI 0 "register_operand" "=r")
15452         (popcount:DI (match_dup 1)))]
15453   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15454   "popcnt{q}\t{%1, %0|%0, %1}"
15455   [(set_attr "prefix_rep" "1")
15456    (set_attr "type" "bitmanip")
15457    (set_attr "mode" "DI")])
15458
15459 (define_expand "clzhi2"
15460   [(parallel
15461      [(set (match_operand:HI 0 "register_operand" "")
15462            (minus:HI (const_int 15)
15463                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15464       (clobber (reg:CC FLAGS_REG))])
15465    (parallel
15466      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15467       (clobber (reg:CC FLAGS_REG))])]
15468   ""
15469 {
15470   if (TARGET_ABM)
15471     {
15472       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15473       DONE;
15474     }
15475 })
15476
15477 (define_insn "clzhi2_abm"
15478   [(set (match_operand:HI 0 "register_operand" "=r")
15479         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15480    (clobber (reg:CC FLAGS_REG))]
15481   "TARGET_ABM"
15482   "lzcnt{w}\t{%1, %0|%0, %1}"
15483   [(set_attr "prefix_rep" "1")
15484    (set_attr "type" "bitmanip")
15485    (set_attr "mode" "HI")])
15486
15487 (define_insn "*bsrhi"
15488   [(set (match_operand:HI 0 "register_operand" "=r")
15489         (minus:HI (const_int 15)
15490                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15491    (clobber (reg:CC FLAGS_REG))]
15492   ""
15493   "bsr{w}\t{%1, %0|%0, %1}"
15494   [(set_attr "prefix_0f" "1")
15495    (set_attr "mode" "HI")])
15496
15497 (define_insn "popcounthi2"
15498   [(set (match_operand:HI 0 "register_operand" "=r")
15499         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15500    (clobber (reg:CC FLAGS_REG))]
15501   "TARGET_POPCNT"
15502   "popcnt{w}\t{%1, %0|%0, %1}"
15503   [(set_attr "prefix_rep" "1")
15504    (set_attr "type" "bitmanip")
15505    (set_attr "mode" "HI")])
15506
15507 (define_insn "*popcounthi2_cmp"
15508   [(set (reg FLAGS_REG)
15509         (compare
15510           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15511           (const_int 0)))
15512    (set (match_operand:HI 0 "register_operand" "=r")
15513         (popcount:HI (match_dup 1)))]
15514   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15515   "popcnt{w}\t{%1, %0|%0, %1}"
15516   [(set_attr "prefix_rep" "1")
15517    (set_attr "type" "bitmanip")
15518    (set_attr "mode" "HI")])
15519
15520 (define_expand "paritydi2"
15521   [(set (match_operand:DI 0 "register_operand" "")
15522         (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15523   "! TARGET_POPCNT"
15524 {
15525   rtx scratch = gen_reg_rtx (QImode);
15526   rtx cond;
15527
15528   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15529                                 NULL_RTX, operands[1]));
15530
15531   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15532                          gen_rtx_REG (CCmode, FLAGS_REG),
15533                          const0_rtx);
15534   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15535
15536   if (TARGET_64BIT)
15537     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15538   else
15539     {
15540       rtx tmp = gen_reg_rtx (SImode);
15541
15542       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15543       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15544     }
15545   DONE;
15546 })
15547
15548 (define_insn_and_split "paritydi2_cmp"
15549   [(set (reg:CC FLAGS_REG)
15550         (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15551    (clobber (match_scratch:DI 0 "=r,X"))
15552    (clobber (match_scratch:SI 1 "=r,r"))
15553    (clobber (match_scratch:HI 2 "=Q,Q"))]
15554   "! TARGET_POPCNT"
15555   "#"
15556   "&& reload_completed"
15557   [(parallel
15558      [(set (match_dup 1)
15559            (xor:SI (match_dup 1) (match_dup 4)))
15560       (clobber (reg:CC FLAGS_REG))])
15561    (parallel
15562      [(set (reg:CC FLAGS_REG)
15563            (parity:CC (match_dup 1)))
15564       (clobber (match_dup 1))
15565       (clobber (match_dup 2))])]
15566 {
15567   operands[4] = gen_lowpart (SImode, operands[3]);
15568
15569   if (MEM_P (operands[3]))
15570     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15571   else if (! TARGET_64BIT)
15572     operands[1] = gen_highpart (SImode, operands[3]);
15573   else
15574     {
15575       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15576       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15577     }
15578 })
15579
15580 (define_expand "paritysi2"
15581   [(set (match_operand:SI 0 "register_operand" "")
15582         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15583   "! TARGET_POPCNT"
15584 {
15585   rtx scratch = gen_reg_rtx (QImode);
15586   rtx cond;
15587
15588   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15589
15590   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15591                          gen_rtx_REG (CCmode, FLAGS_REG),
15592                          const0_rtx);
15593   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15594
15595   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15596   DONE;
15597 })
15598
15599 (define_insn_and_split "paritysi2_cmp"
15600   [(set (reg:CC FLAGS_REG)
15601         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15602    (clobber (match_scratch:SI 0 "=r,X"))
15603    (clobber (match_scratch:HI 1 "=Q,Q"))]
15604   "! TARGET_POPCNT"
15605   "#"
15606   "&& reload_completed"
15607   [(parallel
15608      [(set (match_dup 1)
15609            (xor:HI (match_dup 1) (match_dup 3)))
15610       (clobber (reg:CC FLAGS_REG))])
15611    (parallel
15612      [(set (reg:CC FLAGS_REG)
15613            (parity:CC (match_dup 1)))
15614       (clobber (match_dup 1))])]
15615 {
15616   operands[3] = gen_lowpart (HImode, operands[2]);
15617
15618   if (MEM_P (operands[2]))
15619     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15620   else
15621     {
15622       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15623       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15624     }
15625 })
15626
15627 (define_insn "*parityhi2_cmp"
15628   [(set (reg:CC FLAGS_REG)
15629         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15630    (clobber (match_scratch:HI 0 "=Q"))]
15631   "! TARGET_POPCNT"
15632   "xor{b}\t{%h0, %b0|%b0, %h0}"
15633   [(set_attr "length" "2")
15634    (set_attr "mode" "HI")])
15635
15636 (define_insn "*parityqi2_cmp"
15637   [(set (reg:CC FLAGS_REG)
15638         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15639   "! TARGET_POPCNT"
15640   "test{b}\t%0, %0"
15641   [(set_attr "length" "2")
15642    (set_attr "mode" "QI")])
15643 \f
15644 ;; Thread-local storage patterns for ELF.
15645 ;;
15646 ;; Note that these code sequences must appear exactly as shown
15647 ;; in order to allow linker relaxation.
15648
15649 (define_insn "*tls_global_dynamic_32_gnu"
15650   [(set (match_operand:SI 0 "register_operand" "=a")
15651         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15652                     (match_operand:SI 2 "tls_symbolic_operand" "")
15653                     (match_operand:SI 3 "call_insn_operand" "")]
15654                     UNSPEC_TLS_GD))
15655    (clobber (match_scratch:SI 4 "=d"))
15656    (clobber (match_scratch:SI 5 "=c"))
15657    (clobber (reg:CC FLAGS_REG))]
15658   "!TARGET_64BIT && TARGET_GNU_TLS"
15659   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15660   [(set_attr "type" "multi")
15661    (set_attr "length" "12")])
15662
15663 (define_insn "*tls_global_dynamic_32_sun"
15664   [(set (match_operand:SI 0 "register_operand" "=a")
15665         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15666                     (match_operand:SI 2 "tls_symbolic_operand" "")
15667                     (match_operand:SI 3 "call_insn_operand" "")]
15668                     UNSPEC_TLS_GD))
15669    (clobber (match_scratch:SI 4 "=d"))
15670    (clobber (match_scratch:SI 5 "=c"))
15671    (clobber (reg:CC FLAGS_REG))]
15672   "!TARGET_64BIT && TARGET_SUN_TLS"
15673   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15674         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15675   [(set_attr "type" "multi")
15676    (set_attr "length" "14")])
15677
15678 (define_expand "tls_global_dynamic_32"
15679   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15680                    (unspec:SI
15681                     [(match_dup 2)
15682                      (match_operand:SI 1 "tls_symbolic_operand" "")
15683                      (match_dup 3)]
15684                     UNSPEC_TLS_GD))
15685               (clobber (match_scratch:SI 4 ""))
15686               (clobber (match_scratch:SI 5 ""))
15687               (clobber (reg:CC FLAGS_REG))])]
15688   ""
15689 {
15690   if (flag_pic)
15691     operands[2] = pic_offset_table_rtx;
15692   else
15693     {
15694       operands[2] = gen_reg_rtx (Pmode);
15695       emit_insn (gen_set_got (operands[2]));
15696     }
15697   if (TARGET_GNU2_TLS)
15698     {
15699        emit_insn (gen_tls_dynamic_gnu2_32
15700                   (operands[0], operands[1], operands[2]));
15701        DONE;
15702     }
15703   operands[3] = ix86_tls_get_addr ();
15704 })
15705
15706 (define_insn "*tls_global_dynamic_64"
15707   [(set (match_operand:DI 0 "register_operand" "=a")
15708         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15709                  (match_operand:DI 3 "" "")))
15710    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15711               UNSPEC_TLS_GD)]
15712   "TARGET_64BIT"
15713   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15714   [(set_attr "type" "multi")
15715    (set_attr "length" "16")])
15716
15717 (define_expand "tls_global_dynamic_64"
15718   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15719                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15720               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15721                          UNSPEC_TLS_GD)])]
15722   ""
15723 {
15724   if (TARGET_GNU2_TLS)
15725     {
15726        emit_insn (gen_tls_dynamic_gnu2_64
15727                   (operands[0], operands[1]));
15728        DONE;
15729     }
15730   operands[2] = ix86_tls_get_addr ();
15731 })
15732
15733 (define_insn "*tls_local_dynamic_base_32_gnu"
15734   [(set (match_operand:SI 0 "register_operand" "=a")
15735         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15736                     (match_operand:SI 2 "call_insn_operand" "")]
15737                    UNSPEC_TLS_LD_BASE))
15738    (clobber (match_scratch:SI 3 "=d"))
15739    (clobber (match_scratch:SI 4 "=c"))
15740    (clobber (reg:CC FLAGS_REG))]
15741   "!TARGET_64BIT && TARGET_GNU_TLS"
15742   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15743   [(set_attr "type" "multi")
15744    (set_attr "length" "11")])
15745
15746 (define_insn "*tls_local_dynamic_base_32_sun"
15747   [(set (match_operand:SI 0 "register_operand" "=a")
15748         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15749                     (match_operand:SI 2 "call_insn_operand" "")]
15750                    UNSPEC_TLS_LD_BASE))
15751    (clobber (match_scratch:SI 3 "=d"))
15752    (clobber (match_scratch:SI 4 "=c"))
15753    (clobber (reg:CC FLAGS_REG))]
15754   "!TARGET_64BIT && TARGET_SUN_TLS"
15755   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15756         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15757   [(set_attr "type" "multi")
15758    (set_attr "length" "13")])
15759
15760 (define_expand "tls_local_dynamic_base_32"
15761   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15762                    (unspec:SI [(match_dup 1) (match_dup 2)]
15763                               UNSPEC_TLS_LD_BASE))
15764               (clobber (match_scratch:SI 3 ""))
15765               (clobber (match_scratch:SI 4 ""))
15766               (clobber (reg:CC FLAGS_REG))])]
15767   ""
15768 {
15769   if (flag_pic)
15770     operands[1] = pic_offset_table_rtx;
15771   else
15772     {
15773       operands[1] = gen_reg_rtx (Pmode);
15774       emit_insn (gen_set_got (operands[1]));
15775     }
15776   if (TARGET_GNU2_TLS)
15777     {
15778        emit_insn (gen_tls_dynamic_gnu2_32
15779                   (operands[0], ix86_tls_module_base (), operands[1]));
15780        DONE;
15781     }
15782   operands[2] = ix86_tls_get_addr ();
15783 })
15784
15785 (define_insn "*tls_local_dynamic_base_64"
15786   [(set (match_operand:DI 0 "register_operand" "=a")
15787         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15788                  (match_operand:DI 2 "" "")))
15789    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15790   "TARGET_64BIT"
15791   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15792   [(set_attr "type" "multi")
15793    (set_attr "length" "12")])
15794
15795 (define_expand "tls_local_dynamic_base_64"
15796   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15797                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15798               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15799   ""
15800 {
15801   if (TARGET_GNU2_TLS)
15802     {
15803        emit_insn (gen_tls_dynamic_gnu2_64
15804                   (operands[0], ix86_tls_module_base ()));
15805        DONE;
15806     }
15807   operands[1] = ix86_tls_get_addr ();
15808 })
15809
15810 ;; Local dynamic of a single variable is a lose.  Show combine how
15811 ;; to convert that back to global dynamic.
15812
15813 (define_insn_and_split "*tls_local_dynamic_32_once"
15814   [(set (match_operand:SI 0 "register_operand" "=a")
15815         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15816                              (match_operand:SI 2 "call_insn_operand" "")]
15817                             UNSPEC_TLS_LD_BASE)
15818                  (const:SI (unspec:SI
15819                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15820                             UNSPEC_DTPOFF))))
15821    (clobber (match_scratch:SI 4 "=d"))
15822    (clobber (match_scratch:SI 5 "=c"))
15823    (clobber (reg:CC FLAGS_REG))]
15824   ""
15825   "#"
15826   ""
15827   [(parallel [(set (match_dup 0)
15828                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15829                               UNSPEC_TLS_GD))
15830               (clobber (match_dup 4))
15831               (clobber (match_dup 5))
15832               (clobber (reg:CC FLAGS_REG))])]
15833   "")
15834
15835 ;; Load and add the thread base pointer from %gs:0.
15836
15837 (define_insn "*load_tp_si"
15838   [(set (match_operand:SI 0 "register_operand" "=r")
15839         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15840   "!TARGET_64BIT"
15841   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15842   [(set_attr "type" "imov")
15843    (set_attr "modrm" "0")
15844    (set_attr "length" "7")
15845    (set_attr "memory" "load")
15846    (set_attr "imm_disp" "false")])
15847
15848 (define_insn "*add_tp_si"
15849   [(set (match_operand:SI 0 "register_operand" "=r")
15850         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15851                  (match_operand:SI 1 "register_operand" "0")))
15852    (clobber (reg:CC FLAGS_REG))]
15853   "!TARGET_64BIT"
15854   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15855   [(set_attr "type" "alu")
15856    (set_attr "modrm" "0")
15857    (set_attr "length" "7")
15858    (set_attr "memory" "load")
15859    (set_attr "imm_disp" "false")])
15860
15861 (define_insn "*load_tp_di"
15862   [(set (match_operand:DI 0 "register_operand" "=r")
15863         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15864   "TARGET_64BIT"
15865   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15866   [(set_attr "type" "imov")
15867    (set_attr "modrm" "0")
15868    (set_attr "length" "7")
15869    (set_attr "memory" "load")
15870    (set_attr "imm_disp" "false")])
15871
15872 (define_insn "*add_tp_di"
15873   [(set (match_operand:DI 0 "register_operand" "=r")
15874         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15875                  (match_operand:DI 1 "register_operand" "0")))
15876    (clobber (reg:CC FLAGS_REG))]
15877   "TARGET_64BIT"
15878   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15879   [(set_attr "type" "alu")
15880    (set_attr "modrm" "0")
15881    (set_attr "length" "7")
15882    (set_attr "memory" "load")
15883    (set_attr "imm_disp" "false")])
15884
15885 ;; GNU2 TLS patterns can be split.
15886
15887 (define_expand "tls_dynamic_gnu2_32"
15888   [(set (match_dup 3)
15889         (plus:SI (match_operand:SI 2 "register_operand" "")
15890                  (const:SI
15891                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15892                              UNSPEC_TLSDESC))))
15893    (parallel
15894     [(set (match_operand:SI 0 "register_operand" "")
15895           (unspec:SI [(match_dup 1) (match_dup 3)
15896                       (match_dup 2) (reg:SI SP_REG)]
15897                       UNSPEC_TLSDESC))
15898      (clobber (reg:CC FLAGS_REG))])]
15899   "!TARGET_64BIT && TARGET_GNU2_TLS"
15900 {
15901   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15902   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15903 })
15904
15905 (define_insn "*tls_dynamic_lea_32"
15906   [(set (match_operand:SI 0 "register_operand" "=r")
15907         (plus:SI (match_operand:SI 1 "register_operand" "b")
15908                  (const:SI
15909                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15910                               UNSPEC_TLSDESC))))]
15911   "!TARGET_64BIT && TARGET_GNU2_TLS"
15912   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15913   [(set_attr "type" "lea")
15914    (set_attr "mode" "SI")
15915    (set_attr "length" "6")
15916    (set_attr "length_address" "4")])
15917
15918 (define_insn "*tls_dynamic_call_32"
15919   [(set (match_operand:SI 0 "register_operand" "=a")
15920         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15921                     (match_operand:SI 2 "register_operand" "0")
15922                     ;; we have to make sure %ebx still points to the GOT
15923                     (match_operand:SI 3 "register_operand" "b")
15924                     (reg:SI SP_REG)]
15925                    UNSPEC_TLSDESC))
15926    (clobber (reg:CC FLAGS_REG))]
15927   "!TARGET_64BIT && TARGET_GNU2_TLS"
15928   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15929   [(set_attr "type" "call")
15930    (set_attr "length" "2")
15931    (set_attr "length_address" "0")])
15932
15933 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15934   [(set (match_operand:SI 0 "register_operand" "=&a")
15935         (plus:SI
15936          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15937                      (match_operand:SI 4 "" "")
15938                      (match_operand:SI 2 "register_operand" "b")
15939                      (reg:SI SP_REG)]
15940                     UNSPEC_TLSDESC)
15941          (const:SI (unspec:SI
15942                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15943                     UNSPEC_DTPOFF))))
15944    (clobber (reg:CC FLAGS_REG))]
15945   "!TARGET_64BIT && TARGET_GNU2_TLS"
15946   "#"
15947   ""
15948   [(set (match_dup 0) (match_dup 5))]
15949 {
15950   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15951   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15952 })
15953
15954 (define_expand "tls_dynamic_gnu2_64"
15955   [(set (match_dup 2)
15956         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15957                    UNSPEC_TLSDESC))
15958    (parallel
15959     [(set (match_operand:DI 0 "register_operand" "")
15960           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15961                      UNSPEC_TLSDESC))
15962      (clobber (reg:CC FLAGS_REG))])]
15963   "TARGET_64BIT && TARGET_GNU2_TLS"
15964 {
15965   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15966   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15967 })
15968
15969 (define_insn "*tls_dynamic_lea_64"
15970   [(set (match_operand:DI 0 "register_operand" "=r")
15971         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15972                    UNSPEC_TLSDESC))]
15973   "TARGET_64BIT && TARGET_GNU2_TLS"
15974   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15975   [(set_attr "type" "lea")
15976    (set_attr "mode" "DI")
15977    (set_attr "length" "7")
15978    (set_attr "length_address" "4")])
15979
15980 (define_insn "*tls_dynamic_call_64"
15981   [(set (match_operand:DI 0 "register_operand" "=a")
15982         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15983                     (match_operand:DI 2 "register_operand" "0")
15984                     (reg:DI SP_REG)]
15985                    UNSPEC_TLSDESC))
15986    (clobber (reg:CC FLAGS_REG))]
15987   "TARGET_64BIT && TARGET_GNU2_TLS"
15988   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15989   [(set_attr "type" "call")
15990    (set_attr "length" "2")
15991    (set_attr "length_address" "0")])
15992
15993 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15994   [(set (match_operand:DI 0 "register_operand" "=&a")
15995         (plus:DI
15996          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15997                      (match_operand:DI 3 "" "")
15998                      (reg:DI SP_REG)]
15999                     UNSPEC_TLSDESC)
16000          (const:DI (unspec:DI
16001                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16002                     UNSPEC_DTPOFF))))
16003    (clobber (reg:CC FLAGS_REG))]
16004   "TARGET_64BIT && TARGET_GNU2_TLS"
16005   "#"
16006   ""
16007   [(set (match_dup 0) (match_dup 4))]
16008 {
16009   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16010   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16011 })
16012
16013 ;;
16014 \f
16015 ;; These patterns match the binary 387 instructions for addM3, subM3,
16016 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16017 ;; SFmode.  The first is the normal insn, the second the same insn but
16018 ;; with one operand a conversion, and the third the same insn but with
16019 ;; the other operand a conversion.  The conversion may be SFmode or
16020 ;; SImode if the target mode DFmode, but only SImode if the target mode
16021 ;; is SFmode.
16022
16023 ;; Gcc is slightly more smart about handling normal two address instructions
16024 ;; so use special patterns for add and mull.
16025
16026 (define_insn "*fop_sf_comm_mixed"
16027   [(set (match_operand:SF 0 "register_operand" "=f,x")
16028         (match_operator:SF 3 "binary_fp_operator"
16029                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
16030                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
16031   "TARGET_MIX_SSE_I387
16032    && COMMUTATIVE_ARITH_P (operands[3])
16033    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16034   "* return output_387_binary_op (insn, operands);"
16035   [(set (attr "type")
16036         (if_then_else (eq_attr "alternative" "1")
16037            (if_then_else (match_operand:SF 3 "mult_operator" "")
16038               (const_string "ssemul")
16039               (const_string "sseadd"))
16040            (if_then_else (match_operand:SF 3 "mult_operator" "")
16041               (const_string "fmul")
16042               (const_string "fop"))))
16043    (set_attr "mode" "SF")])
16044
16045 (define_insn "*fop_sf_comm_sse"
16046   [(set (match_operand:SF 0 "register_operand" "=x")
16047         (match_operator:SF 3 "binary_fp_operator"
16048                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
16049                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16050   "TARGET_SSE_MATH
16051    && COMMUTATIVE_ARITH_P (operands[3])
16052    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16053   "* return output_387_binary_op (insn, operands);"
16054   [(set (attr "type")
16055         (if_then_else (match_operand:SF 3 "mult_operator" "")
16056            (const_string "ssemul")
16057            (const_string "sseadd")))
16058    (set_attr "mode" "SF")])
16059
16060 (define_insn "*fop_sf_comm_i387"
16061   [(set (match_operand:SF 0 "register_operand" "=f")
16062         (match_operator:SF 3 "binary_fp_operator"
16063                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
16064                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
16065   "TARGET_80387
16066    && COMMUTATIVE_ARITH_P (operands[3])
16067    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16068   "* return output_387_binary_op (insn, operands);"
16069   [(set (attr "type")
16070         (if_then_else (match_operand:SF 3 "mult_operator" "")
16071            (const_string "fmul")
16072            (const_string "fop")))
16073    (set_attr "mode" "SF")])
16074
16075 (define_insn "*fop_sf_1_mixed"
16076   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
16077         (match_operator:SF 3 "binary_fp_operator"
16078                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
16079                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
16080   "TARGET_MIX_SSE_I387
16081    && !COMMUTATIVE_ARITH_P (operands[3])
16082    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16083   "* return output_387_binary_op (insn, operands);"
16084   [(set (attr "type")
16085         (cond [(and (eq_attr "alternative" "2")
16086                     (match_operand:SF 3 "mult_operator" ""))
16087                  (const_string "ssemul")
16088                (and (eq_attr "alternative" "2")
16089                     (match_operand:SF 3 "div_operator" ""))
16090                  (const_string "ssediv")
16091                (eq_attr "alternative" "2")
16092                  (const_string "sseadd")
16093                (match_operand:SF 3 "mult_operator" "")
16094                  (const_string "fmul")
16095                (match_operand:SF 3 "div_operator" "")
16096                  (const_string "fdiv")
16097               ]
16098               (const_string "fop")))
16099    (set_attr "mode" "SF")])
16100
16101 (define_insn "*rcpsf2_sse"
16102   [(set (match_operand:SF 0 "register_operand" "=x")
16103         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16104                    UNSPEC_RCP))]
16105   "TARGET_SSE_MATH"
16106   "rcpss\t{%1, %0|%0, %1}"
16107   [(set_attr "type" "sse")
16108    (set_attr "mode" "SF")])
16109
16110 (define_insn "*fop_sf_1_sse"
16111   [(set (match_operand:SF 0 "register_operand" "=x")
16112         (match_operator:SF 3 "binary_fp_operator"
16113                         [(match_operand:SF 1 "register_operand" "0")
16114                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16115   "TARGET_SSE_MATH
16116    && !COMMUTATIVE_ARITH_P (operands[3])"
16117   "* return output_387_binary_op (insn, operands);"
16118   [(set (attr "type")
16119         (cond [(match_operand:SF 3 "mult_operator" "")
16120                  (const_string "ssemul")
16121                (match_operand:SF 3 "div_operator" "")
16122                  (const_string "ssediv")
16123               ]
16124               (const_string "sseadd")))
16125    (set_attr "mode" "SF")])
16126
16127 ;; This pattern is not fully shadowed by the pattern above.
16128 (define_insn "*fop_sf_1_i387"
16129   [(set (match_operand:SF 0 "register_operand" "=f,f")
16130         (match_operator:SF 3 "binary_fp_operator"
16131                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
16132                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
16133   "TARGET_80387 && !TARGET_SSE_MATH
16134    && !COMMUTATIVE_ARITH_P (operands[3])
16135    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16136   "* return output_387_binary_op (insn, operands);"
16137   [(set (attr "type")
16138         (cond [(match_operand:SF 3 "mult_operator" "")
16139                  (const_string "fmul")
16140                (match_operand:SF 3 "div_operator" "")
16141                  (const_string "fdiv")
16142               ]
16143               (const_string "fop")))
16144    (set_attr "mode" "SF")])
16145
16146 ;; ??? Add SSE splitters for these!
16147 (define_insn "*fop_sf_2<mode>_i387"
16148   [(set (match_operand:SF 0 "register_operand" "=f,f")
16149         (match_operator:SF 3 "binary_fp_operator"
16150           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16151            (match_operand:SF 2 "register_operand" "0,0")]))]
16152   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16153   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16154   [(set (attr "type")
16155         (cond [(match_operand:SF 3 "mult_operator" "")
16156                  (const_string "fmul")
16157                (match_operand:SF 3 "div_operator" "")
16158                  (const_string "fdiv")
16159               ]
16160               (const_string "fop")))
16161    (set_attr "fp_int_src" "true")
16162    (set_attr "mode" "<MODE>")])
16163
16164 (define_insn "*fop_sf_3<mode>_i387"
16165   [(set (match_operand:SF 0 "register_operand" "=f,f")
16166         (match_operator:SF 3 "binary_fp_operator"
16167           [(match_operand:SF 1 "register_operand" "0,0")
16168            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16169   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16170   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16171   [(set (attr "type")
16172         (cond [(match_operand:SF 3 "mult_operator" "")
16173                  (const_string "fmul")
16174                (match_operand:SF 3 "div_operator" "")
16175                  (const_string "fdiv")
16176               ]
16177               (const_string "fop")))
16178    (set_attr "fp_int_src" "true")
16179    (set_attr "mode" "<MODE>")])
16180
16181 (define_insn "*fop_df_comm_mixed"
16182   [(set (match_operand:DF 0 "register_operand" "=f,x")
16183         (match_operator:DF 3 "binary_fp_operator"
16184           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16185            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16186   "TARGET_SSE2 && TARGET_MIX_SSE_I387
16187    && COMMUTATIVE_ARITH_P (operands[3])
16188    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16189   "* return output_387_binary_op (insn, operands);"
16190   [(set (attr "type")
16191         (if_then_else (eq_attr "alternative" "1")
16192            (if_then_else (match_operand:DF 3 "mult_operator" "")
16193               (const_string "ssemul")
16194               (const_string "sseadd"))
16195            (if_then_else (match_operand:DF 3 "mult_operator" "")
16196               (const_string "fmul")
16197               (const_string "fop"))))
16198    (set_attr "mode" "DF")])
16199
16200 (define_insn "*fop_df_comm_sse"
16201   [(set (match_operand:DF 0 "register_operand" "=x")
16202         (match_operator:DF 3 "binary_fp_operator"
16203           [(match_operand:DF 1 "nonimmediate_operand" "%0")
16204            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16205   "TARGET_SSE2 && TARGET_SSE_MATH
16206    && COMMUTATIVE_ARITH_P (operands[3])
16207    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16208   "* return output_387_binary_op (insn, operands);"
16209   [(set (attr "type")
16210         (if_then_else (match_operand:DF 3 "mult_operator" "")
16211            (const_string "ssemul")
16212            (const_string "sseadd")))
16213    (set_attr "mode" "DF")])
16214
16215 (define_insn "*fop_df_comm_i387"
16216   [(set (match_operand:DF 0 "register_operand" "=f")
16217         (match_operator:DF 3 "binary_fp_operator"
16218                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
16219                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16220   "TARGET_80387
16221    && COMMUTATIVE_ARITH_P (operands[3])
16222    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16223   "* return output_387_binary_op (insn, operands);"
16224   [(set (attr "type")
16225         (if_then_else (match_operand:DF 3 "mult_operator" "")
16226            (const_string "fmul")
16227            (const_string "fop")))
16228    (set_attr "mode" "DF")])
16229
16230 (define_insn "*fop_df_1_mixed"
16231   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16232         (match_operator:DF 3 "binary_fp_operator"
16233           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16234            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16235   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16236    && !COMMUTATIVE_ARITH_P (operands[3])
16237    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16238   "* return output_387_binary_op (insn, operands);"
16239   [(set (attr "type")
16240         (cond [(and (eq_attr "alternative" "2")
16241                     (match_operand:DF 3 "mult_operator" ""))
16242                  (const_string "ssemul")
16243                (and (eq_attr "alternative" "2")
16244                     (match_operand:DF 3 "div_operator" ""))
16245                  (const_string "ssediv")
16246                (eq_attr "alternative" "2")
16247                  (const_string "sseadd")
16248                (match_operand:DF 3 "mult_operator" "")
16249                  (const_string "fmul")
16250                (match_operand:DF 3 "div_operator" "")
16251                  (const_string "fdiv")
16252               ]
16253               (const_string "fop")))
16254    (set_attr "mode" "DF")])
16255
16256 (define_insn "*fop_df_1_sse"
16257   [(set (match_operand:DF 0 "register_operand" "=x")
16258         (match_operator:DF 3 "binary_fp_operator"
16259           [(match_operand:DF 1 "register_operand" "0")
16260            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16261   "TARGET_SSE2 && TARGET_SSE_MATH
16262    && !COMMUTATIVE_ARITH_P (operands[3])"
16263   "* return output_387_binary_op (insn, operands);"
16264   [(set_attr "mode" "DF")
16265    (set (attr "type")
16266         (cond [(match_operand:DF 3 "mult_operator" "")
16267                  (const_string "ssemul")
16268                (match_operand:DF 3 "div_operator" "")
16269                  (const_string "ssediv")
16270               ]
16271               (const_string "sseadd")))])
16272
16273 ;; This pattern is not fully shadowed by the pattern above.
16274 (define_insn "*fop_df_1_i387"
16275   [(set (match_operand:DF 0 "register_operand" "=f,f")
16276         (match_operator:DF 3 "binary_fp_operator"
16277                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16278                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16279   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16280    && !COMMUTATIVE_ARITH_P (operands[3])
16281    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16282   "* return output_387_binary_op (insn, operands);"
16283   [(set (attr "type")
16284         (cond [(match_operand:DF 3 "mult_operator" "")
16285                  (const_string "fmul")
16286                (match_operand:DF 3 "div_operator" "")
16287                  (const_string "fdiv")
16288               ]
16289               (const_string "fop")))
16290    (set_attr "mode" "DF")])
16291
16292 ;; ??? Add SSE splitters for these!
16293 (define_insn "*fop_df_2<mode>_i387"
16294   [(set (match_operand:DF 0 "register_operand" "=f,f")
16295         (match_operator:DF 3 "binary_fp_operator"
16296            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16297             (match_operand:DF 2 "register_operand" "0,0")]))]
16298   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16299    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16300   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16301   [(set (attr "type")
16302         (cond [(match_operand:DF 3 "mult_operator" "")
16303                  (const_string "fmul")
16304                (match_operand:DF 3 "div_operator" "")
16305                  (const_string "fdiv")
16306               ]
16307               (const_string "fop")))
16308    (set_attr "fp_int_src" "true")
16309    (set_attr "mode" "<MODE>")])
16310
16311 (define_insn "*fop_df_3<mode>_i387"
16312   [(set (match_operand:DF 0 "register_operand" "=f,f")
16313         (match_operator:DF 3 "binary_fp_operator"
16314            [(match_operand:DF 1 "register_operand" "0,0")
16315             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16316   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16317    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16318   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16319   [(set (attr "type")
16320         (cond [(match_operand:DF 3 "mult_operator" "")
16321                  (const_string "fmul")
16322                (match_operand:DF 3 "div_operator" "")
16323                  (const_string "fdiv")
16324               ]
16325               (const_string "fop")))
16326    (set_attr "fp_int_src" "true")
16327    (set_attr "mode" "<MODE>")])
16328
16329 (define_insn "*fop_df_4_i387"
16330   [(set (match_operand:DF 0 "register_operand" "=f,f")
16331         (match_operator:DF 3 "binary_fp_operator"
16332            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16333             (match_operand:DF 2 "register_operand" "0,f")]))]
16334   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16335    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16336   "* return output_387_binary_op (insn, operands);"
16337   [(set (attr "type")
16338         (cond [(match_operand:DF 3 "mult_operator" "")
16339                  (const_string "fmul")
16340                (match_operand:DF 3 "div_operator" "")
16341                  (const_string "fdiv")
16342               ]
16343               (const_string "fop")))
16344    (set_attr "mode" "SF")])
16345
16346 (define_insn "*fop_df_5_i387"
16347   [(set (match_operand:DF 0 "register_operand" "=f,f")
16348         (match_operator:DF 3 "binary_fp_operator"
16349           [(match_operand:DF 1 "register_operand" "0,f")
16350            (float_extend:DF
16351             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16352   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16353   "* return output_387_binary_op (insn, operands);"
16354   [(set (attr "type")
16355         (cond [(match_operand:DF 3 "mult_operator" "")
16356                  (const_string "fmul")
16357                (match_operand:DF 3 "div_operator" "")
16358                  (const_string "fdiv")
16359               ]
16360               (const_string "fop")))
16361    (set_attr "mode" "SF")])
16362
16363 (define_insn "*fop_df_6_i387"
16364   [(set (match_operand:DF 0 "register_operand" "=f,f")
16365         (match_operator:DF 3 "binary_fp_operator"
16366           [(float_extend:DF
16367             (match_operand:SF 1 "register_operand" "0,f"))
16368            (float_extend:DF
16369             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16370   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16371   "* return output_387_binary_op (insn, operands);"
16372   [(set (attr "type")
16373         (cond [(match_operand:DF 3 "mult_operator" "")
16374                  (const_string "fmul")
16375                (match_operand:DF 3 "div_operator" "")
16376                  (const_string "fdiv")
16377               ]
16378               (const_string "fop")))
16379    (set_attr "mode" "SF")])
16380
16381 (define_insn "*fop_xf_comm_i387"
16382   [(set (match_operand:XF 0 "register_operand" "=f")
16383         (match_operator:XF 3 "binary_fp_operator"
16384                         [(match_operand:XF 1 "register_operand" "%0")
16385                          (match_operand:XF 2 "register_operand" "f")]))]
16386   "TARGET_80387
16387    && COMMUTATIVE_ARITH_P (operands[3])"
16388   "* return output_387_binary_op (insn, operands);"
16389   [(set (attr "type")
16390         (if_then_else (match_operand:XF 3 "mult_operator" "")
16391            (const_string "fmul")
16392            (const_string "fop")))
16393    (set_attr "mode" "XF")])
16394
16395 (define_insn "*fop_xf_1_i387"
16396   [(set (match_operand:XF 0 "register_operand" "=f,f")
16397         (match_operator:XF 3 "binary_fp_operator"
16398                         [(match_operand:XF 1 "register_operand" "0,f")
16399                          (match_operand:XF 2 "register_operand" "f,0")]))]
16400   "TARGET_80387
16401    && !COMMUTATIVE_ARITH_P (operands[3])"
16402   "* return output_387_binary_op (insn, operands);"
16403   [(set (attr "type")
16404         (cond [(match_operand:XF 3 "mult_operator" "")
16405                  (const_string "fmul")
16406                (match_operand:XF 3 "div_operator" "")
16407                  (const_string "fdiv")
16408               ]
16409               (const_string "fop")))
16410    (set_attr "mode" "XF")])
16411
16412 (define_insn "*fop_xf_2<mode>_i387"
16413   [(set (match_operand:XF 0 "register_operand" "=f,f")
16414         (match_operator:XF 3 "binary_fp_operator"
16415            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16416             (match_operand:XF 2 "register_operand" "0,0")]))]
16417   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16418   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16419   [(set (attr "type")
16420         (cond [(match_operand:XF 3 "mult_operator" "")
16421                  (const_string "fmul")
16422                (match_operand:XF 3 "div_operator" "")
16423                  (const_string "fdiv")
16424               ]
16425               (const_string "fop")))
16426    (set_attr "fp_int_src" "true")
16427    (set_attr "mode" "<MODE>")])
16428
16429 (define_insn "*fop_xf_3<mode>_i387"
16430   [(set (match_operand:XF 0 "register_operand" "=f,f")
16431         (match_operator:XF 3 "binary_fp_operator"
16432           [(match_operand:XF 1 "register_operand" "0,0")
16433            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16434   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16435   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16436   [(set (attr "type")
16437         (cond [(match_operand:XF 3 "mult_operator" "")
16438                  (const_string "fmul")
16439                (match_operand:XF 3 "div_operator" "")
16440                  (const_string "fdiv")
16441               ]
16442               (const_string "fop")))
16443    (set_attr "fp_int_src" "true")
16444    (set_attr "mode" "<MODE>")])
16445
16446 (define_insn "*fop_xf_4_i387"
16447   [(set (match_operand:XF 0 "register_operand" "=f,f")
16448         (match_operator:XF 3 "binary_fp_operator"
16449            [(float_extend:XF
16450               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16451             (match_operand:XF 2 "register_operand" "0,f")]))]
16452   "TARGET_80387"
16453   "* return output_387_binary_op (insn, operands);"
16454   [(set (attr "type")
16455         (cond [(match_operand:XF 3 "mult_operator" "")
16456                  (const_string "fmul")
16457                (match_operand:XF 3 "div_operator" "")
16458                  (const_string "fdiv")
16459               ]
16460               (const_string "fop")))
16461    (set_attr "mode" "SF")])
16462
16463 (define_insn "*fop_xf_5_i387"
16464   [(set (match_operand:XF 0 "register_operand" "=f,f")
16465         (match_operator:XF 3 "binary_fp_operator"
16466           [(match_operand:XF 1 "register_operand" "0,f")
16467            (float_extend:XF
16468              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16469   "TARGET_80387"
16470   "* return output_387_binary_op (insn, operands);"
16471   [(set (attr "type")
16472         (cond [(match_operand:XF 3 "mult_operator" "")
16473                  (const_string "fmul")
16474                (match_operand:XF 3 "div_operator" "")
16475                  (const_string "fdiv")
16476               ]
16477               (const_string "fop")))
16478    (set_attr "mode" "SF")])
16479
16480 (define_insn "*fop_xf_6_i387"
16481   [(set (match_operand:XF 0 "register_operand" "=f,f")
16482         (match_operator:XF 3 "binary_fp_operator"
16483           [(float_extend:XF
16484              (match_operand:MODEF 1 "register_operand" "0,f"))
16485            (float_extend:XF
16486              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16487   "TARGET_80387"
16488   "* return output_387_binary_op (insn, operands);"
16489   [(set (attr "type")
16490         (cond [(match_operand:XF 3 "mult_operator" "")
16491                  (const_string "fmul")
16492                (match_operand:XF 3 "div_operator" "")
16493                  (const_string "fdiv")
16494               ]
16495               (const_string "fop")))
16496    (set_attr "mode" "SF")])
16497
16498 (define_split
16499   [(set (match_operand 0 "register_operand" "")
16500         (match_operator 3 "binary_fp_operator"
16501            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16502             (match_operand 2 "register_operand" "")]))]
16503   "reload_completed
16504    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16505   [(const_int 0)]
16506 {
16507   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16508   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16509   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16510                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16511                                           GET_MODE (operands[3]),
16512                                           operands[4],
16513                                           operands[2])));
16514   ix86_free_from_memory (GET_MODE (operands[1]));
16515   DONE;
16516 })
16517
16518 (define_split
16519   [(set (match_operand 0 "register_operand" "")
16520         (match_operator 3 "binary_fp_operator"
16521            [(match_operand 1 "register_operand" "")
16522             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16523   "reload_completed
16524    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16525   [(const_int 0)]
16526 {
16527   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16528   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16529   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16530                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16531                                           GET_MODE (operands[3]),
16532                                           operands[1],
16533                                           operands[4])));
16534   ix86_free_from_memory (GET_MODE (operands[2]));
16535   DONE;
16536 })
16537 \f
16538 ;; FPU special functions.
16539
16540 ;; This pattern implements a no-op XFmode truncation for
16541 ;; all fancy i386 XFmode math functions.
16542
16543 (define_insn "truncxf<mode>2_i387_noop_unspec"
16544   [(set (match_operand:MODEF 0 "register_operand" "=f")
16545         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16546         UNSPEC_TRUNC_NOOP))]
16547   "TARGET_USE_FANCY_MATH_387"
16548   "* return output_387_reg_move (insn, operands);"
16549   [(set_attr "type" "fmov")
16550    (set_attr "mode" "<MODE>")])
16551
16552 (define_insn "sqrtxf2"
16553   [(set (match_operand:XF 0 "register_operand" "=f")
16554         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16555   "TARGET_USE_FANCY_MATH_387"
16556   "fsqrt"
16557   [(set_attr "type" "fpspc")
16558    (set_attr "mode" "XF")
16559    (set_attr "athlon_decode" "direct")
16560    (set_attr "amdfam10_decode" "direct")])
16561
16562 (define_insn "sqrt_extend<mode>xf2_i387"
16563   [(set (match_operand:XF 0 "register_operand" "=f")
16564         (sqrt:XF
16565           (float_extend:XF
16566             (match_operand:MODEF 1 "register_operand" "0"))))]
16567   "TARGET_USE_FANCY_MATH_387"
16568   "fsqrt"
16569   [(set_attr "type" "fpspc")
16570    (set_attr "mode" "XF")
16571    (set_attr "athlon_decode" "direct")   
16572    (set_attr "amdfam10_decode" "direct")])
16573
16574 (define_insn "*rsqrtsf2_sse"
16575   [(set (match_operand:SF 0 "register_operand" "=x")
16576         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16577                    UNSPEC_RSQRT))]
16578   "TARGET_SSE_MATH"
16579   "rsqrtss\t{%1, %0|%0, %1}"
16580   [(set_attr "type" "sse")
16581    (set_attr "mode" "SF")])
16582
16583 (define_expand "rsqrtsf2"
16584   [(set (match_operand:SF 0 "register_operand" "")
16585         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16586                    UNSPEC_RSQRT))]
16587   "TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16588    && flag_finite_math_only && !flag_trapping_math
16589    && flag_unsafe_math_optimizations"
16590 {
16591   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16592   DONE;
16593 })
16594
16595 (define_insn "*sqrt<mode>2_sse"
16596   [(set (match_operand:MODEF 0 "register_operand" "=x")
16597         (sqrt:MODEF
16598           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16599   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16600   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16601   [(set_attr "type" "sse")
16602    (set_attr "mode" "<MODE>")
16603    (set_attr "athlon_decode" "*")
16604    (set_attr "amdfam10_decode" "*")])
16605
16606 (define_expand "sqrt<mode>2"
16607   [(set (match_operand:MODEF 0 "register_operand" "")
16608         (sqrt:MODEF
16609           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16610   "TARGET_USE_FANCY_MATH_387
16611    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16612 {
16613   if (<MODE>mode == SFmode
16614       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16615       && flag_finite_math_only && !flag_trapping_math
16616       && flag_unsafe_math_optimizations)
16617     {
16618       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16619       DONE;
16620     }
16621
16622   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16623     {
16624       rtx op0 = gen_reg_rtx (XFmode);
16625       rtx op1 = force_reg (<MODE>mode, operands[1]);
16626
16627       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16628       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16629       DONE;
16630    }
16631 })
16632
16633 (define_insn "fpremxf4_i387"
16634   [(set (match_operand:XF 0 "register_operand" "=f")
16635         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16636                     (match_operand:XF 3 "register_operand" "1")]
16637                    UNSPEC_FPREM_F))
16638    (set (match_operand:XF 1 "register_operand" "=u")
16639         (unspec:XF [(match_dup 2) (match_dup 3)]
16640                    UNSPEC_FPREM_U))
16641    (set (reg:CCFP FPSR_REG)
16642         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16643                      UNSPEC_C2_FLAG))]
16644   "TARGET_USE_FANCY_MATH_387"
16645   "fprem"
16646   [(set_attr "type" "fpspc")
16647    (set_attr "mode" "XF")])
16648
16649 (define_expand "fmodxf3"
16650   [(use (match_operand:XF 0 "register_operand" ""))
16651    (use (match_operand:XF 1 "register_operand" ""))
16652    (use (match_operand:XF 2 "register_operand" ""))]
16653   "TARGET_USE_FANCY_MATH_387"
16654 {
16655   rtx label = gen_label_rtx ();
16656
16657   emit_label (label);
16658
16659   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16660                                 operands[1], operands[2]));
16661   ix86_emit_fp_unordered_jump (label);
16662   LABEL_NUSES (label) = 1;
16663
16664   emit_move_insn (operands[0], operands[1]);
16665   DONE;
16666 })
16667
16668 (define_expand "fmod<mode>3"
16669   [(use (match_operand:MODEF 0 "register_operand" ""))
16670    (use (match_operand:MODEF 1 "general_operand" ""))
16671    (use (match_operand:MODEF 2 "general_operand" ""))]
16672   "TARGET_USE_FANCY_MATH_387"
16673 {
16674   rtx label = gen_label_rtx ();
16675
16676   rtx op1 = gen_reg_rtx (XFmode);
16677   rtx op2 = gen_reg_rtx (XFmode);
16678
16679   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16680   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16681
16682   emit_label (label);
16683   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16684   ix86_emit_fp_unordered_jump (label);
16685   LABEL_NUSES (label) = 1;
16686
16687   /* Truncate the result properly for strict SSE math.  */
16688   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16689       && !TARGET_MIX_SSE_I387)
16690     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16691   else
16692     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16693
16694   DONE;
16695 })
16696
16697 (define_insn "fprem1xf4_i387"
16698   [(set (match_operand:XF 0 "register_operand" "=f")
16699         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16700                     (match_operand:XF 3 "register_operand" "1")]
16701                    UNSPEC_FPREM1_F))
16702    (set (match_operand:XF 1 "register_operand" "=u")
16703         (unspec:XF [(match_dup 2) (match_dup 3)]
16704                    UNSPEC_FPREM1_U))
16705    (set (reg:CCFP FPSR_REG)
16706         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16707                      UNSPEC_C2_FLAG))]
16708   "TARGET_USE_FANCY_MATH_387"
16709   "fprem1"
16710   [(set_attr "type" "fpspc")
16711    (set_attr "mode" "XF")])
16712
16713 (define_expand "remainderxf3"
16714   [(use (match_operand:XF 0 "register_operand" ""))
16715    (use (match_operand:XF 1 "register_operand" ""))
16716    (use (match_operand:XF 2 "register_operand" ""))]
16717   "TARGET_USE_FANCY_MATH_387"
16718 {
16719   rtx label = gen_label_rtx ();
16720
16721   emit_label (label);
16722
16723   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16724                                  operands[1], operands[2]));
16725   ix86_emit_fp_unordered_jump (label);
16726   LABEL_NUSES (label) = 1;
16727
16728   emit_move_insn (operands[0], operands[1]);
16729   DONE;
16730 })
16731
16732 (define_expand "remainder<mode>3"
16733   [(use (match_operand:MODEF 0 "register_operand" ""))
16734    (use (match_operand:MODEF 1 "general_operand" ""))
16735    (use (match_operand:MODEF 2 "general_operand" ""))]
16736   "TARGET_USE_FANCY_MATH_387"
16737 {
16738   rtx label = gen_label_rtx ();
16739
16740   rtx op1 = gen_reg_rtx (XFmode);
16741   rtx op2 = gen_reg_rtx (XFmode);
16742
16743   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16744   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16745
16746   emit_label (label);
16747
16748   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16749   ix86_emit_fp_unordered_jump (label);
16750   LABEL_NUSES (label) = 1;
16751
16752   /* Truncate the result properly for strict SSE math.  */
16753   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16754       && !TARGET_MIX_SSE_I387)
16755     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16756   else
16757     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16758
16759   DONE;
16760 })
16761
16762 (define_insn "*sinxf2_i387"
16763   [(set (match_operand:XF 0 "register_operand" "=f")
16764         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16765   "TARGET_USE_FANCY_MATH_387
16766    && flag_unsafe_math_optimizations"
16767   "fsin"
16768   [(set_attr "type" "fpspc")
16769    (set_attr "mode" "XF")])
16770
16771 (define_insn "*sin_extend<mode>xf2_i387"
16772   [(set (match_operand:XF 0 "register_operand" "=f")
16773         (unspec:XF [(float_extend:XF
16774                       (match_operand:MODEF 1 "register_operand" "0"))]
16775                    UNSPEC_SIN))]
16776   "TARGET_USE_FANCY_MATH_387
16777    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16778        || TARGET_MIX_SSE_I387)
16779    && flag_unsafe_math_optimizations"
16780   "fsin"
16781   [(set_attr "type" "fpspc")
16782    (set_attr "mode" "XF")])
16783
16784 (define_insn "*cosxf2_i387"
16785   [(set (match_operand:XF 0 "register_operand" "=f")
16786         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16787   "TARGET_USE_FANCY_MATH_387
16788    && flag_unsafe_math_optimizations"
16789   "fcos"
16790   [(set_attr "type" "fpspc")
16791    (set_attr "mode" "XF")])
16792
16793 (define_insn "*cos_extend<mode>xf2_i387"
16794   [(set (match_operand:XF 0 "register_operand" "=f")
16795         (unspec:XF [(float_extend:XF
16796                       (match_operand:MODEF 1 "register_operand" "0"))]
16797                    UNSPEC_COS))]
16798   "TARGET_USE_FANCY_MATH_387
16799    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16800        || TARGET_MIX_SSE_I387)
16801    && flag_unsafe_math_optimizations"
16802   "fcos"
16803   [(set_attr "type" "fpspc")
16804    (set_attr "mode" "XF")])
16805
16806 ;; When sincos pattern is defined, sin and cos builtin functions will be
16807 ;; expanded to sincos pattern with one of its outputs left unused.
16808 ;; CSE pass will figure out if two sincos patterns can be combined,
16809 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16810 ;; depending on the unused output.
16811
16812 (define_insn "sincosxf3"
16813   [(set (match_operand:XF 0 "register_operand" "=f")
16814         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16815                    UNSPEC_SINCOS_COS))
16816    (set (match_operand:XF 1 "register_operand" "=u")
16817         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16818   "TARGET_USE_FANCY_MATH_387
16819    && flag_unsafe_math_optimizations"
16820   "fsincos"
16821   [(set_attr "type" "fpspc")
16822    (set_attr "mode" "XF")])
16823
16824 (define_split
16825   [(set (match_operand:XF 0 "register_operand" "")
16826         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16827                    UNSPEC_SINCOS_COS))
16828    (set (match_operand:XF 1 "register_operand" "")
16829         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16830   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16831    && !(reload_completed || reload_in_progress)"
16832   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16833   "")
16834
16835 (define_split
16836   [(set (match_operand:XF 0 "register_operand" "")
16837         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16838                    UNSPEC_SINCOS_COS))
16839    (set (match_operand:XF 1 "register_operand" "")
16840         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16841   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16842    && !(reload_completed || reload_in_progress)"
16843   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16844   "")
16845
16846 (define_insn "sincos_extend<mode>xf3_i387"
16847   [(set (match_operand:XF 0 "register_operand" "=f")
16848         (unspec:XF [(float_extend:XF
16849                       (match_operand:MODEF 2 "register_operand" "0"))]
16850                    UNSPEC_SINCOS_COS))
16851    (set (match_operand:XF 1 "register_operand" "=u")
16852         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16853   "TARGET_USE_FANCY_MATH_387
16854    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16855        || TARGET_MIX_SSE_I387)
16856    && flag_unsafe_math_optimizations"
16857   "fsincos"
16858   [(set_attr "type" "fpspc")
16859    (set_attr "mode" "XF")])
16860
16861 (define_split
16862   [(set (match_operand:XF 0 "register_operand" "")
16863         (unspec:XF [(float_extend:XF
16864                       (match_operand:MODEF 2 "register_operand" ""))]
16865                    UNSPEC_SINCOS_COS))
16866    (set (match_operand:XF 1 "register_operand" "")
16867         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16868   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16869    && !(reload_completed || reload_in_progress)"
16870   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16871   "")
16872
16873 (define_split
16874   [(set (match_operand:XF 0 "register_operand" "")
16875         (unspec:XF [(float_extend:XF
16876                       (match_operand:MODEF 2 "register_operand" ""))]
16877                    UNSPEC_SINCOS_COS))
16878    (set (match_operand:XF 1 "register_operand" "")
16879         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16880   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16881    && !(reload_completed || reload_in_progress)"
16882   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16883   "")
16884
16885 (define_expand "sincos<mode>3"
16886   [(use (match_operand:MODEF 0 "register_operand" ""))
16887    (use (match_operand:MODEF 1 "register_operand" ""))
16888    (use (match_operand:MODEF 2 "register_operand" ""))]
16889   "TARGET_USE_FANCY_MATH_387
16890    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16891        || TARGET_MIX_SSE_I387)
16892    && flag_unsafe_math_optimizations"
16893 {
16894   rtx op0 = gen_reg_rtx (XFmode);
16895   rtx op1 = gen_reg_rtx (XFmode);
16896
16897   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16898   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16899   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16900   DONE;
16901 })
16902
16903 (define_insn "fptanxf4_i387"
16904   [(set (match_operand:XF 0 "register_operand" "=f")
16905         (match_operand:XF 3 "const_double_operand" "F"))
16906    (set (match_operand:XF 1 "register_operand" "=u")
16907         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16908                    UNSPEC_TAN))]
16909   "TARGET_USE_FANCY_MATH_387
16910    && flag_unsafe_math_optimizations
16911    && standard_80387_constant_p (operands[3]) == 2"
16912   "fptan"
16913   [(set_attr "type" "fpspc")
16914    (set_attr "mode" "XF")])
16915
16916 (define_insn "fptan_extend<mode>xf4_i387"
16917   [(set (match_operand:MODEF 0 "register_operand" "=f")
16918         (match_operand:MODEF 3 "const_double_operand" "F"))
16919    (set (match_operand:XF 1 "register_operand" "=u")
16920         (unspec:XF [(float_extend:XF
16921                       (match_operand:MODEF 2 "register_operand" "0"))]
16922                    UNSPEC_TAN))]
16923   "TARGET_USE_FANCY_MATH_387
16924    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16925        || TARGET_MIX_SSE_I387)
16926    && flag_unsafe_math_optimizations
16927    && standard_80387_constant_p (operands[3]) == 2"
16928   "fptan"
16929   [(set_attr "type" "fpspc")
16930    (set_attr "mode" "XF")])
16931
16932 (define_expand "tanxf2"
16933   [(use (match_operand:XF 0 "register_operand" ""))
16934    (use (match_operand:XF 1 "register_operand" ""))]
16935   "TARGET_USE_FANCY_MATH_387
16936    && flag_unsafe_math_optimizations"
16937 {
16938   rtx one = gen_reg_rtx (XFmode);
16939   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16940
16941   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16942   DONE;
16943 })
16944
16945 (define_expand "tan<mode>2"
16946   [(use (match_operand:MODEF 0 "register_operand" ""))
16947    (use (match_operand:MODEF 1 "register_operand" ""))]
16948   "TARGET_USE_FANCY_MATH_387
16949    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16950        || TARGET_MIX_SSE_I387)
16951    && flag_unsafe_math_optimizations"
16952 {
16953   rtx op0 = gen_reg_rtx (XFmode);
16954
16955   rtx one = gen_reg_rtx (<MODE>mode);
16956   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16957
16958   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16959                                              operands[1], op2));
16960   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16961   DONE;
16962 })
16963
16964 (define_insn "*fpatanxf3_i387"
16965   [(set (match_operand:XF 0 "register_operand" "=f")
16966         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16967                     (match_operand:XF 2 "register_operand" "u")]
16968                    UNSPEC_FPATAN))
16969    (clobber (match_scratch:XF 3 "=2"))]
16970   "TARGET_USE_FANCY_MATH_387
16971    && flag_unsafe_math_optimizations"
16972   "fpatan"
16973   [(set_attr "type" "fpspc")
16974    (set_attr "mode" "XF")])
16975
16976 (define_insn "fpatan_extend<mode>xf3_i387"
16977   [(set (match_operand:XF 0 "register_operand" "=f")
16978         (unspec:XF [(float_extend:XF
16979                       (match_operand:MODEF 1 "register_operand" "0"))
16980                     (float_extend:XF
16981                       (match_operand:MODEF 2 "register_operand" "u"))]
16982                    UNSPEC_FPATAN))
16983    (clobber (match_scratch:XF 3 "=2"))]
16984   "TARGET_USE_FANCY_MATH_387
16985    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16986        || TARGET_MIX_SSE_I387)
16987    && flag_unsafe_math_optimizations"
16988   "fpatan"
16989   [(set_attr "type" "fpspc")
16990    (set_attr "mode" "XF")])
16991
16992 (define_expand "atan2xf3"
16993   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16994                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16995                                (match_operand:XF 1 "register_operand" "")]
16996                               UNSPEC_FPATAN))
16997               (clobber (match_scratch:XF 3 ""))])]
16998   "TARGET_USE_FANCY_MATH_387
16999    && flag_unsafe_math_optimizations"
17000   "")
17001
17002 (define_expand "atan2<mode>3"
17003   [(use (match_operand:MODEF 0 "register_operand" ""))
17004    (use (match_operand:MODEF 1 "register_operand" ""))
17005    (use (match_operand:MODEF 2 "register_operand" ""))]
17006   "TARGET_USE_FANCY_MATH_387
17007    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17008        || TARGET_MIX_SSE_I387)
17009    && flag_unsafe_math_optimizations"
17010 {
17011   rtx op0 = gen_reg_rtx (XFmode);
17012
17013   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17014   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17015   DONE;
17016 })
17017
17018 (define_expand "atanxf2"
17019   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17020                    (unspec:XF [(match_dup 2)
17021                                (match_operand:XF 1 "register_operand" "")]
17022                               UNSPEC_FPATAN))
17023               (clobber (match_scratch:XF 3 ""))])]
17024   "TARGET_USE_FANCY_MATH_387
17025    && flag_unsafe_math_optimizations"
17026 {
17027   operands[2] = gen_reg_rtx (XFmode);
17028   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17029 })
17030
17031 (define_expand "atan<mode>2"
17032   [(use (match_operand:MODEF 0 "register_operand" ""))
17033    (use (match_operand:MODEF 1 "register_operand" ""))]
17034   "TARGET_USE_FANCY_MATH_387
17035    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17036        || TARGET_MIX_SSE_I387)
17037    && flag_unsafe_math_optimizations"
17038 {
17039   rtx op0 = gen_reg_rtx (XFmode);
17040
17041   rtx op2 = gen_reg_rtx (<MODE>mode);
17042   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17043
17044   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17045   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17046   DONE;
17047 })
17048
17049 (define_expand "asinxf2"
17050   [(set (match_dup 2)
17051         (mult:XF (match_operand:XF 1 "register_operand" "")
17052                  (match_dup 1)))
17053    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17054    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17055    (parallel [(set (match_operand:XF 0 "register_operand" "")
17056                    (unspec:XF [(match_dup 5) (match_dup 1)]
17057                               UNSPEC_FPATAN))
17058               (clobber (match_scratch:XF 6 ""))])]
17059   "TARGET_USE_FANCY_MATH_387
17060    && flag_unsafe_math_optimizations && !optimize_size"
17061 {
17062   int i;
17063
17064   for (i = 2; i < 6; i++)
17065     operands[i] = gen_reg_rtx (XFmode);
17066
17067   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17068 })
17069
17070 (define_expand "asin<mode>2"
17071   [(use (match_operand:MODEF 0 "register_operand" ""))
17072    (use (match_operand:MODEF 1 "general_operand" ""))]
17073  "TARGET_USE_FANCY_MATH_387
17074    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17075        || TARGET_MIX_SSE_I387)
17076    && flag_unsafe_math_optimizations && !optimize_size"
17077 {
17078   rtx op0 = gen_reg_rtx (XFmode);
17079   rtx op1 = gen_reg_rtx (XFmode);
17080
17081   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17082   emit_insn (gen_asinxf2 (op0, op1));
17083   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17084   DONE;
17085 })
17086
17087 (define_expand "acosxf2"
17088   [(set (match_dup 2)
17089         (mult:XF (match_operand:XF 1 "register_operand" "")
17090                  (match_dup 1)))
17091    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17092    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17093    (parallel [(set (match_operand:XF 0 "register_operand" "")
17094                    (unspec:XF [(match_dup 1) (match_dup 5)]
17095                               UNSPEC_FPATAN))
17096               (clobber (match_scratch:XF 6 ""))])]
17097   "TARGET_USE_FANCY_MATH_387
17098    && flag_unsafe_math_optimizations && !optimize_size"
17099 {
17100   int i;
17101
17102   for (i = 2; i < 6; i++)
17103     operands[i] = gen_reg_rtx (XFmode);
17104
17105   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17106 })
17107
17108 (define_expand "acos<mode>2"
17109   [(use (match_operand:MODEF 0 "register_operand" ""))
17110    (use (match_operand:MODEF 1 "general_operand" ""))]
17111  "TARGET_USE_FANCY_MATH_387
17112    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17113        || TARGET_MIX_SSE_I387)
17114    && flag_unsafe_math_optimizations && !optimize_size"
17115 {
17116   rtx op0 = gen_reg_rtx (XFmode);
17117   rtx op1 = gen_reg_rtx (XFmode);
17118
17119   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17120   emit_insn (gen_acosxf2 (op0, op1));
17121   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17122   DONE;
17123 })
17124
17125 (define_insn "fyl2xxf3_i387"
17126   [(set (match_operand:XF 0 "register_operand" "=f")
17127         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17128                     (match_operand:XF 2 "register_operand" "u")]
17129                    UNSPEC_FYL2X))
17130    (clobber (match_scratch:XF 3 "=2"))]
17131   "TARGET_USE_FANCY_MATH_387
17132    && flag_unsafe_math_optimizations"
17133   "fyl2x"
17134   [(set_attr "type" "fpspc")
17135    (set_attr "mode" "XF")])
17136
17137 (define_insn "fyl2x_extend<mode>xf3_i387"
17138   [(set (match_operand:XF 0 "register_operand" "=f")
17139         (unspec:XF [(float_extend:XF
17140                       (match_operand:MODEF 1 "register_operand" "0"))
17141                     (match_operand:XF 2 "register_operand" "u")]
17142                    UNSPEC_FYL2X))
17143    (clobber (match_scratch:XF 3 "=2"))]
17144   "TARGET_USE_FANCY_MATH_387
17145    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17146        || TARGET_MIX_SSE_I387)
17147    && flag_unsafe_math_optimizations"
17148   "fyl2x"
17149   [(set_attr "type" "fpspc")
17150    (set_attr "mode" "XF")])
17151
17152 (define_expand "logxf2"
17153   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17154                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17155                                (match_dup 2)] UNSPEC_FYL2X))
17156               (clobber (match_scratch:XF 3 ""))])]
17157   "TARGET_USE_FANCY_MATH_387
17158    && flag_unsafe_math_optimizations"
17159 {
17160   operands[2] = gen_reg_rtx (XFmode);
17161   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17162 })
17163
17164 (define_expand "log<mode>2"
17165   [(use (match_operand:MODEF 0 "register_operand" ""))
17166    (use (match_operand:MODEF 1 "register_operand" ""))]
17167   "TARGET_USE_FANCY_MATH_387
17168    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17169        || TARGET_MIX_SSE_I387)
17170    && flag_unsafe_math_optimizations"
17171 {
17172   rtx op0 = gen_reg_rtx (XFmode);
17173
17174   rtx op2 = gen_reg_rtx (XFmode);
17175   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17176
17177   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17178   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17179   DONE;
17180 })
17181
17182 (define_expand "log10xf2"
17183   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17184                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17185                                (match_dup 2)] UNSPEC_FYL2X))
17186               (clobber (match_scratch:XF 3 ""))])]
17187   "TARGET_USE_FANCY_MATH_387
17188    && flag_unsafe_math_optimizations"
17189 {
17190   operands[2] = gen_reg_rtx (XFmode);
17191   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17192 })
17193
17194 (define_expand "log10<mode>2"
17195   [(use (match_operand:MODEF 0 "register_operand" ""))
17196    (use (match_operand:MODEF 1 "register_operand" ""))]
17197   "TARGET_USE_FANCY_MATH_387
17198    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17199        || TARGET_MIX_SSE_I387)
17200    && flag_unsafe_math_optimizations"
17201 {
17202   rtx op0 = gen_reg_rtx (XFmode);
17203
17204   rtx op2 = gen_reg_rtx (XFmode);
17205   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17206
17207   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17208   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17209   DONE;
17210 })
17211
17212 (define_expand "log2xf2"
17213   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17214                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17215                                (match_dup 2)] UNSPEC_FYL2X))
17216               (clobber (match_scratch:XF 3 ""))])]
17217   "TARGET_USE_FANCY_MATH_387
17218    && flag_unsafe_math_optimizations"
17219 {
17220   operands[2] = gen_reg_rtx (XFmode);
17221   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17222 })
17223
17224 (define_expand "log2<mode>2"
17225   [(use (match_operand:MODEF 0 "register_operand" ""))
17226    (use (match_operand:MODEF 1 "register_operand" ""))]
17227   "TARGET_USE_FANCY_MATH_387
17228    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17229        || TARGET_MIX_SSE_I387)
17230    && flag_unsafe_math_optimizations"
17231 {
17232   rtx op0 = gen_reg_rtx (XFmode);
17233
17234   rtx op2 = gen_reg_rtx (XFmode);
17235   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17236
17237   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17238   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17239   DONE;
17240 })
17241
17242 (define_insn "fyl2xp1xf3_i387"
17243   [(set (match_operand:XF 0 "register_operand" "=f")
17244         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17245                     (match_operand:XF 2 "register_operand" "u")]
17246                    UNSPEC_FYL2XP1))
17247    (clobber (match_scratch:XF 3 "=2"))]
17248   "TARGET_USE_FANCY_MATH_387
17249    && flag_unsafe_math_optimizations"
17250   "fyl2xp1"
17251   [(set_attr "type" "fpspc")
17252    (set_attr "mode" "XF")])
17253
17254 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17255   [(set (match_operand:XF 0 "register_operand" "=f")
17256         (unspec:XF [(float_extend:XF
17257                       (match_operand:MODEF 1 "register_operand" "0"))
17258                     (match_operand:XF 2 "register_operand" "u")]
17259                    UNSPEC_FYL2XP1))
17260    (clobber (match_scratch:XF 3 "=2"))]
17261   "TARGET_USE_FANCY_MATH_387
17262    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17263        || TARGET_MIX_SSE_I387)
17264    && flag_unsafe_math_optimizations"
17265   "fyl2xp1"
17266   [(set_attr "type" "fpspc")
17267    (set_attr "mode" "XF")])
17268
17269 (define_expand "log1pxf2"
17270   [(use (match_operand:XF 0 "register_operand" ""))
17271    (use (match_operand:XF 1 "register_operand" ""))]
17272   "TARGET_USE_FANCY_MATH_387
17273    && flag_unsafe_math_optimizations && !optimize_size"
17274 {
17275   ix86_emit_i387_log1p (operands[0], operands[1]);
17276   DONE;
17277 })
17278
17279 (define_expand "log1p<mode>2"
17280   [(use (match_operand:MODEF 0 "register_operand" ""))
17281    (use (match_operand:MODEF 1 "register_operand" ""))]
17282   "TARGET_USE_FANCY_MATH_387
17283    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17284        || TARGET_MIX_SSE_I387)
17285    && flag_unsafe_math_optimizations && !optimize_size"
17286 {
17287   rtx op0 = gen_reg_rtx (XFmode);
17288
17289   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17290
17291   ix86_emit_i387_log1p (op0, operands[1]);
17292   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17293   DONE;
17294 })
17295
17296 (define_insn "fxtractxf3_i387"
17297   [(set (match_operand:XF 0 "register_operand" "=f")
17298         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17299                    UNSPEC_XTRACT_FRACT))
17300    (set (match_operand:XF 1 "register_operand" "=u")
17301         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17302   "TARGET_USE_FANCY_MATH_387
17303    && flag_unsafe_math_optimizations"
17304   "fxtract"
17305   [(set_attr "type" "fpspc")
17306    (set_attr "mode" "XF")])
17307
17308 (define_insn "fxtract_extend<mode>xf3_i387"
17309   [(set (match_operand:XF 0 "register_operand" "=f")
17310         (unspec:XF [(float_extend:XF
17311                       (match_operand:MODEF 2 "register_operand" "0"))]
17312                    UNSPEC_XTRACT_FRACT))
17313    (set (match_operand:XF 1 "register_operand" "=u")
17314         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17315   "TARGET_USE_FANCY_MATH_387
17316    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17317        || TARGET_MIX_SSE_I387)
17318    && flag_unsafe_math_optimizations"
17319   "fxtract"
17320   [(set_attr "type" "fpspc")
17321    (set_attr "mode" "XF")])
17322
17323 (define_expand "logbxf2"
17324   [(parallel [(set (match_dup 2)
17325                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17326                               UNSPEC_XTRACT_FRACT))
17327               (set (match_operand:XF 0 "register_operand" "")
17328                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17329   "TARGET_USE_FANCY_MATH_387
17330    && flag_unsafe_math_optimizations"
17331 {
17332   operands[2] = gen_reg_rtx (XFmode);
17333 })
17334
17335 (define_expand "logb<mode>2"
17336   [(use (match_operand:MODEF 0 "register_operand" ""))
17337    (use (match_operand:MODEF 1 "register_operand" ""))]
17338   "TARGET_USE_FANCY_MATH_387
17339    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17340        || TARGET_MIX_SSE_I387)
17341    && flag_unsafe_math_optimizations"
17342 {
17343   rtx op0 = gen_reg_rtx (XFmode);
17344   rtx op1 = gen_reg_rtx (XFmode);
17345
17346   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17347   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17348   DONE;
17349 })
17350
17351 (define_expand "ilogbxf2"
17352   [(use (match_operand:SI 0 "register_operand" ""))
17353    (use (match_operand:XF 1 "register_operand" ""))]
17354   "TARGET_USE_FANCY_MATH_387
17355    && flag_unsafe_math_optimizations && !optimize_size"
17356 {
17357   rtx op0 = gen_reg_rtx (XFmode);
17358   rtx op1 = gen_reg_rtx (XFmode);
17359
17360   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17361   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17362   DONE;
17363 })
17364
17365 (define_expand "ilogb<mode>2"
17366   [(use (match_operand:SI 0 "register_operand" ""))
17367    (use (match_operand:MODEF 1 "register_operand" ""))]
17368   "TARGET_USE_FANCY_MATH_387
17369    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17370        || TARGET_MIX_SSE_I387)
17371    && flag_unsafe_math_optimizations && !optimize_size"
17372 {
17373   rtx op0 = gen_reg_rtx (XFmode);
17374   rtx op1 = gen_reg_rtx (XFmode);
17375
17376   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17377   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17378   DONE;
17379 })
17380
17381 (define_insn "*f2xm1xf2_i387"
17382   [(set (match_operand:XF 0 "register_operand" "=f")
17383         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17384                    UNSPEC_F2XM1))]
17385   "TARGET_USE_FANCY_MATH_387
17386    && flag_unsafe_math_optimizations"
17387   "f2xm1"
17388   [(set_attr "type" "fpspc")
17389    (set_attr "mode" "XF")])
17390
17391 (define_insn "*fscalexf4_i387"
17392   [(set (match_operand:XF 0 "register_operand" "=f")
17393         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17394                     (match_operand:XF 3 "register_operand" "1")]
17395                    UNSPEC_FSCALE_FRACT))
17396    (set (match_operand:XF 1 "register_operand" "=u")
17397         (unspec:XF [(match_dup 2) (match_dup 3)]
17398                    UNSPEC_FSCALE_EXP))]
17399   "TARGET_USE_FANCY_MATH_387
17400    && flag_unsafe_math_optimizations"
17401   "fscale"
17402   [(set_attr "type" "fpspc")
17403    (set_attr "mode" "XF")])
17404
17405 (define_expand "expNcorexf3"
17406   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17407                                (match_operand:XF 2 "register_operand" "")))
17408    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17409    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17410    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17411    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17412    (parallel [(set (match_operand:XF 0 "register_operand" "")
17413                    (unspec:XF [(match_dup 8) (match_dup 4)]
17414                               UNSPEC_FSCALE_FRACT))
17415               (set (match_dup 9)
17416                    (unspec:XF [(match_dup 8) (match_dup 4)]
17417                               UNSPEC_FSCALE_EXP))])]
17418   "TARGET_USE_FANCY_MATH_387
17419    && flag_unsafe_math_optimizations && !optimize_size"
17420 {
17421   int i;
17422
17423   for (i = 3; i < 10; i++)
17424     operands[i] = gen_reg_rtx (XFmode);
17425
17426   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17427 })
17428
17429 (define_expand "expxf2"
17430   [(use (match_operand:XF 0 "register_operand" ""))
17431    (use (match_operand:XF 1 "register_operand" ""))]
17432   "TARGET_USE_FANCY_MATH_387
17433    && flag_unsafe_math_optimizations && !optimize_size"
17434 {
17435   rtx op2 = gen_reg_rtx (XFmode);
17436   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17437
17438   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17439   DONE;
17440 })
17441
17442 (define_expand "exp<mode>2"
17443   [(use (match_operand:MODEF 0 "register_operand" ""))
17444    (use (match_operand:MODEF 1 "general_operand" ""))]
17445  "TARGET_USE_FANCY_MATH_387
17446    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17447        || TARGET_MIX_SSE_I387)
17448    && flag_unsafe_math_optimizations && !optimize_size"
17449 {
17450   rtx op0 = gen_reg_rtx (XFmode);
17451   rtx op1 = gen_reg_rtx (XFmode);
17452
17453   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17454   emit_insn (gen_expxf2 (op0, op1));
17455   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17456   DONE;
17457 })
17458
17459 (define_expand "exp10xf2"
17460   [(use (match_operand:XF 0 "register_operand" ""))
17461    (use (match_operand:XF 1 "register_operand" ""))]
17462   "TARGET_USE_FANCY_MATH_387
17463    && flag_unsafe_math_optimizations && !optimize_size"
17464 {
17465   rtx op2 = gen_reg_rtx (XFmode);
17466   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17467
17468   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17469   DONE;
17470 })
17471
17472 (define_expand "exp10<mode>2"
17473   [(use (match_operand:MODEF 0 "register_operand" ""))
17474    (use (match_operand:MODEF 1 "general_operand" ""))]
17475  "TARGET_USE_FANCY_MATH_387
17476    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17477        || TARGET_MIX_SSE_I387)
17478    && flag_unsafe_math_optimizations && !optimize_size"
17479 {
17480   rtx op0 = gen_reg_rtx (XFmode);
17481   rtx op1 = gen_reg_rtx (XFmode);
17482
17483   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17484   emit_insn (gen_exp10xf2 (op0, op1));
17485   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17486   DONE;
17487 })
17488
17489 (define_expand "exp2xf2"
17490   [(use (match_operand:XF 0 "register_operand" ""))
17491    (use (match_operand:XF 1 "register_operand" ""))]
17492   "TARGET_USE_FANCY_MATH_387
17493    && flag_unsafe_math_optimizations && !optimize_size"
17494 {
17495   rtx op2 = gen_reg_rtx (XFmode);
17496   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17497
17498   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17499   DONE;
17500 })
17501
17502 (define_expand "exp2<mode>2"
17503   [(use (match_operand:MODEF 0 "register_operand" ""))
17504    (use (match_operand:MODEF 1 "general_operand" ""))]
17505  "TARGET_USE_FANCY_MATH_387
17506    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17507        || TARGET_MIX_SSE_I387)
17508    && flag_unsafe_math_optimizations && !optimize_size"
17509 {
17510   rtx op0 = gen_reg_rtx (XFmode);
17511   rtx op1 = gen_reg_rtx (XFmode);
17512
17513   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17514   emit_insn (gen_exp2xf2 (op0, op1));
17515   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17516   DONE;
17517 })
17518
17519 (define_expand "expm1xf2"
17520   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17521                                (match_dup 2)))
17522    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17523    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17524    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17525    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17526    (parallel [(set (match_dup 7)
17527                    (unspec:XF [(match_dup 6) (match_dup 4)]
17528                               UNSPEC_FSCALE_FRACT))
17529               (set (match_dup 8)
17530                    (unspec:XF [(match_dup 6) (match_dup 4)]
17531                               UNSPEC_FSCALE_EXP))])
17532    (parallel [(set (match_dup 10)
17533                    (unspec:XF [(match_dup 9) (match_dup 8)]
17534                               UNSPEC_FSCALE_FRACT))
17535               (set (match_dup 11)
17536                    (unspec:XF [(match_dup 9) (match_dup 8)]
17537                               UNSPEC_FSCALE_EXP))])
17538    (set (match_dup 12) (minus:XF (match_dup 10)
17539                                  (float_extend:XF (match_dup 13))))
17540    (set (match_operand:XF 0 "register_operand" "")
17541         (plus:XF (match_dup 12) (match_dup 7)))]
17542   "TARGET_USE_FANCY_MATH_387
17543    && flag_unsafe_math_optimizations && !optimize_size"
17544 {
17545   int i;
17546
17547   for (i = 2; i < 13; i++)
17548     operands[i] = gen_reg_rtx (XFmode);
17549
17550   operands[13]
17551     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17552
17553   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17554 })
17555
17556 (define_expand "expm1<mode>2"
17557   [(use (match_operand:MODEF 0 "register_operand" ""))
17558    (use (match_operand:MODEF 1 "general_operand" ""))]
17559  "TARGET_USE_FANCY_MATH_387
17560    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17561        || TARGET_MIX_SSE_I387)
17562    && flag_unsafe_math_optimizations && !optimize_size"
17563 {
17564   rtx op0 = gen_reg_rtx (XFmode);
17565   rtx op1 = gen_reg_rtx (XFmode);
17566
17567   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17568   emit_insn (gen_expm1xf2 (op0, op1));
17569   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17570   DONE;
17571 })
17572
17573 (define_expand "ldexpxf3"
17574   [(set (match_dup 3)
17575         (float:XF (match_operand:SI 2 "register_operand" "")))
17576    (parallel [(set (match_operand:XF 0 " register_operand" "")
17577                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17578                                (match_dup 3)]
17579                               UNSPEC_FSCALE_FRACT))
17580               (set (match_dup 4)
17581                    (unspec:XF [(match_dup 1) (match_dup 3)]
17582                               UNSPEC_FSCALE_EXP))])]
17583   "TARGET_USE_FANCY_MATH_387
17584    && flag_unsafe_math_optimizations && !optimize_size"
17585 {
17586   operands[3] = gen_reg_rtx (XFmode);
17587   operands[4] = gen_reg_rtx (XFmode);
17588 })
17589
17590 (define_expand "ldexp<mode>3"
17591   [(use (match_operand:MODEF 0 "register_operand" ""))
17592    (use (match_operand:MODEF 1 "general_operand" ""))
17593    (use (match_operand:SI 2 "register_operand" ""))]
17594  "TARGET_USE_FANCY_MATH_387
17595    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17596        || TARGET_MIX_SSE_I387)
17597    && flag_unsafe_math_optimizations && !optimize_size"
17598 {
17599   rtx op0 = gen_reg_rtx (XFmode);
17600   rtx op1 = gen_reg_rtx (XFmode);
17601
17602   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17603   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17604   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17605   DONE;
17606 })
17607
17608 (define_expand "scalbxf3"
17609   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17610                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17611                                (match_operand:XF 2 "register_operand" "")]
17612                               UNSPEC_FSCALE_FRACT))
17613               (set (match_dup 3)
17614                    (unspec:XF [(match_dup 1) (match_dup 2)]
17615                               UNSPEC_FSCALE_EXP))])]
17616   "TARGET_USE_FANCY_MATH_387
17617    && flag_unsafe_math_optimizations && !optimize_size"
17618 {
17619   operands[3] = gen_reg_rtx (XFmode);
17620 })
17621
17622 (define_expand "scalb<mode>3"
17623   [(use (match_operand:MODEF 0 "register_operand" ""))
17624    (use (match_operand:MODEF 1 "general_operand" ""))
17625    (use (match_operand:MODEF 2 "register_operand" ""))]
17626  "TARGET_USE_FANCY_MATH_387
17627    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17628        || TARGET_MIX_SSE_I387)
17629    && flag_unsafe_math_optimizations && !optimize_size"
17630 {
17631   rtx op0 = gen_reg_rtx (XFmode);
17632   rtx op1 = gen_reg_rtx (XFmode);
17633   rtx op2 = gen_reg_rtx (XFmode);
17634
17635   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17636   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17637   emit_insn (gen_scalbxf3 (op0, op1, op2));
17638   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17639   DONE;
17640 })
17641 \f
17642
17643 (define_insn "sse4_1_round<mode>2"
17644   [(set (match_operand:MODEF 0 "register_operand" "=x")
17645         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17646                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17647                       UNSPEC_ROUND))]
17648   "TARGET_SSE4_1"
17649   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17650   [(set_attr "type" "ssecvt")
17651    (set_attr "prefix_extra" "1")
17652    (set_attr "mode" "<MODE>")])
17653
17654 (define_insn "rintxf2"
17655   [(set (match_operand:XF 0 "register_operand" "=f")
17656         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17657                    UNSPEC_FRNDINT))]
17658   "TARGET_USE_FANCY_MATH_387
17659    && flag_unsafe_math_optimizations"
17660   "frndint"
17661   [(set_attr "type" "fpspc")
17662    (set_attr "mode" "XF")])
17663
17664 (define_expand "rint<mode>2"
17665   [(use (match_operand:MODEF 0 "register_operand" ""))
17666    (use (match_operand:MODEF 1 "register_operand" ""))]
17667   "(TARGET_USE_FANCY_MATH_387
17668     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17669         || TARGET_MIX_SSE_I387)
17670     && flag_unsafe_math_optimizations)
17671    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17672        && !flag_trapping_math
17673        && (TARGET_SSE4_1 || !optimize_size))"
17674 {
17675   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17676       && !flag_trapping_math
17677       && (TARGET_SSE4_1 || !optimize_size))
17678     {
17679       if (TARGET_SSE4_1)
17680         emit_insn (gen_sse4_1_round<mode>2
17681                    (operands[0], operands[1], GEN_INT (0x04)));
17682       else
17683         ix86_expand_rint (operand0, operand1);
17684     }
17685   else
17686     {
17687       rtx op0 = gen_reg_rtx (XFmode);
17688       rtx op1 = gen_reg_rtx (XFmode);
17689
17690       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17691       emit_insn (gen_rintxf2 (op0, op1));
17692
17693       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17694     }
17695   DONE;
17696 })
17697
17698 (define_expand "round<mode>2"
17699   [(match_operand:MODEF 0 "register_operand" "")
17700    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17701   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17702    && !flag_trapping_math && !flag_rounding_math
17703    && !optimize_size"
17704 {
17705   if (TARGET_64BIT || (<MODE>mode != DFmode))
17706     ix86_expand_round (operand0, operand1);
17707   else
17708     ix86_expand_rounddf_32 (operand0, operand1);
17709   DONE;
17710 })
17711
17712 (define_insn_and_split "*fistdi2_1"
17713   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17714         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17715                    UNSPEC_FIST))]
17716   "TARGET_USE_FANCY_MATH_387
17717    && !(reload_completed || reload_in_progress)"
17718   "#"
17719   "&& 1"
17720   [(const_int 0)]
17721 {
17722   if (memory_operand (operands[0], VOIDmode))
17723     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17724   else
17725     {
17726       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17727       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17728                                          operands[2]));
17729     }
17730   DONE;
17731 }
17732   [(set_attr "type" "fpspc")
17733    (set_attr "mode" "DI")])
17734
17735 (define_insn "fistdi2"
17736   [(set (match_operand:DI 0 "memory_operand" "=m")
17737         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17738                    UNSPEC_FIST))
17739    (clobber (match_scratch:XF 2 "=&1f"))]
17740   "TARGET_USE_FANCY_MATH_387"
17741   "* return output_fix_trunc (insn, operands, 0);"
17742   [(set_attr "type" "fpspc")
17743    (set_attr "mode" "DI")])
17744
17745 (define_insn "fistdi2_with_temp"
17746   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17747         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17748                    UNSPEC_FIST))
17749    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17750    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17751   "TARGET_USE_FANCY_MATH_387"
17752   "#"
17753   [(set_attr "type" "fpspc")
17754    (set_attr "mode" "DI")])
17755
17756 (define_split
17757   [(set (match_operand:DI 0 "register_operand" "")
17758         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17759                    UNSPEC_FIST))
17760    (clobber (match_operand:DI 2 "memory_operand" ""))
17761    (clobber (match_scratch 3 ""))]
17762   "reload_completed"
17763   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17764               (clobber (match_dup 3))])
17765    (set (match_dup 0) (match_dup 2))]
17766   "")
17767
17768 (define_split
17769   [(set (match_operand:DI 0 "memory_operand" "")
17770         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17771                    UNSPEC_FIST))
17772    (clobber (match_operand:DI 2 "memory_operand" ""))
17773    (clobber (match_scratch 3 ""))]
17774   "reload_completed"
17775   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17776               (clobber (match_dup 3))])]
17777   "")
17778
17779 (define_insn_and_split "*fist<mode>2_1"
17780   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17781         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17782                            UNSPEC_FIST))]
17783   "TARGET_USE_FANCY_MATH_387
17784    && !(reload_completed || reload_in_progress)"
17785   "#"
17786   "&& 1"
17787   [(const_int 0)]
17788 {
17789   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17790   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17791                                         operands[2]));
17792   DONE;
17793 }
17794   [(set_attr "type" "fpspc")
17795    (set_attr "mode" "<MODE>")])
17796
17797 (define_insn "fist<mode>2"
17798   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17799         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17800                            UNSPEC_FIST))]
17801   "TARGET_USE_FANCY_MATH_387"
17802   "* return output_fix_trunc (insn, operands, 0);"
17803   [(set_attr "type" "fpspc")
17804    (set_attr "mode" "<MODE>")])
17805
17806 (define_insn "fist<mode>2_with_temp"
17807   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17808         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17809                            UNSPEC_FIST))
17810    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17811   "TARGET_USE_FANCY_MATH_387"
17812   "#"
17813   [(set_attr "type" "fpspc")
17814    (set_attr "mode" "<MODE>")])
17815
17816 (define_split
17817   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17818         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17819                            UNSPEC_FIST))
17820    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17821   "reload_completed"
17822   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17823    (set (match_dup 0) (match_dup 2))]
17824   "")
17825
17826 (define_split
17827   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17828         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17829                            UNSPEC_FIST))
17830    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17831   "reload_completed"
17832   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17833   "")
17834
17835 (define_expand "lrintxf<mode>2"
17836   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17837      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17838                       UNSPEC_FIST))]
17839   "TARGET_USE_FANCY_MATH_387"
17840   "")
17841
17842 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17843   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17844      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17845                         UNSPEC_FIX_NOTRUNC))]
17846   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17847    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17848   "")
17849
17850 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17851   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17852    (match_operand:MODEF 1 "register_operand" "")]
17853   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17854    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17855    && !flag_trapping_math && !flag_rounding_math
17856    && !optimize_size"
17857 {
17858   ix86_expand_lround (operand0, operand1);
17859   DONE;
17860 })
17861
17862 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17863 (define_insn_and_split "frndintxf2_floor"
17864   [(set (match_operand:XF 0 "register_operand" "")
17865         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17866          UNSPEC_FRNDINT_FLOOR))
17867    (clobber (reg:CC FLAGS_REG))]
17868   "TARGET_USE_FANCY_MATH_387
17869    && flag_unsafe_math_optimizations
17870    && !(reload_completed || reload_in_progress)"
17871   "#"
17872   "&& 1"
17873   [(const_int 0)]
17874 {
17875   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17876
17877   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17878   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17879
17880   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17881                                         operands[2], operands[3]));
17882   DONE;
17883 }
17884   [(set_attr "type" "frndint")
17885    (set_attr "i387_cw" "floor")
17886    (set_attr "mode" "XF")])
17887
17888 (define_insn "frndintxf2_floor_i387"
17889   [(set (match_operand:XF 0 "register_operand" "=f")
17890         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17891          UNSPEC_FRNDINT_FLOOR))
17892    (use (match_operand:HI 2 "memory_operand" "m"))
17893    (use (match_operand:HI 3 "memory_operand" "m"))]
17894   "TARGET_USE_FANCY_MATH_387
17895    && flag_unsafe_math_optimizations"
17896   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17897   [(set_attr "type" "frndint")
17898    (set_attr "i387_cw" "floor")
17899    (set_attr "mode" "XF")])
17900
17901 (define_expand "floorxf2"
17902   [(use (match_operand:XF 0 "register_operand" ""))
17903    (use (match_operand:XF 1 "register_operand" ""))]
17904   "TARGET_USE_FANCY_MATH_387
17905    && flag_unsafe_math_optimizations && !optimize_size"
17906 {
17907   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17908   DONE;
17909 })
17910
17911 (define_expand "floor<mode>2"
17912   [(use (match_operand:MODEF 0 "register_operand" ""))
17913    (use (match_operand:MODEF 1 "register_operand" ""))]
17914   "(TARGET_USE_FANCY_MATH_387
17915     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17916         || TARGET_MIX_SSE_I387)
17917     && flag_unsafe_math_optimizations && !optimize_size)
17918    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17919        && !flag_trapping_math
17920        && (TARGET_SSE4_1 || !optimize_size))"
17921 {
17922   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17923       && !flag_trapping_math
17924       && (TARGET_SSE4_1 || !optimize_size))
17925     {
17926       if (TARGET_SSE4_1)
17927         emit_insn (gen_sse4_1_round<mode>2
17928                    (operands[0], operands[1], GEN_INT (0x01)));
17929       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17930         ix86_expand_floorceil (operand0, operand1, true);
17931       else
17932         ix86_expand_floorceildf_32 (operand0, operand1, true);
17933     }
17934   else
17935     {
17936       rtx op0 = gen_reg_rtx (XFmode);
17937       rtx op1 = gen_reg_rtx (XFmode);
17938
17939       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17940       emit_insn (gen_frndintxf2_floor (op0, op1));
17941
17942       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17943     }
17944   DONE;
17945 })
17946
17947 (define_insn_and_split "*fist<mode>2_floor_1"
17948   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17949         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17950          UNSPEC_FIST_FLOOR))
17951    (clobber (reg:CC FLAGS_REG))]
17952   "TARGET_USE_FANCY_MATH_387
17953    && flag_unsafe_math_optimizations
17954    && !(reload_completed || reload_in_progress)"
17955   "#"
17956   "&& 1"
17957   [(const_int 0)]
17958 {
17959   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17960
17961   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17962   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17963   if (memory_operand (operands[0], VOIDmode))
17964     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17965                                       operands[2], operands[3]));
17966   else
17967     {
17968       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17969       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17970                                                   operands[2], operands[3],
17971                                                   operands[4]));
17972     }
17973   DONE;
17974 }
17975   [(set_attr "type" "fistp")
17976    (set_attr "i387_cw" "floor")
17977    (set_attr "mode" "<MODE>")])
17978
17979 (define_insn "fistdi2_floor"
17980   [(set (match_operand:DI 0 "memory_operand" "=m")
17981         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17982          UNSPEC_FIST_FLOOR))
17983    (use (match_operand:HI 2 "memory_operand" "m"))
17984    (use (match_operand:HI 3 "memory_operand" "m"))
17985    (clobber (match_scratch:XF 4 "=&1f"))]
17986   "TARGET_USE_FANCY_MATH_387
17987    && flag_unsafe_math_optimizations"
17988   "* return output_fix_trunc (insn, operands, 0);"
17989   [(set_attr "type" "fistp")
17990    (set_attr "i387_cw" "floor")
17991    (set_attr "mode" "DI")])
17992
17993 (define_insn "fistdi2_floor_with_temp"
17994   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17995         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17996          UNSPEC_FIST_FLOOR))
17997    (use (match_operand:HI 2 "memory_operand" "m,m"))
17998    (use (match_operand:HI 3 "memory_operand" "m,m"))
17999    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18000    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18001   "TARGET_USE_FANCY_MATH_387
18002    && flag_unsafe_math_optimizations"
18003   "#"
18004   [(set_attr "type" "fistp")
18005    (set_attr "i387_cw" "floor")
18006    (set_attr "mode" "DI")])
18007
18008 (define_split
18009   [(set (match_operand:DI 0 "register_operand" "")
18010         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18011          UNSPEC_FIST_FLOOR))
18012    (use (match_operand:HI 2 "memory_operand" ""))
18013    (use (match_operand:HI 3 "memory_operand" ""))
18014    (clobber (match_operand:DI 4 "memory_operand" ""))
18015    (clobber (match_scratch 5 ""))]
18016   "reload_completed"
18017   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18018               (use (match_dup 2))
18019               (use (match_dup 3))
18020               (clobber (match_dup 5))])
18021    (set (match_dup 0) (match_dup 4))]
18022   "")
18023
18024 (define_split
18025   [(set (match_operand:DI 0 "memory_operand" "")
18026         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18027          UNSPEC_FIST_FLOOR))
18028    (use (match_operand:HI 2 "memory_operand" ""))
18029    (use (match_operand:HI 3 "memory_operand" ""))
18030    (clobber (match_operand:DI 4 "memory_operand" ""))
18031    (clobber (match_scratch 5 ""))]
18032   "reload_completed"
18033   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18034               (use (match_dup 2))
18035               (use (match_dup 3))
18036               (clobber (match_dup 5))])]
18037   "")
18038
18039 (define_insn "fist<mode>2_floor"
18040   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18041         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18042          UNSPEC_FIST_FLOOR))
18043    (use (match_operand:HI 2 "memory_operand" "m"))
18044    (use (match_operand:HI 3 "memory_operand" "m"))]
18045   "TARGET_USE_FANCY_MATH_387
18046    && flag_unsafe_math_optimizations"
18047   "* return output_fix_trunc (insn, operands, 0);"
18048   [(set_attr "type" "fistp")
18049    (set_attr "i387_cw" "floor")
18050    (set_attr "mode" "<MODE>")])
18051
18052 (define_insn "fist<mode>2_floor_with_temp"
18053   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18054         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18055          UNSPEC_FIST_FLOOR))
18056    (use (match_operand:HI 2 "memory_operand" "m,m"))
18057    (use (match_operand:HI 3 "memory_operand" "m,m"))
18058    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18059   "TARGET_USE_FANCY_MATH_387
18060    && flag_unsafe_math_optimizations"
18061   "#"
18062   [(set_attr "type" "fistp")
18063    (set_attr "i387_cw" "floor")
18064    (set_attr "mode" "<MODE>")])
18065
18066 (define_split
18067   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18068         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18069          UNSPEC_FIST_FLOOR))
18070    (use (match_operand:HI 2 "memory_operand" ""))
18071    (use (match_operand:HI 3 "memory_operand" ""))
18072    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18073   "reload_completed"
18074   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18075                                   UNSPEC_FIST_FLOOR))
18076               (use (match_dup 2))
18077               (use (match_dup 3))])
18078    (set (match_dup 0) (match_dup 4))]
18079   "")
18080
18081 (define_split
18082   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18083         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18084          UNSPEC_FIST_FLOOR))
18085    (use (match_operand:HI 2 "memory_operand" ""))
18086    (use (match_operand:HI 3 "memory_operand" ""))
18087    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18088   "reload_completed"
18089   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18090                                   UNSPEC_FIST_FLOOR))
18091               (use (match_dup 2))
18092               (use (match_dup 3))])]
18093   "")
18094
18095 (define_expand "lfloorxf<mode>2"
18096   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18097                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18098                     UNSPEC_FIST_FLOOR))
18099               (clobber (reg:CC FLAGS_REG))])]
18100   "TARGET_USE_FANCY_MATH_387
18101    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18102    && flag_unsafe_math_optimizations"
18103   "")
18104
18105 (define_expand "lfloor<mode>di2"
18106   [(match_operand:DI 0 "nonimmediate_operand" "")
18107    (match_operand:MODEF 1 "register_operand" "")]
18108   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18109    && !flag_trapping_math
18110    && !optimize_size"
18111 {
18112   ix86_expand_lfloorceil (operand0, operand1, true);
18113   DONE;
18114 })
18115
18116 (define_expand "lfloor<mode>si2"
18117   [(match_operand:SI 0 "nonimmediate_operand" "")
18118    (match_operand:MODEF 1 "register_operand" "")]
18119   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18120    && !flag_trapping_math
18121    && (!optimize_size || !TARGET_64BIT)"
18122 {
18123   ix86_expand_lfloorceil (operand0, operand1, true);
18124   DONE;
18125 })
18126
18127 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18128 (define_insn_and_split "frndintxf2_ceil"
18129   [(set (match_operand:XF 0 "register_operand" "")
18130         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18131          UNSPEC_FRNDINT_CEIL))
18132    (clobber (reg:CC FLAGS_REG))]
18133   "TARGET_USE_FANCY_MATH_387
18134    && flag_unsafe_math_optimizations
18135    && !(reload_completed || reload_in_progress)"
18136   "#"
18137   "&& 1"
18138   [(const_int 0)]
18139 {
18140   ix86_optimize_mode_switching[I387_CEIL] = 1;
18141
18142   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18143   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18144
18145   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18146                                        operands[2], operands[3]));
18147   DONE;
18148 }
18149   [(set_attr "type" "frndint")
18150    (set_attr "i387_cw" "ceil")
18151    (set_attr "mode" "XF")])
18152
18153 (define_insn "frndintxf2_ceil_i387"
18154   [(set (match_operand:XF 0 "register_operand" "=f")
18155         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18156          UNSPEC_FRNDINT_CEIL))
18157    (use (match_operand:HI 2 "memory_operand" "m"))
18158    (use (match_operand:HI 3 "memory_operand" "m"))]
18159   "TARGET_USE_FANCY_MATH_387
18160    && flag_unsafe_math_optimizations"
18161   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18162   [(set_attr "type" "frndint")
18163    (set_attr "i387_cw" "ceil")
18164    (set_attr "mode" "XF")])
18165
18166 (define_expand "ceilxf2"
18167   [(use (match_operand:XF 0 "register_operand" ""))
18168    (use (match_operand:XF 1 "register_operand" ""))]
18169   "TARGET_USE_FANCY_MATH_387
18170    && flag_unsafe_math_optimizations && !optimize_size"
18171 {
18172   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18173   DONE;
18174 })
18175
18176 (define_expand "ceil<mode>2"
18177   [(use (match_operand:MODEF 0 "register_operand" ""))
18178    (use (match_operand:MODEF 1 "register_operand" ""))]
18179   "(TARGET_USE_FANCY_MATH_387
18180     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18181         || TARGET_MIX_SSE_I387)
18182     && flag_unsafe_math_optimizations && !optimize_size)
18183    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18184        && !flag_trapping_math
18185        && (TARGET_SSE4_1 || !optimize_size))"
18186 {
18187   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18188       && !flag_trapping_math
18189       && (TARGET_SSE4_1 || !optimize_size))
18190     {
18191       if (TARGET_SSE4_1)
18192         emit_insn (gen_sse4_1_round<mode>2
18193                    (operands[0], operands[1], GEN_INT (0x02)));
18194       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18195         ix86_expand_floorceil (operand0, operand1, false);
18196       else
18197         ix86_expand_floorceildf_32 (operand0, operand1, false);
18198     }
18199   else
18200     {
18201       rtx op0 = gen_reg_rtx (XFmode);
18202       rtx op1 = gen_reg_rtx (XFmode);
18203
18204       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18205       emit_insn (gen_frndintxf2_ceil (op0, op1));
18206
18207       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18208     }
18209   DONE;
18210 })
18211
18212 (define_insn_and_split "*fist<mode>2_ceil_1"
18213   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18214         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18215          UNSPEC_FIST_CEIL))
18216    (clobber (reg:CC FLAGS_REG))]
18217   "TARGET_USE_FANCY_MATH_387
18218    && flag_unsafe_math_optimizations
18219    && !(reload_completed || reload_in_progress)"
18220   "#"
18221   "&& 1"
18222   [(const_int 0)]
18223 {
18224   ix86_optimize_mode_switching[I387_CEIL] = 1;
18225
18226   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18227   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18228   if (memory_operand (operands[0], VOIDmode))
18229     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18230                                      operands[2], operands[3]));
18231   else
18232     {
18233       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18234       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18235                                                  operands[2], operands[3],
18236                                                  operands[4]));
18237     }
18238   DONE;
18239 }
18240   [(set_attr "type" "fistp")
18241    (set_attr "i387_cw" "ceil")
18242    (set_attr "mode" "<MODE>")])
18243
18244 (define_insn "fistdi2_ceil"
18245   [(set (match_operand:DI 0 "memory_operand" "=m")
18246         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18247          UNSPEC_FIST_CEIL))
18248    (use (match_operand:HI 2 "memory_operand" "m"))
18249    (use (match_operand:HI 3 "memory_operand" "m"))
18250    (clobber (match_scratch:XF 4 "=&1f"))]
18251   "TARGET_USE_FANCY_MATH_387
18252    && flag_unsafe_math_optimizations"
18253   "* return output_fix_trunc (insn, operands, 0);"
18254   [(set_attr "type" "fistp")
18255    (set_attr "i387_cw" "ceil")
18256    (set_attr "mode" "DI")])
18257
18258 (define_insn "fistdi2_ceil_with_temp"
18259   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18260         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18261          UNSPEC_FIST_CEIL))
18262    (use (match_operand:HI 2 "memory_operand" "m,m"))
18263    (use (match_operand:HI 3 "memory_operand" "m,m"))
18264    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18265    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18266   "TARGET_USE_FANCY_MATH_387
18267    && flag_unsafe_math_optimizations"
18268   "#"
18269   [(set_attr "type" "fistp")
18270    (set_attr "i387_cw" "ceil")
18271    (set_attr "mode" "DI")])
18272
18273 (define_split
18274   [(set (match_operand:DI 0 "register_operand" "")
18275         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18276          UNSPEC_FIST_CEIL))
18277    (use (match_operand:HI 2 "memory_operand" ""))
18278    (use (match_operand:HI 3 "memory_operand" ""))
18279    (clobber (match_operand:DI 4 "memory_operand" ""))
18280    (clobber (match_scratch 5 ""))]
18281   "reload_completed"
18282   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18283               (use (match_dup 2))
18284               (use (match_dup 3))
18285               (clobber (match_dup 5))])
18286    (set (match_dup 0) (match_dup 4))]
18287   "")
18288
18289 (define_split
18290   [(set (match_operand:DI 0 "memory_operand" "")
18291         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18292          UNSPEC_FIST_CEIL))
18293    (use (match_operand:HI 2 "memory_operand" ""))
18294    (use (match_operand:HI 3 "memory_operand" ""))
18295    (clobber (match_operand:DI 4 "memory_operand" ""))
18296    (clobber (match_scratch 5 ""))]
18297   "reload_completed"
18298   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18299               (use (match_dup 2))
18300               (use (match_dup 3))
18301               (clobber (match_dup 5))])]
18302   "")
18303
18304 (define_insn "fist<mode>2_ceil"
18305   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18306         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18307          UNSPEC_FIST_CEIL))
18308    (use (match_operand:HI 2 "memory_operand" "m"))
18309    (use (match_operand:HI 3 "memory_operand" "m"))]
18310   "TARGET_USE_FANCY_MATH_387
18311    && flag_unsafe_math_optimizations"
18312   "* return output_fix_trunc (insn, operands, 0);"
18313   [(set_attr "type" "fistp")
18314    (set_attr "i387_cw" "ceil")
18315    (set_attr "mode" "<MODE>")])
18316
18317 (define_insn "fist<mode>2_ceil_with_temp"
18318   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18319         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18320          UNSPEC_FIST_CEIL))
18321    (use (match_operand:HI 2 "memory_operand" "m,m"))
18322    (use (match_operand:HI 3 "memory_operand" "m,m"))
18323    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18324   "TARGET_USE_FANCY_MATH_387
18325    && flag_unsafe_math_optimizations"
18326   "#"
18327   [(set_attr "type" "fistp")
18328    (set_attr "i387_cw" "ceil")
18329    (set_attr "mode" "<MODE>")])
18330
18331 (define_split
18332   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18333         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18334          UNSPEC_FIST_CEIL))
18335    (use (match_operand:HI 2 "memory_operand" ""))
18336    (use (match_operand:HI 3 "memory_operand" ""))
18337    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18338   "reload_completed"
18339   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18340                                   UNSPEC_FIST_CEIL))
18341               (use (match_dup 2))
18342               (use (match_dup 3))])
18343    (set (match_dup 0) (match_dup 4))]
18344   "")
18345
18346 (define_split
18347   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18348         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18349          UNSPEC_FIST_CEIL))
18350    (use (match_operand:HI 2 "memory_operand" ""))
18351    (use (match_operand:HI 3 "memory_operand" ""))
18352    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18353   "reload_completed"
18354   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18355                                   UNSPEC_FIST_CEIL))
18356               (use (match_dup 2))
18357               (use (match_dup 3))])]
18358   "")
18359
18360 (define_expand "lceilxf<mode>2"
18361   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18362                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18363                     UNSPEC_FIST_CEIL))
18364               (clobber (reg:CC FLAGS_REG))])]
18365   "TARGET_USE_FANCY_MATH_387
18366    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18367    && flag_unsafe_math_optimizations"
18368   "")
18369
18370 (define_expand "lceil<mode>di2"
18371   [(match_operand:DI 0 "nonimmediate_operand" "")
18372    (match_operand:MODEF 1 "register_operand" "")]
18373   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18374    && !flag_trapping_math"
18375 {
18376   ix86_expand_lfloorceil (operand0, operand1, false);
18377   DONE;
18378 })
18379
18380 (define_expand "lceil<mode>si2"
18381   [(match_operand:SI 0 "nonimmediate_operand" "")
18382    (match_operand:MODEF 1 "register_operand" "")]
18383   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18384    && !flag_trapping_math"
18385 {
18386   ix86_expand_lfloorceil (operand0, operand1, false);
18387   DONE;
18388 })
18389
18390 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18391 (define_insn_and_split "frndintxf2_trunc"
18392   [(set (match_operand:XF 0 "register_operand" "")
18393         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18394          UNSPEC_FRNDINT_TRUNC))
18395    (clobber (reg:CC FLAGS_REG))]
18396   "TARGET_USE_FANCY_MATH_387
18397    && flag_unsafe_math_optimizations
18398    && !(reload_completed || reload_in_progress)"
18399   "#"
18400   "&& 1"
18401   [(const_int 0)]
18402 {
18403   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18404
18405   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18406   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18407
18408   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18409                                         operands[2], operands[3]));
18410   DONE;
18411 }
18412   [(set_attr "type" "frndint")
18413    (set_attr "i387_cw" "trunc")
18414    (set_attr "mode" "XF")])
18415
18416 (define_insn "frndintxf2_trunc_i387"
18417   [(set (match_operand:XF 0 "register_operand" "=f")
18418         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18419          UNSPEC_FRNDINT_TRUNC))
18420    (use (match_operand:HI 2 "memory_operand" "m"))
18421    (use (match_operand:HI 3 "memory_operand" "m"))]
18422   "TARGET_USE_FANCY_MATH_387
18423    && flag_unsafe_math_optimizations"
18424   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18425   [(set_attr "type" "frndint")
18426    (set_attr "i387_cw" "trunc")
18427    (set_attr "mode" "XF")])
18428
18429 (define_expand "btruncxf2"
18430   [(use (match_operand:XF 0 "register_operand" ""))
18431    (use (match_operand:XF 1 "register_operand" ""))]
18432   "TARGET_USE_FANCY_MATH_387
18433    && flag_unsafe_math_optimizations && !optimize_size"
18434 {
18435   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18436   DONE;
18437 })
18438
18439 (define_expand "btrunc<mode>2"
18440   [(use (match_operand:MODEF 0 "register_operand" ""))
18441    (use (match_operand:MODEF 1 "register_operand" ""))]
18442   "(TARGET_USE_FANCY_MATH_387
18443     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18444         || TARGET_MIX_SSE_I387)
18445     && flag_unsafe_math_optimizations && !optimize_size)
18446    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18447        && !flag_trapping_math
18448        && (TARGET_SSE4_1 || !optimize_size))"
18449 {
18450   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18451       && !flag_trapping_math
18452       && (TARGET_SSE4_1 || !optimize_size))
18453     {
18454       if (TARGET_SSE4_1)
18455         emit_insn (gen_sse4_1_round<mode>2
18456                    (operands[0], operands[1], GEN_INT (0x03)));
18457       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18458         ix86_expand_trunc (operand0, operand1);
18459       else
18460         ix86_expand_truncdf_32 (operand0, operand1);
18461     }
18462   else
18463     {
18464       rtx op0 = gen_reg_rtx (XFmode);
18465       rtx op1 = gen_reg_rtx (XFmode);
18466
18467       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18468       emit_insn (gen_frndintxf2_trunc (op0, op1));
18469
18470       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18471     }
18472   DONE;
18473 })
18474
18475 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18476 (define_insn_and_split "frndintxf2_mask_pm"
18477   [(set (match_operand:XF 0 "register_operand" "")
18478         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18479          UNSPEC_FRNDINT_MASK_PM))
18480    (clobber (reg:CC FLAGS_REG))]
18481   "TARGET_USE_FANCY_MATH_387
18482    && flag_unsafe_math_optimizations
18483    && !(reload_completed || reload_in_progress)"
18484   "#"
18485   "&& 1"
18486   [(const_int 0)]
18487 {
18488   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18489
18490   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18491   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18492
18493   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18494                                           operands[2], operands[3]));
18495   DONE;
18496 }
18497   [(set_attr "type" "frndint")
18498    (set_attr "i387_cw" "mask_pm")
18499    (set_attr "mode" "XF")])
18500
18501 (define_insn "frndintxf2_mask_pm_i387"
18502   [(set (match_operand:XF 0 "register_operand" "=f")
18503         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18504          UNSPEC_FRNDINT_MASK_PM))
18505    (use (match_operand:HI 2 "memory_operand" "m"))
18506    (use (match_operand:HI 3 "memory_operand" "m"))]
18507   "TARGET_USE_FANCY_MATH_387
18508    && flag_unsafe_math_optimizations"
18509   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18510   [(set_attr "type" "frndint")
18511    (set_attr "i387_cw" "mask_pm")
18512    (set_attr "mode" "XF")])
18513
18514 (define_expand "nearbyintxf2"
18515   [(use (match_operand:XF 0 "register_operand" ""))
18516    (use (match_operand:XF 1 "register_operand" ""))]
18517   "TARGET_USE_FANCY_MATH_387
18518    && flag_unsafe_math_optimizations"
18519 {
18520   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18521
18522   DONE;
18523 })
18524
18525 (define_expand "nearbyint<mode>2"
18526   [(use (match_operand:MODEF 0 "register_operand" ""))
18527    (use (match_operand:MODEF 1 "register_operand" ""))]
18528   "TARGET_USE_FANCY_MATH_387
18529    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18530        || TARGET_MIX_SSE_I387)
18531    && flag_unsafe_math_optimizations"
18532 {
18533   rtx op0 = gen_reg_rtx (XFmode);
18534   rtx op1 = gen_reg_rtx (XFmode);
18535
18536   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18537   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18538
18539   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18540   DONE;
18541 })
18542
18543 (define_insn "fxam<mode>2_i387"
18544   [(set (match_operand:HI 0 "register_operand" "=a")
18545         (unspec:HI
18546           [(match_operand:X87MODEF 1 "register_operand" "f")]
18547           UNSPEC_FXAM))]
18548   "TARGET_USE_FANCY_MATH_387"
18549   "fxam\n\tfnstsw\t%0"
18550   [(set_attr "type" "multi")
18551    (set_attr "unit" "i387")
18552    (set_attr "mode" "<MODE>")])
18553
18554 (define_expand "isinf<mode>2"
18555   [(use (match_operand:SI 0 "register_operand" ""))
18556    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18557   "TARGET_USE_FANCY_MATH_387
18558    && TARGET_C99_FUNCTIONS
18559    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18560 {
18561   rtx mask = GEN_INT (0x45);
18562   rtx val = GEN_INT (0x05);
18563
18564   rtx cond;
18565
18566   rtx scratch = gen_reg_rtx (HImode);
18567   rtx res = gen_reg_rtx (QImode);
18568
18569   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18570   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18571   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18572   cond = gen_rtx_fmt_ee (EQ, QImode,
18573                          gen_rtx_REG (CCmode, FLAGS_REG),
18574                          const0_rtx);
18575   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18576   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18577   DONE;
18578 })
18579
18580 (define_expand "signbit<mode>2"
18581   [(use (match_operand:SI 0 "register_operand" ""))
18582    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18583   "TARGET_USE_FANCY_MATH_387
18584    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18585 {
18586   rtx mask = GEN_INT (0x0200);
18587
18588   rtx scratch = gen_reg_rtx (HImode);
18589
18590   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18591   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18592   DONE;
18593 })
18594 \f
18595 ;; Block operation instructions
18596
18597 (define_expand "movmemsi"
18598   [(use (match_operand:BLK 0 "memory_operand" ""))
18599    (use (match_operand:BLK 1 "memory_operand" ""))
18600    (use (match_operand:SI 2 "nonmemory_operand" ""))
18601    (use (match_operand:SI 3 "const_int_operand" ""))
18602    (use (match_operand:SI 4 "const_int_operand" ""))
18603    (use (match_operand:SI 5 "const_int_operand" ""))]
18604   ""
18605 {
18606  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18607                          operands[4], operands[5]))
18608    DONE;
18609  else
18610    FAIL;
18611 })
18612
18613 (define_expand "movmemdi"
18614   [(use (match_operand:BLK 0 "memory_operand" ""))
18615    (use (match_operand:BLK 1 "memory_operand" ""))
18616    (use (match_operand:DI 2 "nonmemory_operand" ""))
18617    (use (match_operand:DI 3 "const_int_operand" ""))
18618    (use (match_operand:SI 4 "const_int_operand" ""))
18619    (use (match_operand:SI 5 "const_int_operand" ""))]
18620   "TARGET_64BIT"
18621 {
18622  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18623                          operands[4], operands[5]))
18624    DONE;
18625  else
18626    FAIL;
18627 })
18628
18629 ;; Most CPUs don't like single string operations
18630 ;; Handle this case here to simplify previous expander.
18631
18632 (define_expand "strmov"
18633   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18634    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18635    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18636               (clobber (reg:CC FLAGS_REG))])
18637    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18638               (clobber (reg:CC FLAGS_REG))])]
18639   ""
18640 {
18641   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18642
18643   /* If .md ever supports :P for Pmode, these can be directly
18644      in the pattern above.  */
18645   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18646   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18647
18648   if (TARGET_SINGLE_STRINGOP || optimize_size)
18649     {
18650       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18651                                       operands[2], operands[3],
18652                                       operands[5], operands[6]));
18653       DONE;
18654     }
18655
18656   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18657 })
18658
18659 (define_expand "strmov_singleop"
18660   [(parallel [(set (match_operand 1 "memory_operand" "")
18661                    (match_operand 3 "memory_operand" ""))
18662               (set (match_operand 0 "register_operand" "")
18663                    (match_operand 4 "" ""))
18664               (set (match_operand 2 "register_operand" "")
18665                    (match_operand 5 "" ""))])]
18666   "TARGET_SINGLE_STRINGOP || optimize_size"
18667   "")
18668
18669 (define_insn "*strmovdi_rex_1"
18670   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18671         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18672    (set (match_operand:DI 0 "register_operand" "=D")
18673         (plus:DI (match_dup 2)
18674                  (const_int 8)))
18675    (set (match_operand:DI 1 "register_operand" "=S")
18676         (plus:DI (match_dup 3)
18677                  (const_int 8)))]
18678   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18679   "movsq"
18680   [(set_attr "type" "str")
18681    (set_attr "mode" "DI")
18682    (set_attr "memory" "both")])
18683
18684 (define_insn "*strmovsi_1"
18685   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18686         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18687    (set (match_operand:SI 0 "register_operand" "=D")
18688         (plus:SI (match_dup 2)
18689                  (const_int 4)))
18690    (set (match_operand:SI 1 "register_operand" "=S")
18691         (plus:SI (match_dup 3)
18692                  (const_int 4)))]
18693   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18694   "{movsl|movsd}"
18695   [(set_attr "type" "str")
18696    (set_attr "mode" "SI")
18697    (set_attr "memory" "both")])
18698
18699 (define_insn "*strmovsi_rex_1"
18700   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18701         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18702    (set (match_operand:DI 0 "register_operand" "=D")
18703         (plus:DI (match_dup 2)
18704                  (const_int 4)))
18705    (set (match_operand:DI 1 "register_operand" "=S")
18706         (plus:DI (match_dup 3)
18707                  (const_int 4)))]
18708   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18709   "{movsl|movsd}"
18710   [(set_attr "type" "str")
18711    (set_attr "mode" "SI")
18712    (set_attr "memory" "both")])
18713
18714 (define_insn "*strmovhi_1"
18715   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18716         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18717    (set (match_operand:SI 0 "register_operand" "=D")
18718         (plus:SI (match_dup 2)
18719                  (const_int 2)))
18720    (set (match_operand:SI 1 "register_operand" "=S")
18721         (plus:SI (match_dup 3)
18722                  (const_int 2)))]
18723   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18724   "movsw"
18725   [(set_attr "type" "str")
18726    (set_attr "memory" "both")
18727    (set_attr "mode" "HI")])
18728
18729 (define_insn "*strmovhi_rex_1"
18730   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18731         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18732    (set (match_operand:DI 0 "register_operand" "=D")
18733         (plus:DI (match_dup 2)
18734                  (const_int 2)))
18735    (set (match_operand:DI 1 "register_operand" "=S")
18736         (plus:DI (match_dup 3)
18737                  (const_int 2)))]
18738   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18739   "movsw"
18740   [(set_attr "type" "str")
18741    (set_attr "memory" "both")
18742    (set_attr "mode" "HI")])
18743
18744 (define_insn "*strmovqi_1"
18745   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18746         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18747    (set (match_operand:SI 0 "register_operand" "=D")
18748         (plus:SI (match_dup 2)
18749                  (const_int 1)))
18750    (set (match_operand:SI 1 "register_operand" "=S")
18751         (plus:SI (match_dup 3)
18752                  (const_int 1)))]
18753   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18754   "movsb"
18755   [(set_attr "type" "str")
18756    (set_attr "memory" "both")
18757    (set_attr "mode" "QI")])
18758
18759 (define_insn "*strmovqi_rex_1"
18760   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18761         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18762    (set (match_operand:DI 0 "register_operand" "=D")
18763         (plus:DI (match_dup 2)
18764                  (const_int 1)))
18765    (set (match_operand:DI 1 "register_operand" "=S")
18766         (plus:DI (match_dup 3)
18767                  (const_int 1)))]
18768   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18769   "movsb"
18770   [(set_attr "type" "str")
18771    (set_attr "memory" "both")
18772    (set_attr "mode" "QI")])
18773
18774 (define_expand "rep_mov"
18775   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18776               (set (match_operand 0 "register_operand" "")
18777                    (match_operand 5 "" ""))
18778               (set (match_operand 2 "register_operand" "")
18779                    (match_operand 6 "" ""))
18780               (set (match_operand 1 "memory_operand" "")
18781                    (match_operand 3 "memory_operand" ""))
18782               (use (match_dup 4))])]
18783   ""
18784   "")
18785
18786 (define_insn "*rep_movdi_rex64"
18787   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18788    (set (match_operand:DI 0 "register_operand" "=D")
18789         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18790                             (const_int 3))
18791                  (match_operand:DI 3 "register_operand" "0")))
18792    (set (match_operand:DI 1 "register_operand" "=S")
18793         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18794                  (match_operand:DI 4 "register_operand" "1")))
18795    (set (mem:BLK (match_dup 3))
18796         (mem:BLK (match_dup 4)))
18797    (use (match_dup 5))]
18798   "TARGET_64BIT"
18799   "rep movsq"
18800   [(set_attr "type" "str")
18801    (set_attr "prefix_rep" "1")
18802    (set_attr "memory" "both")
18803    (set_attr "mode" "DI")])
18804
18805 (define_insn "*rep_movsi"
18806   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18807    (set (match_operand:SI 0 "register_operand" "=D")
18808         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18809                             (const_int 2))
18810                  (match_operand:SI 3 "register_operand" "0")))
18811    (set (match_operand:SI 1 "register_operand" "=S")
18812         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18813                  (match_operand:SI 4 "register_operand" "1")))
18814    (set (mem:BLK (match_dup 3))
18815         (mem:BLK (match_dup 4)))
18816    (use (match_dup 5))]
18817   "!TARGET_64BIT"
18818   "rep movs{l|d}"
18819   [(set_attr "type" "str")
18820    (set_attr "prefix_rep" "1")
18821    (set_attr "memory" "both")
18822    (set_attr "mode" "SI")])
18823
18824 (define_insn "*rep_movsi_rex64"
18825   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18826    (set (match_operand:DI 0 "register_operand" "=D")
18827         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18828                             (const_int 2))
18829                  (match_operand:DI 3 "register_operand" "0")))
18830    (set (match_operand:DI 1 "register_operand" "=S")
18831         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18832                  (match_operand:DI 4 "register_operand" "1")))
18833    (set (mem:BLK (match_dup 3))
18834         (mem:BLK (match_dup 4)))
18835    (use (match_dup 5))]
18836   "TARGET_64BIT"
18837   "rep movs{l|d}"
18838   [(set_attr "type" "str")
18839    (set_attr "prefix_rep" "1")
18840    (set_attr "memory" "both")
18841    (set_attr "mode" "SI")])
18842
18843 (define_insn "*rep_movqi"
18844   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18845    (set (match_operand:SI 0 "register_operand" "=D")
18846         (plus:SI (match_operand:SI 3 "register_operand" "0")
18847                  (match_operand:SI 5 "register_operand" "2")))
18848    (set (match_operand:SI 1 "register_operand" "=S")
18849         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18850    (set (mem:BLK (match_dup 3))
18851         (mem:BLK (match_dup 4)))
18852    (use (match_dup 5))]
18853   "!TARGET_64BIT"
18854   "rep movsb"
18855   [(set_attr "type" "str")
18856    (set_attr "prefix_rep" "1")
18857    (set_attr "memory" "both")
18858    (set_attr "mode" "SI")])
18859
18860 (define_insn "*rep_movqi_rex64"
18861   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18862    (set (match_operand:DI 0 "register_operand" "=D")
18863         (plus:DI (match_operand:DI 3 "register_operand" "0")
18864                  (match_operand:DI 5 "register_operand" "2")))
18865    (set (match_operand:DI 1 "register_operand" "=S")
18866         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18867    (set (mem:BLK (match_dup 3))
18868         (mem:BLK (match_dup 4)))
18869    (use (match_dup 5))]
18870   "TARGET_64BIT"
18871   "rep movsb"
18872   [(set_attr "type" "str")
18873    (set_attr "prefix_rep" "1")
18874    (set_attr "memory" "both")
18875    (set_attr "mode" "SI")])
18876
18877 (define_expand "setmemsi"
18878    [(use (match_operand:BLK 0 "memory_operand" ""))
18879     (use (match_operand:SI 1 "nonmemory_operand" ""))
18880     (use (match_operand 2 "const_int_operand" ""))
18881     (use (match_operand 3 "const_int_operand" ""))
18882     (use (match_operand:SI 4 "const_int_operand" ""))
18883     (use (match_operand:SI 5 "const_int_operand" ""))]
18884   ""
18885 {
18886  if (ix86_expand_setmem (operands[0], operands[1],
18887                          operands[2], operands[3],
18888                          operands[4], operands[5]))
18889    DONE;
18890  else
18891    FAIL;
18892 })
18893
18894 (define_expand "setmemdi"
18895    [(use (match_operand:BLK 0 "memory_operand" ""))
18896     (use (match_operand:DI 1 "nonmemory_operand" ""))
18897     (use (match_operand 2 "const_int_operand" ""))
18898     (use (match_operand 3 "const_int_operand" ""))
18899     (use (match_operand 4 "const_int_operand" ""))
18900     (use (match_operand 5 "const_int_operand" ""))]
18901   "TARGET_64BIT"
18902 {
18903  if (ix86_expand_setmem (operands[0], operands[1],
18904                          operands[2], operands[3],
18905                          operands[4], operands[5]))
18906    DONE;
18907  else
18908    FAIL;
18909 })
18910
18911 ;; Most CPUs don't like single string operations
18912 ;; Handle this case here to simplify previous expander.
18913
18914 (define_expand "strset"
18915   [(set (match_operand 1 "memory_operand" "")
18916         (match_operand 2 "register_operand" ""))
18917    (parallel [(set (match_operand 0 "register_operand" "")
18918                    (match_dup 3))
18919               (clobber (reg:CC FLAGS_REG))])]
18920   ""
18921 {
18922   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18923     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18924
18925   /* If .md ever supports :P for Pmode, this can be directly
18926      in the pattern above.  */
18927   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18928                               GEN_INT (GET_MODE_SIZE (GET_MODE
18929                                                       (operands[2]))));
18930   if (TARGET_SINGLE_STRINGOP || optimize_size)
18931     {
18932       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18933                                       operands[3]));
18934       DONE;
18935     }
18936 })
18937
18938 (define_expand "strset_singleop"
18939   [(parallel [(set (match_operand 1 "memory_operand" "")
18940                    (match_operand 2 "register_operand" ""))
18941               (set (match_operand 0 "register_operand" "")
18942                    (match_operand 3 "" ""))])]
18943   "TARGET_SINGLE_STRINGOP || optimize_size"
18944   "")
18945
18946 (define_insn "*strsetdi_rex_1"
18947   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18948         (match_operand:DI 2 "register_operand" "a"))
18949    (set (match_operand:DI 0 "register_operand" "=D")
18950         (plus:DI (match_dup 1)
18951                  (const_int 8)))]
18952   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18953   "stosq"
18954   [(set_attr "type" "str")
18955    (set_attr "memory" "store")
18956    (set_attr "mode" "DI")])
18957
18958 (define_insn "*strsetsi_1"
18959   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18960         (match_operand:SI 2 "register_operand" "a"))
18961    (set (match_operand:SI 0 "register_operand" "=D")
18962         (plus:SI (match_dup 1)
18963                  (const_int 4)))]
18964   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18965   "{stosl|stosd}"
18966   [(set_attr "type" "str")
18967    (set_attr "memory" "store")
18968    (set_attr "mode" "SI")])
18969
18970 (define_insn "*strsetsi_rex_1"
18971   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18972         (match_operand:SI 2 "register_operand" "a"))
18973    (set (match_operand:DI 0 "register_operand" "=D")
18974         (plus:DI (match_dup 1)
18975                  (const_int 4)))]
18976   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18977   "{stosl|stosd}"
18978   [(set_attr "type" "str")
18979    (set_attr "memory" "store")
18980    (set_attr "mode" "SI")])
18981
18982 (define_insn "*strsethi_1"
18983   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18984         (match_operand:HI 2 "register_operand" "a"))
18985    (set (match_operand:SI 0 "register_operand" "=D")
18986         (plus:SI (match_dup 1)
18987                  (const_int 2)))]
18988   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18989   "stosw"
18990   [(set_attr "type" "str")
18991    (set_attr "memory" "store")
18992    (set_attr "mode" "HI")])
18993
18994 (define_insn "*strsethi_rex_1"
18995   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18996         (match_operand:HI 2 "register_operand" "a"))
18997    (set (match_operand:DI 0 "register_operand" "=D")
18998         (plus:DI (match_dup 1)
18999                  (const_int 2)))]
19000   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19001   "stosw"
19002   [(set_attr "type" "str")
19003    (set_attr "memory" "store")
19004    (set_attr "mode" "HI")])
19005
19006 (define_insn "*strsetqi_1"
19007   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19008         (match_operand:QI 2 "register_operand" "a"))
19009    (set (match_operand:SI 0 "register_operand" "=D")
19010         (plus:SI (match_dup 1)
19011                  (const_int 1)))]
19012   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19013   "stosb"
19014   [(set_attr "type" "str")
19015    (set_attr "memory" "store")
19016    (set_attr "mode" "QI")])
19017
19018 (define_insn "*strsetqi_rex_1"
19019   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19020         (match_operand:QI 2 "register_operand" "a"))
19021    (set (match_operand:DI 0 "register_operand" "=D")
19022         (plus:DI (match_dup 1)
19023                  (const_int 1)))]
19024   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19025   "stosb"
19026   [(set_attr "type" "str")
19027    (set_attr "memory" "store")
19028    (set_attr "mode" "QI")])
19029
19030 (define_expand "rep_stos"
19031   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19032               (set (match_operand 0 "register_operand" "")
19033                    (match_operand 4 "" ""))
19034               (set (match_operand 2 "memory_operand" "") (const_int 0))
19035               (use (match_operand 3 "register_operand" ""))
19036               (use (match_dup 1))])]
19037   ""
19038   "")
19039
19040 (define_insn "*rep_stosdi_rex64"
19041   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19042    (set (match_operand:DI 0 "register_operand" "=D")
19043         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19044                             (const_int 3))
19045                  (match_operand:DI 3 "register_operand" "0")))
19046    (set (mem:BLK (match_dup 3))
19047         (const_int 0))
19048    (use (match_operand:DI 2 "register_operand" "a"))
19049    (use (match_dup 4))]
19050   "TARGET_64BIT"
19051   "rep stosq"
19052   [(set_attr "type" "str")
19053    (set_attr "prefix_rep" "1")
19054    (set_attr "memory" "store")
19055    (set_attr "mode" "DI")])
19056
19057 (define_insn "*rep_stossi"
19058   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19059    (set (match_operand:SI 0 "register_operand" "=D")
19060         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19061                             (const_int 2))
19062                  (match_operand:SI 3 "register_operand" "0")))
19063    (set (mem:BLK (match_dup 3))
19064         (const_int 0))
19065    (use (match_operand:SI 2 "register_operand" "a"))
19066    (use (match_dup 4))]
19067   "!TARGET_64BIT"
19068   "rep stos{l|d}"
19069   [(set_attr "type" "str")
19070    (set_attr "prefix_rep" "1")
19071    (set_attr "memory" "store")
19072    (set_attr "mode" "SI")])
19073
19074 (define_insn "*rep_stossi_rex64"
19075   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19076    (set (match_operand:DI 0 "register_operand" "=D")
19077         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19078                             (const_int 2))
19079                  (match_operand:DI 3 "register_operand" "0")))
19080    (set (mem:BLK (match_dup 3))
19081         (const_int 0))
19082    (use (match_operand:SI 2 "register_operand" "a"))
19083    (use (match_dup 4))]
19084   "TARGET_64BIT"
19085   "rep stos{l|d}"
19086   [(set_attr "type" "str")
19087    (set_attr "prefix_rep" "1")
19088    (set_attr "memory" "store")
19089    (set_attr "mode" "SI")])
19090
19091 (define_insn "*rep_stosqi"
19092   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19093    (set (match_operand:SI 0 "register_operand" "=D")
19094         (plus:SI (match_operand:SI 3 "register_operand" "0")
19095                  (match_operand:SI 4 "register_operand" "1")))
19096    (set (mem:BLK (match_dup 3))
19097         (const_int 0))
19098    (use (match_operand:QI 2 "register_operand" "a"))
19099    (use (match_dup 4))]
19100   "!TARGET_64BIT"
19101   "rep stosb"
19102   [(set_attr "type" "str")
19103    (set_attr "prefix_rep" "1")
19104    (set_attr "memory" "store")
19105    (set_attr "mode" "QI")])
19106
19107 (define_insn "*rep_stosqi_rex64"
19108   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19109    (set (match_operand:DI 0 "register_operand" "=D")
19110         (plus:DI (match_operand:DI 3 "register_operand" "0")
19111                  (match_operand:DI 4 "register_operand" "1")))
19112    (set (mem:BLK (match_dup 3))
19113         (const_int 0))
19114    (use (match_operand:QI 2 "register_operand" "a"))
19115    (use (match_dup 4))]
19116   "TARGET_64BIT"
19117   "rep stosb"
19118   [(set_attr "type" "str")
19119    (set_attr "prefix_rep" "1")
19120    (set_attr "memory" "store")
19121    (set_attr "mode" "QI")])
19122
19123 (define_expand "cmpstrnsi"
19124   [(set (match_operand:SI 0 "register_operand" "")
19125         (compare:SI (match_operand:BLK 1 "general_operand" "")
19126                     (match_operand:BLK 2 "general_operand" "")))
19127    (use (match_operand 3 "general_operand" ""))
19128    (use (match_operand 4 "immediate_operand" ""))]
19129   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
19130 {
19131   rtx addr1, addr2, out, outlow, count, countreg, align;
19132
19133   /* Can't use this if the user has appropriated esi or edi.  */
19134   if (global_regs[4] || global_regs[5])
19135     FAIL;
19136
19137   out = operands[0];
19138   if (!REG_P (out))
19139     out = gen_reg_rtx (SImode);
19140
19141   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19142   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19143   if (addr1 != XEXP (operands[1], 0))
19144     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19145   if (addr2 != XEXP (operands[2], 0))
19146     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19147
19148   count = operands[3];
19149   countreg = ix86_zero_extend_to_Pmode (count);
19150
19151   /* %%% Iff we are testing strict equality, we can use known alignment
19152      to good advantage.  This may be possible with combine, particularly
19153      once cc0 is dead.  */
19154   align = operands[4];
19155
19156   if (CONST_INT_P (count))
19157     {
19158       if (INTVAL (count) == 0)
19159         {
19160           emit_move_insn (operands[0], const0_rtx);
19161           DONE;
19162         }
19163       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19164                                      operands[1], operands[2]));
19165     }
19166   else
19167     {
19168       if (TARGET_64BIT)
19169         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19170       else
19171         emit_insn (gen_cmpsi_1 (countreg, countreg));
19172       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19173                                   operands[1], operands[2]));
19174     }
19175
19176   outlow = gen_lowpart (QImode, out);
19177   emit_insn (gen_cmpintqi (outlow));
19178   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19179
19180   if (operands[0] != out)
19181     emit_move_insn (operands[0], out);
19182
19183   DONE;
19184 })
19185
19186 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19187
19188 (define_expand "cmpintqi"
19189   [(set (match_dup 1)
19190         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19191    (set (match_dup 2)
19192         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19193    (parallel [(set (match_operand:QI 0 "register_operand" "")
19194                    (minus:QI (match_dup 1)
19195                              (match_dup 2)))
19196               (clobber (reg:CC FLAGS_REG))])]
19197   ""
19198   "operands[1] = gen_reg_rtx (QImode);
19199    operands[2] = gen_reg_rtx (QImode);")
19200
19201 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19202 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19203
19204 (define_expand "cmpstrnqi_nz_1"
19205   [(parallel [(set (reg:CC FLAGS_REG)
19206                    (compare:CC (match_operand 4 "memory_operand" "")
19207                                (match_operand 5 "memory_operand" "")))
19208               (use (match_operand 2 "register_operand" ""))
19209               (use (match_operand:SI 3 "immediate_operand" ""))
19210               (clobber (match_operand 0 "register_operand" ""))
19211               (clobber (match_operand 1 "register_operand" ""))
19212               (clobber (match_dup 2))])]
19213   ""
19214   "")
19215
19216 (define_insn "*cmpstrnqi_nz_1"
19217   [(set (reg:CC FLAGS_REG)
19218         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19219                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19220    (use (match_operand:SI 6 "register_operand" "2"))
19221    (use (match_operand:SI 3 "immediate_operand" "i"))
19222    (clobber (match_operand:SI 0 "register_operand" "=S"))
19223    (clobber (match_operand:SI 1 "register_operand" "=D"))
19224    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19225   "!TARGET_64BIT"
19226   "repz cmpsb"
19227   [(set_attr "type" "str")
19228    (set_attr "mode" "QI")
19229    (set_attr "prefix_rep" "1")])
19230
19231 (define_insn "*cmpstrnqi_nz_rex_1"
19232   [(set (reg:CC FLAGS_REG)
19233         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19234                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19235    (use (match_operand:DI 6 "register_operand" "2"))
19236    (use (match_operand:SI 3 "immediate_operand" "i"))
19237    (clobber (match_operand:DI 0 "register_operand" "=S"))
19238    (clobber (match_operand:DI 1 "register_operand" "=D"))
19239    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19240   "TARGET_64BIT"
19241   "repz cmpsb"
19242   [(set_attr "type" "str")
19243    (set_attr "mode" "QI")
19244    (set_attr "prefix_rep" "1")])
19245
19246 ;; The same, but the count is not known to not be zero.
19247
19248 (define_expand "cmpstrnqi_1"
19249   [(parallel [(set (reg:CC FLAGS_REG)
19250                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19251                                      (const_int 0))
19252                   (compare:CC (match_operand 4 "memory_operand" "")
19253                               (match_operand 5 "memory_operand" ""))
19254                   (const_int 0)))
19255               (use (match_operand:SI 3 "immediate_operand" ""))
19256               (use (reg:CC FLAGS_REG))
19257               (clobber (match_operand 0 "register_operand" ""))
19258               (clobber (match_operand 1 "register_operand" ""))
19259               (clobber (match_dup 2))])]
19260   ""
19261   "")
19262
19263 (define_insn "*cmpstrnqi_1"
19264   [(set (reg:CC FLAGS_REG)
19265         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19266                              (const_int 0))
19267           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19268                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19269           (const_int 0)))
19270    (use (match_operand:SI 3 "immediate_operand" "i"))
19271    (use (reg:CC FLAGS_REG))
19272    (clobber (match_operand:SI 0 "register_operand" "=S"))
19273    (clobber (match_operand:SI 1 "register_operand" "=D"))
19274    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19275   "!TARGET_64BIT"
19276   "repz cmpsb"
19277   [(set_attr "type" "str")
19278    (set_attr "mode" "QI")
19279    (set_attr "prefix_rep" "1")])
19280
19281 (define_insn "*cmpstrnqi_rex_1"
19282   [(set (reg:CC FLAGS_REG)
19283         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19284                              (const_int 0))
19285           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19286                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19287           (const_int 0)))
19288    (use (match_operand:SI 3 "immediate_operand" "i"))
19289    (use (reg:CC FLAGS_REG))
19290    (clobber (match_operand:DI 0 "register_operand" "=S"))
19291    (clobber (match_operand:DI 1 "register_operand" "=D"))
19292    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19293   "TARGET_64BIT"
19294   "repz cmpsb"
19295   [(set_attr "type" "str")
19296    (set_attr "mode" "QI")
19297    (set_attr "prefix_rep" "1")])
19298
19299 (define_expand "strlensi"
19300   [(set (match_operand:SI 0 "register_operand" "")
19301         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19302                     (match_operand:QI 2 "immediate_operand" "")
19303                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19304   ""
19305 {
19306  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19307    DONE;
19308  else
19309    FAIL;
19310 })
19311
19312 (define_expand "strlendi"
19313   [(set (match_operand:DI 0 "register_operand" "")
19314         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19315                     (match_operand:QI 2 "immediate_operand" "")
19316                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19317   ""
19318 {
19319  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19320    DONE;
19321  else
19322    FAIL;
19323 })
19324
19325 (define_expand "strlenqi_1"
19326   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19327               (clobber (match_operand 1 "register_operand" ""))
19328               (clobber (reg:CC FLAGS_REG))])]
19329   ""
19330   "")
19331
19332 (define_insn "*strlenqi_1"
19333   [(set (match_operand:SI 0 "register_operand" "=&c")
19334         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19335                     (match_operand:QI 2 "register_operand" "a")
19336                     (match_operand:SI 3 "immediate_operand" "i")
19337                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19338    (clobber (match_operand:SI 1 "register_operand" "=D"))
19339    (clobber (reg:CC FLAGS_REG))]
19340   "!TARGET_64BIT"
19341   "repnz scasb"
19342   [(set_attr "type" "str")
19343    (set_attr "mode" "QI")
19344    (set_attr "prefix_rep" "1")])
19345
19346 (define_insn "*strlenqi_rex_1"
19347   [(set (match_operand:DI 0 "register_operand" "=&c")
19348         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19349                     (match_operand:QI 2 "register_operand" "a")
19350                     (match_operand:DI 3 "immediate_operand" "i")
19351                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19352    (clobber (match_operand:DI 1 "register_operand" "=D"))
19353    (clobber (reg:CC FLAGS_REG))]
19354   "TARGET_64BIT"
19355   "repnz scasb"
19356   [(set_attr "type" "str")
19357    (set_attr "mode" "QI")
19358    (set_attr "prefix_rep" "1")])
19359
19360 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19361 ;; handled in combine, but it is not currently up to the task.
19362 ;; When used for their truth value, the cmpstrn* expanders generate
19363 ;; code like this:
19364 ;;
19365 ;;   repz cmpsb
19366 ;;   seta       %al
19367 ;;   setb       %dl
19368 ;;   cmpb       %al, %dl
19369 ;;   jcc        label
19370 ;;
19371 ;; The intermediate three instructions are unnecessary.
19372
19373 ;; This one handles cmpstrn*_nz_1...
19374 (define_peephole2
19375   [(parallel[
19376      (set (reg:CC FLAGS_REG)
19377           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19378                       (mem:BLK (match_operand 5 "register_operand" ""))))
19379      (use (match_operand 6 "register_operand" ""))
19380      (use (match_operand:SI 3 "immediate_operand" ""))
19381      (clobber (match_operand 0 "register_operand" ""))
19382      (clobber (match_operand 1 "register_operand" ""))
19383      (clobber (match_operand 2 "register_operand" ""))])
19384    (set (match_operand:QI 7 "register_operand" "")
19385         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19386    (set (match_operand:QI 8 "register_operand" "")
19387         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19388    (set (reg FLAGS_REG)
19389         (compare (match_dup 7) (match_dup 8)))
19390   ]
19391   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19392   [(parallel[
19393      (set (reg:CC FLAGS_REG)
19394           (compare:CC (mem:BLK (match_dup 4))
19395                       (mem:BLK (match_dup 5))))
19396      (use (match_dup 6))
19397      (use (match_dup 3))
19398      (clobber (match_dup 0))
19399      (clobber (match_dup 1))
19400      (clobber (match_dup 2))])]
19401   "")
19402
19403 ;; ...and this one handles cmpstrn*_1.
19404 (define_peephole2
19405   [(parallel[
19406      (set (reg:CC FLAGS_REG)
19407           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19408                                (const_int 0))
19409             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19410                         (mem:BLK (match_operand 5 "register_operand" "")))
19411             (const_int 0)))
19412      (use (match_operand:SI 3 "immediate_operand" ""))
19413      (use (reg:CC FLAGS_REG))
19414      (clobber (match_operand 0 "register_operand" ""))
19415      (clobber (match_operand 1 "register_operand" ""))
19416      (clobber (match_operand 2 "register_operand" ""))])
19417    (set (match_operand:QI 7 "register_operand" "")
19418         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19419    (set (match_operand:QI 8 "register_operand" "")
19420         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19421    (set (reg FLAGS_REG)
19422         (compare (match_dup 7) (match_dup 8)))
19423   ]
19424   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19425   [(parallel[
19426      (set (reg:CC FLAGS_REG)
19427           (if_then_else:CC (ne (match_dup 6)
19428                                (const_int 0))
19429             (compare:CC (mem:BLK (match_dup 4))
19430                         (mem:BLK (match_dup 5)))
19431             (const_int 0)))
19432      (use (match_dup 3))
19433      (use (reg:CC FLAGS_REG))
19434      (clobber (match_dup 0))
19435      (clobber (match_dup 1))
19436      (clobber (match_dup 2))])]
19437   "")
19438
19439
19440 \f
19441 ;; Conditional move instructions.
19442
19443 (define_expand "movdicc"
19444   [(set (match_operand:DI 0 "register_operand" "")
19445         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19446                          (match_operand:DI 2 "general_operand" "")
19447                          (match_operand:DI 3 "general_operand" "")))]
19448   "TARGET_64BIT"
19449   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19450
19451 (define_insn "x86_movdicc_0_m1_rex64"
19452   [(set (match_operand:DI 0 "register_operand" "=r")
19453         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19454           (const_int -1)
19455           (const_int 0)))
19456    (clobber (reg:CC FLAGS_REG))]
19457   "TARGET_64BIT"
19458   "sbb{q}\t%0, %0"
19459   ; Since we don't have the proper number of operands for an alu insn,
19460   ; fill in all the blanks.
19461   [(set_attr "type" "alu")
19462    (set_attr "pent_pair" "pu")
19463    (set_attr "memory" "none")
19464    (set_attr "imm_disp" "false")
19465    (set_attr "mode" "DI")
19466    (set_attr "length_immediate" "0")])
19467
19468 (define_insn "*movdicc_c_rex64"
19469   [(set (match_operand:DI 0 "register_operand" "=r,r")
19470         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19471                                 [(reg FLAGS_REG) (const_int 0)])
19472                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19473                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19474   "TARGET_64BIT && TARGET_CMOVE
19475    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19476   "@
19477    cmov%O2%C1\t{%2, %0|%0, %2}
19478    cmov%O2%c1\t{%3, %0|%0, %3}"
19479   [(set_attr "type" "icmov")
19480    (set_attr "mode" "DI")])
19481
19482 (define_expand "movsicc"
19483   [(set (match_operand:SI 0 "register_operand" "")
19484         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19485                          (match_operand:SI 2 "general_operand" "")
19486                          (match_operand:SI 3 "general_operand" "")))]
19487   ""
19488   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19489
19490 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19491 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19492 ;; So just document what we're doing explicitly.
19493
19494 (define_insn "x86_movsicc_0_m1"
19495   [(set (match_operand:SI 0 "register_operand" "=r")
19496         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19497           (const_int -1)
19498           (const_int 0)))
19499    (clobber (reg:CC FLAGS_REG))]
19500   ""
19501   "sbb{l}\t%0, %0"
19502   ; Since we don't have the proper number of operands for an alu insn,
19503   ; fill in all the blanks.
19504   [(set_attr "type" "alu")
19505    (set_attr "pent_pair" "pu")
19506    (set_attr "memory" "none")
19507    (set_attr "imm_disp" "false")
19508    (set_attr "mode" "SI")
19509    (set_attr "length_immediate" "0")])
19510
19511 (define_insn "*movsicc_noc"
19512   [(set (match_operand:SI 0 "register_operand" "=r,r")
19513         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19514                                 [(reg FLAGS_REG) (const_int 0)])
19515                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19516                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19517   "TARGET_CMOVE
19518    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19519   "@
19520    cmov%O2%C1\t{%2, %0|%0, %2}
19521    cmov%O2%c1\t{%3, %0|%0, %3}"
19522   [(set_attr "type" "icmov")
19523    (set_attr "mode" "SI")])
19524
19525 (define_expand "movhicc"
19526   [(set (match_operand:HI 0 "register_operand" "")
19527         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19528                          (match_operand:HI 2 "general_operand" "")
19529                          (match_operand:HI 3 "general_operand" "")))]
19530   "TARGET_HIMODE_MATH"
19531   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19532
19533 (define_insn "*movhicc_noc"
19534   [(set (match_operand:HI 0 "register_operand" "=r,r")
19535         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19536                                 [(reg FLAGS_REG) (const_int 0)])
19537                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19538                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19539   "TARGET_CMOVE
19540    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19541   "@
19542    cmov%O2%C1\t{%2, %0|%0, %2}
19543    cmov%O2%c1\t{%3, %0|%0, %3}"
19544   [(set_attr "type" "icmov")
19545    (set_attr "mode" "HI")])
19546
19547 (define_expand "movqicc"
19548   [(set (match_operand:QI 0 "register_operand" "")
19549         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19550                          (match_operand:QI 2 "general_operand" "")
19551                          (match_operand:QI 3 "general_operand" "")))]
19552   "TARGET_QIMODE_MATH"
19553   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19554
19555 (define_insn_and_split "*movqicc_noc"
19556   [(set (match_operand:QI 0 "register_operand" "=r,r")
19557         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19558                                 [(match_operand 4 "flags_reg_operand" "")
19559                                  (const_int 0)])
19560                       (match_operand:QI 2 "register_operand" "r,0")
19561                       (match_operand:QI 3 "register_operand" "0,r")))]
19562   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19563   "#"
19564   "&& reload_completed"
19565   [(set (match_dup 0)
19566         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19567                       (match_dup 2)
19568                       (match_dup 3)))]
19569   "operands[0] = gen_lowpart (SImode, operands[0]);
19570    operands[2] = gen_lowpart (SImode, operands[2]);
19571    operands[3] = gen_lowpart (SImode, operands[3]);"
19572   [(set_attr "type" "icmov")
19573    (set_attr "mode" "SI")])
19574
19575 (define_expand "movsfcc"
19576   [(set (match_operand:SF 0 "register_operand" "")
19577         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19578                          (match_operand:SF 2 "register_operand" "")
19579                          (match_operand:SF 3 "register_operand" "")))]
19580   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19581   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19582
19583 (define_insn "*movsfcc_1_387"
19584   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19585         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19586                                 [(reg FLAGS_REG) (const_int 0)])
19587                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19588                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19589   "TARGET_80387 && TARGET_CMOVE
19590    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19591   "@
19592    fcmov%F1\t{%2, %0|%0, %2}
19593    fcmov%f1\t{%3, %0|%0, %3}
19594    cmov%O2%C1\t{%2, %0|%0, %2}
19595    cmov%O2%c1\t{%3, %0|%0, %3}"
19596   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19597    (set_attr "mode" "SF,SF,SI,SI")])
19598
19599 (define_expand "movdfcc"
19600   [(set (match_operand:DF 0 "register_operand" "")
19601         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19602                          (match_operand:DF 2 "register_operand" "")
19603                          (match_operand:DF 3 "register_operand" "")))]
19604   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19605   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19606
19607 (define_insn "*movdfcc_1"
19608   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19609         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19610                                 [(reg FLAGS_REG) (const_int 0)])
19611                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19612                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19613   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19614    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19615   "@
19616    fcmov%F1\t{%2, %0|%0, %2}
19617    fcmov%f1\t{%3, %0|%0, %3}
19618    #
19619    #"
19620   [(set_attr "type" "fcmov,fcmov,multi,multi")
19621    (set_attr "mode" "DF")])
19622
19623 (define_insn "*movdfcc_1_rex64"
19624   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19625         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19626                                 [(reg FLAGS_REG) (const_int 0)])
19627                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19628                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19629   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19630    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19631   "@
19632    fcmov%F1\t{%2, %0|%0, %2}
19633    fcmov%f1\t{%3, %0|%0, %3}
19634    cmov%O2%C1\t{%2, %0|%0, %2}
19635    cmov%O2%c1\t{%3, %0|%0, %3}"
19636   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19637    (set_attr "mode" "DF")])
19638
19639 (define_split
19640   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19641         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19642                                 [(match_operand 4 "flags_reg_operand" "")
19643                                  (const_int 0)])
19644                       (match_operand:DF 2 "nonimmediate_operand" "")
19645                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19646   "!TARGET_64BIT && reload_completed"
19647   [(set (match_dup 2)
19648         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19649                       (match_dup 5)
19650                       (match_dup 7)))
19651    (set (match_dup 3)
19652         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19653                       (match_dup 6)
19654                       (match_dup 8)))]
19655   "split_di (operands+2, 1, operands+5, operands+6);
19656    split_di (operands+3, 1, operands+7, operands+8);
19657    split_di (operands, 1, operands+2, operands+3);")
19658
19659 (define_expand "movxfcc"
19660   [(set (match_operand:XF 0 "register_operand" "")
19661         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19662                          (match_operand:XF 2 "register_operand" "")
19663                          (match_operand:XF 3 "register_operand" "")))]
19664   "TARGET_80387 && TARGET_CMOVE"
19665   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19666
19667 (define_insn "*movxfcc_1"
19668   [(set (match_operand:XF 0 "register_operand" "=f,f")
19669         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19670                                 [(reg FLAGS_REG) (const_int 0)])
19671                       (match_operand:XF 2 "register_operand" "f,0")
19672                       (match_operand:XF 3 "register_operand" "0,f")))]
19673   "TARGET_80387 && TARGET_CMOVE"
19674   "@
19675    fcmov%F1\t{%2, %0|%0, %2}
19676    fcmov%f1\t{%3, %0|%0, %3}"
19677   [(set_attr "type" "fcmov")
19678    (set_attr "mode" "XF")])
19679
19680 ;; These versions of the min/max patterns are intentionally ignorant of
19681 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19682 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19683 ;; are undefined in this condition, we're certain this is correct.
19684
19685 (define_insn "sminsf3"
19686   [(set (match_operand:SF 0 "register_operand" "=x")
19687         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19688                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19689   "TARGET_SSE_MATH"
19690   "minss\t{%2, %0|%0, %2}"
19691   [(set_attr "type" "sseadd")
19692    (set_attr "mode" "SF")])
19693
19694 (define_insn "smaxsf3"
19695   [(set (match_operand:SF 0 "register_operand" "=x")
19696         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19697                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19698   "TARGET_SSE_MATH"
19699   "maxss\t{%2, %0|%0, %2}"
19700   [(set_attr "type" "sseadd")
19701    (set_attr "mode" "SF")])
19702
19703 (define_insn "smindf3"
19704   [(set (match_operand:DF 0 "register_operand" "=x")
19705         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19706                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19707   "TARGET_SSE2 && TARGET_SSE_MATH"
19708   "minsd\t{%2, %0|%0, %2}"
19709   [(set_attr "type" "sseadd")
19710    (set_attr "mode" "DF")])
19711
19712 (define_insn "smaxdf3"
19713   [(set (match_operand:DF 0 "register_operand" "=x")
19714         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19715                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19716   "TARGET_SSE2 && TARGET_SSE_MATH"
19717   "maxsd\t{%2, %0|%0, %2}"
19718   [(set_attr "type" "sseadd")
19719    (set_attr "mode" "DF")])
19720
19721 ;; These versions of the min/max patterns implement exactly the operations
19722 ;;   min = (op1 < op2 ? op1 : op2)
19723 ;;   max = (!(op1 < op2) ? op1 : op2)
19724 ;; Their operands are not commutative, and thus they may be used in the
19725 ;; presence of -0.0 and NaN.
19726
19727 (define_insn "*ieee_sminsf3"
19728   [(set (match_operand:SF 0 "register_operand" "=x")
19729         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19730                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19731                    UNSPEC_IEEE_MIN))]
19732   "TARGET_SSE_MATH"
19733   "minss\t{%2, %0|%0, %2}"
19734   [(set_attr "type" "sseadd")
19735    (set_attr "mode" "SF")])
19736
19737 (define_insn "*ieee_smaxsf3"
19738   [(set (match_operand:SF 0 "register_operand" "=x")
19739         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19740                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19741                    UNSPEC_IEEE_MAX))]
19742   "TARGET_SSE_MATH"
19743   "maxss\t{%2, %0|%0, %2}"
19744   [(set_attr "type" "sseadd")
19745    (set_attr "mode" "SF")])
19746
19747 (define_insn "*ieee_smindf3"
19748   [(set (match_operand:DF 0 "register_operand" "=x")
19749         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19750                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19751                    UNSPEC_IEEE_MIN))]
19752   "TARGET_SSE2 && TARGET_SSE_MATH"
19753   "minsd\t{%2, %0|%0, %2}"
19754   [(set_attr "type" "sseadd")
19755    (set_attr "mode" "DF")])
19756
19757 (define_insn "*ieee_smaxdf3"
19758   [(set (match_operand:DF 0 "register_operand" "=x")
19759         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19760                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19761                    UNSPEC_IEEE_MAX))]
19762   "TARGET_SSE2 && TARGET_SSE_MATH"
19763   "maxsd\t{%2, %0|%0, %2}"
19764   [(set_attr "type" "sseadd")
19765    (set_attr "mode" "DF")])
19766
19767 ;; Make two stack loads independent:
19768 ;;   fld aa              fld aa
19769 ;;   fld %st(0)     ->   fld bb
19770 ;;   fmul bb             fmul %st(1), %st
19771 ;;
19772 ;; Actually we only match the last two instructions for simplicity.
19773 (define_peephole2
19774   [(set (match_operand 0 "fp_register_operand" "")
19775         (match_operand 1 "fp_register_operand" ""))
19776    (set (match_dup 0)
19777         (match_operator 2 "binary_fp_operator"
19778            [(match_dup 0)
19779             (match_operand 3 "memory_operand" "")]))]
19780   "REGNO (operands[0]) != REGNO (operands[1])"
19781   [(set (match_dup 0) (match_dup 3))
19782    (set (match_dup 0) (match_dup 4))]
19783
19784   ;; The % modifier is not operational anymore in peephole2's, so we have to
19785   ;; swap the operands manually in the case of addition and multiplication.
19786   "if (COMMUTATIVE_ARITH_P (operands[2]))
19787      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19788                                  operands[0], operands[1]);
19789    else
19790      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19791                                  operands[1], operands[0]);")
19792
19793 ;; Conditional addition patterns
19794 (define_expand "addqicc"
19795   [(match_operand:QI 0 "register_operand" "")
19796    (match_operand 1 "comparison_operator" "")
19797    (match_operand:QI 2 "register_operand" "")
19798    (match_operand:QI 3 "const_int_operand" "")]
19799   ""
19800   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19801
19802 (define_expand "addhicc"
19803   [(match_operand:HI 0 "register_operand" "")
19804    (match_operand 1 "comparison_operator" "")
19805    (match_operand:HI 2 "register_operand" "")
19806    (match_operand:HI 3 "const_int_operand" "")]
19807   ""
19808   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19809
19810 (define_expand "addsicc"
19811   [(match_operand:SI 0 "register_operand" "")
19812    (match_operand 1 "comparison_operator" "")
19813    (match_operand:SI 2 "register_operand" "")
19814    (match_operand:SI 3 "const_int_operand" "")]
19815   ""
19816   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19817
19818 (define_expand "adddicc"
19819   [(match_operand:DI 0 "register_operand" "")
19820    (match_operand 1 "comparison_operator" "")
19821    (match_operand:DI 2 "register_operand" "")
19822    (match_operand:DI 3 "const_int_operand" "")]
19823   "TARGET_64BIT"
19824   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19825
19826 \f
19827 ;; Misc patterns (?)
19828
19829 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19830 ;; Otherwise there will be nothing to keep
19831 ;;
19832 ;; [(set (reg ebp) (reg esp))]
19833 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19834 ;;  (clobber (eflags)]
19835 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19836 ;;
19837 ;; in proper program order.
19838 (define_insn "pro_epilogue_adjust_stack_1"
19839   [(set (match_operand:SI 0 "register_operand" "=r,r")
19840         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19841                  (match_operand:SI 2 "immediate_operand" "i,i")))
19842    (clobber (reg:CC FLAGS_REG))
19843    (clobber (mem:BLK (scratch)))]
19844   "!TARGET_64BIT"
19845 {
19846   switch (get_attr_type (insn))
19847     {
19848     case TYPE_IMOV:
19849       return "mov{l}\t{%1, %0|%0, %1}";
19850
19851     case TYPE_ALU:
19852       if (CONST_INT_P (operands[2])
19853           && (INTVAL (operands[2]) == 128
19854               || (INTVAL (operands[2]) < 0
19855                   && INTVAL (operands[2]) != -128)))
19856         {
19857           operands[2] = GEN_INT (-INTVAL (operands[2]));
19858           return "sub{l}\t{%2, %0|%0, %2}";
19859         }
19860       return "add{l}\t{%2, %0|%0, %2}";
19861
19862     case TYPE_LEA:
19863       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19864       return "lea{l}\t{%a2, %0|%0, %a2}";
19865
19866     default:
19867       gcc_unreachable ();
19868     }
19869 }
19870   [(set (attr "type")
19871         (cond [(eq_attr "alternative" "0")
19872                  (const_string "alu")
19873                (match_operand:SI 2 "const0_operand" "")
19874                  (const_string "imov")
19875               ]
19876               (const_string "lea")))
19877    (set_attr "mode" "SI")])
19878
19879 (define_insn "pro_epilogue_adjust_stack_rex64"
19880   [(set (match_operand:DI 0 "register_operand" "=r,r")
19881         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19882                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19883    (clobber (reg:CC FLAGS_REG))
19884    (clobber (mem:BLK (scratch)))]
19885   "TARGET_64BIT"
19886 {
19887   switch (get_attr_type (insn))
19888     {
19889     case TYPE_IMOV:
19890       return "mov{q}\t{%1, %0|%0, %1}";
19891
19892     case TYPE_ALU:
19893       if (CONST_INT_P (operands[2])
19894           /* Avoid overflows.  */
19895           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19896           && (INTVAL (operands[2]) == 128
19897               || (INTVAL (operands[2]) < 0
19898                   && INTVAL (operands[2]) != -128)))
19899         {
19900           operands[2] = GEN_INT (-INTVAL (operands[2]));
19901           return "sub{q}\t{%2, %0|%0, %2}";
19902         }
19903       return "add{q}\t{%2, %0|%0, %2}";
19904
19905     case TYPE_LEA:
19906       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19907       return "lea{q}\t{%a2, %0|%0, %a2}";
19908
19909     default:
19910       gcc_unreachable ();
19911     }
19912 }
19913   [(set (attr "type")
19914         (cond [(eq_attr "alternative" "0")
19915                  (const_string "alu")
19916                (match_operand:DI 2 "const0_operand" "")
19917                  (const_string "imov")
19918               ]
19919               (const_string "lea")))
19920    (set_attr "mode" "DI")])
19921
19922 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19923   [(set (match_operand:DI 0 "register_operand" "=r,r")
19924         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19925                  (match_operand:DI 3 "immediate_operand" "i,i")))
19926    (use (match_operand:DI 2 "register_operand" "r,r"))
19927    (clobber (reg:CC FLAGS_REG))
19928    (clobber (mem:BLK (scratch)))]
19929   "TARGET_64BIT"
19930 {
19931   switch (get_attr_type (insn))
19932     {
19933     case TYPE_ALU:
19934       return "add{q}\t{%2, %0|%0, %2}";
19935
19936     case TYPE_LEA:
19937       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19938       return "lea{q}\t{%a2, %0|%0, %a2}";
19939
19940     default:
19941       gcc_unreachable ();
19942     }
19943 }
19944   [(set_attr "type" "alu,lea")
19945    (set_attr "mode" "DI")])
19946
19947 (define_insn "allocate_stack_worker_32"
19948   [(set (match_operand:SI 0 "register_operand" "+a")
19949         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19950    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19951    (clobber (reg:CC FLAGS_REG))]
19952   "!TARGET_64BIT && TARGET_STACK_PROBE"
19953   "call\t__alloca"
19954   [(set_attr "type" "multi")
19955    (set_attr "length" "5")])
19956
19957 (define_insn "allocate_stack_worker_64"
19958   [(set (match_operand:DI 0 "register_operand" "=a")
19959         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19960    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19961    (clobber (reg:DI R10_REG))
19962    (clobber (reg:DI R11_REG))
19963    (clobber (reg:CC FLAGS_REG))]
19964   "TARGET_64BIT && TARGET_STACK_PROBE"
19965   "call\t___chkstk"
19966   [(set_attr "type" "multi")
19967    (set_attr "length" "5")])
19968
19969 (define_expand "allocate_stack"
19970   [(match_operand 0 "register_operand" "")
19971    (match_operand 1 "general_operand" "")]
19972   "TARGET_STACK_PROBE"
19973 {
19974   rtx x;
19975
19976 #ifndef CHECK_STACK_LIMIT
19977 #define CHECK_STACK_LIMIT 0
19978 #endif
19979
19980   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19981       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19982     {
19983       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19984                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19985       if (x != stack_pointer_rtx)
19986         emit_move_insn (stack_pointer_rtx, x);
19987     }
19988   else
19989     {
19990       x = copy_to_mode_reg (Pmode, operands[1]);
19991       if (TARGET_64BIT)
19992         x = gen_allocate_stack_worker_64 (x);
19993       else
19994         x = gen_allocate_stack_worker_32 (x);
19995       emit_insn (x);
19996     }
19997
19998   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19999   DONE;
20000 })
20001
20002 (define_expand "builtin_setjmp_receiver"
20003   [(label_ref (match_operand 0 "" ""))]
20004   "!TARGET_64BIT && flag_pic"
20005 {
20006   if (TARGET_MACHO)
20007     {
20008       rtx xops[3];
20009       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20010       rtx label_rtx = gen_label_rtx ();
20011       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20012       xops[0] = xops[1] = picreg;
20013       xops[2] = gen_rtx_CONST (SImode,
20014                   gen_rtx_MINUS (SImode,
20015                     gen_rtx_LABEL_REF (SImode, label_rtx),
20016                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
20017       ix86_expand_binary_operator (MINUS, SImode, xops);
20018     }
20019   else
20020     emit_insn (gen_set_got (pic_offset_table_rtx));
20021   DONE;
20022 })
20023 \f
20024 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20025
20026 (define_split
20027   [(set (match_operand 0 "register_operand" "")
20028         (match_operator 3 "promotable_binary_operator"
20029            [(match_operand 1 "register_operand" "")
20030             (match_operand 2 "aligned_operand" "")]))
20031    (clobber (reg:CC FLAGS_REG))]
20032   "! TARGET_PARTIAL_REG_STALL && reload_completed
20033    && ((GET_MODE (operands[0]) == HImode
20034         && ((!optimize_size && !TARGET_FAST_PREFIX)
20035             /* ??? next two lines just !satisfies_constraint_K (...) */
20036             || !CONST_INT_P (operands[2])
20037             || satisfies_constraint_K (operands[2])))
20038        || (GET_MODE (operands[0]) == QImode
20039            && (TARGET_PROMOTE_QImode || optimize_size)))"
20040   [(parallel [(set (match_dup 0)
20041                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20042               (clobber (reg:CC FLAGS_REG))])]
20043   "operands[0] = gen_lowpart (SImode, operands[0]);
20044    operands[1] = gen_lowpart (SImode, operands[1]);
20045    if (GET_CODE (operands[3]) != ASHIFT)
20046      operands[2] = gen_lowpart (SImode, operands[2]);
20047    PUT_MODE (operands[3], SImode);")
20048
20049 ; Promote the QImode tests, as i386 has encoding of the AND
20050 ; instruction with 32-bit sign-extended immediate and thus the
20051 ; instruction size is unchanged, except in the %eax case for
20052 ; which it is increased by one byte, hence the ! optimize_size.
20053 (define_split
20054   [(set (match_operand 0 "flags_reg_operand" "")
20055         (match_operator 2 "compare_operator"
20056           [(and (match_operand 3 "aligned_operand" "")
20057                 (match_operand 4 "const_int_operand" ""))
20058            (const_int 0)]))
20059    (set (match_operand 1 "register_operand" "")
20060         (and (match_dup 3) (match_dup 4)))]
20061   "! TARGET_PARTIAL_REG_STALL && reload_completed
20062    && ! optimize_size
20063    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20064        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20065    /* Ensure that the operand will remain sign-extended immediate.  */
20066    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20067   [(parallel [(set (match_dup 0)
20068                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20069                                     (const_int 0)]))
20070               (set (match_dup 1)
20071                    (and:SI (match_dup 3) (match_dup 4)))])]
20072 {
20073   operands[4]
20074     = gen_int_mode (INTVAL (operands[4])
20075                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20076   operands[1] = gen_lowpart (SImode, operands[1]);
20077   operands[3] = gen_lowpart (SImode, operands[3]);
20078 })
20079
20080 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20081 ; the TEST instruction with 32-bit sign-extended immediate and thus
20082 ; the instruction size would at least double, which is not what we
20083 ; want even with ! optimize_size.
20084 (define_split
20085   [(set (match_operand 0 "flags_reg_operand" "")
20086         (match_operator 1 "compare_operator"
20087           [(and (match_operand:HI 2 "aligned_operand" "")
20088                 (match_operand:HI 3 "const_int_operand" ""))
20089            (const_int 0)]))]
20090   "! TARGET_PARTIAL_REG_STALL && reload_completed
20091    && ! TARGET_FAST_PREFIX
20092    && ! optimize_size
20093    /* Ensure that the operand will remain sign-extended immediate.  */
20094    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20095   [(set (match_dup 0)
20096         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20097                          (const_int 0)]))]
20098 {
20099   operands[3]
20100     = gen_int_mode (INTVAL (operands[3])
20101                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20102   operands[2] = gen_lowpart (SImode, operands[2]);
20103 })
20104
20105 (define_split
20106   [(set (match_operand 0 "register_operand" "")
20107         (neg (match_operand 1 "register_operand" "")))
20108    (clobber (reg:CC FLAGS_REG))]
20109   "! TARGET_PARTIAL_REG_STALL && reload_completed
20110    && (GET_MODE (operands[0]) == HImode
20111        || (GET_MODE (operands[0]) == QImode
20112            && (TARGET_PROMOTE_QImode || optimize_size)))"
20113   [(parallel [(set (match_dup 0)
20114                    (neg:SI (match_dup 1)))
20115               (clobber (reg:CC FLAGS_REG))])]
20116   "operands[0] = gen_lowpart (SImode, operands[0]);
20117    operands[1] = gen_lowpart (SImode, operands[1]);")
20118
20119 (define_split
20120   [(set (match_operand 0 "register_operand" "")
20121         (not (match_operand 1 "register_operand" "")))]
20122   "! TARGET_PARTIAL_REG_STALL && reload_completed
20123    && (GET_MODE (operands[0]) == HImode
20124        || (GET_MODE (operands[0]) == QImode
20125            && (TARGET_PROMOTE_QImode || optimize_size)))"
20126   [(set (match_dup 0)
20127         (not:SI (match_dup 1)))]
20128   "operands[0] = gen_lowpart (SImode, operands[0]);
20129    operands[1] = gen_lowpart (SImode, operands[1]);")
20130
20131 (define_split
20132   [(set (match_operand 0 "register_operand" "")
20133         (if_then_else (match_operator 1 "comparison_operator"
20134                                 [(reg FLAGS_REG) (const_int 0)])
20135                       (match_operand 2 "register_operand" "")
20136                       (match_operand 3 "register_operand" "")))]
20137   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20138    && (GET_MODE (operands[0]) == HImode
20139        || (GET_MODE (operands[0]) == QImode
20140            && (TARGET_PROMOTE_QImode || optimize_size)))"
20141   [(set (match_dup 0)
20142         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20143   "operands[0] = gen_lowpart (SImode, operands[0]);
20144    operands[2] = gen_lowpart (SImode, operands[2]);
20145    operands[3] = gen_lowpart (SImode, operands[3]);")
20146
20147 \f
20148 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20149 ;; transform a complex memory operation into two memory to register operations.
20150
20151 ;; Don't push memory operands
20152 (define_peephole2
20153   [(set (match_operand:SI 0 "push_operand" "")
20154         (match_operand:SI 1 "memory_operand" ""))
20155    (match_scratch:SI 2 "r")]
20156   "!optimize_size && !TARGET_PUSH_MEMORY
20157    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20158   [(set (match_dup 2) (match_dup 1))
20159    (set (match_dup 0) (match_dup 2))]
20160   "")
20161
20162 (define_peephole2
20163   [(set (match_operand:DI 0 "push_operand" "")
20164         (match_operand:DI 1 "memory_operand" ""))
20165    (match_scratch:DI 2 "r")]
20166   "!optimize_size && !TARGET_PUSH_MEMORY
20167    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20168   [(set (match_dup 2) (match_dup 1))
20169    (set (match_dup 0) (match_dup 2))]
20170   "")
20171
20172 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20173 ;; SImode pushes.
20174 (define_peephole2
20175   [(set (match_operand:SF 0 "push_operand" "")
20176         (match_operand:SF 1 "memory_operand" ""))
20177    (match_scratch:SF 2 "r")]
20178   "!optimize_size && !TARGET_PUSH_MEMORY
20179    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20180   [(set (match_dup 2) (match_dup 1))
20181    (set (match_dup 0) (match_dup 2))]
20182   "")
20183
20184 (define_peephole2
20185   [(set (match_operand:HI 0 "push_operand" "")
20186         (match_operand:HI 1 "memory_operand" ""))
20187    (match_scratch:HI 2 "r")]
20188   "!optimize_size && !TARGET_PUSH_MEMORY
20189    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20190   [(set (match_dup 2) (match_dup 1))
20191    (set (match_dup 0) (match_dup 2))]
20192   "")
20193
20194 (define_peephole2
20195   [(set (match_operand:QI 0 "push_operand" "")
20196         (match_operand:QI 1 "memory_operand" ""))
20197    (match_scratch:QI 2 "q")]
20198   "!optimize_size && !TARGET_PUSH_MEMORY
20199    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20200   [(set (match_dup 2) (match_dup 1))
20201    (set (match_dup 0) (match_dup 2))]
20202   "")
20203
20204 ;; Don't move an immediate directly to memory when the instruction
20205 ;; gets too big.
20206 (define_peephole2
20207   [(match_scratch:SI 1 "r")
20208    (set (match_operand:SI 0 "memory_operand" "")
20209         (const_int 0))]
20210   "! optimize_size
20211    && ! TARGET_USE_MOV0
20212    && TARGET_SPLIT_LONG_MOVES
20213    && get_attr_length (insn) >= ix86_cost->large_insn
20214    && peep2_regno_dead_p (0, FLAGS_REG)"
20215   [(parallel [(set (match_dup 1) (const_int 0))
20216               (clobber (reg:CC FLAGS_REG))])
20217    (set (match_dup 0) (match_dup 1))]
20218   "")
20219
20220 (define_peephole2
20221   [(match_scratch:HI 1 "r")
20222    (set (match_operand:HI 0 "memory_operand" "")
20223         (const_int 0))]
20224   "! optimize_size
20225    && ! TARGET_USE_MOV0
20226    && TARGET_SPLIT_LONG_MOVES
20227    && get_attr_length (insn) >= ix86_cost->large_insn
20228    && peep2_regno_dead_p (0, FLAGS_REG)"
20229   [(parallel [(set (match_dup 2) (const_int 0))
20230               (clobber (reg:CC FLAGS_REG))])
20231    (set (match_dup 0) (match_dup 1))]
20232   "operands[2] = gen_lowpart (SImode, operands[1]);")
20233
20234 (define_peephole2
20235   [(match_scratch:QI 1 "q")
20236    (set (match_operand:QI 0 "memory_operand" "")
20237         (const_int 0))]
20238   "! optimize_size
20239    && ! TARGET_USE_MOV0
20240    && TARGET_SPLIT_LONG_MOVES
20241    && get_attr_length (insn) >= ix86_cost->large_insn
20242    && peep2_regno_dead_p (0, FLAGS_REG)"
20243   [(parallel [(set (match_dup 2) (const_int 0))
20244               (clobber (reg:CC FLAGS_REG))])
20245    (set (match_dup 0) (match_dup 1))]
20246   "operands[2] = gen_lowpart (SImode, operands[1]);")
20247
20248 (define_peephole2
20249   [(match_scratch:SI 2 "r")
20250    (set (match_operand:SI 0 "memory_operand" "")
20251         (match_operand:SI 1 "immediate_operand" ""))]
20252   "! optimize_size
20253    && TARGET_SPLIT_LONG_MOVES
20254    && get_attr_length (insn) >= ix86_cost->large_insn"
20255   [(set (match_dup 2) (match_dup 1))
20256    (set (match_dup 0) (match_dup 2))]
20257   "")
20258
20259 (define_peephole2
20260   [(match_scratch:HI 2 "r")
20261    (set (match_operand:HI 0 "memory_operand" "")
20262         (match_operand:HI 1 "immediate_operand" ""))]
20263   "! optimize_size
20264    && TARGET_SPLIT_LONG_MOVES
20265    && get_attr_length (insn) >= ix86_cost->large_insn"
20266   [(set (match_dup 2) (match_dup 1))
20267    (set (match_dup 0) (match_dup 2))]
20268   "")
20269
20270 (define_peephole2
20271   [(match_scratch:QI 2 "q")
20272    (set (match_operand:QI 0 "memory_operand" "")
20273         (match_operand:QI 1 "immediate_operand" ""))]
20274   "! optimize_size
20275    && TARGET_SPLIT_LONG_MOVES
20276    && get_attr_length (insn) >= ix86_cost->large_insn"
20277   [(set (match_dup 2) (match_dup 1))
20278    (set (match_dup 0) (match_dup 2))]
20279   "")
20280
20281 ;; Don't compare memory with zero, load and use a test instead.
20282 (define_peephole2
20283   [(set (match_operand 0 "flags_reg_operand" "")
20284         (match_operator 1 "compare_operator"
20285           [(match_operand:SI 2 "memory_operand" "")
20286            (const_int 0)]))
20287    (match_scratch:SI 3 "r")]
20288   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20289   [(set (match_dup 3) (match_dup 2))
20290    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20291   "")
20292
20293 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20294 ;; Don't split NOTs with a displacement operand, because resulting XOR
20295 ;; will not be pairable anyway.
20296 ;;
20297 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20298 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20299 ;; so this split helps here as well.
20300 ;;
20301 ;; Note: Can't do this as a regular split because we can't get proper
20302 ;; lifetime information then.
20303
20304 (define_peephole2
20305   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20306         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20307   "!optimize_size
20308    && ((TARGET_NOT_UNPAIRABLE
20309         && (!MEM_P (operands[0])
20310             || !memory_displacement_operand (operands[0], SImode)))
20311        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20312    && peep2_regno_dead_p (0, FLAGS_REG)"
20313   [(parallel [(set (match_dup 0)
20314                    (xor:SI (match_dup 1) (const_int -1)))
20315               (clobber (reg:CC FLAGS_REG))])]
20316   "")
20317
20318 (define_peephole2
20319   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20320         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20321   "!optimize_size
20322    && ((TARGET_NOT_UNPAIRABLE
20323         && (!MEM_P (operands[0])
20324             || !memory_displacement_operand (operands[0], HImode)))
20325        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20326    && peep2_regno_dead_p (0, FLAGS_REG)"
20327   [(parallel [(set (match_dup 0)
20328                    (xor:HI (match_dup 1) (const_int -1)))
20329               (clobber (reg:CC FLAGS_REG))])]
20330   "")
20331
20332 (define_peephole2
20333   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20334         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20335   "!optimize_size
20336    && ((TARGET_NOT_UNPAIRABLE
20337         && (!MEM_P (operands[0])
20338             || !memory_displacement_operand (operands[0], QImode)))
20339        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20340    && peep2_regno_dead_p (0, FLAGS_REG)"
20341   [(parallel [(set (match_dup 0)
20342                    (xor:QI (match_dup 1) (const_int -1)))
20343               (clobber (reg:CC FLAGS_REG))])]
20344   "")
20345
20346 ;; Non pairable "test imm, reg" instructions can be translated to
20347 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20348 ;; byte opcode instead of two, have a short form for byte operands),
20349 ;; so do it for other CPUs as well.  Given that the value was dead,
20350 ;; this should not create any new dependencies.  Pass on the sub-word
20351 ;; versions if we're concerned about partial register stalls.
20352
20353 (define_peephole2
20354   [(set (match_operand 0 "flags_reg_operand" "")
20355         (match_operator 1 "compare_operator"
20356           [(and:SI (match_operand:SI 2 "register_operand" "")
20357                    (match_operand:SI 3 "immediate_operand" ""))
20358            (const_int 0)]))]
20359   "ix86_match_ccmode (insn, CCNOmode)
20360    && (true_regnum (operands[2]) != 0
20361        || satisfies_constraint_K (operands[3]))
20362    && peep2_reg_dead_p (1, operands[2])"
20363   [(parallel
20364      [(set (match_dup 0)
20365            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20366                             (const_int 0)]))
20367       (set (match_dup 2)
20368            (and:SI (match_dup 2) (match_dup 3)))])]
20369   "")
20370
20371 ;; We don't need to handle HImode case, because it will be promoted to SImode
20372 ;; on ! TARGET_PARTIAL_REG_STALL
20373
20374 (define_peephole2
20375   [(set (match_operand 0 "flags_reg_operand" "")
20376         (match_operator 1 "compare_operator"
20377           [(and:QI (match_operand:QI 2 "register_operand" "")
20378                    (match_operand:QI 3 "immediate_operand" ""))
20379            (const_int 0)]))]
20380   "! TARGET_PARTIAL_REG_STALL
20381    && ix86_match_ccmode (insn, CCNOmode)
20382    && true_regnum (operands[2]) != 0
20383    && peep2_reg_dead_p (1, operands[2])"
20384   [(parallel
20385      [(set (match_dup 0)
20386            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20387                             (const_int 0)]))
20388       (set (match_dup 2)
20389            (and:QI (match_dup 2) (match_dup 3)))])]
20390   "")
20391
20392 (define_peephole2
20393   [(set (match_operand 0 "flags_reg_operand" "")
20394         (match_operator 1 "compare_operator"
20395           [(and:SI
20396              (zero_extract:SI
20397                (match_operand 2 "ext_register_operand" "")
20398                (const_int 8)
20399                (const_int 8))
20400              (match_operand 3 "const_int_operand" ""))
20401            (const_int 0)]))]
20402   "! TARGET_PARTIAL_REG_STALL
20403    && ix86_match_ccmode (insn, CCNOmode)
20404    && true_regnum (operands[2]) != 0
20405    && peep2_reg_dead_p (1, operands[2])"
20406   [(parallel [(set (match_dup 0)
20407                    (match_op_dup 1
20408                      [(and:SI
20409                         (zero_extract:SI
20410                           (match_dup 2)
20411                           (const_int 8)
20412                           (const_int 8))
20413                         (match_dup 3))
20414                       (const_int 0)]))
20415               (set (zero_extract:SI (match_dup 2)
20416                                     (const_int 8)
20417                                     (const_int 8))
20418                    (and:SI
20419                      (zero_extract:SI
20420                        (match_dup 2)
20421                        (const_int 8)
20422                        (const_int 8))
20423                      (match_dup 3)))])]
20424   "")
20425
20426 ;; Don't do logical operations with memory inputs.
20427 (define_peephole2
20428   [(match_scratch:SI 2 "r")
20429    (parallel [(set (match_operand:SI 0 "register_operand" "")
20430                    (match_operator:SI 3 "arith_or_logical_operator"
20431                      [(match_dup 0)
20432                       (match_operand:SI 1 "memory_operand" "")]))
20433               (clobber (reg:CC FLAGS_REG))])]
20434   "! optimize_size && ! TARGET_READ_MODIFY"
20435   [(set (match_dup 2) (match_dup 1))
20436    (parallel [(set (match_dup 0)
20437                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20438               (clobber (reg:CC FLAGS_REG))])]
20439   "")
20440
20441 (define_peephole2
20442   [(match_scratch:SI 2 "r")
20443    (parallel [(set (match_operand:SI 0 "register_operand" "")
20444                    (match_operator:SI 3 "arith_or_logical_operator"
20445                      [(match_operand:SI 1 "memory_operand" "")
20446                       (match_dup 0)]))
20447               (clobber (reg:CC FLAGS_REG))])]
20448   "! optimize_size && ! TARGET_READ_MODIFY"
20449   [(set (match_dup 2) (match_dup 1))
20450    (parallel [(set (match_dup 0)
20451                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20452               (clobber (reg:CC FLAGS_REG))])]
20453   "")
20454
20455 ; Don't do logical operations with memory outputs
20456 ;
20457 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20458 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20459 ; the same decoder scheduling characteristics as the original.
20460
20461 (define_peephole2
20462   [(match_scratch:SI 2 "r")
20463    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20464                    (match_operator:SI 3 "arith_or_logical_operator"
20465                      [(match_dup 0)
20466                       (match_operand:SI 1 "nonmemory_operand" "")]))
20467               (clobber (reg:CC FLAGS_REG))])]
20468   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20469   [(set (match_dup 2) (match_dup 0))
20470    (parallel [(set (match_dup 2)
20471                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20472               (clobber (reg:CC FLAGS_REG))])
20473    (set (match_dup 0) (match_dup 2))]
20474   "")
20475
20476 (define_peephole2
20477   [(match_scratch:SI 2 "r")
20478    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20479                    (match_operator:SI 3 "arith_or_logical_operator"
20480                      [(match_operand:SI 1 "nonmemory_operand" "")
20481                       (match_dup 0)]))
20482               (clobber (reg:CC FLAGS_REG))])]
20483   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20484   [(set (match_dup 2) (match_dup 0))
20485    (parallel [(set (match_dup 2)
20486                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20487               (clobber (reg:CC FLAGS_REG))])
20488    (set (match_dup 0) (match_dup 2))]
20489   "")
20490
20491 ;; Attempt to always use XOR for zeroing registers.
20492 (define_peephole2
20493   [(set (match_operand 0 "register_operand" "")
20494         (match_operand 1 "const0_operand" ""))]
20495   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20496    && (! TARGET_USE_MOV0 || optimize_size)
20497    && GENERAL_REG_P (operands[0])
20498    && peep2_regno_dead_p (0, FLAGS_REG)"
20499   [(parallel [(set (match_dup 0) (const_int 0))
20500               (clobber (reg:CC FLAGS_REG))])]
20501 {
20502   operands[0] = gen_lowpart (word_mode, operands[0]);
20503 })
20504
20505 (define_peephole2
20506   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20507         (const_int 0))]
20508   "(GET_MODE (operands[0]) == QImode
20509     || GET_MODE (operands[0]) == HImode)
20510    && (! TARGET_USE_MOV0 || optimize_size)
20511    && peep2_regno_dead_p (0, FLAGS_REG)"
20512   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20513               (clobber (reg:CC FLAGS_REG))])])
20514
20515 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20516 (define_peephole2
20517   [(set (match_operand 0 "register_operand" "")
20518         (const_int -1))]
20519   "(GET_MODE (operands[0]) == HImode
20520     || GET_MODE (operands[0]) == SImode
20521     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20522    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20523    && peep2_regno_dead_p (0, FLAGS_REG)"
20524   [(parallel [(set (match_dup 0) (const_int -1))
20525               (clobber (reg:CC FLAGS_REG))])]
20526   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20527                               operands[0]);")
20528
20529 ;; Attempt to convert simple leas to adds. These can be created by
20530 ;; move expanders.
20531 (define_peephole2
20532   [(set (match_operand:SI 0 "register_operand" "")
20533         (plus:SI (match_dup 0)
20534                  (match_operand:SI 1 "nonmemory_operand" "")))]
20535   "peep2_regno_dead_p (0, FLAGS_REG)"
20536   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20537               (clobber (reg:CC FLAGS_REG))])]
20538   "")
20539
20540 (define_peephole2
20541   [(set (match_operand:SI 0 "register_operand" "")
20542         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20543                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20544   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20545   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20546               (clobber (reg:CC FLAGS_REG))])]
20547   "operands[2] = gen_lowpart (SImode, operands[2]);")
20548
20549 (define_peephole2
20550   [(set (match_operand:DI 0 "register_operand" "")
20551         (plus:DI (match_dup 0)
20552                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20553   "peep2_regno_dead_p (0, FLAGS_REG)"
20554   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20555               (clobber (reg:CC FLAGS_REG))])]
20556   "")
20557
20558 (define_peephole2
20559   [(set (match_operand:SI 0 "register_operand" "")
20560         (mult:SI (match_dup 0)
20561                  (match_operand:SI 1 "const_int_operand" "")))]
20562   "exact_log2 (INTVAL (operands[1])) >= 0
20563    && peep2_regno_dead_p (0, FLAGS_REG)"
20564   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20565               (clobber (reg:CC FLAGS_REG))])]
20566   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20567
20568 (define_peephole2
20569   [(set (match_operand:DI 0 "register_operand" "")
20570         (mult:DI (match_dup 0)
20571                  (match_operand:DI 1 "const_int_operand" "")))]
20572   "exact_log2 (INTVAL (operands[1])) >= 0
20573    && peep2_regno_dead_p (0, FLAGS_REG)"
20574   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20575               (clobber (reg:CC FLAGS_REG))])]
20576   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20577
20578 (define_peephole2
20579   [(set (match_operand:SI 0 "register_operand" "")
20580         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20581                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20582   "exact_log2 (INTVAL (operands[2])) >= 0
20583    && REGNO (operands[0]) == REGNO (operands[1])
20584    && peep2_regno_dead_p (0, FLAGS_REG)"
20585   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20586               (clobber (reg:CC FLAGS_REG))])]
20587   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20588
20589 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20590 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20591 ;; many CPUs it is also faster, since special hardware to avoid esp
20592 ;; dependencies is present.
20593
20594 ;; While some of these conversions may be done using splitters, we use peepholes
20595 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20596
20597 ;; Convert prologue esp subtractions to push.
20598 ;; We need register to push.  In order to keep verify_flow_info happy we have
20599 ;; two choices
20600 ;; - use scratch and clobber it in order to avoid dependencies
20601 ;; - use already live register
20602 ;; We can't use the second way right now, since there is no reliable way how to
20603 ;; verify that given register is live.  First choice will also most likely in
20604 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20605 ;; call clobbered registers are dead.  We may want to use base pointer as an
20606 ;; alternative when no register is available later.
20607
20608 (define_peephole2
20609   [(match_scratch:SI 0 "r")
20610    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20611               (clobber (reg:CC FLAGS_REG))
20612               (clobber (mem:BLK (scratch)))])]
20613   "optimize_size || !TARGET_SUB_ESP_4"
20614   [(clobber (match_dup 0))
20615    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20616               (clobber (mem:BLK (scratch)))])])
20617
20618 (define_peephole2
20619   [(match_scratch:SI 0 "r")
20620    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20621               (clobber (reg:CC FLAGS_REG))
20622               (clobber (mem:BLK (scratch)))])]
20623   "optimize_size || !TARGET_SUB_ESP_8"
20624   [(clobber (match_dup 0))
20625    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20626    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20627               (clobber (mem:BLK (scratch)))])])
20628
20629 ;; Convert esp subtractions to push.
20630 (define_peephole2
20631   [(match_scratch:SI 0 "r")
20632    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20633               (clobber (reg:CC FLAGS_REG))])]
20634   "optimize_size || !TARGET_SUB_ESP_4"
20635   [(clobber (match_dup 0))
20636    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20637
20638 (define_peephole2
20639   [(match_scratch:SI 0 "r")
20640    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20641               (clobber (reg:CC FLAGS_REG))])]
20642   "optimize_size || !TARGET_SUB_ESP_8"
20643   [(clobber (match_dup 0))
20644    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20645    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20646
20647 ;; Convert epilogue deallocator to pop.
20648 (define_peephole2
20649   [(match_scratch:SI 0 "r")
20650    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20651               (clobber (reg:CC FLAGS_REG))
20652               (clobber (mem:BLK (scratch)))])]
20653   "optimize_size || !TARGET_ADD_ESP_4"
20654   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20655               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20656               (clobber (mem:BLK (scratch)))])]
20657   "")
20658
20659 ;; Two pops case is tricky, since pop causes dependency on destination register.
20660 ;; We use two registers if available.
20661 (define_peephole2
20662   [(match_scratch:SI 0 "r")
20663    (match_scratch:SI 1 "r")
20664    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20665               (clobber (reg:CC FLAGS_REG))
20666               (clobber (mem:BLK (scratch)))])]
20667   "optimize_size || !TARGET_ADD_ESP_8"
20668   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20669               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20670               (clobber (mem:BLK (scratch)))])
20671    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20672               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20673   "")
20674
20675 (define_peephole2
20676   [(match_scratch:SI 0 "r")
20677    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20678               (clobber (reg:CC FLAGS_REG))
20679               (clobber (mem:BLK (scratch)))])]
20680   "optimize_size"
20681   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20682               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20683               (clobber (mem:BLK (scratch)))])
20684    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20685               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20686   "")
20687
20688 ;; Convert esp additions to pop.
20689 (define_peephole2
20690   [(match_scratch:SI 0 "r")
20691    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20692               (clobber (reg:CC FLAGS_REG))])]
20693   ""
20694   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20695               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20696   "")
20697
20698 ;; Two pops case is tricky, since pop causes dependency on destination register.
20699 ;; We use two registers if available.
20700 (define_peephole2
20701   [(match_scratch:SI 0 "r")
20702    (match_scratch:SI 1 "r")
20703    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20704               (clobber (reg:CC FLAGS_REG))])]
20705   ""
20706   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20707               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20708    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20709               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20710   "")
20711
20712 (define_peephole2
20713   [(match_scratch:SI 0 "r")
20714    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20715               (clobber (reg:CC FLAGS_REG))])]
20716   "optimize_size"
20717   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20718               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20719    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20720               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20721   "")
20722 \f
20723 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20724 ;; required and register dies.  Similarly for 128 to plus -128.
20725 (define_peephole2
20726   [(set (match_operand 0 "flags_reg_operand" "")
20727         (match_operator 1 "compare_operator"
20728           [(match_operand 2 "register_operand" "")
20729            (match_operand 3 "const_int_operand" "")]))]
20730   "(INTVAL (operands[3]) == -1
20731     || INTVAL (operands[3]) == 1
20732     || INTVAL (operands[3]) == 128)
20733    && ix86_match_ccmode (insn, CCGCmode)
20734    && peep2_reg_dead_p (1, operands[2])"
20735   [(parallel [(set (match_dup 0)
20736                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20737               (clobber (match_dup 2))])]
20738   "")
20739 \f
20740 (define_peephole2
20741   [(match_scratch:DI 0 "r")
20742    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20743               (clobber (reg:CC FLAGS_REG))
20744               (clobber (mem:BLK (scratch)))])]
20745   "optimize_size || !TARGET_SUB_ESP_4"
20746   [(clobber (match_dup 0))
20747    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20748               (clobber (mem:BLK (scratch)))])])
20749
20750 (define_peephole2
20751   [(match_scratch:DI 0 "r")
20752    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20753               (clobber (reg:CC FLAGS_REG))
20754               (clobber (mem:BLK (scratch)))])]
20755   "optimize_size || !TARGET_SUB_ESP_8"
20756   [(clobber (match_dup 0))
20757    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20758    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20759               (clobber (mem:BLK (scratch)))])])
20760
20761 ;; Convert esp subtractions to push.
20762 (define_peephole2
20763   [(match_scratch:DI 0 "r")
20764    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20765               (clobber (reg:CC FLAGS_REG))])]
20766   "optimize_size || !TARGET_SUB_ESP_4"
20767   [(clobber (match_dup 0))
20768    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20769
20770 (define_peephole2
20771   [(match_scratch:DI 0 "r")
20772    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20773               (clobber (reg:CC FLAGS_REG))])]
20774   "optimize_size || !TARGET_SUB_ESP_8"
20775   [(clobber (match_dup 0))
20776    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20777    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20778
20779 ;; Convert epilogue deallocator to pop.
20780 (define_peephole2
20781   [(match_scratch:DI 0 "r")
20782    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20783               (clobber (reg:CC FLAGS_REG))
20784               (clobber (mem:BLK (scratch)))])]
20785   "optimize_size || !TARGET_ADD_ESP_4"
20786   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20787               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20788               (clobber (mem:BLK (scratch)))])]
20789   "")
20790
20791 ;; Two pops case is tricky, since pop causes dependency on destination register.
20792 ;; We use two registers if available.
20793 (define_peephole2
20794   [(match_scratch:DI 0 "r")
20795    (match_scratch:DI 1 "r")
20796    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20797               (clobber (reg:CC FLAGS_REG))
20798               (clobber (mem:BLK (scratch)))])]
20799   "optimize_size || !TARGET_ADD_ESP_8"
20800   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20801               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20802               (clobber (mem:BLK (scratch)))])
20803    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20804               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20805   "")
20806
20807 (define_peephole2
20808   [(match_scratch:DI 0 "r")
20809    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20810               (clobber (reg:CC FLAGS_REG))
20811               (clobber (mem:BLK (scratch)))])]
20812   "optimize_size"
20813   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20814               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20815               (clobber (mem:BLK (scratch)))])
20816    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20817               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20818   "")
20819
20820 ;; Convert esp additions to pop.
20821 (define_peephole2
20822   [(match_scratch:DI 0 "r")
20823    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20824               (clobber (reg:CC FLAGS_REG))])]
20825   ""
20826   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20827               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20828   "")
20829
20830 ;; Two pops case is tricky, since pop causes dependency on destination register.
20831 ;; We use two registers if available.
20832 (define_peephole2
20833   [(match_scratch:DI 0 "r")
20834    (match_scratch:DI 1 "r")
20835    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20836               (clobber (reg:CC FLAGS_REG))])]
20837   ""
20838   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20839               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20840    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20841               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20842   "")
20843
20844 (define_peephole2
20845   [(match_scratch:DI 0 "r")
20846    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20847               (clobber (reg:CC FLAGS_REG))])]
20848   "optimize_size"
20849   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20850               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20851    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20852               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20853   "")
20854 \f
20855 ;; Convert imul by three, five and nine into lea
20856 (define_peephole2
20857   [(parallel
20858     [(set (match_operand:SI 0 "register_operand" "")
20859           (mult:SI (match_operand:SI 1 "register_operand" "")
20860                    (match_operand:SI 2 "const_int_operand" "")))
20861      (clobber (reg:CC FLAGS_REG))])]
20862   "INTVAL (operands[2]) == 3
20863    || INTVAL (operands[2]) == 5
20864    || INTVAL (operands[2]) == 9"
20865   [(set (match_dup 0)
20866         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20867                  (match_dup 1)))]
20868   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20869
20870 (define_peephole2
20871   [(parallel
20872     [(set (match_operand:SI 0 "register_operand" "")
20873           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20874                    (match_operand:SI 2 "const_int_operand" "")))
20875      (clobber (reg:CC FLAGS_REG))])]
20876   "!optimize_size
20877    && (INTVAL (operands[2]) == 3
20878        || INTVAL (operands[2]) == 5
20879        || INTVAL (operands[2]) == 9)"
20880   [(set (match_dup 0) (match_dup 1))
20881    (set (match_dup 0)
20882         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20883                  (match_dup 0)))]
20884   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20885
20886 (define_peephole2
20887   [(parallel
20888     [(set (match_operand:DI 0 "register_operand" "")
20889           (mult:DI (match_operand:DI 1 "register_operand" "")
20890                    (match_operand:DI 2 "const_int_operand" "")))
20891      (clobber (reg:CC FLAGS_REG))])]
20892   "TARGET_64BIT
20893    && (INTVAL (operands[2]) == 3
20894        || INTVAL (operands[2]) == 5
20895        || INTVAL (operands[2]) == 9)"
20896   [(set (match_dup 0)
20897         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20898                  (match_dup 1)))]
20899   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20900
20901 (define_peephole2
20902   [(parallel
20903     [(set (match_operand:DI 0 "register_operand" "")
20904           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20905                    (match_operand:DI 2 "const_int_operand" "")))
20906      (clobber (reg:CC FLAGS_REG))])]
20907   "TARGET_64BIT
20908    && !optimize_size
20909    && (INTVAL (operands[2]) == 3
20910        || INTVAL (operands[2]) == 5
20911        || INTVAL (operands[2]) == 9)"
20912   [(set (match_dup 0) (match_dup 1))
20913    (set (match_dup 0)
20914         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20915                  (match_dup 0)))]
20916   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20917
20918 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20919 ;; imul $32bit_imm, reg, reg is direct decoded.
20920 (define_peephole2
20921   [(match_scratch:DI 3 "r")
20922    (parallel [(set (match_operand:DI 0 "register_operand" "")
20923                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20924                             (match_operand:DI 2 "immediate_operand" "")))
20925               (clobber (reg:CC FLAGS_REG))])]
20926   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20927    && !satisfies_constraint_K (operands[2])"
20928   [(set (match_dup 3) (match_dup 1))
20929    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20930               (clobber (reg:CC FLAGS_REG))])]
20931 "")
20932
20933 (define_peephole2
20934   [(match_scratch:SI 3 "r")
20935    (parallel [(set (match_operand:SI 0 "register_operand" "")
20936                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20937                             (match_operand:SI 2 "immediate_operand" "")))
20938               (clobber (reg:CC FLAGS_REG))])]
20939   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20940    && !satisfies_constraint_K (operands[2])"
20941   [(set (match_dup 3) (match_dup 1))
20942    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20943               (clobber (reg:CC FLAGS_REG))])]
20944 "")
20945
20946 (define_peephole2
20947   [(match_scratch:SI 3 "r")
20948    (parallel [(set (match_operand:DI 0 "register_operand" "")
20949                    (zero_extend:DI
20950                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20951                               (match_operand:SI 2 "immediate_operand" ""))))
20952               (clobber (reg:CC FLAGS_REG))])]
20953   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20954    && !satisfies_constraint_K (operands[2])"
20955   [(set (match_dup 3) (match_dup 1))
20956    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20957               (clobber (reg:CC FLAGS_REG))])]
20958 "")
20959
20960 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20961 ;; Convert it into imul reg, reg
20962 ;; It would be better to force assembler to encode instruction using long
20963 ;; immediate, but there is apparently no way to do so.
20964 (define_peephole2
20965   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20966                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20967                             (match_operand:DI 2 "const_int_operand" "")))
20968               (clobber (reg:CC FLAGS_REG))])
20969    (match_scratch:DI 3 "r")]
20970   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20971    && satisfies_constraint_K (operands[2])"
20972   [(set (match_dup 3) (match_dup 2))
20973    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20974               (clobber (reg:CC FLAGS_REG))])]
20975 {
20976   if (!rtx_equal_p (operands[0], operands[1]))
20977     emit_move_insn (operands[0], operands[1]);
20978 })
20979
20980 (define_peephole2
20981   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20982                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20983                             (match_operand:SI 2 "const_int_operand" "")))
20984               (clobber (reg:CC FLAGS_REG))])
20985    (match_scratch:SI 3 "r")]
20986   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20987    && satisfies_constraint_K (operands[2])"
20988   [(set (match_dup 3) (match_dup 2))
20989    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20990               (clobber (reg:CC FLAGS_REG))])]
20991 {
20992   if (!rtx_equal_p (operands[0], operands[1]))
20993     emit_move_insn (operands[0], operands[1]);
20994 })
20995
20996 (define_peephole2
20997   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20998                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20999                             (match_operand:HI 2 "immediate_operand" "")))
21000               (clobber (reg:CC FLAGS_REG))])
21001    (match_scratch:HI 3 "r")]
21002   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
21003   [(set (match_dup 3) (match_dup 2))
21004    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21005               (clobber (reg:CC FLAGS_REG))])]
21006 {
21007   if (!rtx_equal_p (operands[0], operands[1]))
21008     emit_move_insn (operands[0], operands[1]);
21009 })
21010
21011 ;; After splitting up read-modify operations, array accesses with memory
21012 ;; operands might end up in form:
21013 ;;  sall    $2, %eax
21014 ;;  movl    4(%esp), %edx
21015 ;;  addl    %edx, %eax
21016 ;; instead of pre-splitting:
21017 ;;  sall    $2, %eax
21018 ;;  addl    4(%esp), %eax
21019 ;; Turn it into:
21020 ;;  movl    4(%esp), %edx
21021 ;;  leal    (%edx,%eax,4), %eax
21022
21023 (define_peephole2
21024   [(parallel [(set (match_operand 0 "register_operand" "")
21025                    (ashift (match_operand 1 "register_operand" "")
21026                            (match_operand 2 "const_int_operand" "")))
21027                (clobber (reg:CC FLAGS_REG))])
21028    (set (match_operand 3 "register_operand")
21029         (match_operand 4 "x86_64_general_operand" ""))
21030    (parallel [(set (match_operand 5 "register_operand" "")
21031                    (plus (match_operand 6 "register_operand" "")
21032                          (match_operand 7 "register_operand" "")))
21033                    (clobber (reg:CC FLAGS_REG))])]
21034   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21035    /* Validate MODE for lea.  */
21036    && ((!TARGET_PARTIAL_REG_STALL
21037         && (GET_MODE (operands[0]) == QImode
21038             || GET_MODE (operands[0]) == HImode))
21039        || GET_MODE (operands[0]) == SImode
21040        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21041    /* We reorder load and the shift.  */
21042    && !rtx_equal_p (operands[1], operands[3])
21043    && !reg_overlap_mentioned_p (operands[0], operands[4])
21044    /* Last PLUS must consist of operand 0 and 3.  */
21045    && !rtx_equal_p (operands[0], operands[3])
21046    && (rtx_equal_p (operands[3], operands[6])
21047        || rtx_equal_p (operands[3], operands[7]))
21048    && (rtx_equal_p (operands[0], operands[6])
21049        || rtx_equal_p (operands[0], operands[7]))
21050    /* The intermediate operand 0 must die or be same as output.  */
21051    && (rtx_equal_p (operands[0], operands[5])
21052        || peep2_reg_dead_p (3, operands[0]))"
21053   [(set (match_dup 3) (match_dup 4))
21054    (set (match_dup 0) (match_dup 1))]
21055 {
21056   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21057   int scale = 1 << INTVAL (operands[2]);
21058   rtx index = gen_lowpart (Pmode, operands[1]);
21059   rtx base = gen_lowpart (Pmode, operands[3]);
21060   rtx dest = gen_lowpart (mode, operands[5]);
21061
21062   operands[1] = gen_rtx_PLUS (Pmode, base,
21063                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21064   if (mode != Pmode)
21065     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21066   operands[0] = dest;
21067 })
21068 \f
21069 ;; Call-value patterns last so that the wildcard operand does not
21070 ;; disrupt insn-recog's switch tables.
21071
21072 (define_insn "*call_value_pop_0"
21073   [(set (match_operand 0 "" "")
21074         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21075               (match_operand:SI 2 "" "")))
21076    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21077                             (match_operand:SI 3 "immediate_operand" "")))]
21078   "!TARGET_64BIT"
21079 {
21080   if (SIBLING_CALL_P (insn))
21081     return "jmp\t%P1";
21082   else
21083     return "call\t%P1";
21084 }
21085   [(set_attr "type" "callv")])
21086
21087 (define_insn "*call_value_pop_1"
21088   [(set (match_operand 0 "" "")
21089         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21090               (match_operand:SI 2 "" "")))
21091    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21092                             (match_operand:SI 3 "immediate_operand" "i")))]
21093   "!TARGET_64BIT"
21094 {
21095   if (constant_call_address_operand (operands[1], Pmode))
21096     {
21097       if (SIBLING_CALL_P (insn))
21098         return "jmp\t%P1";
21099       else
21100         return "call\t%P1";
21101     }
21102   if (SIBLING_CALL_P (insn))
21103     return "jmp\t%A1";
21104   else
21105     return "call\t%A1";
21106 }
21107   [(set_attr "type" "callv")])
21108
21109 (define_insn "*call_value_0"
21110   [(set (match_operand 0 "" "")
21111         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21112               (match_operand:SI 2 "" "")))]
21113   "!TARGET_64BIT"
21114 {
21115   if (SIBLING_CALL_P (insn))
21116     return "jmp\t%P1";
21117   else
21118     return "call\t%P1";
21119 }
21120   [(set_attr "type" "callv")])
21121
21122 (define_insn "*call_value_0_rex64"
21123   [(set (match_operand 0 "" "")
21124         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21125               (match_operand:DI 2 "const_int_operand" "")))]
21126   "TARGET_64BIT"
21127 {
21128   if (SIBLING_CALL_P (insn))
21129     return "jmp\t%P1";
21130   else
21131     return "call\t%P1";
21132 }
21133   [(set_attr "type" "callv")])
21134
21135 (define_insn "*call_value_1"
21136   [(set (match_operand 0 "" "")
21137         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21138               (match_operand:SI 2 "" "")))]
21139   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21140 {
21141   if (constant_call_address_operand (operands[1], Pmode))
21142     return "call\t%P1";
21143   return "call\t%A1";
21144 }
21145   [(set_attr "type" "callv")])
21146
21147 (define_insn "*sibcall_value_1"
21148   [(set (match_operand 0 "" "")
21149         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21150               (match_operand:SI 2 "" "")))]
21151   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21152 {
21153   if (constant_call_address_operand (operands[1], Pmode))
21154     return "jmp\t%P1";
21155   return "jmp\t%A1";
21156 }
21157   [(set_attr "type" "callv")])
21158
21159 (define_insn "*call_value_1_rex64"
21160   [(set (match_operand 0 "" "")
21161         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21162               (match_operand:DI 2 "" "")))]
21163   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21164    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21165 {
21166   if (constant_call_address_operand (operands[1], Pmode))
21167     return "call\t%P1";
21168   return "call\t%A1";
21169 }
21170   [(set_attr "type" "callv")])
21171
21172 (define_insn "*call_value_1_rex64_large"
21173   [(set (match_operand 0 "" "")
21174         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21175               (match_operand:DI 2 "" "")))]
21176   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21177   "call\t%A1"
21178   [(set_attr "type" "callv")])
21179
21180 (define_insn "*sibcall_value_1_rex64"
21181   [(set (match_operand 0 "" "")
21182         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21183               (match_operand:DI 2 "" "")))]
21184   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21185   "jmp\t%P1"
21186   [(set_attr "type" "callv")])
21187
21188 (define_insn "*sibcall_value_1_rex64_v"
21189   [(set (match_operand 0 "" "")
21190         (call (mem:QI (reg:DI R11_REG))
21191               (match_operand:DI 1 "" "")))]
21192   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21193   "jmp\t*%%r11"
21194   [(set_attr "type" "callv")])
21195 \f
21196 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21197 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21198 ;; caught for use by garbage collectors and the like.  Using an insn that
21199 ;; maps to SIGILL makes it more likely the program will rightfully die.
21200 ;; Keeping with tradition, "6" is in honor of #UD.
21201 (define_insn "trap"
21202   [(trap_if (const_int 1) (const_int 6))]
21203   ""
21204   { return ASM_SHORT "0x0b0f"; }
21205   [(set_attr "length" "2")])
21206
21207 (define_expand "sse_prologue_save"
21208   [(parallel [(set (match_operand:BLK 0 "" "")
21209                    (unspec:BLK [(reg:DI 21)
21210                                 (reg:DI 22)
21211                                 (reg:DI 23)
21212                                 (reg:DI 24)
21213                                 (reg:DI 25)
21214                                 (reg:DI 26)
21215                                 (reg:DI 27)
21216                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21217               (use (match_operand:DI 1 "register_operand" ""))
21218               (use (match_operand:DI 2 "immediate_operand" ""))
21219               (use (label_ref:DI (match_operand 3 "" "")))])]
21220   "TARGET_64BIT"
21221   "")
21222
21223 (define_insn "*sse_prologue_save_insn"
21224   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21225                           (match_operand:DI 4 "const_int_operand" "n")))
21226         (unspec:BLK [(reg:DI 21)
21227                      (reg:DI 22)
21228                      (reg:DI 23)
21229                      (reg:DI 24)
21230                      (reg:DI 25)
21231                      (reg:DI 26)
21232                      (reg:DI 27)
21233                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21234    (use (match_operand:DI 1 "register_operand" "r"))
21235    (use (match_operand:DI 2 "const_int_operand" "i"))
21236    (use (label_ref:DI (match_operand 3 "" "X")))]
21237   "TARGET_64BIT
21238    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21239    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21240   "*
21241 {
21242   int i;
21243   operands[0] = gen_rtx_MEM (Pmode,
21244                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21245   output_asm_insn (\"jmp\\t%A1\", operands);
21246   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21247     {
21248       operands[4] = adjust_address (operands[0], DImode, i*16);
21249       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21250       PUT_MODE (operands[4], TImode);
21251       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21252         output_asm_insn (\"rex\", operands);
21253       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21254     }
21255   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21256                              CODE_LABEL_NUMBER (operands[3]));
21257   return \"\";
21258 }
21259   "
21260   [(set_attr "type" "other")
21261    (set_attr "length_immediate" "0")
21262    (set_attr "length_address" "0")
21263    (set_attr "length" "135")
21264    (set_attr "memory" "store")
21265    (set_attr "modrm" "0")
21266    (set_attr "mode" "DI")])
21267
21268 (define_expand "prefetch"
21269   [(prefetch (match_operand 0 "address_operand" "")
21270              (match_operand:SI 1 "const_int_operand" "")
21271              (match_operand:SI 2 "const_int_operand" ""))]
21272   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21273 {
21274   int rw = INTVAL (operands[1]);
21275   int locality = INTVAL (operands[2]);
21276
21277   gcc_assert (rw == 0 || rw == 1);
21278   gcc_assert (locality >= 0 && locality <= 3);
21279   gcc_assert (GET_MODE (operands[0]) == Pmode
21280               || GET_MODE (operands[0]) == VOIDmode);
21281
21282   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21283      supported by SSE counterpart or the SSE prefetch is not available
21284      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21285      of locality.  */
21286   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21287     operands[2] = GEN_INT (3);
21288   else
21289     operands[1] = const0_rtx;
21290 })
21291
21292 (define_insn "*prefetch_sse"
21293   [(prefetch (match_operand:SI 0 "address_operand" "p")
21294              (const_int 0)
21295              (match_operand:SI 1 "const_int_operand" ""))]
21296   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21297 {
21298   static const char * const patterns[4] = {
21299    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21300   };
21301
21302   int locality = INTVAL (operands[1]);
21303   gcc_assert (locality >= 0 && locality <= 3);
21304
21305   return patterns[locality];
21306 }
21307   [(set_attr "type" "sse")
21308    (set_attr "memory" "none")])
21309
21310 (define_insn "*prefetch_sse_rex"
21311   [(prefetch (match_operand:DI 0 "address_operand" "p")
21312              (const_int 0)
21313              (match_operand:SI 1 "const_int_operand" ""))]
21314   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21315 {
21316   static const char * const patterns[4] = {
21317    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21318   };
21319
21320   int locality = INTVAL (operands[1]);
21321   gcc_assert (locality >= 0 && locality <= 3);
21322
21323   return patterns[locality];
21324 }
21325   [(set_attr "type" "sse")
21326    (set_attr "memory" "none")])
21327
21328 (define_insn "*prefetch_3dnow"
21329   [(prefetch (match_operand:SI 0 "address_operand" "p")
21330              (match_operand:SI 1 "const_int_operand" "n")
21331              (const_int 3))]
21332   "TARGET_3DNOW && !TARGET_64BIT"
21333 {
21334   if (INTVAL (operands[1]) == 0)
21335     return "prefetch\t%a0";
21336   else
21337     return "prefetchw\t%a0";
21338 }
21339   [(set_attr "type" "mmx")
21340    (set_attr "memory" "none")])
21341
21342 (define_insn "*prefetch_3dnow_rex"
21343   [(prefetch (match_operand:DI 0 "address_operand" "p")
21344              (match_operand:SI 1 "const_int_operand" "n")
21345              (const_int 3))]
21346   "TARGET_3DNOW && TARGET_64BIT"
21347 {
21348   if (INTVAL (operands[1]) == 0)
21349     return "prefetch\t%a0";
21350   else
21351     return "prefetchw\t%a0";
21352 }
21353   [(set_attr "type" "mmx")
21354    (set_attr "memory" "none")])
21355
21356 (define_expand "stack_protect_set"
21357   [(match_operand 0 "memory_operand" "")
21358    (match_operand 1 "memory_operand" "")]
21359   ""
21360 {
21361 #ifdef TARGET_THREAD_SSP_OFFSET
21362   if (TARGET_64BIT)
21363     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21364                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21365   else
21366     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21367                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21368 #else
21369   if (TARGET_64BIT)
21370     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21371   else
21372     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21373 #endif
21374   DONE;
21375 })
21376
21377 (define_insn "stack_protect_set_si"
21378   [(set (match_operand:SI 0 "memory_operand" "=m")
21379         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21380    (set (match_scratch:SI 2 "=&r") (const_int 0))
21381    (clobber (reg:CC FLAGS_REG))]
21382   ""
21383   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21384   [(set_attr "type" "multi")])
21385
21386 (define_insn "stack_protect_set_di"
21387   [(set (match_operand:DI 0 "memory_operand" "=m")
21388         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21389    (set (match_scratch:DI 2 "=&r") (const_int 0))
21390    (clobber (reg:CC FLAGS_REG))]
21391   "TARGET_64BIT"
21392   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21393   [(set_attr "type" "multi")])
21394
21395 (define_insn "stack_tls_protect_set_si"
21396   [(set (match_operand:SI 0 "memory_operand" "=m")
21397         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21398    (set (match_scratch:SI 2 "=&r") (const_int 0))
21399    (clobber (reg:CC FLAGS_REG))]
21400   ""
21401   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21402   [(set_attr "type" "multi")])
21403
21404 (define_insn "stack_tls_protect_set_di"
21405   [(set (match_operand:DI 0 "memory_operand" "=m")
21406         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21407    (set (match_scratch:DI 2 "=&r") (const_int 0))
21408    (clobber (reg:CC FLAGS_REG))]
21409   "TARGET_64BIT"
21410   {
21411      /* The kernel uses a different segment register for performance reasons; a
21412         system call would not have to trash the userspace segment register,
21413         which would be expensive */
21414      if (ix86_cmodel != CM_KERNEL)
21415         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21416      else
21417         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21418   }
21419   [(set_attr "type" "multi")])
21420
21421 (define_expand "stack_protect_test"
21422   [(match_operand 0 "memory_operand" "")
21423    (match_operand 1 "memory_operand" "")
21424    (match_operand 2 "" "")]
21425   ""
21426 {
21427   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21428   ix86_compare_op0 = operands[0];
21429   ix86_compare_op1 = operands[1];
21430   ix86_compare_emitted = flags;
21431
21432 #ifdef TARGET_THREAD_SSP_OFFSET
21433   if (TARGET_64BIT)
21434     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21435                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21436   else
21437     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21438                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21439 #else
21440   if (TARGET_64BIT)
21441     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21442   else
21443     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21444 #endif
21445   emit_jump_insn (gen_beq (operands[2]));
21446   DONE;
21447 })
21448
21449 (define_insn "stack_protect_test_si"
21450   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21451         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21452                      (match_operand:SI 2 "memory_operand" "m")]
21453                     UNSPEC_SP_TEST))
21454    (clobber (match_scratch:SI 3 "=&r"))]
21455   ""
21456   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21457   [(set_attr "type" "multi")])
21458
21459 (define_insn "stack_protect_test_di"
21460   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21461         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21462                      (match_operand:DI 2 "memory_operand" "m")]
21463                     UNSPEC_SP_TEST))
21464    (clobber (match_scratch:DI 3 "=&r"))]
21465   "TARGET_64BIT"
21466   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21467   [(set_attr "type" "multi")])
21468
21469 (define_insn "stack_tls_protect_test_si"
21470   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21471         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21472                      (match_operand:SI 2 "const_int_operand" "i")]
21473                     UNSPEC_SP_TLS_TEST))
21474    (clobber (match_scratch:SI 3 "=r"))]
21475   ""
21476   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21477   [(set_attr "type" "multi")])
21478
21479 (define_insn "stack_tls_protect_test_di"
21480   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21481         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21482                      (match_operand:DI 2 "const_int_operand" "i")]
21483                     UNSPEC_SP_TLS_TEST))
21484    (clobber (match_scratch:DI 3 "=r"))]
21485   "TARGET_64BIT"
21486   {
21487      /* The kernel uses a different segment register for performance reasons; a
21488         system call would not have to trash the userspace segment register,
21489         which would be expensive */
21490      if (ix86_cmodel != CM_KERNEL)
21491         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21492      else
21493         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21494   }
21495   [(set_attr "type" "multi")])
21496
21497 (define_mode_iterator CRC32MODE [QI HI SI])
21498 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21499 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21500
21501 (define_insn "sse4_2_crc32<mode>"
21502   [(set (match_operand:SI 0 "register_operand" "=r")
21503         (unspec:SI
21504           [(match_operand:SI 1 "register_operand" "0")
21505            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21506           UNSPEC_CRC32))]
21507   "TARGET_SSE4_2"
21508   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21509   [(set_attr "type" "sselog1")
21510    (set_attr "prefix_rep" "1")
21511    (set_attr "prefix_extra" "1")
21512    (set_attr "mode" "SI")])
21513
21514 (define_insn "sse4_2_crc32di"
21515   [(set (match_operand:DI 0 "register_operand" "=r")
21516         (unspec:DI
21517           [(match_operand:DI 1 "register_operand" "0")
21518            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21519           UNSPEC_CRC32))]
21520   "TARGET_SSE4_2 && TARGET_64BIT"
21521   "crc32q\t{%2, %0|%0, %2}"
21522   [(set_attr "type" "sselog1")
21523    (set_attr "prefix_rep" "1")
21524    (set_attr "prefix_extra" "1")
21525    (set_attr "mode" "DI")])
21526
21527 (include "mmx.md")
21528 (include "sse.md")
21529 (include "sync.md")