OSDN Git Service

352f67dea7262a1a336c6d9e60d5cfc966b640d5
[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 && !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 && !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 && GET_MODE (operands[1]) == SImode
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    
4783    if (GET_MODE (operands[0]) == SFmode && GET_MODE (operands[1]) == SImode
4784        && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4785        && SSE_FLOAT_MODE_P (SFmode))
4786      {
4787        /* When !flag_trapping_math, we handle SImode->SFmode vector
4788           conversions same way as SImode->DFmode.
4789
4790           For flat_trapping_math we can't safely use vector conversion without
4791           clearing upper half, otherwise precision exception might occur.
4792           However we can still generate the common sequence converting value
4793           from general register to XMM register as:
4794
4795             mov         reg32, mem32
4796             movd        mem32, xmm
4797             cvtdq2pd xmm,xmm
4798
4799           because we know that movd clears the upper half.
4800
4801           Sadly in this case we can't rely on reload moving the value to XMM
4802           register, since we need to know if upper half is OK, so we need
4803           to do reloading by hand.  We force operand to memory unless target
4804           supports inter unit moves.  */
4805        if (!flag_trapping_math)
4806          operands[1] = force_reg (SImode, operands[1]);
4807        else if (!MEM_P (operands[1]))
4808          {
4809            rtx tmp = assign_386_stack_local (SImode, SLOT_VIRTUAL);
4810            emit_move_insn (tmp, operands[1]);
4811            operands[1] = tmp;
4812          }
4813      }
4814   ")
4815
4816 (define_insn "*floatsisf2_mixed_vector"
4817   [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4818         (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4819   "TARGET_MIX_SSE_I387 && !flag_trapping_math 
4820    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4821   "@
4822    cvtpq2ps\t{%1, %0|%0, %1}
4823    fild%z1\t%1
4824    #"
4825   [(set_attr "type" "sseicvt,fmov,multi")
4826    (set_attr "mode" "SF")
4827    (set_attr "unit" "*,i387,*")
4828    (set_attr "athlon_decode" "double,*,*")
4829    (set_attr "amdfam10_decode" "double,*,*")
4830    (set_attr "fp_int_src" "false,true,true")])
4831
4832 (define_insn "*floatsisf2_mixed"
4833   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4834         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4835   "TARGET_MIX_SSE_I387
4836    && (!TARGET_USE_VECTOR_CONVERTS || optimize_size)"
4837   "@
4838    fild%z1\t%1
4839    #
4840    cvtsi2ss\t{%1, %0|%0, %1}
4841    cvtsi2ss\t{%1, %0|%0, %1}"
4842   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4843    (set_attr "mode" "SF")
4844    (set_attr "unit" "*,i387,*,*")
4845    (set_attr "athlon_decode" "*,*,vector,double")
4846    (set_attr "amdfam10_decode" "*,*,vector,double")
4847    (set_attr "fp_int_src" "true")])
4848
4849 (define_insn "*floatsisf2_sse_vector_nointernunit"
4850   [(set (match_operand:SF 0 "register_operand" "=x")
4851         (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4852   "flag_trapping_math && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4853    && !TARGET_INTER_UNIT_MOVES"
4854   "#"
4855   [(set_attr "type" "multi")])
4856
4857 (define_insn "*floatsisf2_sse_vector_internunit"
4858   [(set (match_operand:SF 0 "register_operand" "=x,x")
4859         (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4860   "flag_trapping_math && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4861    && TARGET_INTER_UNIT_MOVES"
4862   "#"
4863   [(set_attr "type" "multi")])
4864
4865 (define_split 
4866   [(set (match_operand:SF 0 "register_operand" "")
4867         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4868   "flag_trapping_math
4869    && TARGET_USE_VECTOR_CONVERTS && reload_completed
4870    && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4871    && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4872   [(set (match_dup 0)
4873         (float:V4SF (match_dup 2)))]
4874 {
4875   operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4876   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4877   emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4878 })
4879
4880 (define_split 
4881   [(set (match_operand:SF 0 "register_operand" "")
4882         (float:SF (match_operand:SI 1 "register_operand" "")))]
4883   "flag_trapping_math
4884    && TARGET_USE_VECTOR_CONVERTS && reload_completed
4885    && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4886   [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4887    (set (match_dup 0)
4888         (float:V4SF (match_dup 2)))]
4889 {
4890   operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4891   operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4892 })
4893
4894 (define_insn "*floatsisf2_sse_vector"
4895   [(set (match_operand:SF 0 "register_operand" "=x")
4896         (float:SF (match_operand:SI 1 "register_operand" "x")))]
4897   "!flag_trapping_math && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4898    && !TARGET_INTER_UNIT_MOVES"
4899   "cvtpq2ps\t{%1, %0|%0, %1}"
4900   [(set_attr "type" "sseicvt")
4901    (set_attr "mode" "SF")
4902    (set_attr "athlon_decode" "double")
4903    (set_attr "amdfam10_decode" "double")
4904    (set_attr "fp_int_src" "true")])
4905
4906 (define_insn "*floatsisf2_sse"
4907   [(set (match_operand:SF 0 "register_operand" "=x,x")
4908         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4909   "TARGET_SSE_MATH
4910    && (!TARGET_USE_VECTOR_CONVERTS || optimize_size)"
4911   "cvtsi2ss\t{%1, %0|%0, %1}"
4912   [(set_attr "type" "sseicvt")
4913    (set_attr "mode" "SF")
4914    (set_attr "athlon_decode" "vector,double")
4915    (set_attr "amdfam10_decode" "vector,double")
4916    (set_attr "fp_int_src" "true")])
4917
4918 (define_insn "*floatsidf2_mixed_vector"
4919   [(set (match_operand:DF 0 "register_operand" "=x,f,f")
4920         (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4921   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4922    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4923   "@
4924    cvtdq2pd\t{%1, %0|%0, %1}
4925    fild%z1\t%1
4926    #"
4927   [(set_attr "type" "sseicvt,fmov,multi")
4928    (set_attr "mode" "V2DF,DF,DF")
4929    (set_attr "unit" "*,*,i387")
4930    (set_attr "athlon_decode" "double,*,*")
4931    (set_attr "amdfam10_decode" "double,*,*")
4932    (set_attr "fp_int_src" "false,true,true")])
4933
4934 (define_insn "*floatsidf2_mixed"
4935   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
4936         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
4937   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4938     && (!TARGET_USE_VECTOR_CONVERTS || !optimize_size)"
4939   "@
4940    fild%z1\t%1
4941    #
4942    cvtsi2sd\t{%1, %0|%0, %1}
4943    cvtsi2sd\t{%1, %0|%0, %1}
4944    cvtdq2pd\t{%1, %0|%0, %1}"
4945   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4946    (set_attr "mode" "DF,DF,DF,DF,V2DF")
4947    (set_attr "unit" "*,i387,*,*,*")
4948    (set_attr "athlon_decode" "*,*,double,direct,double")
4949    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4950    (set_attr "fp_int_src" "true,true,true,true,false")])
4951
4952 (define_insn "*floatsidf2_sse_vector"
4953   [(set (match_operand:DF 0 "register_operand" "=x")
4954         (float:DF (match_operand:SI 1 "register_operand" "x")))]
4955   "TARGET_SSE2 && TARGET_SSE_MATH
4956    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4957   "cvtdq2pd\t{%1, %0|%0, %1}"
4958   [(set_attr "type" "sseicvt")
4959    (set_attr "mode" "V2DF")
4960    (set_attr "athlon_decode" "double")
4961    (set_attr "amdfam10_decode" "double")
4962    (set_attr "fp_int_src" "true")])
4963
4964 (define_split 
4965   [(set (match_operand:DF 0 "register_operand" "")
4966         (float:DF (match_operand:SI 1 "memory_operand" "")))]
4967   "TARGET_USE_VECTOR_CONVERTS && reload_completed
4968    && SSE_REG_P (operands[0])"
4969   [(set (match_dup 0)
4970         (float:V2DF
4971           (vec_select:V2SI
4972             (match_dup 2)
4973             (parallel [(const_int 0) (const_int 1)]))))]
4974 {
4975   operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
4976   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4977   emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4978 })
4979
4980 (define_insn "*floatsidf2_sse"
4981   [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
4982         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
4983   "TARGET_SSE2 && TARGET_SSE_MATH
4984    && (!TARGET_USE_VECTOR_CONVERTS || optimize_size)"
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" "sseicvt")
4990    (set_attr "mode" "DF,DF,V2DF")
4991    (set_attr "athlon_decode" "double,direct,double")
4992    (set_attr "amdfam10_decode" "vector,double,double")
4993    (set_attr "fp_int_src" "true")])
4994
4995 (define_insn "*floatsi<mode>2_i387"
4996   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4997         (float:MODEF
4998           (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4999   "TARGET_80387
5000    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5001   "@
5002    fild%z1\t%1
5003    #"
5004   [(set_attr "type" "fmov,multi")
5005    (set_attr "mode" "<MODE>")
5006    (set_attr "unit" "*,i387")
5007    (set_attr "fp_int_src" "true")])
5008
5009 (define_expand "floatdisf2"
5010   [(set (match_operand:SF 0 "register_operand" "")
5011         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5012   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5013   "")
5014
5015 (define_insn "*floatdisf2_mixed"
5016   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5017         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5018   "TARGET_64BIT && TARGET_MIX_SSE_I387"
5019   "@
5020    fild%z1\t%1
5021    #
5022    cvtsi2ss{q}\t{%1, %0|%0, %1}
5023    cvtsi2ss{q}\t{%1, %0|%0, %1}"
5024   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5025    (set_attr "mode" "SF")
5026    (set_attr "unit" "*,i387,*,*")
5027    (set_attr "athlon_decode" "*,*,vector,double")
5028    (set_attr "amdfam10_decode" "*,*,vector,double")
5029    (set_attr "fp_int_src" "true")])
5030
5031 (define_insn "*floatdisf2_sse"
5032   [(set (match_operand:SF 0 "register_operand" "=x,x")
5033         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5034   "TARGET_64BIT && TARGET_SSE_MATH"
5035   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5036   [(set_attr "type" "sseicvt")
5037    (set_attr "mode" "SF")
5038    (set_attr "athlon_decode" "vector,double")
5039    (set_attr "amdfam10_decode" "vector,double")
5040    (set_attr "fp_int_src" "true")])
5041
5042 (define_expand "floatdidf2"
5043   [(set (match_operand:DF 0 "register_operand" "")
5044         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5045   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5046 {
5047   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5048     {
5049       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5050       DONE;
5051     }
5052 })
5053
5054 (define_insn "*floatdidf2_mixed"
5055   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5056         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5057   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
5058   "@
5059    fild%z1\t%1
5060    #
5061    cvtsi2sd{q}\t{%1, %0|%0, %1}
5062    cvtsi2sd{q}\t{%1, %0|%0, %1}"
5063   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5064    (set_attr "mode" "DF")
5065    (set_attr "unit" "*,i387,*,*")
5066    (set_attr "athlon_decode" "*,*,double,direct")
5067    (set_attr "amdfam10_decode" "*,*,vector,double")
5068    (set_attr "fp_int_src" "true")])
5069
5070 (define_insn "*floatdidf2_sse"
5071   [(set (match_operand:DF 0 "register_operand" "=x,x")
5072         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5073   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
5074   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5075   [(set_attr "type" "sseicvt")
5076    (set_attr "mode" "DF")
5077    (set_attr "athlon_decode" "double,direct")
5078    (set_attr "amdfam10_decode" "vector,double")
5079    (set_attr "fp_int_src" "true")])
5080
5081 (define_insn "*floatdi<mode>2_i387"
5082   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5083         (float:MODEF
5084           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5085   "TARGET_80387"
5086   "@
5087    fild%z1\t%1
5088    #"
5089   [(set_attr "type" "fmov,multi")
5090    (set_attr "mode" "<MODE>")
5091    (set_attr "unit" "*,i387")
5092    (set_attr "fp_int_src" "true")])
5093
5094 (define_insn "float<mode>xf2"
5095   [(set (match_operand:XF 0 "register_operand" "=f,f")
5096         (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5097   "TARGET_80387"
5098   "@
5099    fild%z1\t%1
5100    #"
5101   [(set_attr "type" "fmov,multi")
5102    (set_attr "mode" "XF")
5103    (set_attr "unit" "*,i387")
5104    (set_attr "fp_int_src" "true")])
5105
5106 ;; %%% Kill these when reload knows how to do it.
5107 (define_split
5108   [(set (match_operand 0 "fp_register_operand" "")
5109         (float (match_operand 1 "register_operand" "")))]
5110   "reload_completed
5111    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5112   [(const_int 0)]
5113 {
5114   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5115   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5116   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5117   ix86_free_from_memory (GET_MODE (operands[1]));
5118   DONE;
5119 })
5120
5121 (define_expand "floatunssisf2"
5122   [(use (match_operand:SF 0 "register_operand" ""))
5123    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5124   "!TARGET_64BIT"
5125 {
5126   if (TARGET_SSE_MATH && TARGET_SSE2)
5127     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5128   else
5129     x86_emit_floatuns (operands);
5130   DONE;
5131 })
5132
5133 (define_expand "floatunssidf2"
5134   [(use (match_operand:DF 0 "register_operand" ""))
5135    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5136   "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5137   "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5138
5139 (define_expand "floatunsdisf2"
5140   [(use (match_operand:SF 0 "register_operand" ""))
5141    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5142   "TARGET_64BIT && TARGET_SSE_MATH"
5143   "x86_emit_floatuns (operands); DONE;")
5144
5145 (define_expand "floatunsdidf2"
5146   [(use (match_operand:DF 0 "register_operand" ""))
5147    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5148   "TARGET_SSE_MATH && TARGET_SSE2
5149    && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5150 {
5151   if (TARGET_64BIT)
5152     x86_emit_floatuns (operands);
5153   else
5154     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5155   DONE;
5156 })
5157 \f
5158 ;; Add instructions
5159
5160 ;; %%% splits for addditi3
5161
5162 (define_expand "addti3"
5163   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5164         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5165                  (match_operand:TI 2 "x86_64_general_operand" "")))
5166    (clobber (reg:CC FLAGS_REG))]
5167   "TARGET_64BIT"
5168   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5169
5170 (define_insn "*addti3_1"
5171   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5172         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5173                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5174    (clobber (reg:CC FLAGS_REG))]
5175   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5176   "#")
5177
5178 (define_split
5179   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5180         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5181                  (match_operand:TI 2 "x86_64_general_operand" "")))
5182    (clobber (reg:CC FLAGS_REG))]
5183   "TARGET_64BIT && reload_completed"
5184   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5185                                           UNSPEC_ADD_CARRY))
5186               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5187    (parallel [(set (match_dup 3)
5188                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5189                                      (match_dup 4))
5190                             (match_dup 5)))
5191               (clobber (reg:CC FLAGS_REG))])]
5192   "split_ti (operands+0, 1, operands+0, operands+3);
5193    split_ti (operands+1, 1, operands+1, operands+4);
5194    split_ti (operands+2, 1, operands+2, operands+5);")
5195
5196 ;; %%% splits for addsidi3
5197 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5198 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5199 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5200
5201 (define_expand "adddi3"
5202   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5203         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5204                  (match_operand:DI 2 "x86_64_general_operand" "")))
5205    (clobber (reg:CC FLAGS_REG))]
5206   ""
5207   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5208
5209 (define_insn "*adddi3_1"
5210   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5211         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5212                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5213    (clobber (reg:CC FLAGS_REG))]
5214   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5215   "#")
5216
5217 (define_split
5218   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5219         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5220                  (match_operand:DI 2 "general_operand" "")))
5221    (clobber (reg:CC FLAGS_REG))]
5222   "!TARGET_64BIT && reload_completed"
5223   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5224                                           UNSPEC_ADD_CARRY))
5225               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5226    (parallel [(set (match_dup 3)
5227                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5228                                      (match_dup 4))
5229                             (match_dup 5)))
5230               (clobber (reg:CC FLAGS_REG))])]
5231   "split_di (operands+0, 1, operands+0, operands+3);
5232    split_di (operands+1, 1, operands+1, operands+4);
5233    split_di (operands+2, 1, operands+2, operands+5);")
5234
5235 (define_insn "adddi3_carry_rex64"
5236   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5237           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5238                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5239                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5240    (clobber (reg:CC FLAGS_REG))]
5241   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5242   "adc{q}\t{%2, %0|%0, %2}"
5243   [(set_attr "type" "alu")
5244    (set_attr "pent_pair" "pu")
5245    (set_attr "mode" "DI")])
5246
5247 (define_insn "*adddi3_cc_rex64"
5248   [(set (reg:CC FLAGS_REG)
5249         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5250                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5251                    UNSPEC_ADD_CARRY))
5252    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5253         (plus:DI (match_dup 1) (match_dup 2)))]
5254   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5255   "add{q}\t{%2, %0|%0, %2}"
5256   [(set_attr "type" "alu")
5257    (set_attr "mode" "DI")])
5258
5259 (define_insn "*<addsub><mode>3_cc_overflow"
5260   [(set (reg:CCC FLAGS_REG)
5261         (compare:CCC
5262             (plusminus:SWI
5263                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5264                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5265             (match_dup 1)))
5266    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5267         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5268   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5269   "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5270   [(set_attr "type" "alu")
5271    (set_attr "mode" "<MODE>")])
5272
5273 (define_insn "*add<mode>3_cconly_overflow"
5274   [(set (reg:CCC FLAGS_REG)
5275         (compare:CCC
5276                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5277                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5278                 (match_dup 1)))
5279    (clobber (match_scratch:SWI 0 "=<r>"))]
5280   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5281   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5282   [(set_attr "type" "alu")
5283    (set_attr "mode" "<MODE>")])
5284
5285 (define_insn "*sub<mode>3_cconly_overflow"
5286   [(set (reg:CCC FLAGS_REG)
5287         (compare:CCC
5288              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5289                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5290              (match_dup 0)))]
5291   ""
5292   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5293   [(set_attr "type" "icmp")
5294    (set_attr "mode" "<MODE>")])
5295
5296 (define_insn "*<addsub>si3_zext_cc_overflow"
5297   [(set (reg:CCC FLAGS_REG)
5298         (compare:CCC
5299             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5300                           (match_operand:SI 2 "general_operand" "g"))
5301             (match_dup 1)))
5302    (set (match_operand:DI 0 "register_operand" "=r")
5303         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5304   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5305   "<addsub>{l}\t{%2, %k0|%k0, %2}"
5306   [(set_attr "type" "alu")
5307    (set_attr "mode" "SI")])
5308
5309 (define_insn "addqi3_carry"
5310   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5311           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5312                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5313                    (match_operand:QI 2 "general_operand" "qi,qm")))
5314    (clobber (reg:CC FLAGS_REG))]
5315   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5316   "adc{b}\t{%2, %0|%0, %2}"
5317   [(set_attr "type" "alu")
5318    (set_attr "pent_pair" "pu")
5319    (set_attr "mode" "QI")])
5320
5321 (define_insn "addhi3_carry"
5322   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5323           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5324                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5325                    (match_operand:HI 2 "general_operand" "ri,rm")))
5326    (clobber (reg:CC FLAGS_REG))]
5327   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5328   "adc{w}\t{%2, %0|%0, %2}"
5329   [(set_attr "type" "alu")
5330    (set_attr "pent_pair" "pu")
5331    (set_attr "mode" "HI")])
5332
5333 (define_insn "addsi3_carry"
5334   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5335           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5336                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5337                    (match_operand:SI 2 "general_operand" "ri,rm")))
5338    (clobber (reg:CC FLAGS_REG))]
5339   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5340   "adc{l}\t{%2, %0|%0, %2}"
5341   [(set_attr "type" "alu")
5342    (set_attr "pent_pair" "pu")
5343    (set_attr "mode" "SI")])
5344
5345 (define_insn "*addsi3_carry_zext"
5346   [(set (match_operand:DI 0 "register_operand" "=r")
5347           (zero_extend:DI
5348             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5349                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5350                      (match_operand:SI 2 "general_operand" "g"))))
5351    (clobber (reg:CC FLAGS_REG))]
5352   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5353   "adc{l}\t{%2, %k0|%k0, %2}"
5354   [(set_attr "type" "alu")
5355    (set_attr "pent_pair" "pu")
5356    (set_attr "mode" "SI")])
5357
5358 (define_insn "*addsi3_cc"
5359   [(set (reg:CC FLAGS_REG)
5360         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5361                     (match_operand:SI 2 "general_operand" "ri,rm")]
5362                    UNSPEC_ADD_CARRY))
5363    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5364         (plus:SI (match_dup 1) (match_dup 2)))]
5365   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5366   "add{l}\t{%2, %0|%0, %2}"
5367   [(set_attr "type" "alu")
5368    (set_attr "mode" "SI")])
5369
5370 (define_insn "addqi3_cc"
5371   [(set (reg:CC FLAGS_REG)
5372         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5373                     (match_operand:QI 2 "general_operand" "qi,qm")]
5374                    UNSPEC_ADD_CARRY))
5375    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5376         (plus:QI (match_dup 1) (match_dup 2)))]
5377   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5378   "add{b}\t{%2, %0|%0, %2}"
5379   [(set_attr "type" "alu")
5380    (set_attr "mode" "QI")])
5381
5382 (define_expand "addsi3"
5383   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5384                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5385                             (match_operand:SI 2 "general_operand" "")))
5386               (clobber (reg:CC FLAGS_REG))])]
5387   ""
5388   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5389
5390 (define_insn "*lea_1"
5391   [(set (match_operand:SI 0 "register_operand" "=r")
5392         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5393   "!TARGET_64BIT"
5394   "lea{l}\t{%a1, %0|%0, %a1}"
5395   [(set_attr "type" "lea")
5396    (set_attr "mode" "SI")])
5397
5398 (define_insn "*lea_1_rex64"
5399   [(set (match_operand:SI 0 "register_operand" "=r")
5400         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5401   "TARGET_64BIT"
5402   "lea{l}\t{%a1, %0|%0, %a1}"
5403   [(set_attr "type" "lea")
5404    (set_attr "mode" "SI")])
5405
5406 (define_insn "*lea_1_zext"
5407   [(set (match_operand:DI 0 "register_operand" "=r")
5408         (zero_extend:DI
5409          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5410   "TARGET_64BIT"
5411   "lea{l}\t{%a1, %k0|%k0, %a1}"
5412   [(set_attr "type" "lea")
5413    (set_attr "mode" "SI")])
5414
5415 (define_insn "*lea_2_rex64"
5416   [(set (match_operand:DI 0 "register_operand" "=r")
5417         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5418   "TARGET_64BIT"
5419   "lea{q}\t{%a1, %0|%0, %a1}"
5420   [(set_attr "type" "lea")
5421    (set_attr "mode" "DI")])
5422
5423 ;; The lea patterns for non-Pmodes needs to be matched by several
5424 ;; insns converted to real lea by splitters.
5425
5426 (define_insn_and_split "*lea_general_1"
5427   [(set (match_operand 0 "register_operand" "=r")
5428         (plus (plus (match_operand 1 "index_register_operand" "l")
5429                     (match_operand 2 "register_operand" "r"))
5430               (match_operand 3 "immediate_operand" "i")))]
5431   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5432     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5433    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5434    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5435    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5436    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5437        || GET_MODE (operands[3]) == VOIDmode)"
5438   "#"
5439   "&& reload_completed"
5440   [(const_int 0)]
5441 {
5442   rtx pat;
5443   operands[0] = gen_lowpart (SImode, operands[0]);
5444   operands[1] = gen_lowpart (Pmode, operands[1]);
5445   operands[2] = gen_lowpart (Pmode, operands[2]);
5446   operands[3] = gen_lowpart (Pmode, operands[3]);
5447   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5448                       operands[3]);
5449   if (Pmode != SImode)
5450     pat = gen_rtx_SUBREG (SImode, pat, 0);
5451   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5452   DONE;
5453 }
5454   [(set_attr "type" "lea")
5455    (set_attr "mode" "SI")])
5456
5457 (define_insn_and_split "*lea_general_1_zext"
5458   [(set (match_operand:DI 0 "register_operand" "=r")
5459         (zero_extend:DI
5460           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5461                             (match_operand:SI 2 "register_operand" "r"))
5462                    (match_operand:SI 3 "immediate_operand" "i"))))]
5463   "TARGET_64BIT"
5464   "#"
5465   "&& reload_completed"
5466   [(set (match_dup 0)
5467         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5468                                                      (match_dup 2))
5469                                             (match_dup 3)) 0)))]
5470 {
5471   operands[1] = gen_lowpart (Pmode, operands[1]);
5472   operands[2] = gen_lowpart (Pmode, operands[2]);
5473   operands[3] = gen_lowpart (Pmode, operands[3]);
5474 }
5475   [(set_attr "type" "lea")
5476    (set_attr "mode" "SI")])
5477
5478 (define_insn_and_split "*lea_general_2"
5479   [(set (match_operand 0 "register_operand" "=r")
5480         (plus (mult (match_operand 1 "index_register_operand" "l")
5481                     (match_operand 2 "const248_operand" "i"))
5482               (match_operand 3 "nonmemory_operand" "ri")))]
5483   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5484     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5485    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5486    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5487    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5488        || GET_MODE (operands[3]) == VOIDmode)"
5489   "#"
5490   "&& reload_completed"
5491   [(const_int 0)]
5492 {
5493   rtx pat;
5494   operands[0] = gen_lowpart (SImode, operands[0]);
5495   operands[1] = gen_lowpart (Pmode, operands[1]);
5496   operands[3] = gen_lowpart (Pmode, operands[3]);
5497   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5498                       operands[3]);
5499   if (Pmode != SImode)
5500     pat = gen_rtx_SUBREG (SImode, pat, 0);
5501   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5502   DONE;
5503 }
5504   [(set_attr "type" "lea")
5505    (set_attr "mode" "SI")])
5506
5507 (define_insn_and_split "*lea_general_2_zext"
5508   [(set (match_operand:DI 0 "register_operand" "=r")
5509         (zero_extend:DI
5510           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5511                             (match_operand:SI 2 "const248_operand" "n"))
5512                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5513   "TARGET_64BIT"
5514   "#"
5515   "&& reload_completed"
5516   [(set (match_dup 0)
5517         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5518                                                      (match_dup 2))
5519                                             (match_dup 3)) 0)))]
5520 {
5521   operands[1] = gen_lowpart (Pmode, operands[1]);
5522   operands[3] = gen_lowpart (Pmode, operands[3]);
5523 }
5524   [(set_attr "type" "lea")
5525    (set_attr "mode" "SI")])
5526
5527 (define_insn_and_split "*lea_general_3"
5528   [(set (match_operand 0 "register_operand" "=r")
5529         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5530                           (match_operand 2 "const248_operand" "i"))
5531                     (match_operand 3 "register_operand" "r"))
5532               (match_operand 4 "immediate_operand" "i")))]
5533   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5534     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5535    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5536    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5537    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5538   "#"
5539   "&& reload_completed"
5540   [(const_int 0)]
5541 {
5542   rtx pat;
5543   operands[0] = gen_lowpart (SImode, operands[0]);
5544   operands[1] = gen_lowpart (Pmode, operands[1]);
5545   operands[3] = gen_lowpart (Pmode, operands[3]);
5546   operands[4] = gen_lowpart (Pmode, operands[4]);
5547   pat = gen_rtx_PLUS (Pmode,
5548                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5549                                                          operands[2]),
5550                                     operands[3]),
5551                       operands[4]);
5552   if (Pmode != SImode)
5553     pat = gen_rtx_SUBREG (SImode, pat, 0);
5554   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5555   DONE;
5556 }
5557   [(set_attr "type" "lea")
5558    (set_attr "mode" "SI")])
5559
5560 (define_insn_and_split "*lea_general_3_zext"
5561   [(set (match_operand:DI 0 "register_operand" "=r")
5562         (zero_extend:DI
5563           (plus:SI (plus:SI (mult:SI
5564                               (match_operand:SI 1 "index_register_operand" "l")
5565                               (match_operand:SI 2 "const248_operand" "n"))
5566                             (match_operand:SI 3 "register_operand" "r"))
5567                    (match_operand:SI 4 "immediate_operand" "i"))))]
5568   "TARGET_64BIT"
5569   "#"
5570   "&& reload_completed"
5571   [(set (match_dup 0)
5572         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5573                                                               (match_dup 2))
5574                                                      (match_dup 3))
5575                                             (match_dup 4)) 0)))]
5576 {
5577   operands[1] = gen_lowpart (Pmode, operands[1]);
5578   operands[3] = gen_lowpart (Pmode, operands[3]);
5579   operands[4] = gen_lowpart (Pmode, operands[4]);
5580 }
5581   [(set_attr "type" "lea")
5582    (set_attr "mode" "SI")])
5583
5584 (define_insn "*adddi_1_rex64"
5585   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5586         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5587                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5588    (clobber (reg:CC FLAGS_REG))]
5589   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5590 {
5591   switch (get_attr_type (insn))
5592     {
5593     case TYPE_LEA:
5594       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5595       return "lea{q}\t{%a2, %0|%0, %a2}";
5596
5597     case TYPE_INCDEC:
5598       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5599       if (operands[2] == const1_rtx)
5600         return "inc{q}\t%0";
5601       else
5602         {
5603           gcc_assert (operands[2] == constm1_rtx);
5604           return "dec{q}\t%0";
5605         }
5606
5607     default:
5608       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5609
5610       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5611          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5612       if (CONST_INT_P (operands[2])
5613           /* Avoid overflows.  */
5614           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5615           && (INTVAL (operands[2]) == 128
5616               || (INTVAL (operands[2]) < 0
5617                   && INTVAL (operands[2]) != -128)))
5618         {
5619           operands[2] = GEN_INT (-INTVAL (operands[2]));
5620           return "sub{q}\t{%2, %0|%0, %2}";
5621         }
5622       return "add{q}\t{%2, %0|%0, %2}";
5623     }
5624 }
5625   [(set (attr "type")
5626      (cond [(eq_attr "alternative" "2")
5627               (const_string "lea")
5628             ; Current assemblers are broken and do not allow @GOTOFF in
5629             ; ought but a memory context.
5630             (match_operand:DI 2 "pic_symbolic_operand" "")
5631               (const_string "lea")
5632             (match_operand:DI 2 "incdec_operand" "")
5633               (const_string "incdec")
5634            ]
5635            (const_string "alu")))
5636    (set_attr "mode" "DI")])
5637
5638 ;; Convert lea to the lea pattern to avoid flags dependency.
5639 (define_split
5640   [(set (match_operand:DI 0 "register_operand" "")
5641         (plus:DI (match_operand:DI 1 "register_operand" "")
5642                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5643    (clobber (reg:CC FLAGS_REG))]
5644   "TARGET_64BIT && reload_completed
5645    && true_regnum (operands[0]) != true_regnum (operands[1])"
5646   [(set (match_dup 0)
5647         (plus:DI (match_dup 1)
5648                  (match_dup 2)))]
5649   "")
5650
5651 (define_insn "*adddi_2_rex64"
5652   [(set (reg FLAGS_REG)
5653         (compare
5654           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5655                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5656           (const_int 0)))
5657    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5658         (plus:DI (match_dup 1) (match_dup 2)))]
5659   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5660    && ix86_binary_operator_ok (PLUS, DImode, operands)
5661    /* Current assemblers are broken and do not allow @GOTOFF in
5662       ought but a memory context.  */
5663    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5664 {
5665   switch (get_attr_type (insn))
5666     {
5667     case TYPE_INCDEC:
5668       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5669       if (operands[2] == const1_rtx)
5670         return "inc{q}\t%0";
5671       else
5672         {
5673           gcc_assert (operands[2] == constm1_rtx);
5674           return "dec{q}\t%0";
5675         }
5676
5677     default:
5678       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5679       /* ???? We ought to handle there the 32bit case too
5680          - do we need new constraint?  */
5681       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5682          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5683       if (CONST_INT_P (operands[2])
5684           /* Avoid overflows.  */
5685           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5686           && (INTVAL (operands[2]) == 128
5687               || (INTVAL (operands[2]) < 0
5688                   && INTVAL (operands[2]) != -128)))
5689         {
5690           operands[2] = GEN_INT (-INTVAL (operands[2]));
5691           return "sub{q}\t{%2, %0|%0, %2}";
5692         }
5693       return "add{q}\t{%2, %0|%0, %2}";
5694     }
5695 }
5696   [(set (attr "type")
5697      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5698         (const_string "incdec")
5699         (const_string "alu")))
5700    (set_attr "mode" "DI")])
5701
5702 (define_insn "*adddi_3_rex64"
5703   [(set (reg FLAGS_REG)
5704         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5705                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5706    (clobber (match_scratch:DI 0 "=r"))]
5707   "TARGET_64BIT
5708    && ix86_match_ccmode (insn, CCZmode)
5709    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5710    /* Current assemblers are broken and do not allow @GOTOFF in
5711       ought but a memory context.  */
5712    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5713 {
5714   switch (get_attr_type (insn))
5715     {
5716     case TYPE_INCDEC:
5717       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5718       if (operands[2] == const1_rtx)
5719         return "inc{q}\t%0";
5720       else
5721         {
5722           gcc_assert (operands[2] == constm1_rtx);
5723           return "dec{q}\t%0";
5724         }
5725
5726     default:
5727       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5728       /* ???? We ought to handle there the 32bit case too
5729          - do we need new constraint?  */
5730       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5731          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5732       if (CONST_INT_P (operands[2])
5733           /* Avoid overflows.  */
5734           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5735           && (INTVAL (operands[2]) == 128
5736               || (INTVAL (operands[2]) < 0
5737                   && INTVAL (operands[2]) != -128)))
5738         {
5739           operands[2] = GEN_INT (-INTVAL (operands[2]));
5740           return "sub{q}\t{%2, %0|%0, %2}";
5741         }
5742       return "add{q}\t{%2, %0|%0, %2}";
5743     }
5744 }
5745   [(set (attr "type")
5746      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5747         (const_string "incdec")
5748         (const_string "alu")))
5749    (set_attr "mode" "DI")])
5750
5751 ; For comparisons against 1, -1 and 128, we may generate better code
5752 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5753 ; is matched then.  We can't accept general immediate, because for
5754 ; case of overflows,  the result is messed up.
5755 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5756 ; when negated.
5757 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5758 ; only for comparisons not depending on it.
5759 (define_insn "*adddi_4_rex64"
5760   [(set (reg FLAGS_REG)
5761         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5762                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5763    (clobber (match_scratch:DI 0 "=rm"))]
5764   "TARGET_64BIT
5765    &&  ix86_match_ccmode (insn, CCGCmode)"
5766 {
5767   switch (get_attr_type (insn))
5768     {
5769     case TYPE_INCDEC:
5770       if (operands[2] == constm1_rtx)
5771         return "inc{q}\t%0";
5772       else
5773         {
5774           gcc_assert (operands[2] == const1_rtx);
5775           return "dec{q}\t%0";
5776         }
5777
5778     default:
5779       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5780       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5781          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5782       if ((INTVAL (operands[2]) == -128
5783            || (INTVAL (operands[2]) > 0
5784                && INTVAL (operands[2]) != 128))
5785           /* Avoid overflows.  */
5786           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5787         return "sub{q}\t{%2, %0|%0, %2}";
5788       operands[2] = GEN_INT (-INTVAL (operands[2]));
5789       return "add{q}\t{%2, %0|%0, %2}";
5790     }
5791 }
5792   [(set (attr "type")
5793      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5794         (const_string "incdec")
5795         (const_string "alu")))
5796    (set_attr "mode" "DI")])
5797
5798 (define_insn "*adddi_5_rex64"
5799   [(set (reg FLAGS_REG)
5800         (compare
5801           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5802                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5803           (const_int 0)))
5804    (clobber (match_scratch:DI 0 "=r"))]
5805   "TARGET_64BIT
5806    && ix86_match_ccmode (insn, CCGOCmode)
5807    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5808    /* Current assemblers are broken and do not allow @GOTOFF in
5809       ought but a memory context.  */
5810    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5811 {
5812   switch (get_attr_type (insn))
5813     {
5814     case TYPE_INCDEC:
5815       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5816       if (operands[2] == const1_rtx)
5817         return "inc{q}\t%0";
5818       else
5819         {
5820           gcc_assert (operands[2] == constm1_rtx);
5821           return "dec{q}\t%0";
5822         }
5823
5824     default:
5825       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5826       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5827          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5828       if (CONST_INT_P (operands[2])
5829           /* Avoid overflows.  */
5830           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5831           && (INTVAL (operands[2]) == 128
5832               || (INTVAL (operands[2]) < 0
5833                   && INTVAL (operands[2]) != -128)))
5834         {
5835           operands[2] = GEN_INT (-INTVAL (operands[2]));
5836           return "sub{q}\t{%2, %0|%0, %2}";
5837         }
5838       return "add{q}\t{%2, %0|%0, %2}";
5839     }
5840 }
5841   [(set (attr "type")
5842      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5843         (const_string "incdec")
5844         (const_string "alu")))
5845    (set_attr "mode" "DI")])
5846
5847
5848 (define_insn "*addsi_1"
5849   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5850         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5851                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5852    (clobber (reg:CC FLAGS_REG))]
5853   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5854 {
5855   switch (get_attr_type (insn))
5856     {
5857     case TYPE_LEA:
5858       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5859       return "lea{l}\t{%a2, %0|%0, %a2}";
5860
5861     case TYPE_INCDEC:
5862       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5863       if (operands[2] == const1_rtx)
5864         return "inc{l}\t%0";
5865       else
5866         {
5867           gcc_assert (operands[2] == constm1_rtx);
5868           return "dec{l}\t%0";
5869         }
5870
5871     default:
5872       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5873
5874       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5875          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5876       if (CONST_INT_P (operands[2])
5877           && (INTVAL (operands[2]) == 128
5878               || (INTVAL (operands[2]) < 0
5879                   && INTVAL (operands[2]) != -128)))
5880         {
5881           operands[2] = GEN_INT (-INTVAL (operands[2]));
5882           return "sub{l}\t{%2, %0|%0, %2}";
5883         }
5884       return "add{l}\t{%2, %0|%0, %2}";
5885     }
5886 }
5887   [(set (attr "type")
5888      (cond [(eq_attr "alternative" "2")
5889               (const_string "lea")
5890             ; Current assemblers are broken and do not allow @GOTOFF in
5891             ; ought but a memory context.
5892             (match_operand:SI 2 "pic_symbolic_operand" "")
5893               (const_string "lea")
5894             (match_operand:SI 2 "incdec_operand" "")
5895               (const_string "incdec")
5896            ]
5897            (const_string "alu")))
5898    (set_attr "mode" "SI")])
5899
5900 ;; Convert lea to the lea pattern to avoid flags dependency.
5901 (define_split
5902   [(set (match_operand 0 "register_operand" "")
5903         (plus (match_operand 1 "register_operand" "")
5904               (match_operand 2 "nonmemory_operand" "")))
5905    (clobber (reg:CC FLAGS_REG))]
5906   "reload_completed
5907    && true_regnum (operands[0]) != true_regnum (operands[1])"
5908   [(const_int 0)]
5909 {
5910   rtx pat;
5911   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5912      may confuse gen_lowpart.  */
5913   if (GET_MODE (operands[0]) != Pmode)
5914     {
5915       operands[1] = gen_lowpart (Pmode, operands[1]);
5916       operands[2] = gen_lowpart (Pmode, operands[2]);
5917     }
5918   operands[0] = gen_lowpart (SImode, operands[0]);
5919   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5920   if (Pmode != SImode)
5921     pat = gen_rtx_SUBREG (SImode, pat, 0);
5922   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5923   DONE;
5924 })
5925
5926 ;; It may seem that nonimmediate operand is proper one for operand 1.
5927 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5928 ;; we take care in ix86_binary_operator_ok to not allow two memory
5929 ;; operands so proper swapping will be done in reload.  This allow
5930 ;; patterns constructed from addsi_1 to match.
5931 (define_insn "addsi_1_zext"
5932   [(set (match_operand:DI 0 "register_operand" "=r,r")
5933         (zero_extend:DI
5934           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5935                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5936    (clobber (reg:CC FLAGS_REG))]
5937   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5938 {
5939   switch (get_attr_type (insn))
5940     {
5941     case TYPE_LEA:
5942       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5943       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5944
5945     case TYPE_INCDEC:
5946       if (operands[2] == const1_rtx)
5947         return "inc{l}\t%k0";
5948       else
5949         {
5950           gcc_assert (operands[2] == constm1_rtx);
5951           return "dec{l}\t%k0";
5952         }
5953
5954     default:
5955       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5956          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5957       if (CONST_INT_P (operands[2])
5958           && (INTVAL (operands[2]) == 128
5959               || (INTVAL (operands[2]) < 0
5960                   && INTVAL (operands[2]) != -128)))
5961         {
5962           operands[2] = GEN_INT (-INTVAL (operands[2]));
5963           return "sub{l}\t{%2, %k0|%k0, %2}";
5964         }
5965       return "add{l}\t{%2, %k0|%k0, %2}";
5966     }
5967 }
5968   [(set (attr "type")
5969      (cond [(eq_attr "alternative" "1")
5970               (const_string "lea")
5971             ; Current assemblers are broken and do not allow @GOTOFF in
5972             ; ought but a memory context.
5973             (match_operand:SI 2 "pic_symbolic_operand" "")
5974               (const_string "lea")
5975             (match_operand:SI 2 "incdec_operand" "")
5976               (const_string "incdec")
5977            ]
5978            (const_string "alu")))
5979    (set_attr "mode" "SI")])
5980
5981 ;; Convert lea to the lea pattern to avoid flags dependency.
5982 (define_split
5983   [(set (match_operand:DI 0 "register_operand" "")
5984         (zero_extend:DI
5985           (plus:SI (match_operand:SI 1 "register_operand" "")
5986                    (match_operand:SI 2 "nonmemory_operand" ""))))
5987    (clobber (reg:CC FLAGS_REG))]
5988   "TARGET_64BIT && reload_completed
5989    && true_regnum (operands[0]) != true_regnum (operands[1])"
5990   [(set (match_dup 0)
5991         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5992 {
5993   operands[1] = gen_lowpart (Pmode, operands[1]);
5994   operands[2] = gen_lowpart (Pmode, operands[2]);
5995 })
5996
5997 (define_insn "*addsi_2"
5998   [(set (reg FLAGS_REG)
5999         (compare
6000           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6001                    (match_operand:SI 2 "general_operand" "rmni,rni"))
6002           (const_int 0)))
6003    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6004         (plus:SI (match_dup 1) (match_dup 2)))]
6005   "ix86_match_ccmode (insn, CCGOCmode)
6006    && ix86_binary_operator_ok (PLUS, SImode, operands)
6007    /* Current assemblers are broken and do not allow @GOTOFF in
6008       ought but a memory context.  */
6009    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6010 {
6011   switch (get_attr_type (insn))
6012     {
6013     case TYPE_INCDEC:
6014       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6015       if (operands[2] == const1_rtx)
6016         return "inc{l}\t%0";
6017       else
6018         {
6019           gcc_assert (operands[2] == constm1_rtx);
6020           return "dec{l}\t%0";
6021         }
6022
6023     default:
6024       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6025       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6026          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6027       if (CONST_INT_P (operands[2])
6028           && (INTVAL (operands[2]) == 128
6029               || (INTVAL (operands[2]) < 0
6030                   && INTVAL (operands[2]) != -128)))
6031         {
6032           operands[2] = GEN_INT (-INTVAL (operands[2]));
6033           return "sub{l}\t{%2, %0|%0, %2}";
6034         }
6035       return "add{l}\t{%2, %0|%0, %2}";
6036     }
6037 }
6038   [(set (attr "type")
6039      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6040         (const_string "incdec")
6041         (const_string "alu")))
6042    (set_attr "mode" "SI")])
6043
6044 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6045 (define_insn "*addsi_2_zext"
6046   [(set (reg FLAGS_REG)
6047         (compare
6048           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6049                    (match_operand:SI 2 "general_operand" "rmni"))
6050           (const_int 0)))
6051    (set (match_operand:DI 0 "register_operand" "=r")
6052         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6053   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6054    && ix86_binary_operator_ok (PLUS, SImode, operands)
6055    /* Current assemblers are broken and do not allow @GOTOFF in
6056       ought but a memory context.  */
6057    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6058 {
6059   switch (get_attr_type (insn))
6060     {
6061     case TYPE_INCDEC:
6062       if (operands[2] == const1_rtx)
6063         return "inc{l}\t%k0";
6064       else
6065         {
6066           gcc_assert (operands[2] == constm1_rtx);
6067           return "dec{l}\t%k0";
6068         }
6069
6070     default:
6071       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6072          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6073       if (CONST_INT_P (operands[2])
6074           && (INTVAL (operands[2]) == 128
6075               || (INTVAL (operands[2]) < 0
6076                   && INTVAL (operands[2]) != -128)))
6077         {
6078           operands[2] = GEN_INT (-INTVAL (operands[2]));
6079           return "sub{l}\t{%2, %k0|%k0, %2}";
6080         }
6081       return "add{l}\t{%2, %k0|%k0, %2}";
6082     }
6083 }
6084   [(set (attr "type")
6085      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6086         (const_string "incdec")
6087         (const_string "alu")))
6088    (set_attr "mode" "SI")])
6089
6090 (define_insn "*addsi_3"
6091   [(set (reg FLAGS_REG)
6092         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6093                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6094    (clobber (match_scratch:SI 0 "=r"))]
6095   "ix86_match_ccmode (insn, CCZmode)
6096    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6097    /* Current assemblers are broken and do not allow @GOTOFF in
6098       ought but a memory context.  */
6099    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6100 {
6101   switch (get_attr_type (insn))
6102     {
6103     case TYPE_INCDEC:
6104       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6105       if (operands[2] == const1_rtx)
6106         return "inc{l}\t%0";
6107       else
6108         {
6109           gcc_assert (operands[2] == constm1_rtx);
6110           return "dec{l}\t%0";
6111         }
6112
6113     default:
6114       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6115       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6116          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6117       if (CONST_INT_P (operands[2])
6118           && (INTVAL (operands[2]) == 128
6119               || (INTVAL (operands[2]) < 0
6120                   && INTVAL (operands[2]) != -128)))
6121         {
6122           operands[2] = GEN_INT (-INTVAL (operands[2]));
6123           return "sub{l}\t{%2, %0|%0, %2}";
6124         }
6125       return "add{l}\t{%2, %0|%0, %2}";
6126     }
6127 }
6128   [(set (attr "type")
6129      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6130         (const_string "incdec")
6131         (const_string "alu")))
6132    (set_attr "mode" "SI")])
6133
6134 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6135 (define_insn "*addsi_3_zext"
6136   [(set (reg FLAGS_REG)
6137         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6138                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6139    (set (match_operand:DI 0 "register_operand" "=r")
6140         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6141   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6142    && ix86_binary_operator_ok (PLUS, SImode, operands)
6143    /* Current assemblers are broken and do not allow @GOTOFF in
6144       ought but a memory context.  */
6145    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6146 {
6147   switch (get_attr_type (insn))
6148     {
6149     case TYPE_INCDEC:
6150       if (operands[2] == const1_rtx)
6151         return "inc{l}\t%k0";
6152       else
6153         {
6154           gcc_assert (operands[2] == constm1_rtx);
6155           return "dec{l}\t%k0";
6156         }
6157
6158     default:
6159       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6160          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6161       if (CONST_INT_P (operands[2])
6162           && (INTVAL (operands[2]) == 128
6163               || (INTVAL (operands[2]) < 0
6164                   && INTVAL (operands[2]) != -128)))
6165         {
6166           operands[2] = GEN_INT (-INTVAL (operands[2]));
6167           return "sub{l}\t{%2, %k0|%k0, %2}";
6168         }
6169       return "add{l}\t{%2, %k0|%k0, %2}";
6170     }
6171 }
6172   [(set (attr "type")
6173      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6174         (const_string "incdec")
6175         (const_string "alu")))
6176    (set_attr "mode" "SI")])
6177
6178 ; For comparisons against 1, -1 and 128, we may generate better code
6179 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6180 ; is matched then.  We can't accept general immediate, because for
6181 ; case of overflows,  the result is messed up.
6182 ; This pattern also don't hold of 0x80000000, since the value overflows
6183 ; when negated.
6184 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6185 ; only for comparisons not depending on it.
6186 (define_insn "*addsi_4"
6187   [(set (reg FLAGS_REG)
6188         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6189                  (match_operand:SI 2 "const_int_operand" "n")))
6190    (clobber (match_scratch:SI 0 "=rm"))]
6191   "ix86_match_ccmode (insn, CCGCmode)
6192    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6193 {
6194   switch (get_attr_type (insn))
6195     {
6196     case TYPE_INCDEC:
6197       if (operands[2] == constm1_rtx)
6198         return "inc{l}\t%0";
6199       else
6200         {
6201           gcc_assert (operands[2] == const1_rtx);
6202           return "dec{l}\t%0";
6203         }
6204
6205     default:
6206       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6207       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6208          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6209       if ((INTVAL (operands[2]) == -128
6210            || (INTVAL (operands[2]) > 0
6211                && INTVAL (operands[2]) != 128)))
6212         return "sub{l}\t{%2, %0|%0, %2}";
6213       operands[2] = GEN_INT (-INTVAL (operands[2]));
6214       return "add{l}\t{%2, %0|%0, %2}";
6215     }
6216 }
6217   [(set (attr "type")
6218      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6219         (const_string "incdec")
6220         (const_string "alu")))
6221    (set_attr "mode" "SI")])
6222
6223 (define_insn "*addsi_5"
6224   [(set (reg FLAGS_REG)
6225         (compare
6226           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6227                    (match_operand:SI 2 "general_operand" "rmni"))
6228           (const_int 0)))
6229    (clobber (match_scratch:SI 0 "=r"))]
6230   "ix86_match_ccmode (insn, CCGOCmode)
6231    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6232    /* Current assemblers are broken and do not allow @GOTOFF in
6233       ought but a memory context.  */
6234    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6235 {
6236   switch (get_attr_type (insn))
6237     {
6238     case TYPE_INCDEC:
6239       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6240       if (operands[2] == const1_rtx)
6241         return "inc{l}\t%0";
6242       else
6243         {
6244           gcc_assert (operands[2] == constm1_rtx);
6245           return "dec{l}\t%0";
6246         }
6247
6248     default:
6249       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6250       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6251          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6252       if (CONST_INT_P (operands[2])
6253           && (INTVAL (operands[2]) == 128
6254               || (INTVAL (operands[2]) < 0
6255                   && INTVAL (operands[2]) != -128)))
6256         {
6257           operands[2] = GEN_INT (-INTVAL (operands[2]));
6258           return "sub{l}\t{%2, %0|%0, %2}";
6259         }
6260       return "add{l}\t{%2, %0|%0, %2}";
6261     }
6262 }
6263   [(set (attr "type")
6264      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6265         (const_string "incdec")
6266         (const_string "alu")))
6267    (set_attr "mode" "SI")])
6268
6269 (define_expand "addhi3"
6270   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6271                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6272                             (match_operand:HI 2 "general_operand" "")))
6273               (clobber (reg:CC FLAGS_REG))])]
6274   "TARGET_HIMODE_MATH"
6275   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6276
6277 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6278 ;; type optimizations enabled by define-splits.  This is not important
6279 ;; for PII, and in fact harmful because of partial register stalls.
6280
6281 (define_insn "*addhi_1_lea"
6282   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6283         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6284                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6285    (clobber (reg:CC FLAGS_REG))]
6286   "!TARGET_PARTIAL_REG_STALL
6287    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6288 {
6289   switch (get_attr_type (insn))
6290     {
6291     case TYPE_LEA:
6292       return "#";
6293     case TYPE_INCDEC:
6294       if (operands[2] == const1_rtx)
6295         return "inc{w}\t%0";
6296       else
6297         {
6298           gcc_assert (operands[2] == constm1_rtx);
6299           return "dec{w}\t%0";
6300         }
6301
6302     default:
6303       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6304          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6305       if (CONST_INT_P (operands[2])
6306           && (INTVAL (operands[2]) == 128
6307               || (INTVAL (operands[2]) < 0
6308                   && INTVAL (operands[2]) != -128)))
6309         {
6310           operands[2] = GEN_INT (-INTVAL (operands[2]));
6311           return "sub{w}\t{%2, %0|%0, %2}";
6312         }
6313       return "add{w}\t{%2, %0|%0, %2}";
6314     }
6315 }
6316   [(set (attr "type")
6317      (if_then_else (eq_attr "alternative" "2")
6318         (const_string "lea")
6319         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6320            (const_string "incdec")
6321            (const_string "alu"))))
6322    (set_attr "mode" "HI,HI,SI")])
6323
6324 (define_insn "*addhi_1"
6325   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6326         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6327                  (match_operand:HI 2 "general_operand" "ri,rm")))
6328    (clobber (reg:CC FLAGS_REG))]
6329   "TARGET_PARTIAL_REG_STALL
6330    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6331 {
6332   switch (get_attr_type (insn))
6333     {
6334     case TYPE_INCDEC:
6335       if (operands[2] == const1_rtx)
6336         return "inc{w}\t%0";
6337       else
6338         {
6339           gcc_assert (operands[2] == constm1_rtx);
6340           return "dec{w}\t%0";
6341         }
6342
6343     default:
6344       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6345          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6346       if (CONST_INT_P (operands[2])
6347           && (INTVAL (operands[2]) == 128
6348               || (INTVAL (operands[2]) < 0
6349                   && INTVAL (operands[2]) != -128)))
6350         {
6351           operands[2] = GEN_INT (-INTVAL (operands[2]));
6352           return "sub{w}\t{%2, %0|%0, %2}";
6353         }
6354       return "add{w}\t{%2, %0|%0, %2}";
6355     }
6356 }
6357   [(set (attr "type")
6358      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6359         (const_string "incdec")
6360         (const_string "alu")))
6361    (set_attr "mode" "HI")])
6362
6363 (define_insn "*addhi_2"
6364   [(set (reg FLAGS_REG)
6365         (compare
6366           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6367                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6368           (const_int 0)))
6369    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6370         (plus:HI (match_dup 1) (match_dup 2)))]
6371   "ix86_match_ccmode (insn, CCGOCmode)
6372    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6373 {
6374   switch (get_attr_type (insn))
6375     {
6376     case TYPE_INCDEC:
6377       if (operands[2] == const1_rtx)
6378         return "inc{w}\t%0";
6379       else
6380         {
6381           gcc_assert (operands[2] == constm1_rtx);
6382           return "dec{w}\t%0";
6383         }
6384
6385     default:
6386       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6387          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6388       if (CONST_INT_P (operands[2])
6389           && (INTVAL (operands[2]) == 128
6390               || (INTVAL (operands[2]) < 0
6391                   && INTVAL (operands[2]) != -128)))
6392         {
6393           operands[2] = GEN_INT (-INTVAL (operands[2]));
6394           return "sub{w}\t{%2, %0|%0, %2}";
6395         }
6396       return "add{w}\t{%2, %0|%0, %2}";
6397     }
6398 }
6399   [(set (attr "type")
6400      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6401         (const_string "incdec")
6402         (const_string "alu")))
6403    (set_attr "mode" "HI")])
6404
6405 (define_insn "*addhi_3"
6406   [(set (reg FLAGS_REG)
6407         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6408                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6409    (clobber (match_scratch:HI 0 "=r"))]
6410   "ix86_match_ccmode (insn, CCZmode)
6411    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6412 {
6413   switch (get_attr_type (insn))
6414     {
6415     case TYPE_INCDEC:
6416       if (operands[2] == const1_rtx)
6417         return "inc{w}\t%0";
6418       else
6419         {
6420           gcc_assert (operands[2] == constm1_rtx);
6421           return "dec{w}\t%0";
6422         }
6423
6424     default:
6425       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6426          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6427       if (CONST_INT_P (operands[2])
6428           && (INTVAL (operands[2]) == 128
6429               || (INTVAL (operands[2]) < 0
6430                   && INTVAL (operands[2]) != -128)))
6431         {
6432           operands[2] = GEN_INT (-INTVAL (operands[2]));
6433           return "sub{w}\t{%2, %0|%0, %2}";
6434         }
6435       return "add{w}\t{%2, %0|%0, %2}";
6436     }
6437 }
6438   [(set (attr "type")
6439      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6440         (const_string "incdec")
6441         (const_string "alu")))
6442    (set_attr "mode" "HI")])
6443
6444 ; See comments above addsi_4 for details.
6445 (define_insn "*addhi_4"
6446   [(set (reg FLAGS_REG)
6447         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6448                  (match_operand:HI 2 "const_int_operand" "n")))
6449    (clobber (match_scratch:HI 0 "=rm"))]
6450   "ix86_match_ccmode (insn, CCGCmode)
6451    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6452 {
6453   switch (get_attr_type (insn))
6454     {
6455     case TYPE_INCDEC:
6456       if (operands[2] == constm1_rtx)
6457         return "inc{w}\t%0";
6458       else
6459         {
6460           gcc_assert (operands[2] == const1_rtx);
6461           return "dec{w}\t%0";
6462         }
6463
6464     default:
6465       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6466       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6467          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6468       if ((INTVAL (operands[2]) == -128
6469            || (INTVAL (operands[2]) > 0
6470                && INTVAL (operands[2]) != 128)))
6471         return "sub{w}\t{%2, %0|%0, %2}";
6472       operands[2] = GEN_INT (-INTVAL (operands[2]));
6473       return "add{w}\t{%2, %0|%0, %2}";
6474     }
6475 }
6476   [(set (attr "type")
6477      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6478         (const_string "incdec")
6479         (const_string "alu")))
6480    (set_attr "mode" "SI")])
6481
6482
6483 (define_insn "*addhi_5"
6484   [(set (reg FLAGS_REG)
6485         (compare
6486           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6487                    (match_operand:HI 2 "general_operand" "rmni"))
6488           (const_int 0)))
6489    (clobber (match_scratch:HI 0 "=r"))]
6490   "ix86_match_ccmode (insn, CCGOCmode)
6491    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6492 {
6493   switch (get_attr_type (insn))
6494     {
6495     case TYPE_INCDEC:
6496       if (operands[2] == const1_rtx)
6497         return "inc{w}\t%0";
6498       else
6499         {
6500           gcc_assert (operands[2] == constm1_rtx);
6501           return "dec{w}\t%0";
6502         }
6503
6504     default:
6505       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6506          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6507       if (CONST_INT_P (operands[2])
6508           && (INTVAL (operands[2]) == 128
6509               || (INTVAL (operands[2]) < 0
6510                   && INTVAL (operands[2]) != -128)))
6511         {
6512           operands[2] = GEN_INT (-INTVAL (operands[2]));
6513           return "sub{w}\t{%2, %0|%0, %2}";
6514         }
6515       return "add{w}\t{%2, %0|%0, %2}";
6516     }
6517 }
6518   [(set (attr "type")
6519      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6520         (const_string "incdec")
6521         (const_string "alu")))
6522    (set_attr "mode" "HI")])
6523
6524 (define_expand "addqi3"
6525   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6526                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6527                             (match_operand:QI 2 "general_operand" "")))
6528               (clobber (reg:CC FLAGS_REG))])]
6529   "TARGET_QIMODE_MATH"
6530   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6531
6532 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6533 (define_insn "*addqi_1_lea"
6534   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6535         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6536                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6537    (clobber (reg:CC FLAGS_REG))]
6538   "!TARGET_PARTIAL_REG_STALL
6539    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6540 {
6541   int widen = (which_alternative == 2);
6542   switch (get_attr_type (insn))
6543     {
6544     case TYPE_LEA:
6545       return "#";
6546     case TYPE_INCDEC:
6547       if (operands[2] == const1_rtx)
6548         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6549       else
6550         {
6551           gcc_assert (operands[2] == constm1_rtx);
6552           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6553         }
6554
6555     default:
6556       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6557          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6558       if (CONST_INT_P (operands[2])
6559           && (INTVAL (operands[2]) == 128
6560               || (INTVAL (operands[2]) < 0
6561                   && INTVAL (operands[2]) != -128)))
6562         {
6563           operands[2] = GEN_INT (-INTVAL (operands[2]));
6564           if (widen)
6565             return "sub{l}\t{%2, %k0|%k0, %2}";
6566           else
6567             return "sub{b}\t{%2, %0|%0, %2}";
6568         }
6569       if (widen)
6570         return "add{l}\t{%k2, %k0|%k0, %k2}";
6571       else
6572         return "add{b}\t{%2, %0|%0, %2}";
6573     }
6574 }
6575   [(set (attr "type")
6576      (if_then_else (eq_attr "alternative" "3")
6577         (const_string "lea")
6578         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6579            (const_string "incdec")
6580            (const_string "alu"))))
6581    (set_attr "mode" "QI,QI,SI,SI")])
6582
6583 (define_insn "*addqi_1"
6584   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6585         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6586                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6587    (clobber (reg:CC FLAGS_REG))]
6588   "TARGET_PARTIAL_REG_STALL
6589    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6590 {
6591   int widen = (which_alternative == 2);
6592   switch (get_attr_type (insn))
6593     {
6594     case TYPE_INCDEC:
6595       if (operands[2] == const1_rtx)
6596         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6597       else
6598         {
6599           gcc_assert (operands[2] == constm1_rtx);
6600           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6601         }
6602
6603     default:
6604       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6605          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6606       if (CONST_INT_P (operands[2])
6607           && (INTVAL (operands[2]) == 128
6608               || (INTVAL (operands[2]) < 0
6609                   && INTVAL (operands[2]) != -128)))
6610         {
6611           operands[2] = GEN_INT (-INTVAL (operands[2]));
6612           if (widen)
6613             return "sub{l}\t{%2, %k0|%k0, %2}";
6614           else
6615             return "sub{b}\t{%2, %0|%0, %2}";
6616         }
6617       if (widen)
6618         return "add{l}\t{%k2, %k0|%k0, %k2}";
6619       else
6620         return "add{b}\t{%2, %0|%0, %2}";
6621     }
6622 }
6623   [(set (attr "type")
6624      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6625         (const_string "incdec")
6626         (const_string "alu")))
6627    (set_attr "mode" "QI,QI,SI")])
6628
6629 (define_insn "*addqi_1_slp"
6630   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6631         (plus:QI (match_dup 0)
6632                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6633    (clobber (reg:CC FLAGS_REG))]
6634   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6635    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6636 {
6637   switch (get_attr_type (insn))
6638     {
6639     case TYPE_INCDEC:
6640       if (operands[1] == const1_rtx)
6641         return "inc{b}\t%0";
6642       else
6643         {
6644           gcc_assert (operands[1] == constm1_rtx);
6645           return "dec{b}\t%0";
6646         }
6647
6648     default:
6649       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6650       if (CONST_INT_P (operands[1])
6651           && INTVAL (operands[1]) < 0)
6652         {
6653           operands[1] = GEN_INT (-INTVAL (operands[1]));
6654           return "sub{b}\t{%1, %0|%0, %1}";
6655         }
6656       return "add{b}\t{%1, %0|%0, %1}";
6657     }
6658 }
6659   [(set (attr "type")
6660      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6661         (const_string "incdec")
6662         (const_string "alu1")))
6663    (set (attr "memory")
6664      (if_then_else (match_operand 1 "memory_operand" "")
6665         (const_string "load")
6666         (const_string "none")))
6667    (set_attr "mode" "QI")])
6668
6669 (define_insn "*addqi_2"
6670   [(set (reg FLAGS_REG)
6671         (compare
6672           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6673                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6674           (const_int 0)))
6675    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6676         (plus:QI (match_dup 1) (match_dup 2)))]
6677   "ix86_match_ccmode (insn, CCGOCmode)
6678    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6679 {
6680   switch (get_attr_type (insn))
6681     {
6682     case TYPE_INCDEC:
6683       if (operands[2] == const1_rtx)
6684         return "inc{b}\t%0";
6685       else
6686         {
6687           gcc_assert (operands[2] == constm1_rtx
6688                       || (CONST_INT_P (operands[2])
6689                           && INTVAL (operands[2]) == 255));
6690           return "dec{b}\t%0";
6691         }
6692
6693     default:
6694       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6695       if (CONST_INT_P (operands[2])
6696           && INTVAL (operands[2]) < 0)
6697         {
6698           operands[2] = GEN_INT (-INTVAL (operands[2]));
6699           return "sub{b}\t{%2, %0|%0, %2}";
6700         }
6701       return "add{b}\t{%2, %0|%0, %2}";
6702     }
6703 }
6704   [(set (attr "type")
6705      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6706         (const_string "incdec")
6707         (const_string "alu")))
6708    (set_attr "mode" "QI")])
6709
6710 (define_insn "*addqi_3"
6711   [(set (reg FLAGS_REG)
6712         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6713                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6714    (clobber (match_scratch:QI 0 "=q"))]
6715   "ix86_match_ccmode (insn, CCZmode)
6716    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6717 {
6718   switch (get_attr_type (insn))
6719     {
6720     case TYPE_INCDEC:
6721       if (operands[2] == const1_rtx)
6722         return "inc{b}\t%0";
6723       else
6724         {
6725           gcc_assert (operands[2] == constm1_rtx
6726                       || (CONST_INT_P (operands[2])
6727                           && INTVAL (operands[2]) == 255));
6728           return "dec{b}\t%0";
6729         }
6730
6731     default:
6732       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6733       if (CONST_INT_P (operands[2])
6734           && INTVAL (operands[2]) < 0)
6735         {
6736           operands[2] = GEN_INT (-INTVAL (operands[2]));
6737           return "sub{b}\t{%2, %0|%0, %2}";
6738         }
6739       return "add{b}\t{%2, %0|%0, %2}";
6740     }
6741 }
6742   [(set (attr "type")
6743      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6744         (const_string "incdec")
6745         (const_string "alu")))
6746    (set_attr "mode" "QI")])
6747
6748 ; See comments above addsi_4 for details.
6749 (define_insn "*addqi_4"
6750   [(set (reg FLAGS_REG)
6751         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6752                  (match_operand:QI 2 "const_int_operand" "n")))
6753    (clobber (match_scratch:QI 0 "=qm"))]
6754   "ix86_match_ccmode (insn, CCGCmode)
6755    && (INTVAL (operands[2]) & 0xff) != 0x80"
6756 {
6757   switch (get_attr_type (insn))
6758     {
6759     case TYPE_INCDEC:
6760       if (operands[2] == constm1_rtx
6761           || (CONST_INT_P (operands[2])
6762               && INTVAL (operands[2]) == 255))
6763         return "inc{b}\t%0";
6764       else
6765         {
6766           gcc_assert (operands[2] == const1_rtx);
6767           return "dec{b}\t%0";
6768         }
6769
6770     default:
6771       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6772       if (INTVAL (operands[2]) < 0)
6773         {
6774           operands[2] = GEN_INT (-INTVAL (operands[2]));
6775           return "add{b}\t{%2, %0|%0, %2}";
6776         }
6777       return "sub{b}\t{%2, %0|%0, %2}";
6778     }
6779 }
6780   [(set (attr "type")
6781      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6782         (const_string "incdec")
6783         (const_string "alu")))
6784    (set_attr "mode" "QI")])
6785
6786
6787 (define_insn "*addqi_5"
6788   [(set (reg FLAGS_REG)
6789         (compare
6790           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6791                    (match_operand:QI 2 "general_operand" "qmni"))
6792           (const_int 0)))
6793    (clobber (match_scratch:QI 0 "=q"))]
6794   "ix86_match_ccmode (insn, CCGOCmode)
6795    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6796 {
6797   switch (get_attr_type (insn))
6798     {
6799     case TYPE_INCDEC:
6800       if (operands[2] == const1_rtx)
6801         return "inc{b}\t%0";
6802       else
6803         {
6804           gcc_assert (operands[2] == constm1_rtx
6805                       || (CONST_INT_P (operands[2])
6806                           && INTVAL (operands[2]) == 255));
6807           return "dec{b}\t%0";
6808         }
6809
6810     default:
6811       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6812       if (CONST_INT_P (operands[2])
6813           && INTVAL (operands[2]) < 0)
6814         {
6815           operands[2] = GEN_INT (-INTVAL (operands[2]));
6816           return "sub{b}\t{%2, %0|%0, %2}";
6817         }
6818       return "add{b}\t{%2, %0|%0, %2}";
6819     }
6820 }
6821   [(set (attr "type")
6822      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6823         (const_string "incdec")
6824         (const_string "alu")))
6825    (set_attr "mode" "QI")])
6826
6827
6828 (define_insn "addqi_ext_1"
6829   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6830                          (const_int 8)
6831                          (const_int 8))
6832         (plus:SI
6833           (zero_extract:SI
6834             (match_operand 1 "ext_register_operand" "0")
6835             (const_int 8)
6836             (const_int 8))
6837           (match_operand:QI 2 "general_operand" "Qmn")))
6838    (clobber (reg:CC FLAGS_REG))]
6839   "!TARGET_64BIT"
6840 {
6841   switch (get_attr_type (insn))
6842     {
6843     case TYPE_INCDEC:
6844       if (operands[2] == const1_rtx)
6845         return "inc{b}\t%h0";
6846       else
6847         {
6848           gcc_assert (operands[2] == constm1_rtx
6849                       || (CONST_INT_P (operands[2])
6850                           && INTVAL (operands[2]) == 255));
6851           return "dec{b}\t%h0";
6852         }
6853
6854     default:
6855       return "add{b}\t{%2, %h0|%h0, %2}";
6856     }
6857 }
6858   [(set (attr "type")
6859      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6860         (const_string "incdec")
6861         (const_string "alu")))
6862    (set_attr "mode" "QI")])
6863
6864 (define_insn "*addqi_ext_1_rex64"
6865   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6866                          (const_int 8)
6867                          (const_int 8))
6868         (plus:SI
6869           (zero_extract:SI
6870             (match_operand 1 "ext_register_operand" "0")
6871             (const_int 8)
6872             (const_int 8))
6873           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6874    (clobber (reg:CC FLAGS_REG))]
6875   "TARGET_64BIT"
6876 {
6877   switch (get_attr_type (insn))
6878     {
6879     case TYPE_INCDEC:
6880       if (operands[2] == const1_rtx)
6881         return "inc{b}\t%h0";
6882       else
6883         {
6884           gcc_assert (operands[2] == constm1_rtx
6885                       || (CONST_INT_P (operands[2])
6886                           && INTVAL (operands[2]) == 255));
6887           return "dec{b}\t%h0";
6888         }
6889
6890     default:
6891       return "add{b}\t{%2, %h0|%h0, %2}";
6892     }
6893 }
6894   [(set (attr "type")
6895      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6896         (const_string "incdec")
6897         (const_string "alu")))
6898    (set_attr "mode" "QI")])
6899
6900 (define_insn "*addqi_ext_2"
6901   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6902                          (const_int 8)
6903                          (const_int 8))
6904         (plus:SI
6905           (zero_extract:SI
6906             (match_operand 1 "ext_register_operand" "%0")
6907             (const_int 8)
6908             (const_int 8))
6909           (zero_extract:SI
6910             (match_operand 2 "ext_register_operand" "Q")
6911             (const_int 8)
6912             (const_int 8))))
6913    (clobber (reg:CC FLAGS_REG))]
6914   ""
6915   "add{b}\t{%h2, %h0|%h0, %h2}"
6916   [(set_attr "type" "alu")
6917    (set_attr "mode" "QI")])
6918
6919 ;; The patterns that match these are at the end of this file.
6920
6921 (define_expand "addxf3"
6922   [(set (match_operand:XF 0 "register_operand" "")
6923         (plus:XF (match_operand:XF 1 "register_operand" "")
6924                  (match_operand:XF 2 "register_operand" "")))]
6925   "TARGET_80387"
6926   "")
6927
6928 (define_expand "add<mode>3"
6929   [(set (match_operand:MODEF 0 "register_operand" "")
6930         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
6931                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6932   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6933   "")
6934 \f
6935 ;; Subtract instructions
6936
6937 ;; %%% splits for subditi3
6938
6939 (define_expand "subti3"
6940   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6941                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6942                              (match_operand:TI 2 "x86_64_general_operand" "")))
6943               (clobber (reg:CC FLAGS_REG))])]
6944   "TARGET_64BIT"
6945   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6946
6947 (define_insn "*subti3_1"
6948   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6949         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6950                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6951    (clobber (reg:CC FLAGS_REG))]
6952   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6953   "#")
6954
6955 (define_split
6956   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6957         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6958                   (match_operand:TI 2 "x86_64_general_operand" "")))
6959    (clobber (reg:CC FLAGS_REG))]
6960   "TARGET_64BIT && reload_completed"
6961   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6962               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6963    (parallel [(set (match_dup 3)
6964                    (minus:DI (match_dup 4)
6965                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6966                                       (match_dup 5))))
6967               (clobber (reg:CC FLAGS_REG))])]
6968   "split_ti (operands+0, 1, operands+0, operands+3);
6969    split_ti (operands+1, 1, operands+1, operands+4);
6970    split_ti (operands+2, 1, operands+2, operands+5);")
6971
6972 ;; %%% splits for subsidi3
6973
6974 (define_expand "subdi3"
6975   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6976                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6977                              (match_operand:DI 2 "x86_64_general_operand" "")))
6978               (clobber (reg:CC FLAGS_REG))])]
6979   ""
6980   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6981
6982 (define_insn "*subdi3_1"
6983   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6984         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6985                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6986    (clobber (reg:CC FLAGS_REG))]
6987   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6988   "#")
6989
6990 (define_split
6991   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6992         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6993                   (match_operand:DI 2 "general_operand" "")))
6994    (clobber (reg:CC FLAGS_REG))]
6995   "!TARGET_64BIT && reload_completed"
6996   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6997               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6998    (parallel [(set (match_dup 3)
6999                    (minus:SI (match_dup 4)
7000                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7001                                       (match_dup 5))))
7002               (clobber (reg:CC FLAGS_REG))])]
7003   "split_di (operands+0, 1, operands+0, operands+3);
7004    split_di (operands+1, 1, operands+1, operands+4);
7005    split_di (operands+2, 1, operands+2, operands+5);")
7006
7007 (define_insn "subdi3_carry_rex64"
7008   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7009           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7010             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7011                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7012    (clobber (reg:CC FLAGS_REG))]
7013   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7014   "sbb{q}\t{%2, %0|%0, %2}"
7015   [(set_attr "type" "alu")
7016    (set_attr "pent_pair" "pu")
7017    (set_attr "mode" "DI")])
7018
7019 (define_insn "*subdi_1_rex64"
7020   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7021         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7022                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7023    (clobber (reg:CC FLAGS_REG))]
7024   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7025   "sub{q}\t{%2, %0|%0, %2}"
7026   [(set_attr "type" "alu")
7027    (set_attr "mode" "DI")])
7028
7029 (define_insn "*subdi_2_rex64"
7030   [(set (reg FLAGS_REG)
7031         (compare
7032           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7033                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7034           (const_int 0)))
7035    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7036         (minus:DI (match_dup 1) (match_dup 2)))]
7037   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7038    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7039   "sub{q}\t{%2, %0|%0, %2}"
7040   [(set_attr "type" "alu")
7041    (set_attr "mode" "DI")])
7042
7043 (define_insn "*subdi_3_rex63"
7044   [(set (reg FLAGS_REG)
7045         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7046                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7047    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7048         (minus:DI (match_dup 1) (match_dup 2)))]
7049   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7050    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7051   "sub{q}\t{%2, %0|%0, %2}"
7052   [(set_attr "type" "alu")
7053    (set_attr "mode" "DI")])
7054
7055 (define_insn "subqi3_carry"
7056   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7057           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7058             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7059                (match_operand:QI 2 "general_operand" "qi,qm"))))
7060    (clobber (reg:CC FLAGS_REG))]
7061   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7062   "sbb{b}\t{%2, %0|%0, %2}"
7063   [(set_attr "type" "alu")
7064    (set_attr "pent_pair" "pu")
7065    (set_attr "mode" "QI")])
7066
7067 (define_insn "subhi3_carry"
7068   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7069           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7070             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7071                (match_operand:HI 2 "general_operand" "ri,rm"))))
7072    (clobber (reg:CC FLAGS_REG))]
7073   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7074   "sbb{w}\t{%2, %0|%0, %2}"
7075   [(set_attr "type" "alu")
7076    (set_attr "pent_pair" "pu")
7077    (set_attr "mode" "HI")])
7078
7079 (define_insn "subsi3_carry"
7080   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7081           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7082             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7083                (match_operand:SI 2 "general_operand" "ri,rm"))))
7084    (clobber (reg:CC FLAGS_REG))]
7085   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7086   "sbb{l}\t{%2, %0|%0, %2}"
7087   [(set_attr "type" "alu")
7088    (set_attr "pent_pair" "pu")
7089    (set_attr "mode" "SI")])
7090
7091 (define_insn "subsi3_carry_zext"
7092   [(set (match_operand:DI 0 "register_operand" "=r")
7093           (zero_extend:DI
7094             (minus:SI (match_operand:SI 1 "register_operand" "0")
7095               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7096                  (match_operand:SI 2 "general_operand" "g")))))
7097    (clobber (reg:CC FLAGS_REG))]
7098   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7099   "sbb{l}\t{%2, %k0|%k0, %2}"
7100   [(set_attr "type" "alu")
7101    (set_attr "pent_pair" "pu")
7102    (set_attr "mode" "SI")])
7103
7104 (define_expand "subsi3"
7105   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7106                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7107                              (match_operand:SI 2 "general_operand" "")))
7108               (clobber (reg:CC FLAGS_REG))])]
7109   ""
7110   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7111
7112 (define_insn "*subsi_1"
7113   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7114         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7115                   (match_operand:SI 2 "general_operand" "ri,rm")))
7116    (clobber (reg:CC FLAGS_REG))]
7117   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7118   "sub{l}\t{%2, %0|%0, %2}"
7119   [(set_attr "type" "alu")
7120    (set_attr "mode" "SI")])
7121
7122 (define_insn "*subsi_1_zext"
7123   [(set (match_operand:DI 0 "register_operand" "=r")
7124         (zero_extend:DI
7125           (minus:SI (match_operand:SI 1 "register_operand" "0")
7126                     (match_operand:SI 2 "general_operand" "g"))))
7127    (clobber (reg:CC FLAGS_REG))]
7128   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7129   "sub{l}\t{%2, %k0|%k0, %2}"
7130   [(set_attr "type" "alu")
7131    (set_attr "mode" "SI")])
7132
7133 (define_insn "*subsi_2"
7134   [(set (reg FLAGS_REG)
7135         (compare
7136           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7137                     (match_operand:SI 2 "general_operand" "ri,rm"))
7138           (const_int 0)))
7139    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7140         (minus:SI (match_dup 1) (match_dup 2)))]
7141   "ix86_match_ccmode (insn, CCGOCmode)
7142    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7143   "sub{l}\t{%2, %0|%0, %2}"
7144   [(set_attr "type" "alu")
7145    (set_attr "mode" "SI")])
7146
7147 (define_insn "*subsi_2_zext"
7148   [(set (reg FLAGS_REG)
7149         (compare
7150           (minus:SI (match_operand:SI 1 "register_operand" "0")
7151                     (match_operand:SI 2 "general_operand" "g"))
7152           (const_int 0)))
7153    (set (match_operand:DI 0 "register_operand" "=r")
7154         (zero_extend:DI
7155           (minus:SI (match_dup 1)
7156                     (match_dup 2))))]
7157   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7158    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7159   "sub{l}\t{%2, %k0|%k0, %2}"
7160   [(set_attr "type" "alu")
7161    (set_attr "mode" "SI")])
7162
7163 (define_insn "*subsi_3"
7164   [(set (reg FLAGS_REG)
7165         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7166                  (match_operand:SI 2 "general_operand" "ri,rm")))
7167    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7168         (minus:SI (match_dup 1) (match_dup 2)))]
7169   "ix86_match_ccmode (insn, CCmode)
7170    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7171   "sub{l}\t{%2, %0|%0, %2}"
7172   [(set_attr "type" "alu")
7173    (set_attr "mode" "SI")])
7174
7175 (define_insn "*subsi_3_zext"
7176   [(set (reg FLAGS_REG)
7177         (compare (match_operand:SI 1 "register_operand" "0")
7178                  (match_operand:SI 2 "general_operand" "g")))
7179    (set (match_operand:DI 0 "register_operand" "=r")
7180         (zero_extend:DI
7181           (minus:SI (match_dup 1)
7182                     (match_dup 2))))]
7183   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7184    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7185   "sub{l}\t{%2, %1|%1, %2}"
7186   [(set_attr "type" "alu")
7187    (set_attr "mode" "DI")])
7188
7189 (define_expand "subhi3"
7190   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7191                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7192                              (match_operand:HI 2 "general_operand" "")))
7193               (clobber (reg:CC FLAGS_REG))])]
7194   "TARGET_HIMODE_MATH"
7195   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7196
7197 (define_insn "*subhi_1"
7198   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7199         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7200                   (match_operand:HI 2 "general_operand" "ri,rm")))
7201    (clobber (reg:CC FLAGS_REG))]
7202   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7203   "sub{w}\t{%2, %0|%0, %2}"
7204   [(set_attr "type" "alu")
7205    (set_attr "mode" "HI")])
7206
7207 (define_insn "*subhi_2"
7208   [(set (reg FLAGS_REG)
7209         (compare
7210           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7211                     (match_operand:HI 2 "general_operand" "ri,rm"))
7212           (const_int 0)))
7213    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7214         (minus:HI (match_dup 1) (match_dup 2)))]
7215   "ix86_match_ccmode (insn, CCGOCmode)
7216    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7217   "sub{w}\t{%2, %0|%0, %2}"
7218   [(set_attr "type" "alu")
7219    (set_attr "mode" "HI")])
7220
7221 (define_insn "*subhi_3"
7222   [(set (reg FLAGS_REG)
7223         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7224                  (match_operand:HI 2 "general_operand" "ri,rm")))
7225    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7226         (minus:HI (match_dup 1) (match_dup 2)))]
7227   "ix86_match_ccmode (insn, CCmode)
7228    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7229   "sub{w}\t{%2, %0|%0, %2}"
7230   [(set_attr "type" "alu")
7231    (set_attr "mode" "HI")])
7232
7233 (define_expand "subqi3"
7234   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7235                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7236                              (match_operand:QI 2 "general_operand" "")))
7237               (clobber (reg:CC FLAGS_REG))])]
7238   "TARGET_QIMODE_MATH"
7239   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7240
7241 (define_insn "*subqi_1"
7242   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7243         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7244                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7245    (clobber (reg:CC FLAGS_REG))]
7246   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7247   "sub{b}\t{%2, %0|%0, %2}"
7248   [(set_attr "type" "alu")
7249    (set_attr "mode" "QI")])
7250
7251 (define_insn "*subqi_1_slp"
7252   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7253         (minus:QI (match_dup 0)
7254                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7255    (clobber (reg:CC FLAGS_REG))]
7256   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7257    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7258   "sub{b}\t{%1, %0|%0, %1}"
7259   [(set_attr "type" "alu1")
7260    (set_attr "mode" "QI")])
7261
7262 (define_insn "*subqi_2"
7263   [(set (reg FLAGS_REG)
7264         (compare
7265           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7266                     (match_operand:QI 2 "general_operand" "qi,qm"))
7267           (const_int 0)))
7268    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7269         (minus:HI (match_dup 1) (match_dup 2)))]
7270   "ix86_match_ccmode (insn, CCGOCmode)
7271    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7272   "sub{b}\t{%2, %0|%0, %2}"
7273   [(set_attr "type" "alu")
7274    (set_attr "mode" "QI")])
7275
7276 (define_insn "*subqi_3"
7277   [(set (reg FLAGS_REG)
7278         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7279                  (match_operand:QI 2 "general_operand" "qi,qm")))
7280    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7281         (minus:HI (match_dup 1) (match_dup 2)))]
7282   "ix86_match_ccmode (insn, CCmode)
7283    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7284   "sub{b}\t{%2, %0|%0, %2}"
7285   [(set_attr "type" "alu")
7286    (set_attr "mode" "QI")])
7287
7288 ;; The patterns that match these are at the end of this file.
7289
7290 (define_expand "subxf3"
7291   [(set (match_operand:XF 0 "register_operand" "")
7292         (minus:XF (match_operand:XF 1 "register_operand" "")
7293                   (match_operand:XF 2 "register_operand" "")))]
7294   "TARGET_80387"
7295   "")
7296
7297 (define_expand "sub<mode>3"
7298   [(set (match_operand:MODEF 0 "register_operand" "")
7299         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7300                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7301   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7302   "")
7303 \f
7304 ;; Multiply instructions
7305
7306 (define_expand "muldi3"
7307   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7308                    (mult:DI (match_operand:DI 1 "register_operand" "")
7309                             (match_operand:DI 2 "x86_64_general_operand" "")))
7310               (clobber (reg:CC FLAGS_REG))])]
7311   "TARGET_64BIT"
7312   "")
7313
7314 ;; On AMDFAM10 
7315 ;; IMUL reg64, reg64, imm8      Direct
7316 ;; IMUL reg64, mem64, imm8      VectorPath
7317 ;; IMUL reg64, reg64, imm32     Direct
7318 ;; IMUL reg64, mem64, imm32     VectorPath 
7319 ;; IMUL reg64, reg64            Direct
7320 ;; IMUL reg64, mem64            Direct
7321
7322 (define_insn "*muldi3_1_rex64"
7323   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7324         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7325                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7326    (clobber (reg:CC FLAGS_REG))]
7327   "TARGET_64BIT
7328    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7329   "@
7330    imul{q}\t{%2, %1, %0|%0, %1, %2}
7331    imul{q}\t{%2, %1, %0|%0, %1, %2}
7332    imul{q}\t{%2, %0|%0, %2}"
7333   [(set_attr "type" "imul")
7334    (set_attr "prefix_0f" "0,0,1")
7335    (set (attr "athlon_decode")
7336         (cond [(eq_attr "cpu" "athlon")
7337                   (const_string "vector")
7338                (eq_attr "alternative" "1")
7339                   (const_string "vector")
7340                (and (eq_attr "alternative" "2")
7341                     (match_operand 1 "memory_operand" ""))
7342                   (const_string "vector")]
7343               (const_string "direct")))
7344    (set (attr "amdfam10_decode")
7345         (cond [(and (eq_attr "alternative" "0,1")
7346                     (match_operand 1 "memory_operand" ""))
7347                   (const_string "vector")]
7348               (const_string "direct")))       
7349    (set_attr "mode" "DI")])
7350
7351 (define_expand "mulsi3"
7352   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7353                    (mult:SI (match_operand:SI 1 "register_operand" "")
7354                             (match_operand:SI 2 "general_operand" "")))
7355               (clobber (reg:CC FLAGS_REG))])]
7356   ""
7357   "")
7358
7359 ;; On AMDFAM10 
7360 ;; IMUL reg32, reg32, imm8      Direct
7361 ;; IMUL reg32, mem32, imm8      VectorPath
7362 ;; IMUL reg32, reg32, imm32     Direct
7363 ;; IMUL reg32, mem32, imm32     VectorPath
7364 ;; IMUL reg32, reg32            Direct
7365 ;; IMUL reg32, mem32            Direct
7366
7367 (define_insn "*mulsi3_1"
7368   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7369         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7370                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7371    (clobber (reg:CC FLAGS_REG))]
7372   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7373   "@
7374    imul{l}\t{%2, %1, %0|%0, %1, %2}
7375    imul{l}\t{%2, %1, %0|%0, %1, %2}
7376    imul{l}\t{%2, %0|%0, %2}"
7377   [(set_attr "type" "imul")
7378    (set_attr "prefix_0f" "0,0,1")
7379    (set (attr "athlon_decode")
7380         (cond [(eq_attr "cpu" "athlon")
7381                   (const_string "vector")
7382                (eq_attr "alternative" "1")
7383                   (const_string "vector")
7384                (and (eq_attr "alternative" "2")
7385                     (match_operand 1 "memory_operand" ""))
7386                   (const_string "vector")]
7387               (const_string "direct")))
7388    (set (attr "amdfam10_decode")
7389         (cond [(and (eq_attr "alternative" "0,1")
7390                     (match_operand 1 "memory_operand" ""))
7391                   (const_string "vector")]
7392               (const_string "direct")))       
7393    (set_attr "mode" "SI")])
7394
7395 (define_insn "*mulsi3_1_zext"
7396   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7397         (zero_extend:DI
7398           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7399                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7400    (clobber (reg:CC FLAGS_REG))]
7401   "TARGET_64BIT
7402    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7403   "@
7404    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7405    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7406    imul{l}\t{%2, %k0|%k0, %2}"
7407   [(set_attr "type" "imul")
7408    (set_attr "prefix_0f" "0,0,1")
7409    (set (attr "athlon_decode")
7410         (cond [(eq_attr "cpu" "athlon")
7411                   (const_string "vector")
7412                (eq_attr "alternative" "1")
7413                   (const_string "vector")
7414                (and (eq_attr "alternative" "2")
7415                     (match_operand 1 "memory_operand" ""))
7416                   (const_string "vector")]
7417               (const_string "direct")))
7418    (set (attr "amdfam10_decode")
7419         (cond [(and (eq_attr "alternative" "0,1")
7420                     (match_operand 1 "memory_operand" ""))
7421                   (const_string "vector")]
7422               (const_string "direct")))       
7423    (set_attr "mode" "SI")])
7424
7425 (define_expand "mulhi3"
7426   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7427                    (mult:HI (match_operand:HI 1 "register_operand" "")
7428                             (match_operand:HI 2 "general_operand" "")))
7429               (clobber (reg:CC FLAGS_REG))])]
7430   "TARGET_HIMODE_MATH"
7431   "")
7432
7433 ;; On AMDFAM10
7434 ;; IMUL reg16, reg16, imm8      VectorPath
7435 ;; IMUL reg16, mem16, imm8      VectorPath
7436 ;; IMUL reg16, reg16, imm16     VectorPath
7437 ;; IMUL reg16, mem16, imm16     VectorPath
7438 ;; IMUL reg16, reg16            Direct
7439 ;; IMUL reg16, mem16            Direct
7440 (define_insn "*mulhi3_1"
7441   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7442         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7443                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7444    (clobber (reg:CC FLAGS_REG))]
7445   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7446   "@
7447    imul{w}\t{%2, %1, %0|%0, %1, %2}
7448    imul{w}\t{%2, %1, %0|%0, %1, %2}
7449    imul{w}\t{%2, %0|%0, %2}"
7450   [(set_attr "type" "imul")
7451    (set_attr "prefix_0f" "0,0,1")
7452    (set (attr "athlon_decode")
7453         (cond [(eq_attr "cpu" "athlon")
7454                   (const_string "vector")
7455                (eq_attr "alternative" "1,2")
7456                   (const_string "vector")]
7457               (const_string "direct")))
7458    (set (attr "amdfam10_decode")
7459         (cond [(eq_attr "alternative" "0,1")
7460                   (const_string "vector")]
7461               (const_string "direct")))
7462    (set_attr "mode" "HI")])
7463
7464 (define_expand "mulqi3"
7465   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7466                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7467                             (match_operand:QI 2 "register_operand" "")))
7468               (clobber (reg:CC FLAGS_REG))])]
7469   "TARGET_QIMODE_MATH"
7470   "")
7471
7472 ;;On AMDFAM10
7473 ;; MUL reg8     Direct
7474 ;; MUL mem8     Direct
7475
7476 (define_insn "*mulqi3_1"
7477   [(set (match_operand:QI 0 "register_operand" "=a")
7478         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7479                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7480    (clobber (reg:CC FLAGS_REG))]
7481   "TARGET_QIMODE_MATH
7482    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7483   "mul{b}\t%2"
7484   [(set_attr "type" "imul")
7485    (set_attr "length_immediate" "0")
7486    (set (attr "athlon_decode")
7487      (if_then_else (eq_attr "cpu" "athlon")
7488         (const_string "vector")
7489         (const_string "direct")))
7490    (set_attr "amdfam10_decode" "direct")        
7491    (set_attr "mode" "QI")])
7492
7493 (define_expand "umulqihi3"
7494   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7495                    (mult:HI (zero_extend:HI
7496                               (match_operand:QI 1 "nonimmediate_operand" ""))
7497                             (zero_extend:HI
7498                               (match_operand:QI 2 "register_operand" ""))))
7499               (clobber (reg:CC FLAGS_REG))])]
7500   "TARGET_QIMODE_MATH"
7501   "")
7502
7503 (define_insn "*umulqihi3_1"
7504   [(set (match_operand:HI 0 "register_operand" "=a")
7505         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7506                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7507    (clobber (reg:CC FLAGS_REG))]
7508   "TARGET_QIMODE_MATH
7509    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7510   "mul{b}\t%2"
7511   [(set_attr "type" "imul")
7512    (set_attr "length_immediate" "0")
7513    (set (attr "athlon_decode")
7514      (if_then_else (eq_attr "cpu" "athlon")
7515         (const_string "vector")
7516         (const_string "direct")))
7517    (set_attr "amdfam10_decode" "direct")        
7518    (set_attr "mode" "QI")])
7519
7520 (define_expand "mulqihi3"
7521   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7522                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7523                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7524               (clobber (reg:CC FLAGS_REG))])]
7525   "TARGET_QIMODE_MATH"
7526   "")
7527
7528 (define_insn "*mulqihi3_insn"
7529   [(set (match_operand:HI 0 "register_operand" "=a")
7530         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7531                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7532    (clobber (reg:CC FLAGS_REG))]
7533   "TARGET_QIMODE_MATH
7534    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7535   "imul{b}\t%2"
7536   [(set_attr "type" "imul")
7537    (set_attr "length_immediate" "0")
7538    (set (attr "athlon_decode")
7539      (if_then_else (eq_attr "cpu" "athlon")
7540         (const_string "vector")
7541         (const_string "direct")))
7542    (set_attr "amdfam10_decode" "direct")        
7543    (set_attr "mode" "QI")])
7544
7545 (define_expand "umulditi3"
7546   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7547                    (mult:TI (zero_extend:TI
7548                               (match_operand:DI 1 "nonimmediate_operand" ""))
7549                             (zero_extend:TI
7550                               (match_operand:DI 2 "register_operand" ""))))
7551               (clobber (reg:CC FLAGS_REG))])]
7552   "TARGET_64BIT"
7553   "")
7554
7555 (define_insn "*umulditi3_insn"
7556   [(set (match_operand:TI 0 "register_operand" "=A")
7557         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7558                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7559    (clobber (reg:CC FLAGS_REG))]
7560   "TARGET_64BIT
7561    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7562   "mul{q}\t%2"
7563   [(set_attr "type" "imul")
7564    (set_attr "length_immediate" "0")
7565    (set (attr "athlon_decode")
7566      (if_then_else (eq_attr "cpu" "athlon")
7567         (const_string "vector")
7568         (const_string "double")))
7569    (set_attr "amdfam10_decode" "double")        
7570    (set_attr "mode" "DI")])
7571
7572 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7573 (define_expand "umulsidi3"
7574   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7575                    (mult:DI (zero_extend:DI
7576                               (match_operand:SI 1 "nonimmediate_operand" ""))
7577                             (zero_extend:DI
7578                               (match_operand:SI 2 "register_operand" ""))))
7579               (clobber (reg:CC FLAGS_REG))])]
7580   "!TARGET_64BIT"
7581   "")
7582
7583 (define_insn "*umulsidi3_insn"
7584   [(set (match_operand:DI 0 "register_operand" "=A")
7585         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7586                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7587    (clobber (reg:CC FLAGS_REG))]
7588   "!TARGET_64BIT
7589    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7590   "mul{l}\t%2"
7591   [(set_attr "type" "imul")
7592    (set_attr "length_immediate" "0")
7593    (set (attr "athlon_decode")
7594      (if_then_else (eq_attr "cpu" "athlon")
7595         (const_string "vector")
7596         (const_string "double")))
7597    (set_attr "amdfam10_decode" "double")        
7598    (set_attr "mode" "SI")])
7599
7600 (define_expand "mulditi3"
7601   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7602                    (mult:TI (sign_extend:TI
7603                               (match_operand:DI 1 "nonimmediate_operand" ""))
7604                             (sign_extend:TI
7605                               (match_operand:DI 2 "register_operand" ""))))
7606               (clobber (reg:CC FLAGS_REG))])]
7607   "TARGET_64BIT"
7608   "")
7609
7610 (define_insn "*mulditi3_insn"
7611   [(set (match_operand:TI 0 "register_operand" "=A")
7612         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7613                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7614    (clobber (reg:CC FLAGS_REG))]
7615   "TARGET_64BIT
7616    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7617   "imul{q}\t%2"
7618   [(set_attr "type" "imul")
7619    (set_attr "length_immediate" "0")
7620    (set (attr "athlon_decode")
7621      (if_then_else (eq_attr "cpu" "athlon")
7622         (const_string "vector")
7623         (const_string "double")))
7624    (set_attr "amdfam10_decode" "double")
7625    (set_attr "mode" "DI")])
7626
7627 (define_expand "mulsidi3"
7628   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7629                    (mult:DI (sign_extend:DI
7630                               (match_operand:SI 1 "nonimmediate_operand" ""))
7631                             (sign_extend:DI
7632                               (match_operand:SI 2 "register_operand" ""))))
7633               (clobber (reg:CC FLAGS_REG))])]
7634   "!TARGET_64BIT"
7635   "")
7636
7637 (define_insn "*mulsidi3_insn"
7638   [(set (match_operand:DI 0 "register_operand" "=A")
7639         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7640                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7641    (clobber (reg:CC FLAGS_REG))]
7642   "!TARGET_64BIT
7643    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7644   "imul{l}\t%2"
7645   [(set_attr "type" "imul")
7646    (set_attr "length_immediate" "0")
7647    (set (attr "athlon_decode")
7648      (if_then_else (eq_attr "cpu" "athlon")
7649         (const_string "vector")
7650         (const_string "double")))
7651    (set_attr "amdfam10_decode" "double")        
7652    (set_attr "mode" "SI")])
7653
7654 (define_expand "umuldi3_highpart"
7655   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7656                    (truncate:DI
7657                      (lshiftrt:TI
7658                        (mult:TI (zero_extend:TI
7659                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7660                                 (zero_extend:TI
7661                                   (match_operand:DI 2 "register_operand" "")))
7662                        (const_int 64))))
7663               (clobber (match_scratch:DI 3 ""))
7664               (clobber (reg:CC FLAGS_REG))])]
7665   "TARGET_64BIT"
7666   "")
7667
7668 (define_insn "*umuldi3_highpart_rex64"
7669   [(set (match_operand:DI 0 "register_operand" "=d")
7670         (truncate:DI
7671           (lshiftrt:TI
7672             (mult:TI (zero_extend:TI
7673                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7674                      (zero_extend:TI
7675                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7676             (const_int 64))))
7677    (clobber (match_scratch:DI 3 "=1"))
7678    (clobber (reg:CC FLAGS_REG))]
7679   "TARGET_64BIT
7680    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7681   "mul{q}\t%2"
7682   [(set_attr "type" "imul")
7683    (set_attr "length_immediate" "0")
7684    (set (attr "athlon_decode")
7685      (if_then_else (eq_attr "cpu" "athlon")
7686         (const_string "vector")
7687         (const_string "double")))
7688    (set_attr "amdfam10_decode" "double")        
7689    (set_attr "mode" "DI")])
7690
7691 (define_expand "umulsi3_highpart"
7692   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7693                    (truncate:SI
7694                      (lshiftrt:DI
7695                        (mult:DI (zero_extend:DI
7696                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7697                                 (zero_extend:DI
7698                                   (match_operand:SI 2 "register_operand" "")))
7699                        (const_int 32))))
7700               (clobber (match_scratch:SI 3 ""))
7701               (clobber (reg:CC FLAGS_REG))])]
7702   ""
7703   "")
7704
7705 (define_insn "*umulsi3_highpart_insn"
7706   [(set (match_operand:SI 0 "register_operand" "=d")
7707         (truncate:SI
7708           (lshiftrt:DI
7709             (mult:DI (zero_extend:DI
7710                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7711                      (zero_extend:DI
7712                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7713             (const_int 32))))
7714    (clobber (match_scratch:SI 3 "=1"))
7715    (clobber (reg:CC FLAGS_REG))]
7716   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7717   "mul{l}\t%2"
7718   [(set_attr "type" "imul")
7719    (set_attr "length_immediate" "0")
7720    (set (attr "athlon_decode")
7721      (if_then_else (eq_attr "cpu" "athlon")
7722         (const_string "vector")
7723         (const_string "double")))
7724    (set_attr "amdfam10_decode" "double")
7725    (set_attr "mode" "SI")])
7726
7727 (define_insn "*umulsi3_highpart_zext"
7728   [(set (match_operand:DI 0 "register_operand" "=d")
7729         (zero_extend:DI (truncate:SI
7730           (lshiftrt:DI
7731             (mult:DI (zero_extend:DI
7732                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7733                      (zero_extend:DI
7734                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7735             (const_int 32)))))
7736    (clobber (match_scratch:SI 3 "=1"))
7737    (clobber (reg:CC FLAGS_REG))]
7738   "TARGET_64BIT
7739    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7740   "mul{l}\t%2"
7741   [(set_attr "type" "imul")
7742    (set_attr "length_immediate" "0")
7743    (set (attr "athlon_decode")
7744      (if_then_else (eq_attr "cpu" "athlon")
7745         (const_string "vector")
7746         (const_string "double")))
7747    (set_attr "amdfam10_decode" "double")
7748    (set_attr "mode" "SI")])
7749
7750 (define_expand "smuldi3_highpart"
7751   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7752                    (truncate:DI
7753                      (lshiftrt:TI
7754                        (mult:TI (sign_extend:TI
7755                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7756                                 (sign_extend:TI
7757                                   (match_operand:DI 2 "register_operand" "")))
7758                        (const_int 64))))
7759               (clobber (match_scratch:DI 3 ""))
7760               (clobber (reg:CC FLAGS_REG))])]
7761   "TARGET_64BIT"
7762   "")
7763
7764 (define_insn "*smuldi3_highpart_rex64"
7765   [(set (match_operand:DI 0 "register_operand" "=d")
7766         (truncate:DI
7767           (lshiftrt:TI
7768             (mult:TI (sign_extend:TI
7769                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7770                      (sign_extend:TI
7771                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7772             (const_int 64))))
7773    (clobber (match_scratch:DI 3 "=1"))
7774    (clobber (reg:CC FLAGS_REG))]
7775   "TARGET_64BIT
7776    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7777   "imul{q}\t%2"
7778   [(set_attr "type" "imul")
7779    (set (attr "athlon_decode")
7780      (if_then_else (eq_attr "cpu" "athlon")
7781         (const_string "vector")
7782         (const_string "double")))
7783    (set_attr "amdfam10_decode" "double")
7784    (set_attr "mode" "DI")])
7785
7786 (define_expand "smulsi3_highpart"
7787   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7788                    (truncate:SI
7789                      (lshiftrt:DI
7790                        (mult:DI (sign_extend:DI
7791                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7792                                 (sign_extend:DI
7793                                   (match_operand:SI 2 "register_operand" "")))
7794                        (const_int 32))))
7795               (clobber (match_scratch:SI 3 ""))
7796               (clobber (reg:CC FLAGS_REG))])]
7797   ""
7798   "")
7799
7800 (define_insn "*smulsi3_highpart_insn"
7801   [(set (match_operand:SI 0 "register_operand" "=d")
7802         (truncate:SI
7803           (lshiftrt:DI
7804             (mult:DI (sign_extend:DI
7805                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7806                      (sign_extend:DI
7807                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7808             (const_int 32))))
7809    (clobber (match_scratch:SI 3 "=1"))
7810    (clobber (reg:CC FLAGS_REG))]
7811   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7812   "imul{l}\t%2"
7813   [(set_attr "type" "imul")
7814    (set (attr "athlon_decode")
7815      (if_then_else (eq_attr "cpu" "athlon")
7816         (const_string "vector")
7817         (const_string "double")))
7818    (set_attr "amdfam10_decode" "double")
7819    (set_attr "mode" "SI")])
7820
7821 (define_insn "*smulsi3_highpart_zext"
7822   [(set (match_operand:DI 0 "register_operand" "=d")
7823         (zero_extend:DI (truncate:SI
7824           (lshiftrt:DI
7825             (mult:DI (sign_extend:DI
7826                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7827                      (sign_extend:DI
7828                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7829             (const_int 32)))))
7830    (clobber (match_scratch:SI 3 "=1"))
7831    (clobber (reg:CC FLAGS_REG))]
7832   "TARGET_64BIT
7833    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7834   "imul{l}\t%2"
7835   [(set_attr "type" "imul")
7836    (set (attr "athlon_decode")
7837      (if_then_else (eq_attr "cpu" "athlon")
7838         (const_string "vector")
7839         (const_string "double")))
7840    (set_attr "amdfam10_decode" "double")
7841    (set_attr "mode" "SI")])
7842
7843 ;; The patterns that match these are at the end of this file.
7844
7845 (define_expand "mulxf3"
7846   [(set (match_operand:XF 0 "register_operand" "")
7847         (mult:XF (match_operand:XF 1 "register_operand" "")
7848                  (match_operand:XF 2 "register_operand" "")))]
7849   "TARGET_80387"
7850   "")
7851
7852 (define_expand "mul<mode>3"
7853   [(set (match_operand:MODEF 0 "register_operand" "")
7854         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7855                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7856   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7857   "")
7858 \f
7859 ;; Divide instructions
7860
7861 (define_insn "divqi3"
7862   [(set (match_operand:QI 0 "register_operand" "=a")
7863         (div:QI (match_operand:HI 1 "register_operand" "0")
7864                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7865    (clobber (reg:CC FLAGS_REG))]
7866   "TARGET_QIMODE_MATH"
7867   "idiv{b}\t%2"
7868   [(set_attr "type" "idiv")
7869    (set_attr "mode" "QI")])
7870
7871 (define_insn "udivqi3"
7872   [(set (match_operand:QI 0 "register_operand" "=a")
7873         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7874                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7875    (clobber (reg:CC FLAGS_REG))]
7876   "TARGET_QIMODE_MATH"
7877   "div{b}\t%2"
7878   [(set_attr "type" "idiv")
7879    (set_attr "mode" "QI")])
7880
7881 ;; The patterns that match these are at the end of this file.
7882
7883 (define_expand "divxf3"
7884   [(set (match_operand:XF 0 "register_operand" "")
7885         (div:XF (match_operand:XF 1 "register_operand" "")
7886                 (match_operand:XF 2 "register_operand" "")))]
7887   "TARGET_80387"
7888   "")
7889
7890 (define_expand "divdf3"
7891   [(set (match_operand:DF 0 "register_operand" "")
7892         (div:DF (match_operand:DF 1 "register_operand" "")
7893                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7894    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7895    "")
7896
7897 (define_expand "divsf3"
7898   [(set (match_operand:SF 0 "register_operand" "")
7899         (div:SF (match_operand:SF 1 "register_operand" "")
7900                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7901   "TARGET_80387 || TARGET_SSE_MATH"
7902 {
7903   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
7904       && flag_finite_math_only && !flag_trapping_math
7905       && flag_unsafe_math_optimizations)
7906     {
7907       ix86_emit_swdivsf (operands[0], operands[1],
7908                          operands[2], SFmode);
7909       DONE;
7910     }
7911 })
7912 \f
7913 ;; Remainder instructions.
7914
7915 (define_expand "divmoddi4"
7916   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7917                    (div:DI (match_operand:DI 1 "register_operand" "")
7918                            (match_operand:DI 2 "nonimmediate_operand" "")))
7919               (set (match_operand:DI 3 "register_operand" "")
7920                    (mod:DI (match_dup 1) (match_dup 2)))
7921               (clobber (reg:CC FLAGS_REG))])]
7922   "TARGET_64BIT"
7923   "")
7924
7925 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7926 ;; Penalize eax case slightly because it results in worse scheduling
7927 ;; of code.
7928 (define_insn "*divmoddi4_nocltd_rex64"
7929   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7930         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7931                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7932    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7933         (mod:DI (match_dup 2) (match_dup 3)))
7934    (clobber (reg:CC FLAGS_REG))]
7935   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7936   "#"
7937   [(set_attr "type" "multi")])
7938
7939 (define_insn "*divmoddi4_cltd_rex64"
7940   [(set (match_operand:DI 0 "register_operand" "=a")
7941         (div:DI (match_operand:DI 2 "register_operand" "a")
7942                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7943    (set (match_operand:DI 1 "register_operand" "=&d")
7944         (mod:DI (match_dup 2) (match_dup 3)))
7945    (clobber (reg:CC FLAGS_REG))]
7946   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7947   "#"
7948   [(set_attr "type" "multi")])
7949
7950 (define_insn "*divmoddi_noext_rex64"
7951   [(set (match_operand:DI 0 "register_operand" "=a")
7952         (div:DI (match_operand:DI 1 "register_operand" "0")
7953                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7954    (set (match_operand:DI 3 "register_operand" "=d")
7955         (mod:DI (match_dup 1) (match_dup 2)))
7956    (use (match_operand:DI 4 "register_operand" "3"))
7957    (clobber (reg:CC FLAGS_REG))]
7958   "TARGET_64BIT"
7959   "idiv{q}\t%2"
7960   [(set_attr "type" "idiv")
7961    (set_attr "mode" "DI")])
7962
7963 (define_split
7964   [(set (match_operand:DI 0 "register_operand" "")
7965         (div:DI (match_operand:DI 1 "register_operand" "")
7966                 (match_operand:DI 2 "nonimmediate_operand" "")))
7967    (set (match_operand:DI 3 "register_operand" "")
7968         (mod:DI (match_dup 1) (match_dup 2)))
7969    (clobber (reg:CC FLAGS_REG))]
7970   "TARGET_64BIT && reload_completed"
7971   [(parallel [(set (match_dup 3)
7972                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7973               (clobber (reg:CC FLAGS_REG))])
7974    (parallel [(set (match_dup 0)
7975                    (div:DI (reg:DI 0) (match_dup 2)))
7976               (set (match_dup 3)
7977                    (mod:DI (reg:DI 0) (match_dup 2)))
7978               (use (match_dup 3))
7979               (clobber (reg:CC FLAGS_REG))])]
7980 {
7981   /* Avoid use of cltd in favor of a mov+shift.  */
7982   if (!TARGET_USE_CLTD && !optimize_size)
7983     {
7984       if (true_regnum (operands[1]))
7985         emit_move_insn (operands[0], operands[1]);
7986       else
7987         emit_move_insn (operands[3], operands[1]);
7988       operands[4] = operands[3];
7989     }
7990   else
7991     {
7992       gcc_assert (!true_regnum (operands[1]));
7993       operands[4] = operands[1];
7994     }
7995 })
7996
7997
7998 (define_expand "divmodsi4"
7999   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8000                    (div:SI (match_operand:SI 1 "register_operand" "")
8001                            (match_operand:SI 2 "nonimmediate_operand" "")))
8002               (set (match_operand:SI 3 "register_operand" "")
8003                    (mod:SI (match_dup 1) (match_dup 2)))
8004               (clobber (reg:CC FLAGS_REG))])]
8005   ""
8006   "")
8007
8008 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8009 ;; Penalize eax case slightly because it results in worse scheduling
8010 ;; of code.
8011 (define_insn "*divmodsi4_nocltd"
8012   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8013         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8014                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8015    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8016         (mod:SI (match_dup 2) (match_dup 3)))
8017    (clobber (reg:CC FLAGS_REG))]
8018   "!optimize_size && !TARGET_USE_CLTD"
8019   "#"
8020   [(set_attr "type" "multi")])
8021
8022 (define_insn "*divmodsi4_cltd"
8023   [(set (match_operand:SI 0 "register_operand" "=a")
8024         (div:SI (match_operand:SI 2 "register_operand" "a")
8025                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8026    (set (match_operand:SI 1 "register_operand" "=&d")
8027         (mod:SI (match_dup 2) (match_dup 3)))
8028    (clobber (reg:CC FLAGS_REG))]
8029   "optimize_size || TARGET_USE_CLTD"
8030   "#"
8031   [(set_attr "type" "multi")])
8032
8033 (define_insn "*divmodsi_noext"
8034   [(set (match_operand:SI 0 "register_operand" "=a")
8035         (div:SI (match_operand:SI 1 "register_operand" "0")
8036                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8037    (set (match_operand:SI 3 "register_operand" "=d")
8038         (mod:SI (match_dup 1) (match_dup 2)))
8039    (use (match_operand:SI 4 "register_operand" "3"))
8040    (clobber (reg:CC FLAGS_REG))]
8041   ""
8042   "idiv{l}\t%2"
8043   [(set_attr "type" "idiv")
8044    (set_attr "mode" "SI")])
8045
8046 (define_split
8047   [(set (match_operand:SI 0 "register_operand" "")
8048         (div:SI (match_operand:SI 1 "register_operand" "")
8049                 (match_operand:SI 2 "nonimmediate_operand" "")))
8050    (set (match_operand:SI 3 "register_operand" "")
8051         (mod:SI (match_dup 1) (match_dup 2)))
8052    (clobber (reg:CC FLAGS_REG))]
8053   "reload_completed"
8054   [(parallel [(set (match_dup 3)
8055                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8056               (clobber (reg:CC FLAGS_REG))])
8057    (parallel [(set (match_dup 0)
8058                    (div:SI (reg:SI 0) (match_dup 2)))
8059               (set (match_dup 3)
8060                    (mod:SI (reg:SI 0) (match_dup 2)))
8061               (use (match_dup 3))
8062               (clobber (reg:CC FLAGS_REG))])]
8063 {
8064   /* Avoid use of cltd in favor of a mov+shift.  */
8065   if (!TARGET_USE_CLTD && !optimize_size)
8066     {
8067       if (true_regnum (operands[1]))
8068         emit_move_insn (operands[0], operands[1]);
8069       else
8070         emit_move_insn (operands[3], operands[1]);
8071       operands[4] = operands[3];
8072     }
8073   else
8074     {
8075       gcc_assert (!true_regnum (operands[1]));
8076       operands[4] = operands[1];
8077     }
8078 })
8079 ;; %%% Split me.
8080 (define_insn "divmodhi4"
8081   [(set (match_operand:HI 0 "register_operand" "=a")
8082         (div:HI (match_operand:HI 1 "register_operand" "0")
8083                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8084    (set (match_operand:HI 3 "register_operand" "=&d")
8085         (mod:HI (match_dup 1) (match_dup 2)))
8086    (clobber (reg:CC FLAGS_REG))]
8087   "TARGET_HIMODE_MATH"
8088   "cwtd\;idiv{w}\t%2"
8089   [(set_attr "type" "multi")
8090    (set_attr "length_immediate" "0")
8091    (set_attr "mode" "SI")])
8092
8093 (define_insn "udivmoddi4"
8094   [(set (match_operand:DI 0 "register_operand" "=a")
8095         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8096                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8097    (set (match_operand:DI 3 "register_operand" "=&d")
8098         (umod:DI (match_dup 1) (match_dup 2)))
8099    (clobber (reg:CC FLAGS_REG))]
8100   "TARGET_64BIT"
8101   "xor{q}\t%3, %3\;div{q}\t%2"
8102   [(set_attr "type" "multi")
8103    (set_attr "length_immediate" "0")
8104    (set_attr "mode" "DI")])
8105
8106 (define_insn "*udivmoddi4_noext"
8107   [(set (match_operand:DI 0 "register_operand" "=a")
8108         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8109                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8110    (set (match_operand:DI 3 "register_operand" "=d")
8111         (umod:DI (match_dup 1) (match_dup 2)))
8112    (use (match_dup 3))
8113    (clobber (reg:CC FLAGS_REG))]
8114   "TARGET_64BIT"
8115   "div{q}\t%2"
8116   [(set_attr "type" "idiv")
8117    (set_attr "mode" "DI")])
8118
8119 (define_split
8120   [(set (match_operand:DI 0 "register_operand" "")
8121         (udiv:DI (match_operand:DI 1 "register_operand" "")
8122                  (match_operand:DI 2 "nonimmediate_operand" "")))
8123    (set (match_operand:DI 3 "register_operand" "")
8124         (umod:DI (match_dup 1) (match_dup 2)))
8125    (clobber (reg:CC FLAGS_REG))]
8126   "TARGET_64BIT && reload_completed"
8127   [(set (match_dup 3) (const_int 0))
8128    (parallel [(set (match_dup 0)
8129                    (udiv:DI (match_dup 1) (match_dup 2)))
8130               (set (match_dup 3)
8131                    (umod:DI (match_dup 1) (match_dup 2)))
8132               (use (match_dup 3))
8133               (clobber (reg:CC FLAGS_REG))])]
8134   "")
8135
8136 (define_insn "udivmodsi4"
8137   [(set (match_operand:SI 0 "register_operand" "=a")
8138         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8139                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8140    (set (match_operand:SI 3 "register_operand" "=&d")
8141         (umod:SI (match_dup 1) (match_dup 2)))
8142    (clobber (reg:CC FLAGS_REG))]
8143   ""
8144   "xor{l}\t%3, %3\;div{l}\t%2"
8145   [(set_attr "type" "multi")
8146    (set_attr "length_immediate" "0")
8147    (set_attr "mode" "SI")])
8148
8149 (define_insn "*udivmodsi4_noext"
8150   [(set (match_operand:SI 0 "register_operand" "=a")
8151         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8152                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8153    (set (match_operand:SI 3 "register_operand" "=d")
8154         (umod:SI (match_dup 1) (match_dup 2)))
8155    (use (match_dup 3))
8156    (clobber (reg:CC FLAGS_REG))]
8157   ""
8158   "div{l}\t%2"
8159   [(set_attr "type" "idiv")
8160    (set_attr "mode" "SI")])
8161
8162 (define_split
8163   [(set (match_operand:SI 0 "register_operand" "")
8164         (udiv:SI (match_operand:SI 1 "register_operand" "")
8165                  (match_operand:SI 2 "nonimmediate_operand" "")))
8166    (set (match_operand:SI 3 "register_operand" "")
8167         (umod:SI (match_dup 1) (match_dup 2)))
8168    (clobber (reg:CC FLAGS_REG))]
8169   "reload_completed"
8170   [(set (match_dup 3) (const_int 0))
8171    (parallel [(set (match_dup 0)
8172                    (udiv:SI (match_dup 1) (match_dup 2)))
8173               (set (match_dup 3)
8174                    (umod:SI (match_dup 1) (match_dup 2)))
8175               (use (match_dup 3))
8176               (clobber (reg:CC FLAGS_REG))])]
8177   "")
8178
8179 (define_expand "udivmodhi4"
8180   [(set (match_dup 4) (const_int 0))
8181    (parallel [(set (match_operand:HI 0 "register_operand" "")
8182                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8183                             (match_operand:HI 2 "nonimmediate_operand" "")))
8184               (set (match_operand:HI 3 "register_operand" "")
8185                    (umod:HI (match_dup 1) (match_dup 2)))
8186               (use (match_dup 4))
8187               (clobber (reg:CC FLAGS_REG))])]
8188   "TARGET_HIMODE_MATH"
8189   "operands[4] = gen_reg_rtx (HImode);")
8190
8191 (define_insn "*udivmodhi_noext"
8192   [(set (match_operand:HI 0 "register_operand" "=a")
8193         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8194                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8195    (set (match_operand:HI 3 "register_operand" "=d")
8196         (umod:HI (match_dup 1) (match_dup 2)))
8197    (use (match_operand:HI 4 "register_operand" "3"))
8198    (clobber (reg:CC FLAGS_REG))]
8199   ""
8200   "div{w}\t%2"
8201   [(set_attr "type" "idiv")
8202    (set_attr "mode" "HI")])
8203
8204 ;; We cannot use div/idiv for double division, because it causes
8205 ;; "division by zero" on the overflow and that's not what we expect
8206 ;; from truncate.  Because true (non truncating) double division is
8207 ;; never generated, we can't create this insn anyway.
8208 ;
8209 ;(define_insn ""
8210 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8211 ;       (truncate:SI
8212 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8213 ;                  (zero_extend:DI
8214 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8215 ;   (set (match_operand:SI 3 "register_operand" "=d")
8216 ;       (truncate:SI
8217 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8218 ;   (clobber (reg:CC FLAGS_REG))]
8219 ;  ""
8220 ;  "div{l}\t{%2, %0|%0, %2}"
8221 ;  [(set_attr "type" "idiv")])
8222 \f
8223 ;;- Logical AND instructions
8224
8225 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8226 ;; Note that this excludes ah.
8227
8228 (define_insn "*testdi_1_rex64"
8229   [(set (reg FLAGS_REG)
8230         (compare
8231           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8232                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8233           (const_int 0)))]
8234   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8235    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8236   "@
8237    test{l}\t{%k1, %k0|%k0, %k1}
8238    test{l}\t{%k1, %k0|%k0, %k1}
8239    test{q}\t{%1, %0|%0, %1}
8240    test{q}\t{%1, %0|%0, %1}
8241    test{q}\t{%1, %0|%0, %1}"
8242   [(set_attr "type" "test")
8243    (set_attr "modrm" "0,1,0,1,1")
8244    (set_attr "mode" "SI,SI,DI,DI,DI")
8245    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8246
8247 (define_insn "testsi_1"
8248   [(set (reg FLAGS_REG)
8249         (compare
8250           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8251                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8252           (const_int 0)))]
8253   "ix86_match_ccmode (insn, CCNOmode)
8254    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8255   "test{l}\t{%1, %0|%0, %1}"
8256   [(set_attr "type" "test")
8257    (set_attr "modrm" "0,1,1")
8258    (set_attr "mode" "SI")
8259    (set_attr "pent_pair" "uv,np,uv")])
8260
8261 (define_expand "testsi_ccno_1"
8262   [(set (reg:CCNO FLAGS_REG)
8263         (compare:CCNO
8264           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8265                   (match_operand:SI 1 "nonmemory_operand" ""))
8266           (const_int 0)))]
8267   ""
8268   "")
8269
8270 (define_insn "*testhi_1"
8271   [(set (reg FLAGS_REG)
8272         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8273                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8274                  (const_int 0)))]
8275   "ix86_match_ccmode (insn, CCNOmode)
8276    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8277   "test{w}\t{%1, %0|%0, %1}"
8278   [(set_attr "type" "test")
8279    (set_attr "modrm" "0,1,1")
8280    (set_attr "mode" "HI")
8281    (set_attr "pent_pair" "uv,np,uv")])
8282
8283 (define_expand "testqi_ccz_1"
8284   [(set (reg:CCZ FLAGS_REG)
8285         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8286                              (match_operand:QI 1 "nonmemory_operand" ""))
8287                  (const_int 0)))]
8288   ""
8289   "")
8290
8291 (define_insn "*testqi_1_maybe_si"
8292   [(set (reg FLAGS_REG)
8293         (compare
8294           (and:QI
8295             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8296             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8297           (const_int 0)))]
8298    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8299     && ix86_match_ccmode (insn,
8300                          CONST_INT_P (operands[1])
8301                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8302 {
8303   if (which_alternative == 3)
8304     {
8305       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8306         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8307       return "test{l}\t{%1, %k0|%k0, %1}";
8308     }
8309   return "test{b}\t{%1, %0|%0, %1}";
8310 }
8311   [(set_attr "type" "test")
8312    (set_attr "modrm" "0,1,1,1")
8313    (set_attr "mode" "QI,QI,QI,SI")
8314    (set_attr "pent_pair" "uv,np,uv,np")])
8315
8316 (define_insn "*testqi_1"
8317   [(set (reg FLAGS_REG)
8318         (compare
8319           (and:QI
8320             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8321             (match_operand:QI 1 "general_operand" "n,n,qn"))
8322           (const_int 0)))]
8323   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8324    && ix86_match_ccmode (insn, CCNOmode)"
8325   "test{b}\t{%1, %0|%0, %1}"
8326   [(set_attr "type" "test")
8327    (set_attr "modrm" "0,1,1")
8328    (set_attr "mode" "QI")
8329    (set_attr "pent_pair" "uv,np,uv")])
8330
8331 (define_expand "testqi_ext_ccno_0"
8332   [(set (reg:CCNO FLAGS_REG)
8333         (compare:CCNO
8334           (and:SI
8335             (zero_extract:SI
8336               (match_operand 0 "ext_register_operand" "")
8337               (const_int 8)
8338               (const_int 8))
8339             (match_operand 1 "const_int_operand" ""))
8340           (const_int 0)))]
8341   ""
8342   "")
8343
8344 (define_insn "*testqi_ext_0"
8345   [(set (reg FLAGS_REG)
8346         (compare
8347           (and:SI
8348             (zero_extract:SI
8349               (match_operand 0 "ext_register_operand" "Q")
8350               (const_int 8)
8351               (const_int 8))
8352             (match_operand 1 "const_int_operand" "n"))
8353           (const_int 0)))]
8354   "ix86_match_ccmode (insn, CCNOmode)"
8355   "test{b}\t{%1, %h0|%h0, %1}"
8356   [(set_attr "type" "test")
8357    (set_attr "mode" "QI")
8358    (set_attr "length_immediate" "1")
8359    (set_attr "pent_pair" "np")])
8360
8361 (define_insn "*testqi_ext_1"
8362   [(set (reg FLAGS_REG)
8363         (compare
8364           (and:SI
8365             (zero_extract:SI
8366               (match_operand 0 "ext_register_operand" "Q")
8367               (const_int 8)
8368               (const_int 8))
8369             (zero_extend:SI
8370               (match_operand:QI 1 "general_operand" "Qm")))
8371           (const_int 0)))]
8372   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8373    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8374   "test{b}\t{%1, %h0|%h0, %1}"
8375   [(set_attr "type" "test")
8376    (set_attr "mode" "QI")])
8377
8378 (define_insn "*testqi_ext_1_rex64"
8379   [(set (reg FLAGS_REG)
8380         (compare
8381           (and:SI
8382             (zero_extract:SI
8383               (match_operand 0 "ext_register_operand" "Q")
8384               (const_int 8)
8385               (const_int 8))
8386             (zero_extend:SI
8387               (match_operand:QI 1 "register_operand" "Q")))
8388           (const_int 0)))]
8389   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8390   "test{b}\t{%1, %h0|%h0, %1}"
8391   [(set_attr "type" "test")
8392    (set_attr "mode" "QI")])
8393
8394 (define_insn "*testqi_ext_2"
8395   [(set (reg FLAGS_REG)
8396         (compare
8397           (and:SI
8398             (zero_extract:SI
8399               (match_operand 0 "ext_register_operand" "Q")
8400               (const_int 8)
8401               (const_int 8))
8402             (zero_extract:SI
8403               (match_operand 1 "ext_register_operand" "Q")
8404               (const_int 8)
8405               (const_int 8)))
8406           (const_int 0)))]
8407   "ix86_match_ccmode (insn, CCNOmode)"
8408   "test{b}\t{%h1, %h0|%h0, %h1}"
8409   [(set_attr "type" "test")
8410    (set_attr "mode" "QI")])
8411
8412 ;; Combine likes to form bit extractions for some tests.  Humor it.
8413 (define_insn "*testqi_ext_3"
8414   [(set (reg FLAGS_REG)
8415         (compare (zero_extract:SI
8416                    (match_operand 0 "nonimmediate_operand" "rm")
8417                    (match_operand:SI 1 "const_int_operand" "")
8418                    (match_operand:SI 2 "const_int_operand" ""))
8419                  (const_int 0)))]
8420   "ix86_match_ccmode (insn, CCNOmode)
8421    && INTVAL (operands[1]) > 0
8422    && INTVAL (operands[2]) >= 0
8423    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8424    && (GET_MODE (operands[0]) == SImode
8425        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8426        || GET_MODE (operands[0]) == HImode
8427        || GET_MODE (operands[0]) == QImode)"
8428   "#")
8429
8430 (define_insn "*testqi_ext_3_rex64"
8431   [(set (reg FLAGS_REG)
8432         (compare (zero_extract:DI
8433                    (match_operand 0 "nonimmediate_operand" "rm")
8434                    (match_operand:DI 1 "const_int_operand" "")
8435                    (match_operand:DI 2 "const_int_operand" ""))
8436                  (const_int 0)))]
8437   "TARGET_64BIT
8438    && ix86_match_ccmode (insn, CCNOmode)
8439    && INTVAL (operands[1]) > 0
8440    && INTVAL (operands[2]) >= 0
8441    /* Ensure that resulting mask is zero or sign extended operand.  */
8442    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8443        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8444            && INTVAL (operands[1]) > 32))
8445    && (GET_MODE (operands[0]) == SImode
8446        || GET_MODE (operands[0]) == DImode
8447        || GET_MODE (operands[0]) == HImode
8448        || GET_MODE (operands[0]) == QImode)"
8449   "#")
8450
8451 (define_split
8452   [(set (match_operand 0 "flags_reg_operand" "")
8453         (match_operator 1 "compare_operator"
8454           [(zero_extract
8455              (match_operand 2 "nonimmediate_operand" "")
8456              (match_operand 3 "const_int_operand" "")
8457              (match_operand 4 "const_int_operand" ""))
8458            (const_int 0)]))]
8459   "ix86_match_ccmode (insn, CCNOmode)"
8460   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8461 {
8462   rtx val = operands[2];
8463   HOST_WIDE_INT len = INTVAL (operands[3]);
8464   HOST_WIDE_INT pos = INTVAL (operands[4]);
8465   HOST_WIDE_INT mask;
8466   enum machine_mode mode, submode;
8467
8468   mode = GET_MODE (val);
8469   if (MEM_P (val))
8470     {
8471       /* ??? Combine likes to put non-volatile mem extractions in QImode
8472          no matter the size of the test.  So find a mode that works.  */
8473       if (! MEM_VOLATILE_P (val))
8474         {
8475           mode = smallest_mode_for_size (pos + len, MODE_INT);
8476           val = adjust_address (val, mode, 0);
8477         }
8478     }
8479   else if (GET_CODE (val) == SUBREG
8480            && (submode = GET_MODE (SUBREG_REG (val)),
8481                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8482            && pos + len <= GET_MODE_BITSIZE (submode))
8483     {
8484       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8485       mode = submode;
8486       val = SUBREG_REG (val);
8487     }
8488   else if (mode == HImode && pos + len <= 8)
8489     {
8490       /* Small HImode tests can be converted to QImode.  */
8491       mode = QImode;
8492       val = gen_lowpart (QImode, val);
8493     }
8494
8495   if (len == HOST_BITS_PER_WIDE_INT)
8496     mask = -1;
8497   else
8498     mask = ((HOST_WIDE_INT)1 << len) - 1;
8499   mask <<= pos;
8500
8501   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8502 })
8503
8504 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8505 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8506 ;; this is relatively important trick.
8507 ;; Do the conversion only post-reload to avoid limiting of the register class
8508 ;; to QI regs.
8509 (define_split
8510   [(set (match_operand 0 "flags_reg_operand" "")
8511         (match_operator 1 "compare_operator"
8512           [(and (match_operand 2 "register_operand" "")
8513                 (match_operand 3 "const_int_operand" ""))
8514            (const_int 0)]))]
8515    "reload_completed
8516     && QI_REG_P (operands[2])
8517     && GET_MODE (operands[2]) != QImode
8518     && ((ix86_match_ccmode (insn, CCZmode)
8519          && !(INTVAL (operands[3]) & ~(255 << 8)))
8520         || (ix86_match_ccmode (insn, CCNOmode)
8521             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8522   [(set (match_dup 0)
8523         (match_op_dup 1
8524           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8525                    (match_dup 3))
8526            (const_int 0)]))]
8527   "operands[2] = gen_lowpart (SImode, operands[2]);
8528    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8529
8530 (define_split
8531   [(set (match_operand 0 "flags_reg_operand" "")
8532         (match_operator 1 "compare_operator"
8533           [(and (match_operand 2 "nonimmediate_operand" "")
8534                 (match_operand 3 "const_int_operand" ""))
8535            (const_int 0)]))]
8536    "reload_completed
8537     && GET_MODE (operands[2]) != QImode
8538     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8539     && ((ix86_match_ccmode (insn, CCZmode)
8540          && !(INTVAL (operands[3]) & ~255))
8541         || (ix86_match_ccmode (insn, CCNOmode)
8542             && !(INTVAL (operands[3]) & ~127)))"
8543   [(set (match_dup 0)
8544         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8545                          (const_int 0)]))]
8546   "operands[2] = gen_lowpart (QImode, operands[2]);
8547    operands[3] = gen_lowpart (QImode, operands[3]);")
8548
8549
8550 ;; %%% This used to optimize known byte-wide and operations to memory,
8551 ;; and sometimes to QImode registers.  If this is considered useful,
8552 ;; it should be done with splitters.
8553
8554 (define_expand "anddi3"
8555   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8556         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8557                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8558    (clobber (reg:CC FLAGS_REG))]
8559   "TARGET_64BIT"
8560   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8561
8562 (define_insn "*anddi_1_rex64"
8563   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8564         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8565                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8566    (clobber (reg:CC FLAGS_REG))]
8567   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8568 {
8569   switch (get_attr_type (insn))
8570     {
8571     case TYPE_IMOVX:
8572       {
8573         enum machine_mode mode;
8574
8575         gcc_assert (CONST_INT_P (operands[2]));
8576         if (INTVAL (operands[2]) == 0xff)
8577           mode = QImode;
8578         else
8579           {
8580             gcc_assert (INTVAL (operands[2]) == 0xffff);
8581             mode = HImode;
8582           }
8583
8584         operands[1] = gen_lowpart (mode, operands[1]);
8585         if (mode == QImode)
8586           return "movz{bq|x}\t{%1,%0|%0, %1}";
8587         else
8588           return "movz{wq|x}\t{%1,%0|%0, %1}";
8589       }
8590
8591     default:
8592       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8593       if (get_attr_mode (insn) == MODE_SI)
8594         return "and{l}\t{%k2, %k0|%k0, %k2}";
8595       else
8596         return "and{q}\t{%2, %0|%0, %2}";
8597     }
8598 }
8599   [(set_attr "type" "alu,alu,alu,imovx")
8600    (set_attr "length_immediate" "*,*,*,0")
8601    (set_attr "mode" "SI,DI,DI,DI")])
8602
8603 (define_insn "*anddi_2"
8604   [(set (reg FLAGS_REG)
8605         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8606                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8607                  (const_int 0)))
8608    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8609         (and:DI (match_dup 1) (match_dup 2)))]
8610   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8611    && ix86_binary_operator_ok (AND, DImode, operands)"
8612   "@
8613    and{l}\t{%k2, %k0|%k0, %k2}
8614    and{q}\t{%2, %0|%0, %2}
8615    and{q}\t{%2, %0|%0, %2}"
8616   [(set_attr "type" "alu")
8617    (set_attr "mode" "SI,DI,DI")])
8618
8619 (define_expand "andsi3"
8620   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8621         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8622                 (match_operand:SI 2 "general_operand" "")))
8623    (clobber (reg:CC FLAGS_REG))]
8624   ""
8625   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8626
8627 (define_insn "*andsi_1"
8628   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8629         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8630                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8631    (clobber (reg:CC FLAGS_REG))]
8632   "ix86_binary_operator_ok (AND, SImode, operands)"
8633 {
8634   switch (get_attr_type (insn))
8635     {
8636     case TYPE_IMOVX:
8637       {
8638         enum machine_mode mode;
8639
8640         gcc_assert (CONST_INT_P (operands[2]));
8641         if (INTVAL (operands[2]) == 0xff)
8642           mode = QImode;
8643         else
8644           {
8645             gcc_assert (INTVAL (operands[2]) == 0xffff);
8646             mode = HImode;
8647           }
8648
8649         operands[1] = gen_lowpart (mode, operands[1]);
8650         if (mode == QImode)
8651           return "movz{bl|x}\t{%1,%0|%0, %1}";
8652         else
8653           return "movz{wl|x}\t{%1,%0|%0, %1}";
8654       }
8655
8656     default:
8657       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8658       return "and{l}\t{%2, %0|%0, %2}";
8659     }
8660 }
8661   [(set_attr "type" "alu,alu,imovx")
8662    (set_attr "length_immediate" "*,*,0")
8663    (set_attr "mode" "SI")])
8664
8665 (define_split
8666   [(set (match_operand 0 "register_operand" "")
8667         (and (match_dup 0)
8668              (const_int -65536)))
8669    (clobber (reg:CC FLAGS_REG))]
8670   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8671   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8672   "operands[1] = gen_lowpart (HImode, operands[0]);")
8673
8674 (define_split
8675   [(set (match_operand 0 "ext_register_operand" "")
8676         (and (match_dup 0)
8677              (const_int -256)))
8678    (clobber (reg:CC FLAGS_REG))]
8679   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8680   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8681   "operands[1] = gen_lowpart (QImode, operands[0]);")
8682
8683 (define_split
8684   [(set (match_operand 0 "ext_register_operand" "")
8685         (and (match_dup 0)
8686              (const_int -65281)))
8687    (clobber (reg:CC FLAGS_REG))]
8688   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8689   [(parallel [(set (zero_extract:SI (match_dup 0)
8690                                     (const_int 8)
8691                                     (const_int 8))
8692                    (xor:SI
8693                      (zero_extract:SI (match_dup 0)
8694                                       (const_int 8)
8695                                       (const_int 8))
8696                      (zero_extract:SI (match_dup 0)
8697                                       (const_int 8)
8698                                       (const_int 8))))
8699               (clobber (reg:CC FLAGS_REG))])]
8700   "operands[0] = gen_lowpart (SImode, operands[0]);")
8701
8702 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8703 (define_insn "*andsi_1_zext"
8704   [(set (match_operand:DI 0 "register_operand" "=r")
8705         (zero_extend:DI
8706           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8707                   (match_operand:SI 2 "general_operand" "g"))))
8708    (clobber (reg:CC FLAGS_REG))]
8709   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8710   "and{l}\t{%2, %k0|%k0, %2}"
8711   [(set_attr "type" "alu")
8712    (set_attr "mode" "SI")])
8713
8714 (define_insn "*andsi_2"
8715   [(set (reg FLAGS_REG)
8716         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8717                          (match_operand:SI 2 "general_operand" "g,ri"))
8718                  (const_int 0)))
8719    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8720         (and:SI (match_dup 1) (match_dup 2)))]
8721   "ix86_match_ccmode (insn, CCNOmode)
8722    && ix86_binary_operator_ok (AND, SImode, operands)"
8723   "and{l}\t{%2, %0|%0, %2}"
8724   [(set_attr "type" "alu")
8725    (set_attr "mode" "SI")])
8726
8727 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8728 (define_insn "*andsi_2_zext"
8729   [(set (reg FLAGS_REG)
8730         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8731                          (match_operand:SI 2 "general_operand" "g"))
8732                  (const_int 0)))
8733    (set (match_operand:DI 0 "register_operand" "=r")
8734         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8735   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8736    && ix86_binary_operator_ok (AND, SImode, operands)"
8737   "and{l}\t{%2, %k0|%k0, %2}"
8738   [(set_attr "type" "alu")
8739    (set_attr "mode" "SI")])
8740
8741 (define_expand "andhi3"
8742   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8743         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8744                 (match_operand:HI 2 "general_operand" "")))
8745    (clobber (reg:CC FLAGS_REG))]
8746   "TARGET_HIMODE_MATH"
8747   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8748
8749 (define_insn "*andhi_1"
8750   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8751         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8752                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8753    (clobber (reg:CC FLAGS_REG))]
8754   "ix86_binary_operator_ok (AND, HImode, operands)"
8755 {
8756   switch (get_attr_type (insn))
8757     {
8758     case TYPE_IMOVX:
8759       gcc_assert (CONST_INT_P (operands[2]));
8760       gcc_assert (INTVAL (operands[2]) == 0xff);
8761       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8762
8763     default:
8764       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8765
8766       return "and{w}\t{%2, %0|%0, %2}";
8767     }
8768 }
8769   [(set_attr "type" "alu,alu,imovx")
8770    (set_attr "length_immediate" "*,*,0")
8771    (set_attr "mode" "HI,HI,SI")])
8772
8773 (define_insn "*andhi_2"
8774   [(set (reg FLAGS_REG)
8775         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8776                          (match_operand:HI 2 "general_operand" "g,ri"))
8777                  (const_int 0)))
8778    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8779         (and:HI (match_dup 1) (match_dup 2)))]
8780   "ix86_match_ccmode (insn, CCNOmode)
8781    && ix86_binary_operator_ok (AND, HImode, operands)"
8782   "and{w}\t{%2, %0|%0, %2}"
8783   [(set_attr "type" "alu")
8784    (set_attr "mode" "HI")])
8785
8786 (define_expand "andqi3"
8787   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8788         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8789                 (match_operand:QI 2 "general_operand" "")))
8790    (clobber (reg:CC FLAGS_REG))]
8791   "TARGET_QIMODE_MATH"
8792   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8793
8794 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8795 (define_insn "*andqi_1"
8796   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8797         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8798                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8799    (clobber (reg:CC FLAGS_REG))]
8800   "ix86_binary_operator_ok (AND, QImode, operands)"
8801   "@
8802    and{b}\t{%2, %0|%0, %2}
8803    and{b}\t{%2, %0|%0, %2}
8804    and{l}\t{%k2, %k0|%k0, %k2}"
8805   [(set_attr "type" "alu")
8806    (set_attr "mode" "QI,QI,SI")])
8807
8808 (define_insn "*andqi_1_slp"
8809   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8810         (and:QI (match_dup 0)
8811                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8812    (clobber (reg:CC FLAGS_REG))]
8813   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8814    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8815   "and{b}\t{%1, %0|%0, %1}"
8816   [(set_attr "type" "alu1")
8817    (set_attr "mode" "QI")])
8818
8819 (define_insn "*andqi_2_maybe_si"
8820   [(set (reg FLAGS_REG)
8821         (compare (and:QI
8822                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8823                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8824                  (const_int 0)))
8825    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8826         (and:QI (match_dup 1) (match_dup 2)))]
8827   "ix86_binary_operator_ok (AND, QImode, operands)
8828    && ix86_match_ccmode (insn,
8829                          CONST_INT_P (operands[2])
8830                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8831 {
8832   if (which_alternative == 2)
8833     {
8834       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8835         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8836       return "and{l}\t{%2, %k0|%k0, %2}";
8837     }
8838   return "and{b}\t{%2, %0|%0, %2}";
8839 }
8840   [(set_attr "type" "alu")
8841    (set_attr "mode" "QI,QI,SI")])
8842
8843 (define_insn "*andqi_2"
8844   [(set (reg FLAGS_REG)
8845         (compare (and:QI
8846                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8847                    (match_operand:QI 2 "general_operand" "qim,qi"))
8848                  (const_int 0)))
8849    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8850         (and:QI (match_dup 1) (match_dup 2)))]
8851   "ix86_match_ccmode (insn, CCNOmode)
8852    && ix86_binary_operator_ok (AND, QImode, operands)"
8853   "and{b}\t{%2, %0|%0, %2}"
8854   [(set_attr "type" "alu")
8855    (set_attr "mode" "QI")])
8856
8857 (define_insn "*andqi_2_slp"
8858   [(set (reg FLAGS_REG)
8859         (compare (and:QI
8860                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8861                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8862                  (const_int 0)))
8863    (set (strict_low_part (match_dup 0))
8864         (and:QI (match_dup 0) (match_dup 1)))]
8865   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8866    && ix86_match_ccmode (insn, CCNOmode)
8867    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8868   "and{b}\t{%1, %0|%0, %1}"
8869   [(set_attr "type" "alu1")
8870    (set_attr "mode" "QI")])
8871
8872 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8873 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8874 ;; for a QImode operand, which of course failed.
8875
8876 (define_insn "andqi_ext_0"
8877   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8878                          (const_int 8)
8879                          (const_int 8))
8880         (and:SI
8881           (zero_extract:SI
8882             (match_operand 1 "ext_register_operand" "0")
8883             (const_int 8)
8884             (const_int 8))
8885           (match_operand 2 "const_int_operand" "n")))
8886    (clobber (reg:CC FLAGS_REG))]
8887   ""
8888   "and{b}\t{%2, %h0|%h0, %2}"
8889   [(set_attr "type" "alu")
8890    (set_attr "length_immediate" "1")
8891    (set_attr "mode" "QI")])
8892
8893 ;; Generated by peephole translating test to and.  This shows up
8894 ;; often in fp comparisons.
8895
8896 (define_insn "*andqi_ext_0_cc"
8897   [(set (reg FLAGS_REG)
8898         (compare
8899           (and:SI
8900             (zero_extract:SI
8901               (match_operand 1 "ext_register_operand" "0")
8902               (const_int 8)
8903               (const_int 8))
8904             (match_operand 2 "const_int_operand" "n"))
8905           (const_int 0)))
8906    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8907                          (const_int 8)
8908                          (const_int 8))
8909         (and:SI
8910           (zero_extract:SI
8911             (match_dup 1)
8912             (const_int 8)
8913             (const_int 8))
8914           (match_dup 2)))]
8915   "ix86_match_ccmode (insn, CCNOmode)"
8916   "and{b}\t{%2, %h0|%h0, %2}"
8917   [(set_attr "type" "alu")
8918    (set_attr "length_immediate" "1")
8919    (set_attr "mode" "QI")])
8920
8921 (define_insn "*andqi_ext_1"
8922   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8923                          (const_int 8)
8924                          (const_int 8))
8925         (and:SI
8926           (zero_extract:SI
8927             (match_operand 1 "ext_register_operand" "0")
8928             (const_int 8)
8929             (const_int 8))
8930           (zero_extend:SI
8931             (match_operand:QI 2 "general_operand" "Qm"))))
8932    (clobber (reg:CC FLAGS_REG))]
8933   "!TARGET_64BIT"
8934   "and{b}\t{%2, %h0|%h0, %2}"
8935   [(set_attr "type" "alu")
8936    (set_attr "length_immediate" "0")
8937    (set_attr "mode" "QI")])
8938
8939 (define_insn "*andqi_ext_1_rex64"
8940   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8941                          (const_int 8)
8942                          (const_int 8))
8943         (and:SI
8944           (zero_extract:SI
8945             (match_operand 1 "ext_register_operand" "0")
8946             (const_int 8)
8947             (const_int 8))
8948           (zero_extend:SI
8949             (match_operand 2 "ext_register_operand" "Q"))))
8950    (clobber (reg:CC FLAGS_REG))]
8951   "TARGET_64BIT"
8952   "and{b}\t{%2, %h0|%h0, %2}"
8953   [(set_attr "type" "alu")
8954    (set_attr "length_immediate" "0")
8955    (set_attr "mode" "QI")])
8956
8957 (define_insn "*andqi_ext_2"
8958   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8959                          (const_int 8)
8960                          (const_int 8))
8961         (and:SI
8962           (zero_extract:SI
8963             (match_operand 1 "ext_register_operand" "%0")
8964             (const_int 8)
8965             (const_int 8))
8966           (zero_extract:SI
8967             (match_operand 2 "ext_register_operand" "Q")
8968             (const_int 8)
8969             (const_int 8))))
8970    (clobber (reg:CC FLAGS_REG))]
8971   ""
8972   "and{b}\t{%h2, %h0|%h0, %h2}"
8973   [(set_attr "type" "alu")
8974    (set_attr "length_immediate" "0")
8975    (set_attr "mode" "QI")])
8976
8977 ;; Convert wide AND instructions with immediate operand to shorter QImode
8978 ;; equivalents when possible.
8979 ;; Don't do the splitting with memory operands, since it introduces risk
8980 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8981 ;; for size, but that can (should?) be handled by generic code instead.
8982 (define_split
8983   [(set (match_operand 0 "register_operand" "")
8984         (and (match_operand 1 "register_operand" "")
8985              (match_operand 2 "const_int_operand" "")))
8986    (clobber (reg:CC FLAGS_REG))]
8987    "reload_completed
8988     && QI_REG_P (operands[0])
8989     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8990     && !(~INTVAL (operands[2]) & ~(255 << 8))
8991     && GET_MODE (operands[0]) != QImode"
8992   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8993                    (and:SI (zero_extract:SI (match_dup 1)
8994                                             (const_int 8) (const_int 8))
8995                            (match_dup 2)))
8996               (clobber (reg:CC FLAGS_REG))])]
8997   "operands[0] = gen_lowpart (SImode, operands[0]);
8998    operands[1] = gen_lowpart (SImode, operands[1]);
8999    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9000
9001 ;; Since AND can be encoded with sign extended immediate, this is only
9002 ;; profitable when 7th bit is not set.
9003 (define_split
9004   [(set (match_operand 0 "register_operand" "")
9005         (and (match_operand 1 "general_operand" "")
9006              (match_operand 2 "const_int_operand" "")))
9007    (clobber (reg:CC FLAGS_REG))]
9008    "reload_completed
9009     && ANY_QI_REG_P (operands[0])
9010     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9011     && !(~INTVAL (operands[2]) & ~255)
9012     && !(INTVAL (operands[2]) & 128)
9013     && GET_MODE (operands[0]) != QImode"
9014   [(parallel [(set (strict_low_part (match_dup 0))
9015                    (and:QI (match_dup 1)
9016                            (match_dup 2)))
9017               (clobber (reg:CC FLAGS_REG))])]
9018   "operands[0] = gen_lowpart (QImode, operands[0]);
9019    operands[1] = gen_lowpart (QImode, operands[1]);
9020    operands[2] = gen_lowpart (QImode, operands[2]);")
9021 \f
9022 ;; Logical inclusive OR instructions
9023
9024 ;; %%% This used to optimize known byte-wide and operations to memory.
9025 ;; If this is considered useful, it should be done with splitters.
9026
9027 (define_expand "iordi3"
9028   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9029         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9030                 (match_operand:DI 2 "x86_64_general_operand" "")))
9031    (clobber (reg:CC FLAGS_REG))]
9032   "TARGET_64BIT"
9033   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9034
9035 (define_insn "*iordi_1_rex64"
9036   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9037         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9038                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9039    (clobber (reg:CC FLAGS_REG))]
9040   "TARGET_64BIT
9041    && ix86_binary_operator_ok (IOR, DImode, operands)"
9042   "or{q}\t{%2, %0|%0, %2}"
9043   [(set_attr "type" "alu")
9044    (set_attr "mode" "DI")])
9045
9046 (define_insn "*iordi_2_rex64"
9047   [(set (reg FLAGS_REG)
9048         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9049                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9050                  (const_int 0)))
9051    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9052         (ior:DI (match_dup 1) (match_dup 2)))]
9053   "TARGET_64BIT
9054    && ix86_match_ccmode (insn, CCNOmode)
9055    && ix86_binary_operator_ok (IOR, DImode, operands)"
9056   "or{q}\t{%2, %0|%0, %2}"
9057   [(set_attr "type" "alu")
9058    (set_attr "mode" "DI")])
9059
9060 (define_insn "*iordi_3_rex64"
9061   [(set (reg FLAGS_REG)
9062         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9063                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9064                  (const_int 0)))
9065    (clobber (match_scratch:DI 0 "=r"))]
9066   "TARGET_64BIT
9067    && ix86_match_ccmode (insn, CCNOmode)
9068    && ix86_binary_operator_ok (IOR, DImode, operands)"
9069   "or{q}\t{%2, %0|%0, %2}"
9070   [(set_attr "type" "alu")
9071    (set_attr "mode" "DI")])
9072
9073
9074 (define_expand "iorsi3"
9075   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9076         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9077                 (match_operand:SI 2 "general_operand" "")))
9078    (clobber (reg:CC FLAGS_REG))]
9079   ""
9080   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9081
9082 (define_insn "*iorsi_1"
9083   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9084         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9085                 (match_operand:SI 2 "general_operand" "ri,g")))
9086    (clobber (reg:CC FLAGS_REG))]
9087   "ix86_binary_operator_ok (IOR, SImode, operands)"
9088   "or{l}\t{%2, %0|%0, %2}"
9089   [(set_attr "type" "alu")
9090    (set_attr "mode" "SI")])
9091
9092 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9093 (define_insn "*iorsi_1_zext"
9094   [(set (match_operand:DI 0 "register_operand" "=r")
9095         (zero_extend:DI
9096           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9097                   (match_operand:SI 2 "general_operand" "g"))))
9098    (clobber (reg:CC FLAGS_REG))]
9099   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9100   "or{l}\t{%2, %k0|%k0, %2}"
9101   [(set_attr "type" "alu")
9102    (set_attr "mode" "SI")])
9103
9104 (define_insn "*iorsi_1_zext_imm"
9105   [(set (match_operand:DI 0 "register_operand" "=r")
9106         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9107                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9108    (clobber (reg:CC FLAGS_REG))]
9109   "TARGET_64BIT"
9110   "or{l}\t{%2, %k0|%k0, %2}"
9111   [(set_attr "type" "alu")
9112    (set_attr "mode" "SI")])
9113
9114 (define_insn "*iorsi_2"
9115   [(set (reg FLAGS_REG)
9116         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9117                          (match_operand:SI 2 "general_operand" "g,ri"))
9118                  (const_int 0)))
9119    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9120         (ior:SI (match_dup 1) (match_dup 2)))]
9121   "ix86_match_ccmode (insn, CCNOmode)
9122    && ix86_binary_operator_ok (IOR, SImode, operands)"
9123   "or{l}\t{%2, %0|%0, %2}"
9124   [(set_attr "type" "alu")
9125    (set_attr "mode" "SI")])
9126
9127 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9128 ;; ??? Special case for immediate operand is missing - it is tricky.
9129 (define_insn "*iorsi_2_zext"
9130   [(set (reg FLAGS_REG)
9131         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9132                          (match_operand:SI 2 "general_operand" "g"))
9133                  (const_int 0)))
9134    (set (match_operand:DI 0 "register_operand" "=r")
9135         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9136   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9137    && ix86_binary_operator_ok (IOR, SImode, operands)"
9138   "or{l}\t{%2, %k0|%k0, %2}"
9139   [(set_attr "type" "alu")
9140    (set_attr "mode" "SI")])
9141
9142 (define_insn "*iorsi_2_zext_imm"
9143   [(set (reg FLAGS_REG)
9144         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9145                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9146                  (const_int 0)))
9147    (set (match_operand:DI 0 "register_operand" "=r")
9148         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9149   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9150    && ix86_binary_operator_ok (IOR, SImode, operands)"
9151   "or{l}\t{%2, %k0|%k0, %2}"
9152   [(set_attr "type" "alu")
9153    (set_attr "mode" "SI")])
9154
9155 (define_insn "*iorsi_3"
9156   [(set (reg FLAGS_REG)
9157         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9158                          (match_operand:SI 2 "general_operand" "g"))
9159                  (const_int 0)))
9160    (clobber (match_scratch:SI 0 "=r"))]
9161   "ix86_match_ccmode (insn, CCNOmode)
9162    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9163   "or{l}\t{%2, %0|%0, %2}"
9164   [(set_attr "type" "alu")
9165    (set_attr "mode" "SI")])
9166
9167 (define_expand "iorhi3"
9168   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9169         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9170                 (match_operand:HI 2 "general_operand" "")))
9171    (clobber (reg:CC FLAGS_REG))]
9172   "TARGET_HIMODE_MATH"
9173   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9174
9175 (define_insn "*iorhi_1"
9176   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9177         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9178                 (match_operand:HI 2 "general_operand" "g,ri")))
9179    (clobber (reg:CC FLAGS_REG))]
9180   "ix86_binary_operator_ok (IOR, HImode, operands)"
9181   "or{w}\t{%2, %0|%0, %2}"
9182   [(set_attr "type" "alu")
9183    (set_attr "mode" "HI")])
9184
9185 (define_insn "*iorhi_2"
9186   [(set (reg FLAGS_REG)
9187         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9188                          (match_operand:HI 2 "general_operand" "g,ri"))
9189                  (const_int 0)))
9190    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9191         (ior:HI (match_dup 1) (match_dup 2)))]
9192   "ix86_match_ccmode (insn, CCNOmode)
9193    && ix86_binary_operator_ok (IOR, HImode, operands)"
9194   "or{w}\t{%2, %0|%0, %2}"
9195   [(set_attr "type" "alu")
9196    (set_attr "mode" "HI")])
9197
9198 (define_insn "*iorhi_3"
9199   [(set (reg FLAGS_REG)
9200         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9201                          (match_operand:HI 2 "general_operand" "g"))
9202                  (const_int 0)))
9203    (clobber (match_scratch:HI 0 "=r"))]
9204   "ix86_match_ccmode (insn, CCNOmode)
9205    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9206   "or{w}\t{%2, %0|%0, %2}"
9207   [(set_attr "type" "alu")
9208    (set_attr "mode" "HI")])
9209
9210 (define_expand "iorqi3"
9211   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9212         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9213                 (match_operand:QI 2 "general_operand" "")))
9214    (clobber (reg:CC FLAGS_REG))]
9215   "TARGET_QIMODE_MATH"
9216   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9217
9218 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9219 (define_insn "*iorqi_1"
9220   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9221         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9222                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9223    (clobber (reg:CC FLAGS_REG))]
9224   "ix86_binary_operator_ok (IOR, QImode, operands)"
9225   "@
9226    or{b}\t{%2, %0|%0, %2}
9227    or{b}\t{%2, %0|%0, %2}
9228    or{l}\t{%k2, %k0|%k0, %k2}"
9229   [(set_attr "type" "alu")
9230    (set_attr "mode" "QI,QI,SI")])
9231
9232 (define_insn "*iorqi_1_slp"
9233   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9234         (ior:QI (match_dup 0)
9235                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9236    (clobber (reg:CC FLAGS_REG))]
9237   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9238    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9239   "or{b}\t{%1, %0|%0, %1}"
9240   [(set_attr "type" "alu1")
9241    (set_attr "mode" "QI")])
9242
9243 (define_insn "*iorqi_2"
9244   [(set (reg FLAGS_REG)
9245         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9246                          (match_operand:QI 2 "general_operand" "qim,qi"))
9247                  (const_int 0)))
9248    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9249         (ior:QI (match_dup 1) (match_dup 2)))]
9250   "ix86_match_ccmode (insn, CCNOmode)
9251    && ix86_binary_operator_ok (IOR, QImode, operands)"
9252   "or{b}\t{%2, %0|%0, %2}"
9253   [(set_attr "type" "alu")
9254    (set_attr "mode" "QI")])
9255
9256 (define_insn "*iorqi_2_slp"
9257   [(set (reg FLAGS_REG)
9258         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9259                          (match_operand:QI 1 "general_operand" "qim,qi"))
9260                  (const_int 0)))
9261    (set (strict_low_part (match_dup 0))
9262         (ior:QI (match_dup 0) (match_dup 1)))]
9263   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9264    && ix86_match_ccmode (insn, CCNOmode)
9265    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9266   "or{b}\t{%1, %0|%0, %1}"
9267   [(set_attr "type" "alu1")
9268    (set_attr "mode" "QI")])
9269
9270 (define_insn "*iorqi_3"
9271   [(set (reg FLAGS_REG)
9272         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9273                          (match_operand:QI 2 "general_operand" "qim"))
9274                  (const_int 0)))
9275    (clobber (match_scratch:QI 0 "=q"))]
9276   "ix86_match_ccmode (insn, CCNOmode)
9277    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9278   "or{b}\t{%2, %0|%0, %2}"
9279   [(set_attr "type" "alu")
9280    (set_attr "mode" "QI")])
9281
9282 (define_insn "iorqi_ext_0"
9283   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9284                          (const_int 8)
9285                          (const_int 8))
9286         (ior:SI
9287           (zero_extract:SI
9288             (match_operand 1 "ext_register_operand" "0")
9289             (const_int 8)
9290             (const_int 8))
9291           (match_operand 2 "const_int_operand" "n")))
9292    (clobber (reg:CC FLAGS_REG))]
9293   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9294   "or{b}\t{%2, %h0|%h0, %2}"
9295   [(set_attr "type" "alu")
9296    (set_attr "length_immediate" "1")
9297    (set_attr "mode" "QI")])
9298
9299 (define_insn "*iorqi_ext_1"
9300   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9301                          (const_int 8)
9302                          (const_int 8))
9303         (ior:SI
9304           (zero_extract:SI
9305             (match_operand 1 "ext_register_operand" "0")
9306             (const_int 8)
9307             (const_int 8))
9308           (zero_extend:SI
9309             (match_operand:QI 2 "general_operand" "Qm"))))
9310    (clobber (reg:CC FLAGS_REG))]
9311   "!TARGET_64BIT
9312    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9313   "or{b}\t{%2, %h0|%h0, %2}"
9314   [(set_attr "type" "alu")
9315    (set_attr "length_immediate" "0")
9316    (set_attr "mode" "QI")])
9317
9318 (define_insn "*iorqi_ext_1_rex64"
9319   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9320                          (const_int 8)
9321                          (const_int 8))
9322         (ior:SI
9323           (zero_extract:SI
9324             (match_operand 1 "ext_register_operand" "0")
9325             (const_int 8)
9326             (const_int 8))
9327           (zero_extend:SI
9328             (match_operand 2 "ext_register_operand" "Q"))))
9329    (clobber (reg:CC FLAGS_REG))]
9330   "TARGET_64BIT
9331    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9332   "or{b}\t{%2, %h0|%h0, %2}"
9333   [(set_attr "type" "alu")
9334    (set_attr "length_immediate" "0")
9335    (set_attr "mode" "QI")])
9336
9337 (define_insn "*iorqi_ext_2"
9338   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9339                          (const_int 8)
9340                          (const_int 8))
9341         (ior:SI
9342           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9343                            (const_int 8)
9344                            (const_int 8))
9345           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9346                            (const_int 8)
9347                            (const_int 8))))
9348    (clobber (reg:CC FLAGS_REG))]
9349   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9350   "ior{b}\t{%h2, %h0|%h0, %h2}"
9351   [(set_attr "type" "alu")
9352    (set_attr "length_immediate" "0")
9353    (set_attr "mode" "QI")])
9354
9355 (define_split
9356   [(set (match_operand 0 "register_operand" "")
9357         (ior (match_operand 1 "register_operand" "")
9358              (match_operand 2 "const_int_operand" "")))
9359    (clobber (reg:CC FLAGS_REG))]
9360    "reload_completed
9361     && QI_REG_P (operands[0])
9362     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9363     && !(INTVAL (operands[2]) & ~(255 << 8))
9364     && GET_MODE (operands[0]) != QImode"
9365   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9366                    (ior:SI (zero_extract:SI (match_dup 1)
9367                                             (const_int 8) (const_int 8))
9368                            (match_dup 2)))
9369               (clobber (reg:CC FLAGS_REG))])]
9370   "operands[0] = gen_lowpart (SImode, operands[0]);
9371    operands[1] = gen_lowpart (SImode, operands[1]);
9372    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9373
9374 ;; Since OR can be encoded with sign extended immediate, this is only
9375 ;; profitable when 7th bit is set.
9376 (define_split
9377   [(set (match_operand 0 "register_operand" "")
9378         (ior (match_operand 1 "general_operand" "")
9379              (match_operand 2 "const_int_operand" "")))
9380    (clobber (reg:CC FLAGS_REG))]
9381    "reload_completed
9382     && ANY_QI_REG_P (operands[0])
9383     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9384     && !(INTVAL (operands[2]) & ~255)
9385     && (INTVAL (operands[2]) & 128)
9386     && GET_MODE (operands[0]) != QImode"
9387   [(parallel [(set (strict_low_part (match_dup 0))
9388                    (ior:QI (match_dup 1)
9389                            (match_dup 2)))
9390               (clobber (reg:CC FLAGS_REG))])]
9391   "operands[0] = gen_lowpart (QImode, operands[0]);
9392    operands[1] = gen_lowpart (QImode, operands[1]);
9393    operands[2] = gen_lowpart (QImode, operands[2]);")
9394 \f
9395 ;; Logical XOR instructions
9396
9397 ;; %%% This used to optimize known byte-wide and operations to memory.
9398 ;; If this is considered useful, it should be done with splitters.
9399
9400 (define_expand "xordi3"
9401   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9402         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9403                 (match_operand:DI 2 "x86_64_general_operand" "")))
9404    (clobber (reg:CC FLAGS_REG))]
9405   "TARGET_64BIT"
9406   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9407
9408 (define_insn "*xordi_1_rex64"
9409   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9410         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9411                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9412    (clobber (reg:CC FLAGS_REG))]
9413   "TARGET_64BIT
9414    && ix86_binary_operator_ok (XOR, DImode, operands)"
9415   "@
9416    xor{q}\t{%2, %0|%0, %2}
9417    xor{q}\t{%2, %0|%0, %2}"
9418   [(set_attr "type" "alu")
9419    (set_attr "mode" "DI,DI")])
9420
9421 (define_insn "*xordi_2_rex64"
9422   [(set (reg FLAGS_REG)
9423         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9424                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9425                  (const_int 0)))
9426    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9427         (xor:DI (match_dup 1) (match_dup 2)))]
9428   "TARGET_64BIT
9429    && ix86_match_ccmode (insn, CCNOmode)
9430    && ix86_binary_operator_ok (XOR, DImode, operands)"
9431   "@
9432    xor{q}\t{%2, %0|%0, %2}
9433    xor{q}\t{%2, %0|%0, %2}"
9434   [(set_attr "type" "alu")
9435    (set_attr "mode" "DI,DI")])
9436
9437 (define_insn "*xordi_3_rex64"
9438   [(set (reg FLAGS_REG)
9439         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9440                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9441                  (const_int 0)))
9442    (clobber (match_scratch:DI 0 "=r"))]
9443   "TARGET_64BIT
9444    && ix86_match_ccmode (insn, CCNOmode)
9445    && ix86_binary_operator_ok (XOR, DImode, operands)"
9446   "xor{q}\t{%2, %0|%0, %2}"
9447   [(set_attr "type" "alu")
9448    (set_attr "mode" "DI")])
9449
9450 (define_expand "xorsi3"
9451   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9452         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9453                 (match_operand:SI 2 "general_operand" "")))
9454    (clobber (reg:CC FLAGS_REG))]
9455   ""
9456   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9457
9458 (define_insn "*xorsi_1"
9459   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9460         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9461                 (match_operand:SI 2 "general_operand" "ri,rm")))
9462    (clobber (reg:CC FLAGS_REG))]
9463   "ix86_binary_operator_ok (XOR, SImode, operands)"
9464   "xor{l}\t{%2, %0|%0, %2}"
9465   [(set_attr "type" "alu")
9466    (set_attr "mode" "SI")])
9467
9468 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9469 ;; Add speccase for immediates
9470 (define_insn "*xorsi_1_zext"
9471   [(set (match_operand:DI 0 "register_operand" "=r")
9472         (zero_extend:DI
9473           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9474                   (match_operand:SI 2 "general_operand" "g"))))
9475    (clobber (reg:CC FLAGS_REG))]
9476   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9477   "xor{l}\t{%2, %k0|%k0, %2}"
9478   [(set_attr "type" "alu")
9479    (set_attr "mode" "SI")])
9480
9481 (define_insn "*xorsi_1_zext_imm"
9482   [(set (match_operand:DI 0 "register_operand" "=r")
9483         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9484                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9485    (clobber (reg:CC FLAGS_REG))]
9486   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9487   "xor{l}\t{%2, %k0|%k0, %2}"
9488   [(set_attr "type" "alu")
9489    (set_attr "mode" "SI")])
9490
9491 (define_insn "*xorsi_2"
9492   [(set (reg FLAGS_REG)
9493         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9494                          (match_operand:SI 2 "general_operand" "g,ri"))
9495                  (const_int 0)))
9496    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9497         (xor:SI (match_dup 1) (match_dup 2)))]
9498   "ix86_match_ccmode (insn, CCNOmode)
9499    && ix86_binary_operator_ok (XOR, SImode, operands)"
9500   "xor{l}\t{%2, %0|%0, %2}"
9501   [(set_attr "type" "alu")
9502    (set_attr "mode" "SI")])
9503
9504 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9505 ;; ??? Special case for immediate operand is missing - it is tricky.
9506 (define_insn "*xorsi_2_zext"
9507   [(set (reg FLAGS_REG)
9508         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9509                          (match_operand:SI 2 "general_operand" "g"))
9510                  (const_int 0)))
9511    (set (match_operand:DI 0 "register_operand" "=r")
9512         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9513   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9514    && ix86_binary_operator_ok (XOR, SImode, operands)"
9515   "xor{l}\t{%2, %k0|%k0, %2}"
9516   [(set_attr "type" "alu")
9517    (set_attr "mode" "SI")])
9518
9519 (define_insn "*xorsi_2_zext_imm"
9520   [(set (reg FLAGS_REG)
9521         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9522                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9523                  (const_int 0)))
9524    (set (match_operand:DI 0 "register_operand" "=r")
9525         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9526   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9527    && ix86_binary_operator_ok (XOR, SImode, operands)"
9528   "xor{l}\t{%2, %k0|%k0, %2}"
9529   [(set_attr "type" "alu")
9530    (set_attr "mode" "SI")])
9531
9532 (define_insn "*xorsi_3"
9533   [(set (reg FLAGS_REG)
9534         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9535                          (match_operand:SI 2 "general_operand" "g"))
9536                  (const_int 0)))
9537    (clobber (match_scratch:SI 0 "=r"))]
9538   "ix86_match_ccmode (insn, CCNOmode)
9539    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9540   "xor{l}\t{%2, %0|%0, %2}"
9541   [(set_attr "type" "alu")
9542    (set_attr "mode" "SI")])
9543
9544 (define_expand "xorhi3"
9545   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9546         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9547                 (match_operand:HI 2 "general_operand" "")))
9548    (clobber (reg:CC FLAGS_REG))]
9549   "TARGET_HIMODE_MATH"
9550   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9551
9552 (define_insn "*xorhi_1"
9553   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9554         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9555                 (match_operand:HI 2 "general_operand" "g,ri")))
9556    (clobber (reg:CC FLAGS_REG))]
9557   "ix86_binary_operator_ok (XOR, HImode, operands)"
9558   "xor{w}\t{%2, %0|%0, %2}"
9559   [(set_attr "type" "alu")
9560    (set_attr "mode" "HI")])
9561
9562 (define_insn "*xorhi_2"
9563   [(set (reg FLAGS_REG)
9564         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9565                          (match_operand:HI 2 "general_operand" "g,ri"))
9566                  (const_int 0)))
9567    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9568         (xor:HI (match_dup 1) (match_dup 2)))]
9569   "ix86_match_ccmode (insn, CCNOmode)
9570    && ix86_binary_operator_ok (XOR, HImode, operands)"
9571   "xor{w}\t{%2, %0|%0, %2}"
9572   [(set_attr "type" "alu")
9573    (set_attr "mode" "HI")])
9574
9575 (define_insn "*xorhi_3"
9576   [(set (reg FLAGS_REG)
9577         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9578                          (match_operand:HI 2 "general_operand" "g"))
9579                  (const_int 0)))
9580    (clobber (match_scratch:HI 0 "=r"))]
9581   "ix86_match_ccmode (insn, CCNOmode)
9582    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9583   "xor{w}\t{%2, %0|%0, %2}"
9584   [(set_attr "type" "alu")
9585    (set_attr "mode" "HI")])
9586
9587 (define_expand "xorqi3"
9588   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9589         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9590                 (match_operand:QI 2 "general_operand" "")))
9591    (clobber (reg:CC FLAGS_REG))]
9592   "TARGET_QIMODE_MATH"
9593   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9594
9595 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9596 (define_insn "*xorqi_1"
9597   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9598         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9599                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9600    (clobber (reg:CC FLAGS_REG))]
9601   "ix86_binary_operator_ok (XOR, QImode, operands)"
9602   "@
9603    xor{b}\t{%2, %0|%0, %2}
9604    xor{b}\t{%2, %0|%0, %2}
9605    xor{l}\t{%k2, %k0|%k0, %k2}"
9606   [(set_attr "type" "alu")
9607    (set_attr "mode" "QI,QI,SI")])
9608
9609 (define_insn "*xorqi_1_slp"
9610   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9611         (xor:QI (match_dup 0)
9612                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9613    (clobber (reg:CC FLAGS_REG))]
9614   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9615    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9616   "xor{b}\t{%1, %0|%0, %1}"
9617   [(set_attr "type" "alu1")
9618    (set_attr "mode" "QI")])
9619
9620 (define_insn "xorqi_ext_0"
9621   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9622                          (const_int 8)
9623                          (const_int 8))
9624         (xor:SI
9625           (zero_extract:SI
9626             (match_operand 1 "ext_register_operand" "0")
9627             (const_int 8)
9628             (const_int 8))
9629           (match_operand 2 "const_int_operand" "n")))
9630    (clobber (reg:CC FLAGS_REG))]
9631   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9632   "xor{b}\t{%2, %h0|%h0, %2}"
9633   [(set_attr "type" "alu")
9634    (set_attr "length_immediate" "1")
9635    (set_attr "mode" "QI")])
9636
9637 (define_insn "*xorqi_ext_1"
9638   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9639                          (const_int 8)
9640                          (const_int 8))
9641         (xor:SI
9642           (zero_extract:SI
9643             (match_operand 1 "ext_register_operand" "0")
9644             (const_int 8)
9645             (const_int 8))
9646           (zero_extend:SI
9647             (match_operand:QI 2 "general_operand" "Qm"))))
9648    (clobber (reg:CC FLAGS_REG))]
9649   "!TARGET_64BIT
9650    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9651   "xor{b}\t{%2, %h0|%h0, %2}"
9652   [(set_attr "type" "alu")
9653    (set_attr "length_immediate" "0")
9654    (set_attr "mode" "QI")])
9655
9656 (define_insn "*xorqi_ext_1_rex64"
9657   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9658                          (const_int 8)
9659                          (const_int 8))
9660         (xor:SI
9661           (zero_extract:SI
9662             (match_operand 1 "ext_register_operand" "0")
9663             (const_int 8)
9664             (const_int 8))
9665           (zero_extend:SI
9666             (match_operand 2 "ext_register_operand" "Q"))))
9667    (clobber (reg:CC FLAGS_REG))]
9668   "TARGET_64BIT
9669    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9670   "xor{b}\t{%2, %h0|%h0, %2}"
9671   [(set_attr "type" "alu")
9672    (set_attr "length_immediate" "0")
9673    (set_attr "mode" "QI")])
9674
9675 (define_insn "*xorqi_ext_2"
9676   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9677                          (const_int 8)
9678                          (const_int 8))
9679         (xor:SI
9680           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9681                            (const_int 8)
9682                            (const_int 8))
9683           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9684                            (const_int 8)
9685                            (const_int 8))))
9686    (clobber (reg:CC FLAGS_REG))]
9687   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9688   "xor{b}\t{%h2, %h0|%h0, %h2}"
9689   [(set_attr "type" "alu")
9690    (set_attr "length_immediate" "0")
9691    (set_attr "mode" "QI")])
9692
9693 (define_insn "*xorqi_cc_1"
9694   [(set (reg FLAGS_REG)
9695         (compare
9696           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9697                   (match_operand:QI 2 "general_operand" "qim,qi"))
9698           (const_int 0)))
9699    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9700         (xor:QI (match_dup 1) (match_dup 2)))]
9701   "ix86_match_ccmode (insn, CCNOmode)
9702    && ix86_binary_operator_ok (XOR, QImode, operands)"
9703   "xor{b}\t{%2, %0|%0, %2}"
9704   [(set_attr "type" "alu")
9705    (set_attr "mode" "QI")])
9706
9707 (define_insn "*xorqi_2_slp"
9708   [(set (reg FLAGS_REG)
9709         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9710                          (match_operand:QI 1 "general_operand" "qim,qi"))
9711                  (const_int 0)))
9712    (set (strict_low_part (match_dup 0))
9713         (xor:QI (match_dup 0) (match_dup 1)))]
9714   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9715    && ix86_match_ccmode (insn, CCNOmode)
9716    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9717   "xor{b}\t{%1, %0|%0, %1}"
9718   [(set_attr "type" "alu1")
9719    (set_attr "mode" "QI")])
9720
9721 (define_insn "*xorqi_cc_2"
9722   [(set (reg FLAGS_REG)
9723         (compare
9724           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9725                   (match_operand:QI 2 "general_operand" "qim"))
9726           (const_int 0)))
9727    (clobber (match_scratch:QI 0 "=q"))]
9728   "ix86_match_ccmode (insn, CCNOmode)
9729    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9730   "xor{b}\t{%2, %0|%0, %2}"
9731   [(set_attr "type" "alu")
9732    (set_attr "mode" "QI")])
9733
9734 (define_insn "*xorqi_cc_ext_1"
9735   [(set (reg FLAGS_REG)
9736         (compare
9737           (xor:SI
9738             (zero_extract:SI
9739               (match_operand 1 "ext_register_operand" "0")
9740               (const_int 8)
9741               (const_int 8))
9742             (match_operand:QI 2 "general_operand" "qmn"))
9743           (const_int 0)))
9744    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9745                          (const_int 8)
9746                          (const_int 8))
9747         (xor:SI
9748           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9749           (match_dup 2)))]
9750   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9751   "xor{b}\t{%2, %h0|%h0, %2}"
9752   [(set_attr "type" "alu")
9753    (set_attr "mode" "QI")])
9754
9755 (define_insn "*xorqi_cc_ext_1_rex64"
9756   [(set (reg FLAGS_REG)
9757         (compare
9758           (xor:SI
9759             (zero_extract:SI
9760               (match_operand 1 "ext_register_operand" "0")
9761               (const_int 8)
9762               (const_int 8))
9763             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9764           (const_int 0)))
9765    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9766                          (const_int 8)
9767                          (const_int 8))
9768         (xor:SI
9769           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9770           (match_dup 2)))]
9771   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9772   "xor{b}\t{%2, %h0|%h0, %2}"
9773   [(set_attr "type" "alu")
9774    (set_attr "mode" "QI")])
9775
9776 (define_expand "xorqi_cc_ext_1"
9777   [(parallel [
9778      (set (reg:CCNO FLAGS_REG)
9779           (compare:CCNO
9780             (xor:SI
9781               (zero_extract:SI
9782                 (match_operand 1 "ext_register_operand" "")
9783                 (const_int 8)
9784                 (const_int 8))
9785               (match_operand:QI 2 "general_operand" ""))
9786             (const_int 0)))
9787      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9788                            (const_int 8)
9789                            (const_int 8))
9790           (xor:SI
9791             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9792             (match_dup 2)))])]
9793   ""
9794   "")
9795
9796 (define_split
9797   [(set (match_operand 0 "register_operand" "")
9798         (xor (match_operand 1 "register_operand" "")
9799              (match_operand 2 "const_int_operand" "")))
9800    (clobber (reg:CC FLAGS_REG))]
9801    "reload_completed
9802     && QI_REG_P (operands[0])
9803     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9804     && !(INTVAL (operands[2]) & ~(255 << 8))
9805     && GET_MODE (operands[0]) != QImode"
9806   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9807                    (xor:SI (zero_extract:SI (match_dup 1)
9808                                             (const_int 8) (const_int 8))
9809                            (match_dup 2)))
9810               (clobber (reg:CC FLAGS_REG))])]
9811   "operands[0] = gen_lowpart (SImode, operands[0]);
9812    operands[1] = gen_lowpart (SImode, operands[1]);
9813    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9814
9815 ;; Since XOR can be encoded with sign extended immediate, this is only
9816 ;; profitable when 7th bit is set.
9817 (define_split
9818   [(set (match_operand 0 "register_operand" "")
9819         (xor (match_operand 1 "general_operand" "")
9820              (match_operand 2 "const_int_operand" "")))
9821    (clobber (reg:CC FLAGS_REG))]
9822    "reload_completed
9823     && ANY_QI_REG_P (operands[0])
9824     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9825     && !(INTVAL (operands[2]) & ~255)
9826     && (INTVAL (operands[2]) & 128)
9827     && GET_MODE (operands[0]) != QImode"
9828   [(parallel [(set (strict_low_part (match_dup 0))
9829                    (xor:QI (match_dup 1)
9830                            (match_dup 2)))
9831               (clobber (reg:CC FLAGS_REG))])]
9832   "operands[0] = gen_lowpart (QImode, operands[0]);
9833    operands[1] = gen_lowpart (QImode, operands[1]);
9834    operands[2] = gen_lowpart (QImode, operands[2]);")
9835 \f
9836 ;; Negation instructions
9837
9838 (define_expand "negti2"
9839   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9840                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9841               (clobber (reg:CC FLAGS_REG))])]
9842   "TARGET_64BIT"
9843   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9844
9845 (define_insn "*negti2_1"
9846   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9847         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9848    (clobber (reg:CC FLAGS_REG))]
9849   "TARGET_64BIT
9850    && ix86_unary_operator_ok (NEG, TImode, operands)"
9851   "#")
9852
9853 (define_split
9854   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9855         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9856    (clobber (reg:CC FLAGS_REG))]
9857   "TARGET_64BIT && reload_completed"
9858   [(parallel
9859     [(set (reg:CCZ FLAGS_REG)
9860           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9861      (set (match_dup 0) (neg:DI (match_dup 2)))])
9862    (parallel
9863     [(set (match_dup 1)
9864           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9865                             (match_dup 3))
9866                    (const_int 0)))
9867      (clobber (reg:CC FLAGS_REG))])
9868    (parallel
9869     [(set (match_dup 1)
9870           (neg:DI (match_dup 1)))
9871      (clobber (reg:CC FLAGS_REG))])]
9872   "split_ti (operands+1, 1, operands+2, operands+3);
9873    split_ti (operands+0, 1, operands+0, operands+1);")
9874
9875 (define_expand "negdi2"
9876   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9877                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9878               (clobber (reg:CC FLAGS_REG))])]
9879   ""
9880   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9881
9882 (define_insn "*negdi2_1"
9883   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9884         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9885    (clobber (reg:CC FLAGS_REG))]
9886   "!TARGET_64BIT
9887    && ix86_unary_operator_ok (NEG, DImode, operands)"
9888   "#")
9889
9890 (define_split
9891   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9892         (neg:DI (match_operand:DI 1 "general_operand" "")))
9893    (clobber (reg:CC FLAGS_REG))]
9894   "!TARGET_64BIT && reload_completed"
9895   [(parallel
9896     [(set (reg:CCZ FLAGS_REG)
9897           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9898      (set (match_dup 0) (neg:SI (match_dup 2)))])
9899    (parallel
9900     [(set (match_dup 1)
9901           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9902                             (match_dup 3))
9903                    (const_int 0)))
9904      (clobber (reg:CC FLAGS_REG))])
9905    (parallel
9906     [(set (match_dup 1)
9907           (neg:SI (match_dup 1)))
9908      (clobber (reg:CC FLAGS_REG))])]
9909   "split_di (operands+1, 1, operands+2, operands+3);
9910    split_di (operands+0, 1, operands+0, operands+1);")
9911
9912 (define_insn "*negdi2_1_rex64"
9913   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9914         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9915    (clobber (reg:CC FLAGS_REG))]
9916   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9917   "neg{q}\t%0"
9918   [(set_attr "type" "negnot")
9919    (set_attr "mode" "DI")])
9920
9921 ;; The problem with neg is that it does not perform (compare x 0),
9922 ;; it really performs (compare 0 x), which leaves us with the zero
9923 ;; flag being the only useful item.
9924
9925 (define_insn "*negdi2_cmpz_rex64"
9926   [(set (reg:CCZ FLAGS_REG)
9927         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9928                      (const_int 0)))
9929    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9930         (neg:DI (match_dup 1)))]
9931   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9932   "neg{q}\t%0"
9933   [(set_attr "type" "negnot")
9934    (set_attr "mode" "DI")])
9935
9936
9937 (define_expand "negsi2"
9938   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9939                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9940               (clobber (reg:CC FLAGS_REG))])]
9941   ""
9942   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9943
9944 (define_insn "*negsi2_1"
9945   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9946         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9947    (clobber (reg:CC FLAGS_REG))]
9948   "ix86_unary_operator_ok (NEG, SImode, operands)"
9949   "neg{l}\t%0"
9950   [(set_attr "type" "negnot")
9951    (set_attr "mode" "SI")])
9952
9953 ;; Combine is quite creative about this pattern.
9954 (define_insn "*negsi2_1_zext"
9955   [(set (match_operand:DI 0 "register_operand" "=r")
9956         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9957                                         (const_int 32)))
9958                      (const_int 32)))
9959    (clobber (reg:CC FLAGS_REG))]
9960   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9961   "neg{l}\t%k0"
9962   [(set_attr "type" "negnot")
9963    (set_attr "mode" "SI")])
9964
9965 ;; The problem with neg is that it does not perform (compare x 0),
9966 ;; it really performs (compare 0 x), which leaves us with the zero
9967 ;; flag being the only useful item.
9968
9969 (define_insn "*negsi2_cmpz"
9970   [(set (reg:CCZ FLAGS_REG)
9971         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9972                      (const_int 0)))
9973    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9974         (neg:SI (match_dup 1)))]
9975   "ix86_unary_operator_ok (NEG, SImode, operands)"
9976   "neg{l}\t%0"
9977   [(set_attr "type" "negnot")
9978    (set_attr "mode" "SI")])
9979
9980 (define_insn "*negsi2_cmpz_zext"
9981   [(set (reg:CCZ FLAGS_REG)
9982         (compare:CCZ (lshiftrt:DI
9983                        (neg:DI (ashift:DI
9984                                  (match_operand:DI 1 "register_operand" "0")
9985                                  (const_int 32)))
9986                        (const_int 32))
9987                      (const_int 0)))
9988    (set (match_operand:DI 0 "register_operand" "=r")
9989         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9990                                         (const_int 32)))
9991                      (const_int 32)))]
9992   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9993   "neg{l}\t%k0"
9994   [(set_attr "type" "negnot")
9995    (set_attr "mode" "SI")])
9996
9997 (define_expand "neghi2"
9998   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9999                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10000               (clobber (reg:CC FLAGS_REG))])]
10001   "TARGET_HIMODE_MATH"
10002   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10003
10004 (define_insn "*neghi2_1"
10005   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10006         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10007    (clobber (reg:CC FLAGS_REG))]
10008   "ix86_unary_operator_ok (NEG, HImode, operands)"
10009   "neg{w}\t%0"
10010   [(set_attr "type" "negnot")
10011    (set_attr "mode" "HI")])
10012
10013 (define_insn "*neghi2_cmpz"
10014   [(set (reg:CCZ FLAGS_REG)
10015         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10016                      (const_int 0)))
10017    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10018         (neg:HI (match_dup 1)))]
10019   "ix86_unary_operator_ok (NEG, HImode, operands)"
10020   "neg{w}\t%0"
10021   [(set_attr "type" "negnot")
10022    (set_attr "mode" "HI")])
10023
10024 (define_expand "negqi2"
10025   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10026                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10027               (clobber (reg:CC FLAGS_REG))])]
10028   "TARGET_QIMODE_MATH"
10029   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10030
10031 (define_insn "*negqi2_1"
10032   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10033         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10034    (clobber (reg:CC FLAGS_REG))]
10035   "ix86_unary_operator_ok (NEG, QImode, operands)"
10036   "neg{b}\t%0"
10037   [(set_attr "type" "negnot")
10038    (set_attr "mode" "QI")])
10039
10040 (define_insn "*negqi2_cmpz"
10041   [(set (reg:CCZ FLAGS_REG)
10042         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10043                      (const_int 0)))
10044    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10045         (neg:QI (match_dup 1)))]
10046   "ix86_unary_operator_ok (NEG, QImode, operands)"
10047   "neg{b}\t%0"
10048   [(set_attr "type" "negnot")
10049    (set_attr "mode" "QI")])
10050
10051 ;; Changing of sign for FP values is doable using integer unit too.
10052
10053 (define_expand "negsf2"
10054   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10055         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10056   "TARGET_80387 || TARGET_SSE_MATH"
10057   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
10058
10059 (define_expand "abssf2"
10060   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10061         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10062   "TARGET_80387 || TARGET_SSE_MATH"
10063   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
10064
10065 (define_insn "*absnegsf2_mixed"
10066   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
10067         (match_operator:SF 3 "absneg_operator"
10068           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
10069    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
10070    (clobber (reg:CC FLAGS_REG))]
10071   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10072    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10073   "#")
10074
10075 (define_insn "*absnegsf2_sse"
10076   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
10077         (match_operator:SF 3 "absneg_operator"
10078           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
10079    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
10080    (clobber (reg:CC FLAGS_REG))]
10081   "TARGET_SSE_MATH
10082    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10083   "#")
10084
10085 (define_insn "*absnegsf2_i387"
10086   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
10087         (match_operator:SF 3 "absneg_operator"
10088           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
10089    (use (match_operand 2 "" ""))
10090    (clobber (reg:CC FLAGS_REG))]
10091   "TARGET_80387 && !TARGET_SSE_MATH
10092    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10093   "#")
10094
10095 (define_expand "negdf2"
10096   [(set (match_operand:DF 0 "nonimmediate_operand" "")
10097         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10098   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10099   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
10100
10101 (define_expand "absdf2"
10102   [(set (match_operand:DF 0 "nonimmediate_operand" "")
10103         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10104   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10105   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
10106
10107 (define_insn "*absnegdf2_mixed"
10108   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
10109         (match_operator:DF 3 "absneg_operator"
10110           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
10111    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
10112    (clobber (reg:CC FLAGS_REG))]
10113   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10114    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10115   "#")
10116
10117 (define_insn "*absnegdf2_sse"
10118   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
10119         (match_operator:DF 3 "absneg_operator"
10120           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10121    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
10122    (clobber (reg:CC FLAGS_REG))]
10123   "TARGET_SSE2 && TARGET_SSE_MATH
10124    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10125   "#")
10126
10127 (define_insn "*absnegdf2_i387"
10128   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10129         (match_operator:DF 3 "absneg_operator"
10130           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10131    (use (match_operand 2 "" ""))
10132    (clobber (reg:CC FLAGS_REG))]
10133   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10134    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10135   "#")
10136
10137 (define_expand "negxf2"
10138   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10139         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10140   "TARGET_80387"
10141   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10142
10143 (define_expand "absxf2"
10144   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10145         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10146   "TARGET_80387"
10147   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10148
10149 (define_insn "*absnegxf2_i387"
10150   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10151         (match_operator:XF 3 "absneg_operator"
10152           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10153    (use (match_operand 2 "" ""))
10154    (clobber (reg:CC FLAGS_REG))]
10155   "TARGET_80387
10156    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10157   "#")
10158
10159 (define_expand "negtf2"
10160   [(set (match_operand:TF 0 "nonimmediate_operand" "")
10161         (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
10162   "TARGET_64BIT"
10163   "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10164
10165 (define_expand "abstf2"
10166   [(set (match_operand:TF 0 "nonimmediate_operand" "")
10167         (abs:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
10168   "TARGET_64BIT"
10169   "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10170
10171 (define_insn "*absnegtf2_sse"
10172   [(set (match_operand:TF 0 "nonimmediate_operand"    "=x,x,m")
10173         (match_operator:TF 3 "absneg_operator"
10174           [(match_operand:TF 1 "nonimmediate_operand" "0, x,0")]))
10175    (use (match_operand:TF 2 "nonimmediate_operand"    "xm,0,X"))
10176    (clobber (reg:CC FLAGS_REG))]
10177   "TARGET_64BIT
10178    && ix86_unary_operator_ok (GET_CODE (operands[3]), TFmode, operands)"
10179   "#")
10180
10181 ;; Splitters for fp abs and neg.
10182
10183 (define_split
10184   [(set (match_operand 0 "fp_register_operand" "")
10185         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10186    (use (match_operand 2 "" ""))
10187    (clobber (reg:CC FLAGS_REG))]
10188   "reload_completed"
10189   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10190
10191 (define_split
10192   [(set (match_operand 0 "register_operand" "")
10193         (match_operator 3 "absneg_operator"
10194           [(match_operand 1 "register_operand" "")]))
10195    (use (match_operand 2 "nonimmediate_operand" ""))
10196    (clobber (reg:CC FLAGS_REG))]
10197   "reload_completed && SSE_REG_P (operands[0])"
10198   [(set (match_dup 0) (match_dup 3))]
10199 {
10200   enum machine_mode mode = GET_MODE (operands[0]);
10201   enum machine_mode vmode = GET_MODE (operands[2]);
10202   rtx tmp;
10203
10204   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10205   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10206   if (operands_match_p (operands[0], operands[2]))
10207     {
10208       tmp = operands[1];
10209       operands[1] = operands[2];
10210       operands[2] = tmp;
10211     }
10212   if (GET_CODE (operands[3]) == ABS)
10213     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10214   else
10215     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10216   operands[3] = tmp;
10217 })
10218
10219 (define_split
10220   [(set (match_operand:SF 0 "register_operand" "")
10221         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10222    (use (match_operand:V4SF 2 "" ""))
10223    (clobber (reg:CC FLAGS_REG))]
10224   "reload_completed"
10225   [(parallel [(set (match_dup 0) (match_dup 1))
10226               (clobber (reg:CC FLAGS_REG))])]
10227 {
10228   rtx tmp;
10229   operands[0] = gen_lowpart (SImode, operands[0]);
10230   if (GET_CODE (operands[1]) == ABS)
10231     {
10232       tmp = gen_int_mode (0x7fffffff, SImode);
10233       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10234     }
10235   else
10236     {
10237       tmp = gen_int_mode (0x80000000, SImode);
10238       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10239     }
10240   operands[1] = tmp;
10241 })
10242
10243 (define_split
10244   [(set (match_operand:DF 0 "register_operand" "")
10245         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10246    (use (match_operand 2 "" ""))
10247    (clobber (reg:CC FLAGS_REG))]
10248   "reload_completed"
10249   [(parallel [(set (match_dup 0) (match_dup 1))
10250               (clobber (reg:CC FLAGS_REG))])]
10251 {
10252   rtx tmp;
10253   if (TARGET_64BIT)
10254     {
10255       tmp = gen_lowpart (DImode, operands[0]);
10256       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10257       operands[0] = tmp;
10258
10259       if (GET_CODE (operands[1]) == ABS)
10260         tmp = const0_rtx;
10261       else
10262         tmp = gen_rtx_NOT (DImode, tmp);
10263     }
10264   else
10265     {
10266       operands[0] = gen_highpart (SImode, operands[0]);
10267       if (GET_CODE (operands[1]) == ABS)
10268         {
10269           tmp = gen_int_mode (0x7fffffff, SImode);
10270           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10271         }
10272       else
10273         {
10274           tmp = gen_int_mode (0x80000000, SImode);
10275           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10276         }
10277     }
10278   operands[1] = tmp;
10279 })
10280
10281 (define_split
10282   [(set (match_operand:XF 0 "register_operand" "")
10283         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10284    (use (match_operand 2 "" ""))
10285    (clobber (reg:CC FLAGS_REG))]
10286   "reload_completed"
10287   [(parallel [(set (match_dup 0) (match_dup 1))
10288               (clobber (reg:CC FLAGS_REG))])]
10289 {
10290   rtx tmp;
10291   operands[0] = gen_rtx_REG (SImode,
10292                              true_regnum (operands[0])
10293                              + (TARGET_64BIT ? 1 : 2));
10294   if (GET_CODE (operands[1]) == ABS)
10295     {
10296       tmp = GEN_INT (0x7fff);
10297       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10298     }
10299   else
10300     {
10301       tmp = GEN_INT (0x8000);
10302       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10303     }
10304   operands[1] = tmp;
10305 })
10306
10307 (define_split
10308   [(set (match_operand 0 "memory_operand" "")
10309         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10310    (use (match_operand 2 "" ""))
10311    (clobber (reg:CC FLAGS_REG))]
10312   "reload_completed"
10313   [(parallel [(set (match_dup 0) (match_dup 1))
10314               (clobber (reg:CC FLAGS_REG))])]
10315 {
10316   enum machine_mode mode = GET_MODE (operands[0]);
10317   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10318   rtx tmp;
10319
10320   operands[0] = adjust_address (operands[0], QImode, size - 1);
10321   if (GET_CODE (operands[1]) == ABS)
10322     {
10323       tmp = gen_int_mode (0x7f, QImode);
10324       tmp = gen_rtx_AND (QImode, operands[0], tmp);
10325     }
10326   else
10327     {
10328       tmp = gen_int_mode (0x80, QImode);
10329       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10330     }
10331   operands[1] = tmp;
10332 })
10333
10334 ;; Conditionalize these after reload. If they match before reload, we
10335 ;; lose the clobber and ability to use integer instructions.
10336
10337 (define_insn "*negsf2_1"
10338   [(set (match_operand:SF 0 "register_operand" "=f")
10339         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10340   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10341   "fchs"
10342   [(set_attr "type" "fsgn")
10343    (set_attr "mode" "SF")])
10344
10345 (define_insn "*negdf2_1"
10346   [(set (match_operand:DF 0 "register_operand" "=f")
10347         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10348   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10349   "fchs"
10350   [(set_attr "type" "fsgn")
10351    (set_attr "mode" "DF")])
10352
10353 (define_insn "*negxf2_1"
10354   [(set (match_operand:XF 0 "register_operand" "=f")
10355         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10356   "TARGET_80387"
10357   "fchs"
10358   [(set_attr "type" "fsgn")
10359    (set_attr "mode" "XF")])
10360
10361 (define_insn "*abssf2_1"
10362   [(set (match_operand:SF 0 "register_operand" "=f")
10363         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10364   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10365   "fabs"
10366   [(set_attr "type" "fsgn")
10367    (set_attr "mode" "SF")])
10368
10369 (define_insn "*absdf2_1"
10370   [(set (match_operand:DF 0 "register_operand" "=f")
10371         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10372   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10373   "fabs"
10374   [(set_attr "type" "fsgn")
10375    (set_attr "mode" "DF")])
10376
10377 (define_insn "*absxf2_1"
10378   [(set (match_operand:XF 0 "register_operand" "=f")
10379         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10380   "TARGET_80387"
10381   "fabs"
10382   [(set_attr "type" "fsgn")
10383    (set_attr "mode" "DF")])
10384
10385 (define_insn "*negextendsfdf2"
10386   [(set (match_operand:DF 0 "register_operand" "=f")
10387         (neg:DF (float_extend:DF
10388                   (match_operand:SF 1 "register_operand" "0"))))]
10389   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10390   "fchs"
10391   [(set_attr "type" "fsgn")
10392    (set_attr "mode" "DF")])
10393
10394 (define_insn "*negextenddfxf2"
10395   [(set (match_operand:XF 0 "register_operand" "=f")
10396         (neg:XF (float_extend:XF
10397                   (match_operand:DF 1 "register_operand" "0"))))]
10398   "TARGET_80387"
10399   "fchs"
10400   [(set_attr "type" "fsgn")
10401    (set_attr "mode" "XF")])
10402
10403 (define_insn "*negextendsfxf2"
10404   [(set (match_operand:XF 0 "register_operand" "=f")
10405         (neg:XF (float_extend:XF
10406                   (match_operand:SF 1 "register_operand" "0"))))]
10407   "TARGET_80387"
10408   "fchs"
10409   [(set_attr "type" "fsgn")
10410    (set_attr "mode" "XF")])
10411
10412 (define_insn "*absextendsfdf2"
10413   [(set (match_operand:DF 0 "register_operand" "=f")
10414         (abs:DF (float_extend:DF
10415                   (match_operand:SF 1 "register_operand" "0"))))]
10416   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10417   "fabs"
10418   [(set_attr "type" "fsgn")
10419    (set_attr "mode" "DF")])
10420
10421 (define_insn "*absextenddfxf2"
10422   [(set (match_operand:XF 0 "register_operand" "=f")
10423         (abs:XF (float_extend:XF
10424           (match_operand:DF 1 "register_operand" "0"))))]
10425   "TARGET_80387"
10426   "fabs"
10427   [(set_attr "type" "fsgn")
10428    (set_attr "mode" "XF")])
10429
10430 (define_insn "*absextendsfxf2"
10431   [(set (match_operand:XF 0 "register_operand" "=f")
10432         (abs:XF (float_extend:XF
10433           (match_operand:SF 1 "register_operand" "0"))))]
10434   "TARGET_80387"
10435   "fabs"
10436   [(set_attr "type" "fsgn")
10437    (set_attr "mode" "XF")])
10438
10439 ;; Copysign instructions
10440
10441 (define_mode_iterator CSGNMODE [SF DF TF])
10442 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10443
10444 (define_expand "copysign<mode>3"
10445   [(match_operand:CSGNMODE 0 "register_operand" "")
10446    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10447    (match_operand:CSGNMODE 2 "register_operand" "")]
10448   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10449    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10450 {
10451   ix86_expand_copysign (operands);
10452   DONE;
10453 })
10454
10455 (define_insn_and_split "copysign<mode>3_const"
10456   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10457         (unspec:CSGNMODE
10458           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10459            (match_operand:CSGNMODE 2 "register_operand" "0")
10460            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10461           UNSPEC_COPYSIGN))]
10462   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10463    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10464   "#"
10465   "&& reload_completed"
10466   [(const_int 0)]
10467 {
10468   ix86_split_copysign_const (operands);
10469   DONE;
10470 })
10471
10472 (define_insn "copysign<mode>3_var"
10473   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10474         (unspec:CSGNMODE
10475           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10476            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10477            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10478            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10479           UNSPEC_COPYSIGN))
10480    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10481   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10482    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10483   "#")
10484
10485 (define_split
10486   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10487         (unspec:CSGNMODE
10488           [(match_operand:CSGNMODE 2 "register_operand" "")
10489            (match_operand:CSGNMODE 3 "register_operand" "")
10490            (match_operand:<CSGNVMODE> 4 "" "")
10491            (match_operand:<CSGNVMODE> 5 "" "")]
10492           UNSPEC_COPYSIGN))
10493    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10494   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10495     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10496    && reload_completed"
10497   [(const_int 0)]
10498 {
10499   ix86_split_copysign_var (operands);
10500   DONE;
10501 })
10502 \f
10503 ;; One complement instructions
10504
10505 (define_expand "one_cmpldi2"
10506   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10507         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10508   "TARGET_64BIT"
10509   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10510
10511 (define_insn "*one_cmpldi2_1_rex64"
10512   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10513         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10514   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10515   "not{q}\t%0"
10516   [(set_attr "type" "negnot")
10517    (set_attr "mode" "DI")])
10518
10519 (define_insn "*one_cmpldi2_2_rex64"
10520   [(set (reg FLAGS_REG)
10521         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10522                  (const_int 0)))
10523    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10524         (not:DI (match_dup 1)))]
10525   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10526    && ix86_unary_operator_ok (NOT, DImode, operands)"
10527   "#"
10528   [(set_attr "type" "alu1")
10529    (set_attr "mode" "DI")])
10530
10531 (define_split
10532   [(set (match_operand 0 "flags_reg_operand" "")
10533         (match_operator 2 "compare_operator"
10534           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10535            (const_int 0)]))
10536    (set (match_operand:DI 1 "nonimmediate_operand" "")
10537         (not:DI (match_dup 3)))]
10538   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10539   [(parallel [(set (match_dup 0)
10540                    (match_op_dup 2
10541                      [(xor:DI (match_dup 3) (const_int -1))
10542                       (const_int 0)]))
10543               (set (match_dup 1)
10544                    (xor:DI (match_dup 3) (const_int -1)))])]
10545   "")
10546
10547 (define_expand "one_cmplsi2"
10548   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10549         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10550   ""
10551   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10552
10553 (define_insn "*one_cmplsi2_1"
10554   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10555         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10556   "ix86_unary_operator_ok (NOT, SImode, operands)"
10557   "not{l}\t%0"
10558   [(set_attr "type" "negnot")
10559    (set_attr "mode" "SI")])
10560
10561 ;; ??? Currently never generated - xor is used instead.
10562 (define_insn "*one_cmplsi2_1_zext"
10563   [(set (match_operand:DI 0 "register_operand" "=r")
10564         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10565   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10566   "not{l}\t%k0"
10567   [(set_attr "type" "negnot")
10568    (set_attr "mode" "SI")])
10569
10570 (define_insn "*one_cmplsi2_2"
10571   [(set (reg FLAGS_REG)
10572         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10573                  (const_int 0)))
10574    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10575         (not:SI (match_dup 1)))]
10576   "ix86_match_ccmode (insn, CCNOmode)
10577    && ix86_unary_operator_ok (NOT, SImode, operands)"
10578   "#"
10579   [(set_attr "type" "alu1")
10580    (set_attr "mode" "SI")])
10581
10582 (define_split
10583   [(set (match_operand 0 "flags_reg_operand" "")
10584         (match_operator 2 "compare_operator"
10585           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10586            (const_int 0)]))
10587    (set (match_operand:SI 1 "nonimmediate_operand" "")
10588         (not:SI (match_dup 3)))]
10589   "ix86_match_ccmode (insn, CCNOmode)"
10590   [(parallel [(set (match_dup 0)
10591                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10592                                     (const_int 0)]))
10593               (set (match_dup 1)
10594                    (xor:SI (match_dup 3) (const_int -1)))])]
10595   "")
10596
10597 ;; ??? Currently never generated - xor is used instead.
10598 (define_insn "*one_cmplsi2_2_zext"
10599   [(set (reg FLAGS_REG)
10600         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10601                  (const_int 0)))
10602    (set (match_operand:DI 0 "register_operand" "=r")
10603         (zero_extend:DI (not:SI (match_dup 1))))]
10604   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10605    && ix86_unary_operator_ok (NOT, SImode, operands)"
10606   "#"
10607   [(set_attr "type" "alu1")
10608    (set_attr "mode" "SI")])
10609
10610 (define_split
10611   [(set (match_operand 0 "flags_reg_operand" "")
10612         (match_operator 2 "compare_operator"
10613           [(not:SI (match_operand:SI 3 "register_operand" ""))
10614            (const_int 0)]))
10615    (set (match_operand:DI 1 "register_operand" "")
10616         (zero_extend:DI (not:SI (match_dup 3))))]
10617   "ix86_match_ccmode (insn, CCNOmode)"
10618   [(parallel [(set (match_dup 0)
10619                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10620                                     (const_int 0)]))
10621               (set (match_dup 1)
10622                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10623   "")
10624
10625 (define_expand "one_cmplhi2"
10626   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10627         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10628   "TARGET_HIMODE_MATH"
10629   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10630
10631 (define_insn "*one_cmplhi2_1"
10632   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10633         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10634   "ix86_unary_operator_ok (NOT, HImode, operands)"
10635   "not{w}\t%0"
10636   [(set_attr "type" "negnot")
10637    (set_attr "mode" "HI")])
10638
10639 (define_insn "*one_cmplhi2_2"
10640   [(set (reg FLAGS_REG)
10641         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10642                  (const_int 0)))
10643    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10644         (not:HI (match_dup 1)))]
10645   "ix86_match_ccmode (insn, CCNOmode)
10646    && ix86_unary_operator_ok (NEG, HImode, operands)"
10647   "#"
10648   [(set_attr "type" "alu1")
10649    (set_attr "mode" "HI")])
10650
10651 (define_split
10652   [(set (match_operand 0 "flags_reg_operand" "")
10653         (match_operator 2 "compare_operator"
10654           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10655            (const_int 0)]))
10656    (set (match_operand:HI 1 "nonimmediate_operand" "")
10657         (not:HI (match_dup 3)))]
10658   "ix86_match_ccmode (insn, CCNOmode)"
10659   [(parallel [(set (match_dup 0)
10660                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10661                                     (const_int 0)]))
10662               (set (match_dup 1)
10663                    (xor:HI (match_dup 3) (const_int -1)))])]
10664   "")
10665
10666 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10667 (define_expand "one_cmplqi2"
10668   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10669         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10670   "TARGET_QIMODE_MATH"
10671   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10672
10673 (define_insn "*one_cmplqi2_1"
10674   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10675         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10676   "ix86_unary_operator_ok (NOT, QImode, operands)"
10677   "@
10678    not{b}\t%0
10679    not{l}\t%k0"
10680   [(set_attr "type" "negnot")
10681    (set_attr "mode" "QI,SI")])
10682
10683 (define_insn "*one_cmplqi2_2"
10684   [(set (reg FLAGS_REG)
10685         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10686                  (const_int 0)))
10687    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10688         (not:QI (match_dup 1)))]
10689   "ix86_match_ccmode (insn, CCNOmode)
10690    && ix86_unary_operator_ok (NOT, QImode, operands)"
10691   "#"
10692   [(set_attr "type" "alu1")
10693    (set_attr "mode" "QI")])
10694
10695 (define_split
10696   [(set (match_operand 0 "flags_reg_operand" "")
10697         (match_operator 2 "compare_operator"
10698           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10699            (const_int 0)]))
10700    (set (match_operand:QI 1 "nonimmediate_operand" "")
10701         (not:QI (match_dup 3)))]
10702   "ix86_match_ccmode (insn, CCNOmode)"
10703   [(parallel [(set (match_dup 0)
10704                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10705                                     (const_int 0)]))
10706               (set (match_dup 1)
10707                    (xor:QI (match_dup 3) (const_int -1)))])]
10708   "")
10709 \f
10710 ;; Arithmetic shift instructions
10711
10712 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10713 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10714 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10715 ;; from the assembler input.
10716 ;;
10717 ;; This instruction shifts the target reg/mem as usual, but instead of
10718 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10719 ;; is a left shift double, bits are taken from the high order bits of
10720 ;; reg, else if the insn is a shift right double, bits are taken from the
10721 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10722 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10723 ;;
10724 ;; Since sh[lr]d does not change the `reg' operand, that is done
10725 ;; separately, making all shifts emit pairs of shift double and normal
10726 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10727 ;; support a 63 bit shift, each shift where the count is in a reg expands
10728 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10729 ;;
10730 ;; If the shift count is a constant, we need never emit more than one
10731 ;; shift pair, instead using moves and sign extension for counts greater
10732 ;; than 31.
10733
10734 (define_expand "ashlti3"
10735   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10736                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10737                               (match_operand:QI 2 "nonmemory_operand" "")))
10738               (clobber (reg:CC FLAGS_REG))])]
10739   "TARGET_64BIT"
10740 {
10741   if (! immediate_operand (operands[2], QImode))
10742     {
10743       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10744       DONE;
10745     }
10746   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10747   DONE;
10748 })
10749
10750 (define_insn "ashlti3_1"
10751   [(set (match_operand:TI 0 "register_operand" "=r")
10752         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10753                    (match_operand:QI 2 "register_operand" "c")))
10754    (clobber (match_scratch:DI 3 "=&r"))
10755    (clobber (reg:CC FLAGS_REG))]
10756   "TARGET_64BIT"
10757   "#"
10758   [(set_attr "type" "multi")])
10759
10760 ;; This pattern must be defined before *ashlti3_2 to prevent
10761 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10762
10763 (define_insn "sse2_ashlti3"
10764   [(set (match_operand:TI 0 "register_operand" "=x")
10765         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10766                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10767   "TARGET_SSE2"
10768 {
10769   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10770   return "pslldq\t{%2, %0|%0, %2}";
10771 }
10772   [(set_attr "type" "sseishft")
10773    (set_attr "prefix_data16" "1")
10774    (set_attr "mode" "TI")])
10775
10776 (define_insn "*ashlti3_2"
10777   [(set (match_operand:TI 0 "register_operand" "=r")
10778         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10779                    (match_operand:QI 2 "immediate_operand" "O")))
10780    (clobber (reg:CC FLAGS_REG))]
10781   "TARGET_64BIT"
10782   "#"
10783   [(set_attr "type" "multi")])
10784
10785 (define_split
10786   [(set (match_operand:TI 0 "register_operand" "")
10787         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10788                    (match_operand:QI 2 "register_operand" "")))
10789    (clobber (match_scratch:DI 3 ""))
10790    (clobber (reg:CC FLAGS_REG))]
10791   "TARGET_64BIT && reload_completed"
10792   [(const_int 0)]
10793   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10794
10795 (define_split
10796   [(set (match_operand:TI 0 "register_operand" "")
10797         (ashift:TI (match_operand:TI 1 "register_operand" "")
10798                    (match_operand:QI 2 "immediate_operand" "")))
10799    (clobber (reg:CC FLAGS_REG))]
10800   "TARGET_64BIT && reload_completed"
10801   [(const_int 0)]
10802   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10803
10804 (define_insn "x86_64_shld"
10805   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10806         (ior:DI (ashift:DI (match_dup 0)
10807                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10808                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10809                   (minus:QI (const_int 64) (match_dup 2)))))
10810    (clobber (reg:CC FLAGS_REG))]
10811   "TARGET_64BIT"
10812   "@
10813    shld{q}\t{%2, %1, %0|%0, %1, %2}
10814    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10815   [(set_attr "type" "ishift")
10816    (set_attr "prefix_0f" "1")
10817    (set_attr "mode" "DI")
10818    (set_attr "athlon_decode" "vector")
10819    (set_attr "amdfam10_decode" "vector")])   
10820
10821 (define_expand "x86_64_shift_adj"
10822   [(set (reg:CCZ FLAGS_REG)
10823         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10824                              (const_int 64))
10825                      (const_int 0)))
10826    (set (match_operand:DI 0 "register_operand" "")
10827         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10828                          (match_operand:DI 1 "register_operand" "")
10829                          (match_dup 0)))
10830    (set (match_dup 1)
10831         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10832                          (match_operand:DI 3 "register_operand" "r")
10833                          (match_dup 1)))]
10834   "TARGET_64BIT"
10835   "")
10836
10837 (define_expand "ashldi3"
10838   [(set (match_operand:DI 0 "shiftdi_operand" "")
10839         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10840                    (match_operand:QI 2 "nonmemory_operand" "")))]
10841   ""
10842   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10843
10844 (define_insn "*ashldi3_1_rex64"
10845   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10846         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10847                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10848    (clobber (reg:CC FLAGS_REG))]
10849   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10850 {
10851   switch (get_attr_type (insn))
10852     {
10853     case TYPE_ALU:
10854       gcc_assert (operands[2] == const1_rtx);
10855       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10856       return "add{q}\t%0, %0";
10857
10858     case TYPE_LEA:
10859       gcc_assert (CONST_INT_P (operands[2]));
10860       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10861       operands[1] = gen_rtx_MULT (DImode, operands[1],
10862                                   GEN_INT (1 << INTVAL (operands[2])));
10863       return "lea{q}\t{%a1, %0|%0, %a1}";
10864
10865     default:
10866       if (REG_P (operands[2]))
10867         return "sal{q}\t{%b2, %0|%0, %b2}";
10868       else if (operands[2] == const1_rtx
10869                && (TARGET_SHIFT1 || optimize_size))
10870         return "sal{q}\t%0";
10871       else
10872         return "sal{q}\t{%2, %0|%0, %2}";
10873     }
10874 }
10875   [(set (attr "type")
10876      (cond [(eq_attr "alternative" "1")
10877               (const_string "lea")
10878             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10879                           (const_int 0))
10880                       (match_operand 0 "register_operand" ""))
10881                  (match_operand 2 "const1_operand" ""))
10882               (const_string "alu")
10883            ]
10884            (const_string "ishift")))
10885    (set_attr "mode" "DI")])
10886
10887 ;; Convert lea to the lea pattern to avoid flags dependency.
10888 (define_split
10889   [(set (match_operand:DI 0 "register_operand" "")
10890         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10891                    (match_operand:QI 2 "immediate_operand" "")))
10892    (clobber (reg:CC FLAGS_REG))]
10893   "TARGET_64BIT && reload_completed
10894    && true_regnum (operands[0]) != true_regnum (operands[1])"
10895   [(set (match_dup 0)
10896         (mult:DI (match_dup 1)
10897                  (match_dup 2)))]
10898   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10899
10900 ;; This pattern can't accept a variable shift count, since shifts by
10901 ;; zero don't affect the flags.  We assume that shifts by constant
10902 ;; zero are optimized away.
10903 (define_insn "*ashldi3_cmp_rex64"
10904   [(set (reg FLAGS_REG)
10905         (compare
10906           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10907                      (match_operand:QI 2 "immediate_operand" "e"))
10908           (const_int 0)))
10909    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10910         (ashift:DI (match_dup 1) (match_dup 2)))]
10911   "TARGET_64BIT
10912    && (optimize_size
10913        || !TARGET_PARTIAL_FLAG_REG_STALL
10914        || (operands[2] == const1_rtx
10915            && (TARGET_SHIFT1
10916                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10917    && ix86_match_ccmode (insn, CCGOCmode)
10918    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10919 {
10920   switch (get_attr_type (insn))
10921     {
10922     case TYPE_ALU:
10923       gcc_assert (operands[2] == const1_rtx);
10924       return "add{q}\t%0, %0";
10925
10926     default:
10927       if (REG_P (operands[2]))
10928         return "sal{q}\t{%b2, %0|%0, %b2}";
10929       else if (operands[2] == const1_rtx
10930                && (TARGET_SHIFT1 || optimize_size))
10931         return "sal{q}\t%0";
10932       else
10933         return "sal{q}\t{%2, %0|%0, %2}";
10934     }
10935 }
10936   [(set (attr "type")
10937      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10938                           (const_int 0))
10939                       (match_operand 0 "register_operand" ""))
10940                  (match_operand 2 "const1_operand" ""))
10941               (const_string "alu")
10942            ]
10943            (const_string "ishift")))
10944    (set_attr "mode" "DI")])
10945
10946 (define_insn "*ashldi3_cconly_rex64"
10947   [(set (reg FLAGS_REG)
10948         (compare
10949           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10950                      (match_operand:QI 2 "immediate_operand" "e"))
10951           (const_int 0)))
10952    (clobber (match_scratch:DI 0 "=r"))]
10953   "TARGET_64BIT
10954    && (optimize_size
10955        || !TARGET_PARTIAL_FLAG_REG_STALL
10956        || (operands[2] == const1_rtx
10957            && (TARGET_SHIFT1
10958                || TARGET_DOUBLE_WITH_ADD)))
10959    && ix86_match_ccmode (insn, CCGOCmode)
10960    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10961 {
10962   switch (get_attr_type (insn))
10963     {
10964     case TYPE_ALU:
10965       gcc_assert (operands[2] == const1_rtx);
10966       return "add{q}\t%0, %0";
10967
10968     default:
10969       if (REG_P (operands[2]))
10970         return "sal{q}\t{%b2, %0|%0, %b2}";
10971       else if (operands[2] == const1_rtx
10972                && (TARGET_SHIFT1 || optimize_size))
10973         return "sal{q}\t%0";
10974       else
10975         return "sal{q}\t{%2, %0|%0, %2}";
10976     }
10977 }
10978   [(set (attr "type")
10979      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980                           (const_int 0))
10981                       (match_operand 0 "register_operand" ""))
10982                  (match_operand 2 "const1_operand" ""))
10983               (const_string "alu")
10984            ]
10985            (const_string "ishift")))
10986    (set_attr "mode" "DI")])
10987
10988 (define_insn "*ashldi3_1"
10989   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10990         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10991                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10992    (clobber (reg:CC FLAGS_REG))]
10993   "!TARGET_64BIT"
10994   "#"
10995   [(set_attr "type" "multi")])
10996
10997 ;; By default we don't ask for a scratch register, because when DImode
10998 ;; values are manipulated, registers are already at a premium.  But if
10999 ;; we have one handy, we won't turn it away.
11000 (define_peephole2
11001   [(match_scratch:SI 3 "r")
11002    (parallel [(set (match_operand:DI 0 "register_operand" "")
11003                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11004                               (match_operand:QI 2 "nonmemory_operand" "")))
11005               (clobber (reg:CC FLAGS_REG))])
11006    (match_dup 3)]
11007   "!TARGET_64BIT && TARGET_CMOVE"
11008   [(const_int 0)]
11009   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11010
11011 (define_split
11012   [(set (match_operand:DI 0 "register_operand" "")
11013         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11014                    (match_operand:QI 2 "nonmemory_operand" "")))
11015    (clobber (reg:CC FLAGS_REG))]
11016   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11017                      ? epilogue_completed : reload_completed)"
11018   [(const_int 0)]
11019   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11020
11021 (define_insn "x86_shld_1"
11022   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11023         (ior:SI (ashift:SI (match_dup 0)
11024                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11025                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11026                   (minus:QI (const_int 32) (match_dup 2)))))
11027    (clobber (reg:CC FLAGS_REG))]
11028   ""
11029   "@
11030    shld{l}\t{%2, %1, %0|%0, %1, %2}
11031    shld{l}\t{%s2%1, %0|%0, %1, %2}"
11032   [(set_attr "type" "ishift")
11033    (set_attr "prefix_0f" "1")
11034    (set_attr "mode" "SI")
11035    (set_attr "pent_pair" "np")
11036    (set_attr "athlon_decode" "vector")
11037    (set_attr "amdfam10_decode" "vector")])   
11038
11039 (define_expand "x86_shift_adj_1"
11040   [(set (reg:CCZ FLAGS_REG)
11041         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11042                              (const_int 32))
11043                      (const_int 0)))
11044    (set (match_operand:SI 0 "register_operand" "")
11045         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11046                          (match_operand:SI 1 "register_operand" "")
11047                          (match_dup 0)))
11048    (set (match_dup 1)
11049         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11050                          (match_operand:SI 3 "register_operand" "r")
11051                          (match_dup 1)))]
11052   "TARGET_CMOVE"
11053   "")
11054
11055 (define_expand "x86_shift_adj_2"
11056   [(use (match_operand:SI 0 "register_operand" ""))
11057    (use (match_operand:SI 1 "register_operand" ""))
11058    (use (match_operand:QI 2 "register_operand" ""))]
11059   ""
11060 {
11061   rtx label = gen_label_rtx ();
11062   rtx tmp;
11063
11064   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11065
11066   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11067   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11068   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11069                               gen_rtx_LABEL_REF (VOIDmode, label),
11070                               pc_rtx);
11071   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11072   JUMP_LABEL (tmp) = label;
11073
11074   emit_move_insn (operands[0], operands[1]);
11075   ix86_expand_clear (operands[1]);
11076
11077   emit_label (label);
11078   LABEL_NUSES (label) = 1;
11079
11080   DONE;
11081 })
11082
11083 (define_expand "ashlsi3"
11084   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11085         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11086                    (match_operand:QI 2 "nonmemory_operand" "")))
11087    (clobber (reg:CC FLAGS_REG))]
11088   ""
11089   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11090
11091 (define_insn "*ashlsi3_1"
11092   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11093         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11094                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11095    (clobber (reg:CC FLAGS_REG))]
11096   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11097 {
11098   switch (get_attr_type (insn))
11099     {
11100     case TYPE_ALU:
11101       gcc_assert (operands[2] == const1_rtx);
11102       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11103       return "add{l}\t%0, %0";
11104
11105     case TYPE_LEA:
11106       return "#";
11107
11108     default:
11109       if (REG_P (operands[2]))
11110         return "sal{l}\t{%b2, %0|%0, %b2}";
11111       else if (operands[2] == const1_rtx
11112                && (TARGET_SHIFT1 || optimize_size))
11113         return "sal{l}\t%0";
11114       else
11115         return "sal{l}\t{%2, %0|%0, %2}";
11116     }
11117 }
11118   [(set (attr "type")
11119      (cond [(eq_attr "alternative" "1")
11120               (const_string "lea")
11121             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11122                           (const_int 0))
11123                       (match_operand 0 "register_operand" ""))
11124                  (match_operand 2 "const1_operand" ""))
11125               (const_string "alu")
11126            ]
11127            (const_string "ishift")))
11128    (set_attr "mode" "SI")])
11129
11130 ;; Convert lea to the lea pattern to avoid flags dependency.
11131 (define_split
11132   [(set (match_operand 0 "register_operand" "")
11133         (ashift (match_operand 1 "index_register_operand" "")
11134                 (match_operand:QI 2 "const_int_operand" "")))
11135    (clobber (reg:CC FLAGS_REG))]
11136   "reload_completed
11137    && true_regnum (operands[0]) != true_regnum (operands[1])
11138    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11139   [(const_int 0)]
11140 {
11141   rtx pat;
11142   enum machine_mode mode = GET_MODE (operands[0]);
11143
11144   if (GET_MODE_SIZE (mode) < 4)
11145     operands[0] = gen_lowpart (SImode, operands[0]);
11146   if (mode != Pmode)
11147     operands[1] = gen_lowpart (Pmode, operands[1]);
11148   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11149
11150   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11151   if (Pmode != SImode)
11152     pat = gen_rtx_SUBREG (SImode, pat, 0);
11153   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11154   DONE;
11155 })
11156
11157 ;; Rare case of shifting RSP is handled by generating move and shift
11158 (define_split
11159   [(set (match_operand 0 "register_operand" "")
11160         (ashift (match_operand 1 "register_operand" "")
11161                 (match_operand:QI 2 "const_int_operand" "")))
11162    (clobber (reg:CC FLAGS_REG))]
11163   "reload_completed
11164    && true_regnum (operands[0]) != true_regnum (operands[1])"
11165   [(const_int 0)]
11166 {
11167   rtx pat, clob;
11168   emit_move_insn (operands[0], operands[1]);
11169   pat = gen_rtx_SET (VOIDmode, operands[0],
11170                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11171                                      operands[0], operands[2]));
11172   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11173   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11174   DONE;
11175 })
11176
11177 (define_insn "*ashlsi3_1_zext"
11178   [(set (match_operand:DI 0 "register_operand" "=r,r")
11179         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11180                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11181    (clobber (reg:CC FLAGS_REG))]
11182   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11183 {
11184   switch (get_attr_type (insn))
11185     {
11186     case TYPE_ALU:
11187       gcc_assert (operands[2] == const1_rtx);
11188       return "add{l}\t%k0, %k0";
11189
11190     case TYPE_LEA:
11191       return "#";
11192
11193     default:
11194       if (REG_P (operands[2]))
11195         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11196       else if (operands[2] == const1_rtx
11197                && (TARGET_SHIFT1 || optimize_size))
11198         return "sal{l}\t%k0";
11199       else
11200         return "sal{l}\t{%2, %k0|%k0, %2}";
11201     }
11202 }
11203   [(set (attr "type")
11204      (cond [(eq_attr "alternative" "1")
11205               (const_string "lea")
11206             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11207                      (const_int 0))
11208                  (match_operand 2 "const1_operand" ""))
11209               (const_string "alu")
11210            ]
11211            (const_string "ishift")))
11212    (set_attr "mode" "SI")])
11213
11214 ;; Convert lea to the lea pattern to avoid flags dependency.
11215 (define_split
11216   [(set (match_operand:DI 0 "register_operand" "")
11217         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11218                                 (match_operand:QI 2 "const_int_operand" ""))))
11219    (clobber (reg:CC FLAGS_REG))]
11220   "TARGET_64BIT && reload_completed
11221    && true_regnum (operands[0]) != true_regnum (operands[1])"
11222   [(set (match_dup 0) (zero_extend:DI
11223                         (subreg:SI (mult:SI (match_dup 1)
11224                                             (match_dup 2)) 0)))]
11225 {
11226   operands[1] = gen_lowpart (Pmode, operands[1]);
11227   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11228 })
11229
11230 ;; This pattern can't accept a variable shift count, since shifts by
11231 ;; zero don't affect the flags.  We assume that shifts by constant
11232 ;; zero are optimized away.
11233 (define_insn "*ashlsi3_cmp"
11234   [(set (reg FLAGS_REG)
11235         (compare
11236           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11237                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11238           (const_int 0)))
11239    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11240         (ashift:SI (match_dup 1) (match_dup 2)))]
11241    "(optimize_size
11242      || !TARGET_PARTIAL_FLAG_REG_STALL
11243      || (operands[2] == const1_rtx
11244          && (TARGET_SHIFT1
11245              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11246    && ix86_match_ccmode (insn, CCGOCmode)
11247    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11248 {
11249   switch (get_attr_type (insn))
11250     {
11251     case TYPE_ALU:
11252       gcc_assert (operands[2] == const1_rtx);
11253       return "add{l}\t%0, %0";
11254
11255     default:
11256       if (REG_P (operands[2]))
11257         return "sal{l}\t{%b2, %0|%0, %b2}";
11258       else if (operands[2] == const1_rtx
11259                && (TARGET_SHIFT1 || optimize_size))
11260         return "sal{l}\t%0";
11261       else
11262         return "sal{l}\t{%2, %0|%0, %2}";
11263     }
11264 }
11265   [(set (attr "type")
11266      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11267                           (const_int 0))
11268                       (match_operand 0 "register_operand" ""))
11269                  (match_operand 2 "const1_operand" ""))
11270               (const_string "alu")
11271            ]
11272            (const_string "ishift")))
11273    (set_attr "mode" "SI")])
11274
11275 (define_insn "*ashlsi3_cconly"
11276   [(set (reg FLAGS_REG)
11277         (compare
11278           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11279                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11280           (const_int 0)))
11281    (clobber (match_scratch:SI 0 "=r"))]
11282   "(optimize_size
11283     || !TARGET_PARTIAL_FLAG_REG_STALL
11284     || (operands[2] == const1_rtx
11285         && (TARGET_SHIFT1
11286             || TARGET_DOUBLE_WITH_ADD)))
11287    && ix86_match_ccmode (insn, CCGOCmode)
11288    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11289 {
11290   switch (get_attr_type (insn))
11291     {
11292     case TYPE_ALU:
11293       gcc_assert (operands[2] == const1_rtx);
11294       return "add{l}\t%0, %0";
11295
11296     default:
11297       if (REG_P (operands[2]))
11298         return "sal{l}\t{%b2, %0|%0, %b2}";
11299       else if (operands[2] == const1_rtx
11300                && (TARGET_SHIFT1 || optimize_size))
11301         return "sal{l}\t%0";
11302       else
11303         return "sal{l}\t{%2, %0|%0, %2}";
11304     }
11305 }
11306   [(set (attr "type")
11307      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11308                           (const_int 0))
11309                       (match_operand 0 "register_operand" ""))
11310                  (match_operand 2 "const1_operand" ""))
11311               (const_string "alu")
11312            ]
11313            (const_string "ishift")))
11314    (set_attr "mode" "SI")])
11315
11316 (define_insn "*ashlsi3_cmp_zext"
11317   [(set (reg FLAGS_REG)
11318         (compare
11319           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11320                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11321           (const_int 0)))
11322    (set (match_operand:DI 0 "register_operand" "=r")
11323         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11324   "TARGET_64BIT
11325    && (optimize_size
11326        || !TARGET_PARTIAL_FLAG_REG_STALL
11327        || (operands[2] == const1_rtx
11328            && (TARGET_SHIFT1
11329                || TARGET_DOUBLE_WITH_ADD)))
11330    && ix86_match_ccmode (insn, CCGOCmode)
11331    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11332 {
11333   switch (get_attr_type (insn))
11334     {
11335     case TYPE_ALU:
11336       gcc_assert (operands[2] == const1_rtx);
11337       return "add{l}\t%k0, %k0";
11338
11339     default:
11340       if (REG_P (operands[2]))
11341         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11342       else if (operands[2] == const1_rtx
11343                && (TARGET_SHIFT1 || optimize_size))
11344         return "sal{l}\t%k0";
11345       else
11346         return "sal{l}\t{%2, %k0|%k0, %2}";
11347     }
11348 }
11349   [(set (attr "type")
11350      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11351                      (const_int 0))
11352                  (match_operand 2 "const1_operand" ""))
11353               (const_string "alu")
11354            ]
11355            (const_string "ishift")))
11356    (set_attr "mode" "SI")])
11357
11358 (define_expand "ashlhi3"
11359   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11360         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11361                    (match_operand:QI 2 "nonmemory_operand" "")))
11362    (clobber (reg:CC FLAGS_REG))]
11363   "TARGET_HIMODE_MATH"
11364   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11365
11366 (define_insn "*ashlhi3_1_lea"
11367   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11368         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11369                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11370    (clobber (reg:CC FLAGS_REG))]
11371   "!TARGET_PARTIAL_REG_STALL
11372    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11373 {
11374   switch (get_attr_type (insn))
11375     {
11376     case TYPE_LEA:
11377       return "#";
11378     case TYPE_ALU:
11379       gcc_assert (operands[2] == const1_rtx);
11380       return "add{w}\t%0, %0";
11381
11382     default:
11383       if (REG_P (operands[2]))
11384         return "sal{w}\t{%b2, %0|%0, %b2}";
11385       else if (operands[2] == const1_rtx
11386                && (TARGET_SHIFT1 || optimize_size))
11387         return "sal{w}\t%0";
11388       else
11389         return "sal{w}\t{%2, %0|%0, %2}";
11390     }
11391 }
11392   [(set (attr "type")
11393      (cond [(eq_attr "alternative" "1")
11394               (const_string "lea")
11395             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11396                           (const_int 0))
11397                       (match_operand 0 "register_operand" ""))
11398                  (match_operand 2 "const1_operand" ""))
11399               (const_string "alu")
11400            ]
11401            (const_string "ishift")))
11402    (set_attr "mode" "HI,SI")])
11403
11404 (define_insn "*ashlhi3_1"
11405   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11406         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11407                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11408    (clobber (reg:CC FLAGS_REG))]
11409   "TARGET_PARTIAL_REG_STALL
11410    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11411 {
11412   switch (get_attr_type (insn))
11413     {
11414     case TYPE_ALU:
11415       gcc_assert (operands[2] == const1_rtx);
11416       return "add{w}\t%0, %0";
11417
11418     default:
11419       if (REG_P (operands[2]))
11420         return "sal{w}\t{%b2, %0|%0, %b2}";
11421       else if (operands[2] == const1_rtx
11422                && (TARGET_SHIFT1 || optimize_size))
11423         return "sal{w}\t%0";
11424       else
11425         return "sal{w}\t{%2, %0|%0, %2}";
11426     }
11427 }
11428   [(set (attr "type")
11429      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11430                           (const_int 0))
11431                       (match_operand 0 "register_operand" ""))
11432                  (match_operand 2 "const1_operand" ""))
11433               (const_string "alu")
11434            ]
11435            (const_string "ishift")))
11436    (set_attr "mode" "HI")])
11437
11438 ;; This pattern can't accept a variable shift count, since shifts by
11439 ;; zero don't affect the flags.  We assume that shifts by constant
11440 ;; zero are optimized away.
11441 (define_insn "*ashlhi3_cmp"
11442   [(set (reg FLAGS_REG)
11443         (compare
11444           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11445                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11446           (const_int 0)))
11447    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11448         (ashift:HI (match_dup 1) (match_dup 2)))]
11449   "(optimize_size
11450     || !TARGET_PARTIAL_FLAG_REG_STALL
11451     || (operands[2] == const1_rtx
11452         && (TARGET_SHIFT1
11453             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11454    && ix86_match_ccmode (insn, CCGOCmode)
11455    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11456 {
11457   switch (get_attr_type (insn))
11458     {
11459     case TYPE_ALU:
11460       gcc_assert (operands[2] == const1_rtx);
11461       return "add{w}\t%0, %0";
11462
11463     default:
11464       if (REG_P (operands[2]))
11465         return "sal{w}\t{%b2, %0|%0, %b2}";
11466       else if (operands[2] == const1_rtx
11467                && (TARGET_SHIFT1 || optimize_size))
11468         return "sal{w}\t%0";
11469       else
11470         return "sal{w}\t{%2, %0|%0, %2}";
11471     }
11472 }
11473   [(set (attr "type")
11474      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11475                           (const_int 0))
11476                       (match_operand 0 "register_operand" ""))
11477                  (match_operand 2 "const1_operand" ""))
11478               (const_string "alu")
11479            ]
11480            (const_string "ishift")))
11481    (set_attr "mode" "HI")])
11482
11483 (define_insn "*ashlhi3_cconly"
11484   [(set (reg FLAGS_REG)
11485         (compare
11486           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11487                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11488           (const_int 0)))
11489    (clobber (match_scratch:HI 0 "=r"))]
11490   "(optimize_size
11491     || !TARGET_PARTIAL_FLAG_REG_STALL
11492     || (operands[2] == const1_rtx
11493         && (TARGET_SHIFT1
11494             || TARGET_DOUBLE_WITH_ADD)))
11495    && ix86_match_ccmode (insn, CCGOCmode)
11496    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11497 {
11498   switch (get_attr_type (insn))
11499     {
11500     case TYPE_ALU:
11501       gcc_assert (operands[2] == const1_rtx);
11502       return "add{w}\t%0, %0";
11503
11504     default:
11505       if (REG_P (operands[2]))
11506         return "sal{w}\t{%b2, %0|%0, %b2}";
11507       else if (operands[2] == const1_rtx
11508                && (TARGET_SHIFT1 || optimize_size))
11509         return "sal{w}\t%0";
11510       else
11511         return "sal{w}\t{%2, %0|%0, %2}";
11512     }
11513 }
11514   [(set (attr "type")
11515      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11516                           (const_int 0))
11517                       (match_operand 0 "register_operand" ""))
11518                  (match_operand 2 "const1_operand" ""))
11519               (const_string "alu")
11520            ]
11521            (const_string "ishift")))
11522    (set_attr "mode" "HI")])
11523
11524 (define_expand "ashlqi3"
11525   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11526         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11527                    (match_operand:QI 2 "nonmemory_operand" "")))
11528    (clobber (reg:CC FLAGS_REG))]
11529   "TARGET_QIMODE_MATH"
11530   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11531
11532 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11533
11534 (define_insn "*ashlqi3_1_lea"
11535   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11536         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11537                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11538    (clobber (reg:CC FLAGS_REG))]
11539   "!TARGET_PARTIAL_REG_STALL
11540    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11541 {
11542   switch (get_attr_type (insn))
11543     {
11544     case TYPE_LEA:
11545       return "#";
11546     case TYPE_ALU:
11547       gcc_assert (operands[2] == const1_rtx);
11548       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11549         return "add{l}\t%k0, %k0";
11550       else
11551         return "add{b}\t%0, %0";
11552
11553     default:
11554       if (REG_P (operands[2]))
11555         {
11556           if (get_attr_mode (insn) == MODE_SI)
11557             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11558           else
11559             return "sal{b}\t{%b2, %0|%0, %b2}";
11560         }
11561       else if (operands[2] == const1_rtx
11562                && (TARGET_SHIFT1 || optimize_size))
11563         {
11564           if (get_attr_mode (insn) == MODE_SI)
11565             return "sal{l}\t%0";
11566           else
11567             return "sal{b}\t%0";
11568         }
11569       else
11570         {
11571           if (get_attr_mode (insn) == MODE_SI)
11572             return "sal{l}\t{%2, %k0|%k0, %2}";
11573           else
11574             return "sal{b}\t{%2, %0|%0, %2}";
11575         }
11576     }
11577 }
11578   [(set (attr "type")
11579      (cond [(eq_attr "alternative" "2")
11580               (const_string "lea")
11581             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11582                           (const_int 0))
11583                       (match_operand 0 "register_operand" ""))
11584                  (match_operand 2 "const1_operand" ""))
11585               (const_string "alu")
11586            ]
11587            (const_string "ishift")))
11588    (set_attr "mode" "QI,SI,SI")])
11589
11590 (define_insn "*ashlqi3_1"
11591   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11592         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11593                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11594    (clobber (reg:CC FLAGS_REG))]
11595   "TARGET_PARTIAL_REG_STALL
11596    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11597 {
11598   switch (get_attr_type (insn))
11599     {
11600     case TYPE_ALU:
11601       gcc_assert (operands[2] == const1_rtx);
11602       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11603         return "add{l}\t%k0, %k0";
11604       else
11605         return "add{b}\t%0, %0";
11606
11607     default:
11608       if (REG_P (operands[2]))
11609         {
11610           if (get_attr_mode (insn) == MODE_SI)
11611             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11612           else
11613             return "sal{b}\t{%b2, %0|%0, %b2}";
11614         }
11615       else if (operands[2] == const1_rtx
11616                && (TARGET_SHIFT1 || optimize_size))
11617         {
11618           if (get_attr_mode (insn) == MODE_SI)
11619             return "sal{l}\t%0";
11620           else
11621             return "sal{b}\t%0";
11622         }
11623       else
11624         {
11625           if (get_attr_mode (insn) == MODE_SI)
11626             return "sal{l}\t{%2, %k0|%k0, %2}";
11627           else
11628             return "sal{b}\t{%2, %0|%0, %2}";
11629         }
11630     }
11631 }
11632   [(set (attr "type")
11633      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11634                           (const_int 0))
11635                       (match_operand 0 "register_operand" ""))
11636                  (match_operand 2 "const1_operand" ""))
11637               (const_string "alu")
11638            ]
11639            (const_string "ishift")))
11640    (set_attr "mode" "QI,SI")])
11641
11642 ;; This pattern can't accept a variable shift count, since shifts by
11643 ;; zero don't affect the flags.  We assume that shifts by constant
11644 ;; zero are optimized away.
11645 (define_insn "*ashlqi3_cmp"
11646   [(set (reg FLAGS_REG)
11647         (compare
11648           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11649                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11650           (const_int 0)))
11651    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11652         (ashift:QI (match_dup 1) (match_dup 2)))]
11653   "(optimize_size
11654     || !TARGET_PARTIAL_FLAG_REG_STALL
11655     || (operands[2] == const1_rtx
11656         && (TARGET_SHIFT1
11657             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11658    && ix86_match_ccmode (insn, CCGOCmode)
11659    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11660 {
11661   switch (get_attr_type (insn))
11662     {
11663     case TYPE_ALU:
11664       gcc_assert (operands[2] == const1_rtx);
11665       return "add{b}\t%0, %0";
11666
11667     default:
11668       if (REG_P (operands[2]))
11669         return "sal{b}\t{%b2, %0|%0, %b2}";
11670       else if (operands[2] == const1_rtx
11671                && (TARGET_SHIFT1 || optimize_size))
11672         return "sal{b}\t%0";
11673       else
11674         return "sal{b}\t{%2, %0|%0, %2}";
11675     }
11676 }
11677   [(set (attr "type")
11678      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11679                           (const_int 0))
11680                       (match_operand 0 "register_operand" ""))
11681                  (match_operand 2 "const1_operand" ""))
11682               (const_string "alu")
11683            ]
11684            (const_string "ishift")))
11685    (set_attr "mode" "QI")])
11686
11687 (define_insn "*ashlqi3_cconly"
11688   [(set (reg FLAGS_REG)
11689         (compare
11690           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11691                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11692           (const_int 0)))
11693    (clobber (match_scratch:QI 0 "=q"))]
11694   "(optimize_size
11695     || !TARGET_PARTIAL_FLAG_REG_STALL
11696     || (operands[2] == const1_rtx
11697         && (TARGET_SHIFT1
11698             || TARGET_DOUBLE_WITH_ADD)))
11699    && ix86_match_ccmode (insn, CCGOCmode)
11700    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11701 {
11702   switch (get_attr_type (insn))
11703     {
11704     case TYPE_ALU:
11705       gcc_assert (operands[2] == const1_rtx);
11706       return "add{b}\t%0, %0";
11707
11708     default:
11709       if (REG_P (operands[2]))
11710         return "sal{b}\t{%b2, %0|%0, %b2}";
11711       else if (operands[2] == const1_rtx
11712                && (TARGET_SHIFT1 || optimize_size))
11713         return "sal{b}\t%0";
11714       else
11715         return "sal{b}\t{%2, %0|%0, %2}";
11716     }
11717 }
11718   [(set (attr "type")
11719      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11720                           (const_int 0))
11721                       (match_operand 0 "register_operand" ""))
11722                  (match_operand 2 "const1_operand" ""))
11723               (const_string "alu")
11724            ]
11725            (const_string "ishift")))
11726    (set_attr "mode" "QI")])
11727
11728 ;; See comment above `ashldi3' about how this works.
11729
11730 (define_expand "ashrti3"
11731   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11732                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11733                                 (match_operand:QI 2 "nonmemory_operand" "")))
11734               (clobber (reg:CC FLAGS_REG))])]
11735   "TARGET_64BIT"
11736 {
11737   if (! immediate_operand (operands[2], QImode))
11738     {
11739       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11740       DONE;
11741     }
11742   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11743   DONE;
11744 })
11745
11746 (define_insn "ashrti3_1"
11747   [(set (match_operand:TI 0 "register_operand" "=r")
11748         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11749                      (match_operand:QI 2 "register_operand" "c")))
11750    (clobber (match_scratch:DI 3 "=&r"))
11751    (clobber (reg:CC FLAGS_REG))]
11752   "TARGET_64BIT"
11753   "#"
11754   [(set_attr "type" "multi")])
11755
11756 (define_insn "*ashrti3_2"
11757   [(set (match_operand:TI 0 "register_operand" "=r")
11758         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11759                      (match_operand:QI 2 "immediate_operand" "O")))
11760    (clobber (reg:CC FLAGS_REG))]
11761   "TARGET_64BIT"
11762   "#"
11763   [(set_attr "type" "multi")])
11764
11765 (define_split
11766   [(set (match_operand:TI 0 "register_operand" "")
11767         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11768                      (match_operand:QI 2 "register_operand" "")))
11769    (clobber (match_scratch:DI 3 ""))
11770    (clobber (reg:CC FLAGS_REG))]
11771   "TARGET_64BIT && reload_completed"
11772   [(const_int 0)]
11773   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11774
11775 (define_split
11776   [(set (match_operand:TI 0 "register_operand" "")
11777         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11778                      (match_operand:QI 2 "immediate_operand" "")))
11779    (clobber (reg:CC FLAGS_REG))]
11780   "TARGET_64BIT && reload_completed"
11781   [(const_int 0)]
11782   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11783
11784 (define_insn "x86_64_shrd"
11785   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11786         (ior:DI (ashiftrt:DI (match_dup 0)
11787                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11788                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11789                   (minus:QI (const_int 64) (match_dup 2)))))
11790    (clobber (reg:CC FLAGS_REG))]
11791   "TARGET_64BIT"
11792   "@
11793    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11794    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11795   [(set_attr "type" "ishift")
11796    (set_attr "prefix_0f" "1")
11797    (set_attr "mode" "DI")
11798    (set_attr "athlon_decode" "vector")
11799    (set_attr "amdfam10_decode" "vector")])   
11800
11801 (define_expand "ashrdi3"
11802   [(set (match_operand:DI 0 "shiftdi_operand" "")
11803         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11804                      (match_operand:QI 2 "nonmemory_operand" "")))]
11805   ""
11806   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11807
11808 (define_insn "*ashrdi3_63_rex64"
11809   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11810         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11811                      (match_operand:DI 2 "const_int_operand" "i,i")))
11812    (clobber (reg:CC FLAGS_REG))]
11813   "TARGET_64BIT && INTVAL (operands[2]) == 63
11814    && (TARGET_USE_CLTD || optimize_size)
11815    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11816   "@
11817    {cqto|cqo}
11818    sar{q}\t{%2, %0|%0, %2}"
11819   [(set_attr "type" "imovx,ishift")
11820    (set_attr "prefix_0f" "0,*")
11821    (set_attr "length_immediate" "0,*")
11822    (set_attr "modrm" "0,1")
11823    (set_attr "mode" "DI")])
11824
11825 (define_insn "*ashrdi3_1_one_bit_rex64"
11826   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11827         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11828                      (match_operand:QI 2 "const1_operand" "")))
11829    (clobber (reg:CC FLAGS_REG))]
11830   "TARGET_64BIT
11831    && (TARGET_SHIFT1 || optimize_size)
11832    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11833   "sar{q}\t%0"
11834   [(set_attr "type" "ishift")
11835    (set (attr "length")
11836      (if_then_else (match_operand:DI 0 "register_operand" "")
11837         (const_string "2")
11838         (const_string "*")))])
11839
11840 (define_insn "*ashrdi3_1_rex64"
11841   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11842         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11843                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11844    (clobber (reg:CC FLAGS_REG))]
11845   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11846   "@
11847    sar{q}\t{%2, %0|%0, %2}
11848    sar{q}\t{%b2, %0|%0, %b2}"
11849   [(set_attr "type" "ishift")
11850    (set_attr "mode" "DI")])
11851
11852 ;; This pattern can't accept a variable shift count, since shifts by
11853 ;; zero don't affect the flags.  We assume that shifts by constant
11854 ;; zero are optimized away.
11855 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11856   [(set (reg FLAGS_REG)
11857         (compare
11858           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11859                        (match_operand:QI 2 "const1_operand" ""))
11860           (const_int 0)))
11861    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11862         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11863   "TARGET_64BIT
11864    && (TARGET_SHIFT1 || optimize_size)
11865    && ix86_match_ccmode (insn, CCGOCmode)
11866    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11867   "sar{q}\t%0"
11868   [(set_attr "type" "ishift")
11869    (set (attr "length")
11870      (if_then_else (match_operand:DI 0 "register_operand" "")
11871         (const_string "2")
11872         (const_string "*")))])
11873
11874 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11875   [(set (reg FLAGS_REG)
11876         (compare
11877           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11878                        (match_operand:QI 2 "const1_operand" ""))
11879           (const_int 0)))
11880    (clobber (match_scratch:DI 0 "=r"))]
11881   "TARGET_64BIT
11882    && (TARGET_SHIFT1 || optimize_size)
11883    && ix86_match_ccmode (insn, CCGOCmode)
11884    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11885   "sar{q}\t%0"
11886   [(set_attr "type" "ishift")
11887    (set_attr "length" "2")])
11888
11889 ;; This pattern can't accept a variable shift count, since shifts by
11890 ;; zero don't affect the flags.  We assume that shifts by constant
11891 ;; zero are optimized away.
11892 (define_insn "*ashrdi3_cmp_rex64"
11893   [(set (reg FLAGS_REG)
11894         (compare
11895           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11896                        (match_operand:QI 2 "const_int_operand" "n"))
11897           (const_int 0)))
11898    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11899         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11900   "TARGET_64BIT
11901    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11902    && ix86_match_ccmode (insn, CCGOCmode)
11903    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11904   "sar{q}\t{%2, %0|%0, %2}"
11905   [(set_attr "type" "ishift")
11906    (set_attr "mode" "DI")])
11907
11908 (define_insn "*ashrdi3_cconly_rex64"
11909   [(set (reg FLAGS_REG)
11910         (compare
11911           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11912                        (match_operand:QI 2 "const_int_operand" "n"))
11913           (const_int 0)))
11914    (clobber (match_scratch:DI 0 "=r"))]
11915   "TARGET_64BIT
11916    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11917    && ix86_match_ccmode (insn, CCGOCmode)
11918    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11919   "sar{q}\t{%2, %0|%0, %2}"
11920   [(set_attr "type" "ishift")
11921    (set_attr "mode" "DI")])
11922
11923 (define_insn "*ashrdi3_1"
11924   [(set (match_operand:DI 0 "register_operand" "=r")
11925         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11926                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11927    (clobber (reg:CC FLAGS_REG))]
11928   "!TARGET_64BIT"
11929   "#"
11930   [(set_attr "type" "multi")])
11931
11932 ;; By default we don't ask for a scratch register, because when DImode
11933 ;; values are manipulated, registers are already at a premium.  But if
11934 ;; we have one handy, we won't turn it away.
11935 (define_peephole2
11936   [(match_scratch:SI 3 "r")
11937    (parallel [(set (match_operand:DI 0 "register_operand" "")
11938                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11939                                 (match_operand:QI 2 "nonmemory_operand" "")))
11940               (clobber (reg:CC FLAGS_REG))])
11941    (match_dup 3)]
11942   "!TARGET_64BIT && TARGET_CMOVE"
11943   [(const_int 0)]
11944   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11945
11946 (define_split
11947   [(set (match_operand:DI 0 "register_operand" "")
11948         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11949                      (match_operand:QI 2 "nonmemory_operand" "")))
11950    (clobber (reg:CC FLAGS_REG))]
11951   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11952                      ? epilogue_completed : reload_completed)"
11953   [(const_int 0)]
11954   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11955
11956 (define_insn "x86_shrd_1"
11957   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11958         (ior:SI (ashiftrt:SI (match_dup 0)
11959                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11960                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11961                   (minus:QI (const_int 32) (match_dup 2)))))
11962    (clobber (reg:CC FLAGS_REG))]
11963   ""
11964   "@
11965    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11966    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11967   [(set_attr "type" "ishift")
11968    (set_attr "prefix_0f" "1")
11969    (set_attr "pent_pair" "np")
11970    (set_attr "mode" "SI")])
11971
11972 (define_expand "x86_shift_adj_3"
11973   [(use (match_operand:SI 0 "register_operand" ""))
11974    (use (match_operand:SI 1 "register_operand" ""))
11975    (use (match_operand:QI 2 "register_operand" ""))]
11976   ""
11977 {
11978   rtx label = gen_label_rtx ();
11979   rtx tmp;
11980
11981   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11982
11983   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11984   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11985   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11986                               gen_rtx_LABEL_REF (VOIDmode, label),
11987                               pc_rtx);
11988   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11989   JUMP_LABEL (tmp) = label;
11990
11991   emit_move_insn (operands[0], operands[1]);
11992   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11993
11994   emit_label (label);
11995   LABEL_NUSES (label) = 1;
11996
11997   DONE;
11998 })
11999
12000 (define_insn "ashrsi3_31"
12001   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12002         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12003                      (match_operand:SI 2 "const_int_operand" "i,i")))
12004    (clobber (reg:CC FLAGS_REG))]
12005   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12006    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12007   "@
12008    {cltd|cdq}
12009    sar{l}\t{%2, %0|%0, %2}"
12010   [(set_attr "type" "imovx,ishift")
12011    (set_attr "prefix_0f" "0,*")
12012    (set_attr "length_immediate" "0,*")
12013    (set_attr "modrm" "0,1")
12014    (set_attr "mode" "SI")])
12015
12016 (define_insn "*ashrsi3_31_zext"
12017   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12018         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12019                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12020    (clobber (reg:CC FLAGS_REG))]
12021   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12022    && INTVAL (operands[2]) == 31
12023    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12024   "@
12025    {cltd|cdq}
12026    sar{l}\t{%2, %k0|%k0, %2}"
12027   [(set_attr "type" "imovx,ishift")
12028    (set_attr "prefix_0f" "0,*")
12029    (set_attr "length_immediate" "0,*")
12030    (set_attr "modrm" "0,1")
12031    (set_attr "mode" "SI")])
12032
12033 (define_expand "ashrsi3"
12034   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12035         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12036                      (match_operand:QI 2 "nonmemory_operand" "")))
12037    (clobber (reg:CC FLAGS_REG))]
12038   ""
12039   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12040
12041 (define_insn "*ashrsi3_1_one_bit"
12042   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12043         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12044                      (match_operand:QI 2 "const1_operand" "")))
12045    (clobber (reg:CC FLAGS_REG))]
12046   "(TARGET_SHIFT1 || optimize_size)
12047    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12048   "sar{l}\t%0"
12049   [(set_attr "type" "ishift")
12050    (set (attr "length")
12051      (if_then_else (match_operand:SI 0 "register_operand" "")
12052         (const_string "2")
12053         (const_string "*")))])
12054
12055 (define_insn "*ashrsi3_1_one_bit_zext"
12056   [(set (match_operand:DI 0 "register_operand" "=r")
12057         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12058                                      (match_operand:QI 2 "const1_operand" ""))))
12059    (clobber (reg:CC FLAGS_REG))]
12060   "TARGET_64BIT
12061    && (TARGET_SHIFT1 || optimize_size)
12062    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12063   "sar{l}\t%k0"
12064   [(set_attr "type" "ishift")
12065    (set_attr "length" "2")])
12066
12067 (define_insn "*ashrsi3_1"
12068   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12069         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12070                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12071    (clobber (reg:CC FLAGS_REG))]
12072   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12073   "@
12074    sar{l}\t{%2, %0|%0, %2}
12075    sar{l}\t{%b2, %0|%0, %b2}"
12076   [(set_attr "type" "ishift")
12077    (set_attr "mode" "SI")])
12078
12079 (define_insn "*ashrsi3_1_zext"
12080   [(set (match_operand:DI 0 "register_operand" "=r,r")
12081         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12082                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12083    (clobber (reg:CC FLAGS_REG))]
12084   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12085   "@
12086    sar{l}\t{%2, %k0|%k0, %2}
12087    sar{l}\t{%b2, %k0|%k0, %b2}"
12088   [(set_attr "type" "ishift")
12089    (set_attr "mode" "SI")])
12090
12091 ;; This pattern can't accept a variable shift count, since shifts by
12092 ;; zero don't affect the flags.  We assume that shifts by constant
12093 ;; zero are optimized away.
12094 (define_insn "*ashrsi3_one_bit_cmp"
12095   [(set (reg FLAGS_REG)
12096         (compare
12097           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12098                        (match_operand:QI 2 "const1_operand" ""))
12099           (const_int 0)))
12100    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12101         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12102   "(TARGET_SHIFT1 || optimize_size)
12103    && ix86_match_ccmode (insn, CCGOCmode)
12104    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12105   "sar{l}\t%0"
12106   [(set_attr "type" "ishift")
12107    (set (attr "length")
12108      (if_then_else (match_operand:SI 0 "register_operand" "")
12109         (const_string "2")
12110         (const_string "*")))])
12111
12112 (define_insn "*ashrsi3_one_bit_cconly"
12113   [(set (reg FLAGS_REG)
12114         (compare
12115           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12116                        (match_operand:QI 2 "const1_operand" ""))
12117           (const_int 0)))
12118    (clobber (match_scratch:SI 0 "=r"))]
12119   "(TARGET_SHIFT1 || optimize_size)
12120    && ix86_match_ccmode (insn, CCGOCmode)
12121    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12122   "sar{l}\t%0"
12123   [(set_attr "type" "ishift")
12124    (set_attr "length" "2")])
12125
12126 (define_insn "*ashrsi3_one_bit_cmp_zext"
12127   [(set (reg FLAGS_REG)
12128         (compare
12129           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12130                        (match_operand:QI 2 "const1_operand" ""))
12131           (const_int 0)))
12132    (set (match_operand:DI 0 "register_operand" "=r")
12133         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12134   "TARGET_64BIT
12135    && (TARGET_SHIFT1 || optimize_size)
12136    && ix86_match_ccmode (insn, CCmode)
12137    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12138   "sar{l}\t%k0"
12139   [(set_attr "type" "ishift")
12140    (set_attr "length" "2")])
12141
12142 ;; This pattern can't accept a variable shift count, since shifts by
12143 ;; zero don't affect the flags.  We assume that shifts by constant
12144 ;; zero are optimized away.
12145 (define_insn "*ashrsi3_cmp"
12146   [(set (reg FLAGS_REG)
12147         (compare
12148           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12149                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12150           (const_int 0)))
12151    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12152         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12153   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12154    && ix86_match_ccmode (insn, CCGOCmode)
12155    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12156   "sar{l}\t{%2, %0|%0, %2}"
12157   [(set_attr "type" "ishift")
12158    (set_attr "mode" "SI")])
12159
12160 (define_insn "*ashrsi3_cconly"
12161   [(set (reg FLAGS_REG)
12162         (compare
12163           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12164                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12165           (const_int 0)))
12166    (clobber (match_scratch:SI 0 "=r"))]
12167   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12168    && ix86_match_ccmode (insn, CCGOCmode)
12169    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12170   "sar{l}\t{%2, %0|%0, %2}"
12171   [(set_attr "type" "ishift")
12172    (set_attr "mode" "SI")])
12173
12174 (define_insn "*ashrsi3_cmp_zext"
12175   [(set (reg FLAGS_REG)
12176         (compare
12177           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12178                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12179           (const_int 0)))
12180    (set (match_operand:DI 0 "register_operand" "=r")
12181         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12182   "TARGET_64BIT
12183    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12184    && ix86_match_ccmode (insn, CCGOCmode)
12185    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12186   "sar{l}\t{%2, %k0|%k0, %2}"
12187   [(set_attr "type" "ishift")
12188    (set_attr "mode" "SI")])
12189
12190 (define_expand "ashrhi3"
12191   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12192         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12193                      (match_operand:QI 2 "nonmemory_operand" "")))
12194    (clobber (reg:CC FLAGS_REG))]
12195   "TARGET_HIMODE_MATH"
12196   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12197
12198 (define_insn "*ashrhi3_1_one_bit"
12199   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12200         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12201                      (match_operand:QI 2 "const1_operand" "")))
12202    (clobber (reg:CC FLAGS_REG))]
12203   "(TARGET_SHIFT1 || optimize_size)
12204    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12205   "sar{w}\t%0"
12206   [(set_attr "type" "ishift")
12207    (set (attr "length")
12208      (if_then_else (match_operand 0 "register_operand" "")
12209         (const_string "2")
12210         (const_string "*")))])
12211
12212 (define_insn "*ashrhi3_1"
12213   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12214         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12215                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12216    (clobber (reg:CC FLAGS_REG))]
12217   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12218   "@
12219    sar{w}\t{%2, %0|%0, %2}
12220    sar{w}\t{%b2, %0|%0, %b2}"
12221   [(set_attr "type" "ishift")
12222    (set_attr "mode" "HI")])
12223
12224 ;; This pattern can't accept a variable shift count, since shifts by
12225 ;; zero don't affect the flags.  We assume that shifts by constant
12226 ;; zero are optimized away.
12227 (define_insn "*ashrhi3_one_bit_cmp"
12228   [(set (reg FLAGS_REG)
12229         (compare
12230           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12231                        (match_operand:QI 2 "const1_operand" ""))
12232           (const_int 0)))
12233    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12234         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12235   "(TARGET_SHIFT1 || optimize_size)
12236    && ix86_match_ccmode (insn, CCGOCmode)
12237    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12238   "sar{w}\t%0"
12239   [(set_attr "type" "ishift")
12240    (set (attr "length")
12241      (if_then_else (match_operand 0 "register_operand" "")
12242         (const_string "2")
12243         (const_string "*")))])
12244
12245 (define_insn "*ashrhi3_one_bit_cconly"
12246   [(set (reg FLAGS_REG)
12247         (compare
12248           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12249                        (match_operand:QI 2 "const1_operand" ""))
12250           (const_int 0)))
12251    (clobber (match_scratch:HI 0 "=r"))]
12252   "(TARGET_SHIFT1 || optimize_size)
12253    && ix86_match_ccmode (insn, CCGOCmode)
12254    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12255   "sar{w}\t%0"
12256   [(set_attr "type" "ishift")
12257    (set_attr "length" "2")])
12258
12259 ;; This pattern can't accept a variable shift count, since shifts by
12260 ;; zero don't affect the flags.  We assume that shifts by constant
12261 ;; zero are optimized away.
12262 (define_insn "*ashrhi3_cmp"
12263   [(set (reg FLAGS_REG)
12264         (compare
12265           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12266                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12267           (const_int 0)))
12268    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12269         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12270   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12271    && ix86_match_ccmode (insn, CCGOCmode)
12272    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12273   "sar{w}\t{%2, %0|%0, %2}"
12274   [(set_attr "type" "ishift")
12275    (set_attr "mode" "HI")])
12276
12277 (define_insn "*ashrhi3_cconly"
12278   [(set (reg FLAGS_REG)
12279         (compare
12280           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12281                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12282           (const_int 0)))
12283    (clobber (match_scratch:HI 0 "=r"))]
12284   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12285    && ix86_match_ccmode (insn, CCGOCmode)
12286    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12287   "sar{w}\t{%2, %0|%0, %2}"
12288   [(set_attr "type" "ishift")
12289    (set_attr "mode" "HI")])
12290
12291 (define_expand "ashrqi3"
12292   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12293         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12294                      (match_operand:QI 2 "nonmemory_operand" "")))
12295    (clobber (reg:CC FLAGS_REG))]
12296   "TARGET_QIMODE_MATH"
12297   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12298
12299 (define_insn "*ashrqi3_1_one_bit"
12300   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12301         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12302                      (match_operand:QI 2 "const1_operand" "")))
12303    (clobber (reg:CC FLAGS_REG))]
12304   "(TARGET_SHIFT1 || optimize_size)
12305    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12306   "sar{b}\t%0"
12307   [(set_attr "type" "ishift")
12308    (set (attr "length")
12309      (if_then_else (match_operand 0 "register_operand" "")
12310         (const_string "2")
12311         (const_string "*")))])
12312
12313 (define_insn "*ashrqi3_1_one_bit_slp"
12314   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12315         (ashiftrt:QI (match_dup 0)
12316                      (match_operand:QI 1 "const1_operand" "")))
12317    (clobber (reg:CC FLAGS_REG))]
12318   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12319    && (TARGET_SHIFT1 || optimize_size)
12320    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12321   "sar{b}\t%0"
12322   [(set_attr "type" "ishift1")
12323    (set (attr "length")
12324      (if_then_else (match_operand 0 "register_operand" "")
12325         (const_string "2")
12326         (const_string "*")))])
12327
12328 (define_insn "*ashrqi3_1"
12329   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12330         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12331                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12332    (clobber (reg:CC FLAGS_REG))]
12333   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12334   "@
12335    sar{b}\t{%2, %0|%0, %2}
12336    sar{b}\t{%b2, %0|%0, %b2}"
12337   [(set_attr "type" "ishift")
12338    (set_attr "mode" "QI")])
12339
12340 (define_insn "*ashrqi3_1_slp"
12341   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12342         (ashiftrt:QI (match_dup 0)
12343                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12344    (clobber (reg:CC FLAGS_REG))]
12345   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12346    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12347   "@
12348    sar{b}\t{%1, %0|%0, %1}
12349    sar{b}\t{%b1, %0|%0, %b1}"
12350   [(set_attr "type" "ishift1")
12351    (set_attr "mode" "QI")])
12352
12353 ;; This pattern can't accept a variable shift count, since shifts by
12354 ;; zero don't affect the flags.  We assume that shifts by constant
12355 ;; zero are optimized away.
12356 (define_insn "*ashrqi3_one_bit_cmp"
12357   [(set (reg FLAGS_REG)
12358         (compare
12359           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12360                        (match_operand:QI 2 "const1_operand" "I"))
12361           (const_int 0)))
12362    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12363         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12364   "(TARGET_SHIFT1 || optimize_size)
12365    && ix86_match_ccmode (insn, CCGOCmode)
12366    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12367   "sar{b}\t%0"
12368   [(set_attr "type" "ishift")
12369    (set (attr "length")
12370      (if_then_else (match_operand 0 "register_operand" "")
12371         (const_string "2")
12372         (const_string "*")))])
12373
12374 (define_insn "*ashrqi3_one_bit_cconly"
12375   [(set (reg FLAGS_REG)
12376         (compare
12377           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12378                        (match_operand:QI 2 "const1_operand" "I"))
12379           (const_int 0)))
12380    (clobber (match_scratch:QI 0 "=q"))]
12381   "(TARGET_SHIFT1 || optimize_size)
12382    && ix86_match_ccmode (insn, CCGOCmode)
12383    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12384   "sar{b}\t%0"
12385   [(set_attr "type" "ishift")
12386    (set_attr "length" "2")])
12387
12388 ;; This pattern can't accept a variable shift count, since shifts by
12389 ;; zero don't affect the flags.  We assume that shifts by constant
12390 ;; zero are optimized away.
12391 (define_insn "*ashrqi3_cmp"
12392   [(set (reg FLAGS_REG)
12393         (compare
12394           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12395                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12396           (const_int 0)))
12397    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12398         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12399   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12400    && ix86_match_ccmode (insn, CCGOCmode)
12401    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12402   "sar{b}\t{%2, %0|%0, %2}"
12403   [(set_attr "type" "ishift")
12404    (set_attr "mode" "QI")])
12405
12406 (define_insn "*ashrqi3_cconly"
12407   [(set (reg FLAGS_REG)
12408         (compare
12409           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12410                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12411           (const_int 0)))
12412    (clobber (match_scratch:QI 0 "=q"))]
12413   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12414    && ix86_match_ccmode (insn, CCGOCmode)
12415    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12416   "sar{b}\t{%2, %0|%0, %2}"
12417   [(set_attr "type" "ishift")
12418    (set_attr "mode" "QI")])
12419
12420 \f
12421 ;; Logical shift instructions
12422
12423 ;; See comment above `ashldi3' about how this works.
12424
12425 (define_expand "lshrti3"
12426   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12427                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12428                                 (match_operand:QI 2 "nonmemory_operand" "")))
12429               (clobber (reg:CC FLAGS_REG))])]
12430   "TARGET_64BIT"
12431 {
12432   if (! immediate_operand (operands[2], QImode))
12433     {
12434       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12435       DONE;
12436     }
12437   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12438   DONE;
12439 })
12440
12441 (define_insn "lshrti3_1"
12442   [(set (match_operand:TI 0 "register_operand" "=r")
12443         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12444                      (match_operand:QI 2 "register_operand" "c")))
12445    (clobber (match_scratch:DI 3 "=&r"))
12446    (clobber (reg:CC FLAGS_REG))]
12447   "TARGET_64BIT"
12448   "#"
12449   [(set_attr "type" "multi")])
12450
12451 ;; This pattern must be defined before *lshrti3_2 to prevent
12452 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12453
12454 (define_insn "sse2_lshrti3"
12455   [(set (match_operand:TI 0 "register_operand" "=x")
12456         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12457                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12458   "TARGET_SSE2"
12459 {
12460   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12461   return "psrldq\t{%2, %0|%0, %2}";
12462 }
12463   [(set_attr "type" "sseishft")
12464    (set_attr "prefix_data16" "1")
12465    (set_attr "mode" "TI")])
12466
12467 (define_insn "*lshrti3_2"
12468   [(set (match_operand:TI 0 "register_operand" "=r")
12469         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12470                      (match_operand:QI 2 "immediate_operand" "O")))
12471    (clobber (reg:CC FLAGS_REG))]
12472   "TARGET_64BIT"
12473   "#"
12474   [(set_attr "type" "multi")])
12475
12476 (define_split
12477   [(set (match_operand:TI 0 "register_operand" "")
12478         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12479                      (match_operand:QI 2 "register_operand" "")))
12480    (clobber (match_scratch:DI 3 ""))
12481    (clobber (reg:CC FLAGS_REG))]
12482   "TARGET_64BIT && reload_completed"
12483   [(const_int 0)]
12484   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12485
12486 (define_split
12487   [(set (match_operand:TI 0 "register_operand" "")
12488         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12489                      (match_operand:QI 2 "immediate_operand" "")))
12490    (clobber (reg:CC FLAGS_REG))]
12491   "TARGET_64BIT && reload_completed"
12492   [(const_int 0)]
12493   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12494
12495 (define_expand "lshrdi3"
12496   [(set (match_operand:DI 0 "shiftdi_operand" "")
12497         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12498                      (match_operand:QI 2 "nonmemory_operand" "")))]
12499   ""
12500   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12501
12502 (define_insn "*lshrdi3_1_one_bit_rex64"
12503   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12504         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12505                      (match_operand:QI 2 "const1_operand" "")))
12506    (clobber (reg:CC FLAGS_REG))]
12507   "TARGET_64BIT
12508    && (TARGET_SHIFT1 || optimize_size)
12509    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12510   "shr{q}\t%0"
12511   [(set_attr "type" "ishift")
12512    (set (attr "length")
12513      (if_then_else (match_operand:DI 0 "register_operand" "")
12514         (const_string "2")
12515         (const_string "*")))])
12516
12517 (define_insn "*lshrdi3_1_rex64"
12518   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12519         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12520                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12521    (clobber (reg:CC FLAGS_REG))]
12522   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12523   "@
12524    shr{q}\t{%2, %0|%0, %2}
12525    shr{q}\t{%b2, %0|%0, %b2}"
12526   [(set_attr "type" "ishift")
12527    (set_attr "mode" "DI")])
12528
12529 ;; This pattern can't accept a variable shift count, since shifts by
12530 ;; zero don't affect the flags.  We assume that shifts by constant
12531 ;; zero are optimized away.
12532 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12533   [(set (reg FLAGS_REG)
12534         (compare
12535           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12536                        (match_operand:QI 2 "const1_operand" ""))
12537           (const_int 0)))
12538    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12539         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12540   "TARGET_64BIT
12541    && (TARGET_SHIFT1 || optimize_size)
12542    && ix86_match_ccmode (insn, CCGOCmode)
12543    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12544   "shr{q}\t%0"
12545   [(set_attr "type" "ishift")
12546    (set (attr "length")
12547      (if_then_else (match_operand:DI 0 "register_operand" "")
12548         (const_string "2")
12549         (const_string "*")))])
12550
12551 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12552   [(set (reg FLAGS_REG)
12553         (compare
12554           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12555                        (match_operand:QI 2 "const1_operand" ""))
12556           (const_int 0)))
12557    (clobber (match_scratch:DI 0 "=r"))]
12558   "TARGET_64BIT
12559    && (TARGET_SHIFT1 || optimize_size)
12560    && ix86_match_ccmode (insn, CCGOCmode)
12561    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12562   "shr{q}\t%0"
12563   [(set_attr "type" "ishift")
12564    (set_attr "length" "2")])
12565
12566 ;; This pattern can't accept a variable shift count, since shifts by
12567 ;; zero don't affect the flags.  We assume that shifts by constant
12568 ;; zero are optimized away.
12569 (define_insn "*lshrdi3_cmp_rex64"
12570   [(set (reg FLAGS_REG)
12571         (compare
12572           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12573                        (match_operand:QI 2 "const_int_operand" "e"))
12574           (const_int 0)))
12575    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12576         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12577   "TARGET_64BIT
12578    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12579    && ix86_match_ccmode (insn, CCGOCmode)
12580    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12581   "shr{q}\t{%2, %0|%0, %2}"
12582   [(set_attr "type" "ishift")
12583    (set_attr "mode" "DI")])
12584
12585 (define_insn "*lshrdi3_cconly_rex64"
12586   [(set (reg FLAGS_REG)
12587         (compare
12588           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12589                        (match_operand:QI 2 "const_int_operand" "e"))
12590           (const_int 0)))
12591    (clobber (match_scratch:DI 0 "=r"))]
12592   "TARGET_64BIT
12593    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12594    && ix86_match_ccmode (insn, CCGOCmode)
12595    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12596   "shr{q}\t{%2, %0|%0, %2}"
12597   [(set_attr "type" "ishift")
12598    (set_attr "mode" "DI")])
12599
12600 (define_insn "*lshrdi3_1"
12601   [(set (match_operand:DI 0 "register_operand" "=r")
12602         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12603                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12604    (clobber (reg:CC FLAGS_REG))]
12605   "!TARGET_64BIT"
12606   "#"
12607   [(set_attr "type" "multi")])
12608
12609 ;; By default we don't ask for a scratch register, because when DImode
12610 ;; values are manipulated, registers are already at a premium.  But if
12611 ;; we have one handy, we won't turn it away.
12612 (define_peephole2
12613   [(match_scratch:SI 3 "r")
12614    (parallel [(set (match_operand:DI 0 "register_operand" "")
12615                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12616                                 (match_operand:QI 2 "nonmemory_operand" "")))
12617               (clobber (reg:CC FLAGS_REG))])
12618    (match_dup 3)]
12619   "!TARGET_64BIT && TARGET_CMOVE"
12620   [(const_int 0)]
12621   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12622
12623 (define_split
12624   [(set (match_operand:DI 0 "register_operand" "")
12625         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12626                      (match_operand:QI 2 "nonmemory_operand" "")))
12627    (clobber (reg:CC FLAGS_REG))]
12628   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12629                      ? epilogue_completed : reload_completed)"
12630   [(const_int 0)]
12631   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12632
12633 (define_expand "lshrsi3"
12634   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12635         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12636                      (match_operand:QI 2 "nonmemory_operand" "")))
12637    (clobber (reg:CC FLAGS_REG))]
12638   ""
12639   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12640
12641 (define_insn "*lshrsi3_1_one_bit"
12642   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12643         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12644                      (match_operand:QI 2 "const1_operand" "")))
12645    (clobber (reg:CC FLAGS_REG))]
12646   "(TARGET_SHIFT1 || optimize_size)
12647    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12648   "shr{l}\t%0"
12649   [(set_attr "type" "ishift")
12650    (set (attr "length")
12651      (if_then_else (match_operand:SI 0 "register_operand" "")
12652         (const_string "2")
12653         (const_string "*")))])
12654
12655 (define_insn "*lshrsi3_1_one_bit_zext"
12656   [(set (match_operand:DI 0 "register_operand" "=r")
12657         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12658                      (match_operand:QI 2 "const1_operand" "")))
12659    (clobber (reg:CC FLAGS_REG))]
12660   "TARGET_64BIT
12661    && (TARGET_SHIFT1 || optimize_size)
12662    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12663   "shr{l}\t%k0"
12664   [(set_attr "type" "ishift")
12665    (set_attr "length" "2")])
12666
12667 (define_insn "*lshrsi3_1"
12668   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12669         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12670                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12671    (clobber (reg:CC FLAGS_REG))]
12672   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12673   "@
12674    shr{l}\t{%2, %0|%0, %2}
12675    shr{l}\t{%b2, %0|%0, %b2}"
12676   [(set_attr "type" "ishift")
12677    (set_attr "mode" "SI")])
12678
12679 (define_insn "*lshrsi3_1_zext"
12680   [(set (match_operand:DI 0 "register_operand" "=r,r")
12681         (zero_extend:DI
12682           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12683                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12684    (clobber (reg:CC FLAGS_REG))]
12685   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12686   "@
12687    shr{l}\t{%2, %k0|%k0, %2}
12688    shr{l}\t{%b2, %k0|%k0, %b2}"
12689   [(set_attr "type" "ishift")
12690    (set_attr "mode" "SI")])
12691
12692 ;; This pattern can't accept a variable shift count, since shifts by
12693 ;; zero don't affect the flags.  We assume that shifts by constant
12694 ;; zero are optimized away.
12695 (define_insn "*lshrsi3_one_bit_cmp"
12696   [(set (reg FLAGS_REG)
12697         (compare
12698           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12699                        (match_operand:QI 2 "const1_operand" ""))
12700           (const_int 0)))
12701    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12702         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12703   "(TARGET_SHIFT1 || optimize_size)
12704    && ix86_match_ccmode (insn, CCGOCmode)
12705    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12706   "shr{l}\t%0"
12707   [(set_attr "type" "ishift")
12708    (set (attr "length")
12709      (if_then_else (match_operand:SI 0 "register_operand" "")
12710         (const_string "2")
12711         (const_string "*")))])
12712
12713 (define_insn "*lshrsi3_one_bit_cconly"
12714   [(set (reg FLAGS_REG)
12715         (compare
12716           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12717                        (match_operand:QI 2 "const1_operand" ""))
12718           (const_int 0)))
12719    (clobber (match_scratch:SI 0 "=r"))]
12720   "(TARGET_SHIFT1 || optimize_size)
12721    && ix86_match_ccmode (insn, CCGOCmode)
12722    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12723   "shr{l}\t%0"
12724   [(set_attr "type" "ishift")
12725    (set_attr "length" "2")])
12726
12727 (define_insn "*lshrsi3_cmp_one_bit_zext"
12728   [(set (reg FLAGS_REG)
12729         (compare
12730           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12731                        (match_operand:QI 2 "const1_operand" ""))
12732           (const_int 0)))
12733    (set (match_operand:DI 0 "register_operand" "=r")
12734         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12735   "TARGET_64BIT
12736    && (TARGET_SHIFT1 || optimize_size)
12737    && ix86_match_ccmode (insn, CCGOCmode)
12738    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12739   "shr{l}\t%k0"
12740   [(set_attr "type" "ishift")
12741    (set_attr "length" "2")])
12742
12743 ;; This pattern can't accept a variable shift count, since shifts by
12744 ;; zero don't affect the flags.  We assume that shifts by constant
12745 ;; zero are optimized away.
12746 (define_insn "*lshrsi3_cmp"
12747   [(set (reg FLAGS_REG)
12748         (compare
12749           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12750                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12751           (const_int 0)))
12752    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12753         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12754   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12755    && ix86_match_ccmode (insn, CCGOCmode)
12756    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12757   "shr{l}\t{%2, %0|%0, %2}"
12758   [(set_attr "type" "ishift")
12759    (set_attr "mode" "SI")])
12760
12761 (define_insn "*lshrsi3_cconly"
12762   [(set (reg FLAGS_REG)
12763       (compare
12764         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12765                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12766         (const_int 0)))
12767    (clobber (match_scratch:SI 0 "=r"))]
12768   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12769    && ix86_match_ccmode (insn, CCGOCmode)
12770    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12771   "shr{l}\t{%2, %0|%0, %2}"
12772   [(set_attr "type" "ishift")
12773    (set_attr "mode" "SI")])
12774
12775 (define_insn "*lshrsi3_cmp_zext"
12776   [(set (reg FLAGS_REG)
12777         (compare
12778           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12779                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12780           (const_int 0)))
12781    (set (match_operand:DI 0 "register_operand" "=r")
12782         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12783   "TARGET_64BIT
12784    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12785    && ix86_match_ccmode (insn, CCGOCmode)
12786    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12787   "shr{l}\t{%2, %k0|%k0, %2}"
12788   [(set_attr "type" "ishift")
12789    (set_attr "mode" "SI")])
12790
12791 (define_expand "lshrhi3"
12792   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12793         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12794                      (match_operand:QI 2 "nonmemory_operand" "")))
12795    (clobber (reg:CC FLAGS_REG))]
12796   "TARGET_HIMODE_MATH"
12797   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12798
12799 (define_insn "*lshrhi3_1_one_bit"
12800   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12801         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12802                      (match_operand:QI 2 "const1_operand" "")))
12803    (clobber (reg:CC FLAGS_REG))]
12804   "(TARGET_SHIFT1 || optimize_size)
12805    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12806   "shr{w}\t%0"
12807   [(set_attr "type" "ishift")
12808    (set (attr "length")
12809      (if_then_else (match_operand 0 "register_operand" "")
12810         (const_string "2")
12811         (const_string "*")))])
12812
12813 (define_insn "*lshrhi3_1"
12814   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12815         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12816                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12817    (clobber (reg:CC FLAGS_REG))]
12818   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12819   "@
12820    shr{w}\t{%2, %0|%0, %2}
12821    shr{w}\t{%b2, %0|%0, %b2}"
12822   [(set_attr "type" "ishift")
12823    (set_attr "mode" "HI")])
12824
12825 ;; This pattern can't accept a variable shift count, since shifts by
12826 ;; zero don't affect the flags.  We assume that shifts by constant
12827 ;; zero are optimized away.
12828 (define_insn "*lshrhi3_one_bit_cmp"
12829   [(set (reg FLAGS_REG)
12830         (compare
12831           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12832                        (match_operand:QI 2 "const1_operand" ""))
12833           (const_int 0)))
12834    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12835         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12836   "(TARGET_SHIFT1 || optimize_size)
12837    && ix86_match_ccmode (insn, CCGOCmode)
12838    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12839   "shr{w}\t%0"
12840   [(set_attr "type" "ishift")
12841    (set (attr "length")
12842      (if_then_else (match_operand:SI 0 "register_operand" "")
12843         (const_string "2")
12844         (const_string "*")))])
12845
12846 (define_insn "*lshrhi3_one_bit_cconly"
12847   [(set (reg FLAGS_REG)
12848         (compare
12849           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12850                        (match_operand:QI 2 "const1_operand" ""))
12851           (const_int 0)))
12852    (clobber (match_scratch:HI 0 "=r"))]
12853   "(TARGET_SHIFT1 || optimize_size)
12854    && ix86_match_ccmode (insn, CCGOCmode)
12855    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12856   "shr{w}\t%0"
12857   [(set_attr "type" "ishift")
12858    (set_attr "length" "2")])
12859
12860 ;; This pattern can't accept a variable shift count, since shifts by
12861 ;; zero don't affect the flags.  We assume that shifts by constant
12862 ;; zero are optimized away.
12863 (define_insn "*lshrhi3_cmp"
12864   [(set (reg FLAGS_REG)
12865         (compare
12866           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12867                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12868           (const_int 0)))
12869    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12870         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12871   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12872    && ix86_match_ccmode (insn, CCGOCmode)
12873    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12874   "shr{w}\t{%2, %0|%0, %2}"
12875   [(set_attr "type" "ishift")
12876    (set_attr "mode" "HI")])
12877
12878 (define_insn "*lshrhi3_cconly"
12879   [(set (reg FLAGS_REG)
12880         (compare
12881           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12882                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12883           (const_int 0)))
12884    (clobber (match_scratch:HI 0 "=r"))]
12885   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12886    && ix86_match_ccmode (insn, CCGOCmode)
12887    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12888   "shr{w}\t{%2, %0|%0, %2}"
12889   [(set_attr "type" "ishift")
12890    (set_attr "mode" "HI")])
12891
12892 (define_expand "lshrqi3"
12893   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12894         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12895                      (match_operand:QI 2 "nonmemory_operand" "")))
12896    (clobber (reg:CC FLAGS_REG))]
12897   "TARGET_QIMODE_MATH"
12898   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12899
12900 (define_insn "*lshrqi3_1_one_bit"
12901   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12902         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12903                      (match_operand:QI 2 "const1_operand" "")))
12904    (clobber (reg:CC FLAGS_REG))]
12905   "(TARGET_SHIFT1 || optimize_size)
12906    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12907   "shr{b}\t%0"
12908   [(set_attr "type" "ishift")
12909    (set (attr "length")
12910      (if_then_else (match_operand 0 "register_operand" "")
12911         (const_string "2")
12912         (const_string "*")))])
12913
12914 (define_insn "*lshrqi3_1_one_bit_slp"
12915   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12916         (lshiftrt:QI (match_dup 0)
12917                      (match_operand:QI 1 "const1_operand" "")))
12918    (clobber (reg:CC FLAGS_REG))]
12919   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12920    && (TARGET_SHIFT1 || optimize_size)"
12921   "shr{b}\t%0"
12922   [(set_attr "type" "ishift1")
12923    (set (attr "length")
12924      (if_then_else (match_operand 0 "register_operand" "")
12925         (const_string "2")
12926         (const_string "*")))])
12927
12928 (define_insn "*lshrqi3_1"
12929   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12930         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12931                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12932    (clobber (reg:CC FLAGS_REG))]
12933   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12934   "@
12935    shr{b}\t{%2, %0|%0, %2}
12936    shr{b}\t{%b2, %0|%0, %b2}"
12937   [(set_attr "type" "ishift")
12938    (set_attr "mode" "QI")])
12939
12940 (define_insn "*lshrqi3_1_slp"
12941   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12942         (lshiftrt:QI (match_dup 0)
12943                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12944    (clobber (reg:CC FLAGS_REG))]
12945   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12946    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12947   "@
12948    shr{b}\t{%1, %0|%0, %1}
12949    shr{b}\t{%b1, %0|%0, %b1}"
12950   [(set_attr "type" "ishift1")
12951    (set_attr "mode" "QI")])
12952
12953 ;; This pattern can't accept a variable shift count, since shifts by
12954 ;; zero don't affect the flags.  We assume that shifts by constant
12955 ;; zero are optimized away.
12956 (define_insn "*lshrqi2_one_bit_cmp"
12957   [(set (reg FLAGS_REG)
12958         (compare
12959           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12960                        (match_operand:QI 2 "const1_operand" ""))
12961           (const_int 0)))
12962    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12963         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12964   "(TARGET_SHIFT1 || optimize_size)
12965    && ix86_match_ccmode (insn, CCGOCmode)
12966    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12967   "shr{b}\t%0"
12968   [(set_attr "type" "ishift")
12969    (set (attr "length")
12970      (if_then_else (match_operand:SI 0 "register_operand" "")
12971         (const_string "2")
12972         (const_string "*")))])
12973
12974 (define_insn "*lshrqi2_one_bit_cconly"
12975   [(set (reg FLAGS_REG)
12976         (compare
12977           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12978                        (match_operand:QI 2 "const1_operand" ""))
12979           (const_int 0)))
12980    (clobber (match_scratch:QI 0 "=q"))]
12981   "(TARGET_SHIFT1 || optimize_size)
12982    && ix86_match_ccmode (insn, CCGOCmode)
12983    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12984   "shr{b}\t%0"
12985   [(set_attr "type" "ishift")
12986    (set_attr "length" "2")])
12987
12988 ;; This pattern can't accept a variable shift count, since shifts by
12989 ;; zero don't affect the flags.  We assume that shifts by constant
12990 ;; zero are optimized away.
12991 (define_insn "*lshrqi2_cmp"
12992   [(set (reg FLAGS_REG)
12993         (compare
12994           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12995                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12996           (const_int 0)))
12997    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12998         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12999   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13000    && ix86_match_ccmode (insn, CCGOCmode)
13001    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13002   "shr{b}\t{%2, %0|%0, %2}"
13003   [(set_attr "type" "ishift")
13004    (set_attr "mode" "QI")])
13005
13006 (define_insn "*lshrqi2_cconly"
13007   [(set (reg FLAGS_REG)
13008         (compare
13009           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13010                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13011           (const_int 0)))
13012    (clobber (match_scratch:QI 0 "=q"))]
13013   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13014    && ix86_match_ccmode (insn, CCGOCmode)
13015    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13016   "shr{b}\t{%2, %0|%0, %2}"
13017   [(set_attr "type" "ishift")
13018    (set_attr "mode" "QI")])
13019 \f
13020 ;; Rotate instructions
13021
13022 (define_expand "rotldi3"
13023   [(set (match_operand:DI 0 "shiftdi_operand" "")
13024         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13025                    (match_operand:QI 2 "nonmemory_operand" "")))
13026    (clobber (reg:CC FLAGS_REG))]
13027  ""
13028 {
13029   if (TARGET_64BIT)
13030     {
13031       ix86_expand_binary_operator (ROTATE, DImode, operands);
13032       DONE;
13033     }
13034   if (!const_1_to_31_operand (operands[2], VOIDmode))
13035     FAIL;
13036   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13037   DONE;
13038 })
13039
13040 ;; Implement rotation using two double-precision shift instructions
13041 ;; and a scratch register.
13042 (define_insn_and_split "ix86_rotldi3"
13043  [(set (match_operand:DI 0 "register_operand" "=r")
13044        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13045                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13046   (clobber (reg:CC FLAGS_REG))
13047   (clobber (match_scratch:SI 3 "=&r"))]
13048  "!TARGET_64BIT"
13049  ""
13050  "&& reload_completed"
13051  [(set (match_dup 3) (match_dup 4))
13052   (parallel
13053    [(set (match_dup 4)
13054          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13055                  (lshiftrt:SI (match_dup 5)
13056                               (minus:QI (const_int 32) (match_dup 2)))))
13057     (clobber (reg:CC FLAGS_REG))])
13058   (parallel
13059    [(set (match_dup 5)
13060          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13061                  (lshiftrt:SI (match_dup 3)
13062                               (minus:QI (const_int 32) (match_dup 2)))))
13063     (clobber (reg:CC FLAGS_REG))])]
13064  "split_di (operands, 1, operands + 4, operands + 5);")
13065
13066 (define_insn "*rotlsi3_1_one_bit_rex64"
13067   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13068         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13069                    (match_operand:QI 2 "const1_operand" "")))
13070    (clobber (reg:CC FLAGS_REG))]
13071   "TARGET_64BIT
13072    && (TARGET_SHIFT1 || optimize_size)
13073    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13074   "rol{q}\t%0"
13075   [(set_attr "type" "rotate")
13076    (set (attr "length")
13077      (if_then_else (match_operand:DI 0 "register_operand" "")
13078         (const_string "2")
13079         (const_string "*")))])
13080
13081 (define_insn "*rotldi3_1_rex64"
13082   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13083         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13084                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13085    (clobber (reg:CC FLAGS_REG))]
13086   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13087   "@
13088    rol{q}\t{%2, %0|%0, %2}
13089    rol{q}\t{%b2, %0|%0, %b2}"
13090   [(set_attr "type" "rotate")
13091    (set_attr "mode" "DI")])
13092
13093 (define_expand "rotlsi3"
13094   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13095         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13096                    (match_operand:QI 2 "nonmemory_operand" "")))
13097    (clobber (reg:CC FLAGS_REG))]
13098   ""
13099   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13100
13101 (define_insn "*rotlsi3_1_one_bit"
13102   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13103         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13104                    (match_operand:QI 2 "const1_operand" "")))
13105    (clobber (reg:CC FLAGS_REG))]
13106   "(TARGET_SHIFT1 || optimize_size)
13107    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13108   "rol{l}\t%0"
13109   [(set_attr "type" "rotate")
13110    (set (attr "length")
13111      (if_then_else (match_operand:SI 0 "register_operand" "")
13112         (const_string "2")
13113         (const_string "*")))])
13114
13115 (define_insn "*rotlsi3_1_one_bit_zext"
13116   [(set (match_operand:DI 0 "register_operand" "=r")
13117         (zero_extend:DI
13118           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13119                      (match_operand:QI 2 "const1_operand" ""))))
13120    (clobber (reg:CC FLAGS_REG))]
13121   "TARGET_64BIT
13122    && (TARGET_SHIFT1 || optimize_size)
13123    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13124   "rol{l}\t%k0"
13125   [(set_attr "type" "rotate")
13126    (set_attr "length" "2")])
13127
13128 (define_insn "*rotlsi3_1"
13129   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13130         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13131                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13132    (clobber (reg:CC FLAGS_REG))]
13133   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13134   "@
13135    rol{l}\t{%2, %0|%0, %2}
13136    rol{l}\t{%b2, %0|%0, %b2}"
13137   [(set_attr "type" "rotate")
13138    (set_attr "mode" "SI")])
13139
13140 (define_insn "*rotlsi3_1_zext"
13141   [(set (match_operand:DI 0 "register_operand" "=r,r")
13142         (zero_extend:DI
13143           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13144                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13145    (clobber (reg:CC FLAGS_REG))]
13146   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13147   "@
13148    rol{l}\t{%2, %k0|%k0, %2}
13149    rol{l}\t{%b2, %k0|%k0, %b2}"
13150   [(set_attr "type" "rotate")
13151    (set_attr "mode" "SI")])
13152
13153 (define_expand "rotlhi3"
13154   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13155         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13156                    (match_operand:QI 2 "nonmemory_operand" "")))
13157    (clobber (reg:CC FLAGS_REG))]
13158   "TARGET_HIMODE_MATH"
13159   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13160
13161 (define_insn "*rotlhi3_1_one_bit"
13162   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13163         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13164                    (match_operand:QI 2 "const1_operand" "")))
13165    (clobber (reg:CC FLAGS_REG))]
13166   "(TARGET_SHIFT1 || optimize_size)
13167    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13168   "rol{w}\t%0"
13169   [(set_attr "type" "rotate")
13170    (set (attr "length")
13171      (if_then_else (match_operand 0 "register_operand" "")
13172         (const_string "2")
13173         (const_string "*")))])
13174
13175 (define_insn "*rotlhi3_1"
13176   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13177         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13178                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13179    (clobber (reg:CC FLAGS_REG))]
13180   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13181   "@
13182    rol{w}\t{%2, %0|%0, %2}
13183    rol{w}\t{%b2, %0|%0, %b2}"
13184   [(set_attr "type" "rotate")
13185    (set_attr "mode" "HI")])
13186
13187 (define_split
13188  [(set (match_operand:HI 0 "register_operand" "")
13189        (rotate:HI (match_dup 0) (const_int 8)))
13190   (clobber (reg:CC FLAGS_REG))]
13191  "reload_completed"
13192  [(parallel [(set (strict_low_part (match_dup 0))
13193                   (bswap:HI (match_dup 0)))
13194              (clobber (reg:CC FLAGS_REG))])]
13195  "")
13196
13197 (define_expand "rotlqi3"
13198   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13199         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13200                    (match_operand:QI 2 "nonmemory_operand" "")))
13201    (clobber (reg:CC FLAGS_REG))]
13202   "TARGET_QIMODE_MATH"
13203   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13204
13205 (define_insn "*rotlqi3_1_one_bit_slp"
13206   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13207         (rotate:QI (match_dup 0)
13208                    (match_operand:QI 1 "const1_operand" "")))
13209    (clobber (reg:CC FLAGS_REG))]
13210   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13211    && (TARGET_SHIFT1 || optimize_size)"
13212   "rol{b}\t%0"
13213   [(set_attr "type" "rotate1")
13214    (set (attr "length")
13215      (if_then_else (match_operand 0 "register_operand" "")
13216         (const_string "2")
13217         (const_string "*")))])
13218
13219 (define_insn "*rotlqi3_1_one_bit"
13220   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13221         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13222                    (match_operand:QI 2 "const1_operand" "")))
13223    (clobber (reg:CC FLAGS_REG))]
13224   "(TARGET_SHIFT1 || optimize_size)
13225    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13226   "rol{b}\t%0"
13227   [(set_attr "type" "rotate")
13228    (set (attr "length")
13229      (if_then_else (match_operand 0 "register_operand" "")
13230         (const_string "2")
13231         (const_string "*")))])
13232
13233 (define_insn "*rotlqi3_1_slp"
13234   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13235         (rotate:QI (match_dup 0)
13236                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13237    (clobber (reg:CC FLAGS_REG))]
13238   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13239    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13240   "@
13241    rol{b}\t{%1, %0|%0, %1}
13242    rol{b}\t{%b1, %0|%0, %b1}"
13243   [(set_attr "type" "rotate1")
13244    (set_attr "mode" "QI")])
13245
13246 (define_insn "*rotlqi3_1"
13247   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13248         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13249                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13250    (clobber (reg:CC FLAGS_REG))]
13251   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13252   "@
13253    rol{b}\t{%2, %0|%0, %2}
13254    rol{b}\t{%b2, %0|%0, %b2}"
13255   [(set_attr "type" "rotate")
13256    (set_attr "mode" "QI")])
13257
13258 (define_expand "rotrdi3"
13259   [(set (match_operand:DI 0 "shiftdi_operand" "")
13260         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13261                    (match_operand:QI 2 "nonmemory_operand" "")))
13262    (clobber (reg:CC FLAGS_REG))]
13263  ""
13264 {
13265   if (TARGET_64BIT)
13266     {
13267       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13268       DONE;
13269     }
13270   if (!const_1_to_31_operand (operands[2], VOIDmode))
13271     FAIL;
13272   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13273   DONE;
13274 })
13275
13276 ;; Implement rotation using two double-precision shift instructions
13277 ;; and a scratch register.
13278 (define_insn_and_split "ix86_rotrdi3"
13279  [(set (match_operand:DI 0 "register_operand" "=r")
13280        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13281                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13282   (clobber (reg:CC FLAGS_REG))
13283   (clobber (match_scratch:SI 3 "=&r"))]
13284  "!TARGET_64BIT"
13285  ""
13286  "&& reload_completed"
13287  [(set (match_dup 3) (match_dup 4))
13288   (parallel
13289    [(set (match_dup 4)
13290          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13291                  (ashift:SI (match_dup 5)
13292                             (minus:QI (const_int 32) (match_dup 2)))))
13293     (clobber (reg:CC FLAGS_REG))])
13294   (parallel
13295    [(set (match_dup 5)
13296          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13297                  (ashift:SI (match_dup 3)
13298                             (minus:QI (const_int 32) (match_dup 2)))))
13299     (clobber (reg:CC FLAGS_REG))])]
13300  "split_di (operands, 1, operands + 4, operands + 5);")
13301
13302 (define_insn "*rotrdi3_1_one_bit_rex64"
13303   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13304         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13305                      (match_operand:QI 2 "const1_operand" "")))
13306    (clobber (reg:CC FLAGS_REG))]
13307   "TARGET_64BIT
13308    && (TARGET_SHIFT1 || optimize_size)
13309    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13310   "ror{q}\t%0"
13311   [(set_attr "type" "rotate")
13312    (set (attr "length")
13313      (if_then_else (match_operand:DI 0 "register_operand" "")
13314         (const_string "2")
13315         (const_string "*")))])
13316
13317 (define_insn "*rotrdi3_1_rex64"
13318   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13319         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13320                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13321    (clobber (reg:CC FLAGS_REG))]
13322   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13323   "@
13324    ror{q}\t{%2, %0|%0, %2}
13325    ror{q}\t{%b2, %0|%0, %b2}"
13326   [(set_attr "type" "rotate")
13327    (set_attr "mode" "DI")])
13328
13329 (define_expand "rotrsi3"
13330   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13331         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13332                      (match_operand:QI 2 "nonmemory_operand" "")))
13333    (clobber (reg:CC FLAGS_REG))]
13334   ""
13335   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13336
13337 (define_insn "*rotrsi3_1_one_bit"
13338   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13339         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13340                      (match_operand:QI 2 "const1_operand" "")))
13341    (clobber (reg:CC FLAGS_REG))]
13342   "(TARGET_SHIFT1 || optimize_size)
13343    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13344   "ror{l}\t%0"
13345   [(set_attr "type" "rotate")
13346    (set (attr "length")
13347      (if_then_else (match_operand:SI 0 "register_operand" "")
13348         (const_string "2")
13349         (const_string "*")))])
13350
13351 (define_insn "*rotrsi3_1_one_bit_zext"
13352   [(set (match_operand:DI 0 "register_operand" "=r")
13353         (zero_extend:DI
13354           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13355                        (match_operand:QI 2 "const1_operand" ""))))
13356    (clobber (reg:CC FLAGS_REG))]
13357   "TARGET_64BIT
13358    && (TARGET_SHIFT1 || optimize_size)
13359    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13360   "ror{l}\t%k0"
13361   [(set_attr "type" "rotate")
13362    (set (attr "length")
13363      (if_then_else (match_operand:SI 0 "register_operand" "")
13364         (const_string "2")
13365         (const_string "*")))])
13366
13367 (define_insn "*rotrsi3_1"
13368   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13369         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13370                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13371    (clobber (reg:CC FLAGS_REG))]
13372   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13373   "@
13374    ror{l}\t{%2, %0|%0, %2}
13375    ror{l}\t{%b2, %0|%0, %b2}"
13376   [(set_attr "type" "rotate")
13377    (set_attr "mode" "SI")])
13378
13379 (define_insn "*rotrsi3_1_zext"
13380   [(set (match_operand:DI 0 "register_operand" "=r,r")
13381         (zero_extend:DI
13382           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13383                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13384    (clobber (reg:CC FLAGS_REG))]
13385   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13386   "@
13387    ror{l}\t{%2, %k0|%k0, %2}
13388    ror{l}\t{%b2, %k0|%k0, %b2}"
13389   [(set_attr "type" "rotate")
13390    (set_attr "mode" "SI")])
13391
13392 (define_expand "rotrhi3"
13393   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13394         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13395                      (match_operand:QI 2 "nonmemory_operand" "")))
13396    (clobber (reg:CC FLAGS_REG))]
13397   "TARGET_HIMODE_MATH"
13398   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13399
13400 (define_insn "*rotrhi3_one_bit"
13401   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13402         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13403                      (match_operand:QI 2 "const1_operand" "")))
13404    (clobber (reg:CC FLAGS_REG))]
13405   "(TARGET_SHIFT1 || optimize_size)
13406    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13407   "ror{w}\t%0"
13408   [(set_attr "type" "rotate")
13409    (set (attr "length")
13410      (if_then_else (match_operand 0 "register_operand" "")
13411         (const_string "2")
13412         (const_string "*")))])
13413
13414 (define_insn "*rotrhi3_1"
13415   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13416         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13417                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13418    (clobber (reg:CC FLAGS_REG))]
13419   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13420   "@
13421    ror{w}\t{%2, %0|%0, %2}
13422    ror{w}\t{%b2, %0|%0, %b2}"
13423   [(set_attr "type" "rotate")
13424    (set_attr "mode" "HI")])
13425
13426 (define_split
13427  [(set (match_operand:HI 0 "register_operand" "")
13428        (rotatert:HI (match_dup 0) (const_int 8)))
13429   (clobber (reg:CC FLAGS_REG))]
13430  "reload_completed"
13431  [(parallel [(set (strict_low_part (match_dup 0))
13432                   (bswap:HI (match_dup 0)))
13433              (clobber (reg:CC FLAGS_REG))])]
13434  "")
13435
13436 (define_expand "rotrqi3"
13437   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13438         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13439                      (match_operand:QI 2 "nonmemory_operand" "")))
13440    (clobber (reg:CC FLAGS_REG))]
13441   "TARGET_QIMODE_MATH"
13442   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13443
13444 (define_insn "*rotrqi3_1_one_bit"
13445   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13446         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13447                      (match_operand:QI 2 "const1_operand" "")))
13448    (clobber (reg:CC FLAGS_REG))]
13449   "(TARGET_SHIFT1 || optimize_size)
13450    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13451   "ror{b}\t%0"
13452   [(set_attr "type" "rotate")
13453    (set (attr "length")
13454      (if_then_else (match_operand 0 "register_operand" "")
13455         (const_string "2")
13456         (const_string "*")))])
13457
13458 (define_insn "*rotrqi3_1_one_bit_slp"
13459   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13460         (rotatert:QI (match_dup 0)
13461                      (match_operand:QI 1 "const1_operand" "")))
13462    (clobber (reg:CC FLAGS_REG))]
13463   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13464    && (TARGET_SHIFT1 || optimize_size)"
13465   "ror{b}\t%0"
13466   [(set_attr "type" "rotate1")
13467    (set (attr "length")
13468      (if_then_else (match_operand 0 "register_operand" "")
13469         (const_string "2")
13470         (const_string "*")))])
13471
13472 (define_insn "*rotrqi3_1"
13473   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13474         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13475                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13476    (clobber (reg:CC FLAGS_REG))]
13477   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13478   "@
13479    ror{b}\t{%2, %0|%0, %2}
13480    ror{b}\t{%b2, %0|%0, %b2}"
13481   [(set_attr "type" "rotate")
13482    (set_attr "mode" "QI")])
13483
13484 (define_insn "*rotrqi3_1_slp"
13485   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13486         (rotatert:QI (match_dup 0)
13487                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13488    (clobber (reg:CC FLAGS_REG))]
13489   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13490    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13491   "@
13492    ror{b}\t{%1, %0|%0, %1}
13493    ror{b}\t{%b1, %0|%0, %b1}"
13494   [(set_attr "type" "rotate1")
13495    (set_attr "mode" "QI")])
13496 \f
13497 ;; Bit set / bit test instructions
13498
13499 (define_expand "extv"
13500   [(set (match_operand:SI 0 "register_operand" "")
13501         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13502                          (match_operand:SI 2 "const8_operand" "")
13503                          (match_operand:SI 3 "const8_operand" "")))]
13504   ""
13505 {
13506   /* Handle extractions from %ah et al.  */
13507   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13508     FAIL;
13509
13510   /* From mips.md: extract_bit_field doesn't verify that our source
13511      matches the predicate, so check it again here.  */
13512   if (! ext_register_operand (operands[1], VOIDmode))
13513     FAIL;
13514 })
13515
13516 (define_expand "extzv"
13517   [(set (match_operand:SI 0 "register_operand" "")
13518         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13519                          (match_operand:SI 2 "const8_operand" "")
13520                          (match_operand:SI 3 "const8_operand" "")))]
13521   ""
13522 {
13523   /* Handle extractions from %ah et al.  */
13524   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13525     FAIL;
13526
13527   /* From mips.md: extract_bit_field doesn't verify that our source
13528      matches the predicate, so check it again here.  */
13529   if (! ext_register_operand (operands[1], VOIDmode))
13530     FAIL;
13531 })
13532
13533 (define_expand "insv"
13534   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13535                       (match_operand 1 "const8_operand" "")
13536                       (match_operand 2 "const8_operand" ""))
13537         (match_operand 3 "register_operand" ""))]
13538   ""
13539 {
13540   /* Handle insertions to %ah et al.  */
13541   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13542     FAIL;
13543
13544   /* From mips.md: insert_bit_field doesn't verify that our source
13545      matches the predicate, so check it again here.  */
13546   if (! ext_register_operand (operands[0], VOIDmode))
13547     FAIL;
13548
13549   if (TARGET_64BIT)
13550     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13551   else
13552     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13553
13554   DONE;
13555 })
13556
13557 ;; %%% bts, btr, btc, bt.
13558 ;; In general these instructions are *slow* when applied to memory,
13559 ;; since they enforce atomic operation.  When applied to registers,
13560 ;; it depends on the cpu implementation.  They're never faster than
13561 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13562 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13563 ;; within the instruction itself, so operating on bits in the high
13564 ;; 32-bits of a register becomes easier.
13565 ;;
13566 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13567 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13568 ;; negdf respectively, so they can never be disabled entirely.
13569
13570 (define_insn "*btsq"
13571   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13572                          (const_int 1)
13573                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13574         (const_int 1))
13575    (clobber (reg:CC FLAGS_REG))]
13576   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13577   "bts{q} %1,%0"
13578   [(set_attr "type" "alu1")])
13579
13580 (define_insn "*btrq"
13581   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13582                          (const_int 1)
13583                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13584         (const_int 0))
13585    (clobber (reg:CC FLAGS_REG))]
13586   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13587   "btr{q} %1,%0"
13588   [(set_attr "type" "alu1")])
13589
13590 (define_insn "*btcq"
13591   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13592                          (const_int 1)
13593                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13594         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13595    (clobber (reg:CC FLAGS_REG))]
13596   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13597   "btc{q} %1,%0"
13598   [(set_attr "type" "alu1")])
13599
13600 ;; Allow Nocona to avoid these instructions if a register is available.
13601
13602 (define_peephole2
13603   [(match_scratch:DI 2 "r")
13604    (parallel [(set (zero_extract:DI
13605                      (match_operand:DI 0 "register_operand" "")
13606                      (const_int 1)
13607                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13608                    (const_int 1))
13609               (clobber (reg:CC FLAGS_REG))])]
13610   "TARGET_64BIT && !TARGET_USE_BT"
13611   [(const_int 0)]
13612 {
13613   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13614   rtx op1;
13615
13616   if (HOST_BITS_PER_WIDE_INT >= 64)
13617     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13618   else if (i < HOST_BITS_PER_WIDE_INT)
13619     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13620   else
13621     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13622
13623   op1 = immed_double_const (lo, hi, DImode);
13624   if (i >= 31)
13625     {
13626       emit_move_insn (operands[2], op1);
13627       op1 = operands[2];
13628     }
13629
13630   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13631   DONE;
13632 })
13633
13634 (define_peephole2
13635   [(match_scratch:DI 2 "r")
13636    (parallel [(set (zero_extract:DI
13637                      (match_operand:DI 0 "register_operand" "")
13638                      (const_int 1)
13639                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13640                    (const_int 0))
13641               (clobber (reg:CC FLAGS_REG))])]
13642   "TARGET_64BIT && !TARGET_USE_BT"
13643   [(const_int 0)]
13644 {
13645   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13646   rtx op1;
13647
13648   if (HOST_BITS_PER_WIDE_INT >= 64)
13649     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13650   else if (i < HOST_BITS_PER_WIDE_INT)
13651     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13652   else
13653     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13654
13655   op1 = immed_double_const (~lo, ~hi, DImode);
13656   if (i >= 32)
13657     {
13658       emit_move_insn (operands[2], op1);
13659       op1 = operands[2];
13660     }
13661
13662   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13663   DONE;
13664 })
13665
13666 (define_peephole2
13667   [(match_scratch:DI 2 "r")
13668    (parallel [(set (zero_extract:DI
13669                      (match_operand:DI 0 "register_operand" "")
13670                      (const_int 1)
13671                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13672               (not:DI (zero_extract:DI
13673                         (match_dup 0) (const_int 1) (match_dup 1))))
13674               (clobber (reg:CC FLAGS_REG))])]
13675   "TARGET_64BIT && !TARGET_USE_BT"
13676   [(const_int 0)]
13677 {
13678   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13679   rtx op1;
13680
13681   if (HOST_BITS_PER_WIDE_INT >= 64)
13682     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13683   else if (i < HOST_BITS_PER_WIDE_INT)
13684     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13685   else
13686     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13687
13688   op1 = immed_double_const (lo, hi, DImode);
13689   if (i >= 31)
13690     {
13691       emit_move_insn (operands[2], op1);
13692       op1 = operands[2];
13693     }
13694
13695   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13696   DONE;
13697 })
13698 \f
13699 ;; Store-flag instructions.
13700
13701 ;; For all sCOND expanders, also expand the compare or test insn that
13702 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13703
13704 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13705 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13706 ;; way, which can later delete the movzx if only QImode is needed.
13707
13708 (define_expand "seq"
13709   [(set (match_operand:QI 0 "register_operand" "")
13710         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13711   ""
13712   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13713
13714 (define_expand "sne"
13715   [(set (match_operand:QI 0 "register_operand" "")
13716         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13717   ""
13718   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13719
13720 (define_expand "sgt"
13721   [(set (match_operand:QI 0 "register_operand" "")
13722         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13723   ""
13724   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13725
13726 (define_expand "sgtu"
13727   [(set (match_operand:QI 0 "register_operand" "")
13728         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13729   ""
13730   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13731
13732 (define_expand "slt"
13733   [(set (match_operand:QI 0 "register_operand" "")
13734         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13735   ""
13736   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13737
13738 (define_expand "sltu"
13739   [(set (match_operand:QI 0 "register_operand" "")
13740         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13741   ""
13742   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13743
13744 (define_expand "sge"
13745   [(set (match_operand:QI 0 "register_operand" "")
13746         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13747   ""
13748   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13749
13750 (define_expand "sgeu"
13751   [(set (match_operand:QI 0 "register_operand" "")
13752         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13753   ""
13754   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13755
13756 (define_expand "sle"
13757   [(set (match_operand:QI 0 "register_operand" "")
13758         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13759   ""
13760   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13761
13762 (define_expand "sleu"
13763   [(set (match_operand:QI 0 "register_operand" "")
13764         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13765   ""
13766   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13767
13768 (define_expand "sunordered"
13769   [(set (match_operand:QI 0 "register_operand" "")
13770         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13771   "TARGET_80387 || TARGET_SSE"
13772   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13773
13774 (define_expand "sordered"
13775   [(set (match_operand:QI 0 "register_operand" "")
13776         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13777   "TARGET_80387"
13778   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13779
13780 (define_expand "suneq"
13781   [(set (match_operand:QI 0 "register_operand" "")
13782         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13783   "TARGET_80387 || TARGET_SSE"
13784   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13785
13786 (define_expand "sunge"
13787   [(set (match_operand:QI 0 "register_operand" "")
13788         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13789   "TARGET_80387 || TARGET_SSE"
13790   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13791
13792 (define_expand "sungt"
13793   [(set (match_operand:QI 0 "register_operand" "")
13794         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13795   "TARGET_80387 || TARGET_SSE"
13796   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13797
13798 (define_expand "sunle"
13799   [(set (match_operand:QI 0 "register_operand" "")
13800         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13801   "TARGET_80387 || TARGET_SSE"
13802   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13803
13804 (define_expand "sunlt"
13805   [(set (match_operand:QI 0 "register_operand" "")
13806         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13807   "TARGET_80387 || TARGET_SSE"
13808   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13809
13810 (define_expand "sltgt"
13811   [(set (match_operand:QI 0 "register_operand" "")
13812         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13813   "TARGET_80387 || TARGET_SSE"
13814   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13815
13816 (define_insn "*setcc_1"
13817   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13818         (match_operator:QI 1 "ix86_comparison_operator"
13819           [(reg FLAGS_REG) (const_int 0)]))]
13820   ""
13821   "set%C1\t%0"
13822   [(set_attr "type" "setcc")
13823    (set_attr "mode" "QI")])
13824
13825 (define_insn "*setcc_2"
13826   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13827         (match_operator:QI 1 "ix86_comparison_operator"
13828           [(reg FLAGS_REG) (const_int 0)]))]
13829   ""
13830   "set%C1\t%0"
13831   [(set_attr "type" "setcc")
13832    (set_attr "mode" "QI")])
13833
13834 ;; In general it is not safe to assume too much about CCmode registers,
13835 ;; so simplify-rtx stops when it sees a second one.  Under certain
13836 ;; conditions this is safe on x86, so help combine not create
13837 ;;
13838 ;;      seta    %al
13839 ;;      testb   %al, %al
13840 ;;      sete    %al
13841
13842 (define_split
13843   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13844         (ne:QI (match_operator 1 "ix86_comparison_operator"
13845                  [(reg FLAGS_REG) (const_int 0)])
13846             (const_int 0)))]
13847   ""
13848   [(set (match_dup 0) (match_dup 1))]
13849 {
13850   PUT_MODE (operands[1], QImode);
13851 })
13852
13853 (define_split
13854   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13855         (ne:QI (match_operator 1 "ix86_comparison_operator"
13856                  [(reg FLAGS_REG) (const_int 0)])
13857             (const_int 0)))]
13858   ""
13859   [(set (match_dup 0) (match_dup 1))]
13860 {
13861   PUT_MODE (operands[1], QImode);
13862 })
13863
13864 (define_split
13865   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13866         (eq:QI (match_operator 1 "ix86_comparison_operator"
13867                  [(reg FLAGS_REG) (const_int 0)])
13868             (const_int 0)))]
13869   ""
13870   [(set (match_dup 0) (match_dup 1))]
13871 {
13872   rtx new_op1 = copy_rtx (operands[1]);
13873   operands[1] = new_op1;
13874   PUT_MODE (new_op1, QImode);
13875   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13876                                              GET_MODE (XEXP (new_op1, 0))));
13877
13878   /* Make sure that (a) the CCmode we have for the flags is strong
13879      enough for the reversed compare or (b) we have a valid FP compare.  */
13880   if (! ix86_comparison_operator (new_op1, VOIDmode))
13881     FAIL;
13882 })
13883
13884 (define_split
13885   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13886         (eq:QI (match_operator 1 "ix86_comparison_operator"
13887                  [(reg FLAGS_REG) (const_int 0)])
13888             (const_int 0)))]
13889   ""
13890   [(set (match_dup 0) (match_dup 1))]
13891 {
13892   rtx new_op1 = copy_rtx (operands[1]);
13893   operands[1] = new_op1;
13894   PUT_MODE (new_op1, QImode);
13895   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13896                                              GET_MODE (XEXP (new_op1, 0))));
13897
13898   /* Make sure that (a) the CCmode we have for the flags is strong
13899      enough for the reversed compare or (b) we have a valid FP compare.  */
13900   if (! ix86_comparison_operator (new_op1, VOIDmode))
13901     FAIL;
13902 })
13903
13904 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13905 ;; subsequent logical operations are used to imitate conditional moves.
13906 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13907 ;; it directly.
13908
13909 (define_insn "*sse_setccsf"
13910   [(set (match_operand:SF 0 "register_operand" "=x")
13911         (match_operator:SF 1 "sse_comparison_operator"
13912           [(match_operand:SF 2 "register_operand" "0")
13913            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13914   "TARGET_SSE"
13915   "cmp%D1ss\t{%3, %0|%0, %3}"
13916   [(set_attr "type" "ssecmp")
13917    (set_attr "mode" "SF")])
13918
13919 (define_insn "*sse_setccdf"
13920   [(set (match_operand:DF 0 "register_operand" "=x")
13921         (match_operator:DF 1 "sse_comparison_operator"
13922           [(match_operand:DF 2 "register_operand" "0")
13923            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13924   "TARGET_SSE2"
13925   "cmp%D1sd\t{%3, %0|%0, %3}"
13926   [(set_attr "type" "ssecmp")
13927    (set_attr "mode" "DF")])
13928 \f
13929 ;; Basic conditional jump instructions.
13930 ;; We ignore the overflow flag for signed branch instructions.
13931
13932 ;; For all bCOND expanders, also expand the compare or test insn that
13933 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13934
13935 (define_expand "beq"
13936   [(set (pc)
13937         (if_then_else (match_dup 1)
13938                       (label_ref (match_operand 0 "" ""))
13939                       (pc)))]
13940   ""
13941   "ix86_expand_branch (EQ, operands[0]); DONE;")
13942
13943 (define_expand "bne"
13944   [(set (pc)
13945         (if_then_else (match_dup 1)
13946                       (label_ref (match_operand 0 "" ""))
13947                       (pc)))]
13948   ""
13949   "ix86_expand_branch (NE, operands[0]); DONE;")
13950
13951 (define_expand "bgt"
13952   [(set (pc)
13953         (if_then_else (match_dup 1)
13954                       (label_ref (match_operand 0 "" ""))
13955                       (pc)))]
13956   ""
13957   "ix86_expand_branch (GT, operands[0]); DONE;")
13958
13959 (define_expand "bgtu"
13960   [(set (pc)
13961         (if_then_else (match_dup 1)
13962                       (label_ref (match_operand 0 "" ""))
13963                       (pc)))]
13964   ""
13965   "ix86_expand_branch (GTU, operands[0]); DONE;")
13966
13967 (define_expand "blt"
13968   [(set (pc)
13969         (if_then_else (match_dup 1)
13970                       (label_ref (match_operand 0 "" ""))
13971                       (pc)))]
13972   ""
13973   "ix86_expand_branch (LT, operands[0]); DONE;")
13974
13975 (define_expand "bltu"
13976   [(set (pc)
13977         (if_then_else (match_dup 1)
13978                       (label_ref (match_operand 0 "" ""))
13979                       (pc)))]
13980   ""
13981   "ix86_expand_branch (LTU, operands[0]); DONE;")
13982
13983 (define_expand "bge"
13984   [(set (pc)
13985         (if_then_else (match_dup 1)
13986                       (label_ref (match_operand 0 "" ""))
13987                       (pc)))]
13988   ""
13989   "ix86_expand_branch (GE, operands[0]); DONE;")
13990
13991 (define_expand "bgeu"
13992   [(set (pc)
13993         (if_then_else (match_dup 1)
13994                       (label_ref (match_operand 0 "" ""))
13995                       (pc)))]
13996   ""
13997   "ix86_expand_branch (GEU, operands[0]); DONE;")
13998
13999 (define_expand "ble"
14000   [(set (pc)
14001         (if_then_else (match_dup 1)
14002                       (label_ref (match_operand 0 "" ""))
14003                       (pc)))]
14004   ""
14005   "ix86_expand_branch (LE, operands[0]); DONE;")
14006
14007 (define_expand "bleu"
14008   [(set (pc)
14009         (if_then_else (match_dup 1)
14010                       (label_ref (match_operand 0 "" ""))
14011                       (pc)))]
14012   ""
14013   "ix86_expand_branch (LEU, operands[0]); DONE;")
14014
14015 (define_expand "bunordered"
14016   [(set (pc)
14017         (if_then_else (match_dup 1)
14018                       (label_ref (match_operand 0 "" ""))
14019                       (pc)))]
14020   "TARGET_80387 || TARGET_SSE_MATH"
14021   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
14022
14023 (define_expand "bordered"
14024   [(set (pc)
14025         (if_then_else (match_dup 1)
14026                       (label_ref (match_operand 0 "" ""))
14027                       (pc)))]
14028   "TARGET_80387 || TARGET_SSE_MATH"
14029   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
14030
14031 (define_expand "buneq"
14032   [(set (pc)
14033         (if_then_else (match_dup 1)
14034                       (label_ref (match_operand 0 "" ""))
14035                       (pc)))]
14036   "TARGET_80387 || TARGET_SSE_MATH"
14037   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
14038
14039 (define_expand "bunge"
14040   [(set (pc)
14041         (if_then_else (match_dup 1)
14042                       (label_ref (match_operand 0 "" ""))
14043                       (pc)))]
14044   "TARGET_80387 || TARGET_SSE_MATH"
14045   "ix86_expand_branch (UNGE, operands[0]); DONE;")
14046
14047 (define_expand "bungt"
14048   [(set (pc)
14049         (if_then_else (match_dup 1)
14050                       (label_ref (match_operand 0 "" ""))
14051                       (pc)))]
14052   "TARGET_80387 || TARGET_SSE_MATH"
14053   "ix86_expand_branch (UNGT, operands[0]); DONE;")
14054
14055 (define_expand "bunle"
14056   [(set (pc)
14057         (if_then_else (match_dup 1)
14058                       (label_ref (match_operand 0 "" ""))
14059                       (pc)))]
14060   "TARGET_80387 || TARGET_SSE_MATH"
14061   "ix86_expand_branch (UNLE, operands[0]); DONE;")
14062
14063 (define_expand "bunlt"
14064   [(set (pc)
14065         (if_then_else (match_dup 1)
14066                       (label_ref (match_operand 0 "" ""))
14067                       (pc)))]
14068   "TARGET_80387 || TARGET_SSE_MATH"
14069   "ix86_expand_branch (UNLT, operands[0]); DONE;")
14070
14071 (define_expand "bltgt"
14072   [(set (pc)
14073         (if_then_else (match_dup 1)
14074                       (label_ref (match_operand 0 "" ""))
14075                       (pc)))]
14076   "TARGET_80387 || TARGET_SSE_MATH"
14077   "ix86_expand_branch (LTGT, operands[0]); DONE;")
14078
14079 (define_insn "*jcc_1"
14080   [(set (pc)
14081         (if_then_else (match_operator 1 "ix86_comparison_operator"
14082                                       [(reg FLAGS_REG) (const_int 0)])
14083                       (label_ref (match_operand 0 "" ""))
14084                       (pc)))]
14085   ""
14086   "%+j%C1\t%l0"
14087   [(set_attr "type" "ibr")
14088    (set_attr "modrm" "0")
14089    (set (attr "length")
14090            (if_then_else (and (ge (minus (match_dup 0) (pc))
14091                                   (const_int -126))
14092                               (lt (minus (match_dup 0) (pc))
14093                                   (const_int 128)))
14094              (const_int 2)
14095              (const_int 6)))])
14096
14097 (define_insn "*jcc_2"
14098   [(set (pc)
14099         (if_then_else (match_operator 1 "ix86_comparison_operator"
14100                                       [(reg FLAGS_REG) (const_int 0)])
14101                       (pc)
14102                       (label_ref (match_operand 0 "" ""))))]
14103   ""
14104   "%+j%c1\t%l0"
14105   [(set_attr "type" "ibr")
14106    (set_attr "modrm" "0")
14107    (set (attr "length")
14108            (if_then_else (and (ge (minus (match_dup 0) (pc))
14109                                   (const_int -126))
14110                               (lt (minus (match_dup 0) (pc))
14111                                   (const_int 128)))
14112              (const_int 2)
14113              (const_int 6)))])
14114
14115 ;; In general it is not safe to assume too much about CCmode registers,
14116 ;; so simplify-rtx stops when it sees a second one.  Under certain
14117 ;; conditions this is safe on x86, so help combine not create
14118 ;;
14119 ;;      seta    %al
14120 ;;      testb   %al, %al
14121 ;;      je      Lfoo
14122
14123 (define_split
14124   [(set (pc)
14125         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14126                                       [(reg FLAGS_REG) (const_int 0)])
14127                           (const_int 0))
14128                       (label_ref (match_operand 1 "" ""))
14129                       (pc)))]
14130   ""
14131   [(set (pc)
14132         (if_then_else (match_dup 0)
14133                       (label_ref (match_dup 1))
14134                       (pc)))]
14135 {
14136   PUT_MODE (operands[0], VOIDmode);
14137 })
14138
14139 (define_split
14140   [(set (pc)
14141         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14142                                       [(reg FLAGS_REG) (const_int 0)])
14143                           (const_int 0))
14144                       (label_ref (match_operand 1 "" ""))
14145                       (pc)))]
14146   ""
14147   [(set (pc)
14148         (if_then_else (match_dup 0)
14149                       (label_ref (match_dup 1))
14150                       (pc)))]
14151 {
14152   rtx new_op0 = copy_rtx (operands[0]);
14153   operands[0] = new_op0;
14154   PUT_MODE (new_op0, VOIDmode);
14155   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14156                                              GET_MODE (XEXP (new_op0, 0))));
14157
14158   /* Make sure that (a) the CCmode we have for the flags is strong
14159      enough for the reversed compare or (b) we have a valid FP compare.  */
14160   if (! ix86_comparison_operator (new_op0, VOIDmode))
14161     FAIL;
14162 })
14163
14164 ;; Define combination compare-and-branch fp compare instructions to use
14165 ;; during early optimization.  Splitting the operation apart early makes
14166 ;; for bad code when we want to reverse the operation.
14167
14168 (define_insn "*fp_jcc_1_mixed"
14169   [(set (pc)
14170         (if_then_else (match_operator 0 "comparison_operator"
14171                         [(match_operand 1 "register_operand" "f,x")
14172                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14173           (label_ref (match_operand 3 "" ""))
14174           (pc)))
14175    (clobber (reg:CCFP FPSR_REG))
14176    (clobber (reg:CCFP FLAGS_REG))]
14177   "TARGET_MIX_SSE_I387
14178    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14179    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14180    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14181   "#")
14182
14183 (define_insn "*fp_jcc_1_sse"
14184   [(set (pc)
14185         (if_then_else (match_operator 0 "comparison_operator"
14186                         [(match_operand 1 "register_operand" "x")
14187                          (match_operand 2 "nonimmediate_operand" "xm")])
14188           (label_ref (match_operand 3 "" ""))
14189           (pc)))
14190    (clobber (reg:CCFP FPSR_REG))
14191    (clobber (reg:CCFP FLAGS_REG))]
14192   "TARGET_SSE_MATH
14193    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14194    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14195    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14196   "#")
14197
14198 (define_insn "*fp_jcc_1_387"
14199   [(set (pc)
14200         (if_then_else (match_operator 0 "comparison_operator"
14201                         [(match_operand 1 "register_operand" "f")
14202                          (match_operand 2 "register_operand" "f")])
14203           (label_ref (match_operand 3 "" ""))
14204           (pc)))
14205    (clobber (reg:CCFP FPSR_REG))
14206    (clobber (reg:CCFP FLAGS_REG))]
14207   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14208    && TARGET_CMOVE
14209    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14210    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14211   "#")
14212
14213 (define_insn "*fp_jcc_2_mixed"
14214   [(set (pc)
14215         (if_then_else (match_operator 0 "comparison_operator"
14216                         [(match_operand 1 "register_operand" "f,x")
14217                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14218           (pc)
14219           (label_ref (match_operand 3 "" ""))))
14220    (clobber (reg:CCFP FPSR_REG))
14221    (clobber (reg:CCFP FLAGS_REG))]
14222   "TARGET_MIX_SSE_I387
14223    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14224    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14225    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14226   "#")
14227
14228 (define_insn "*fp_jcc_2_sse"
14229   [(set (pc)
14230         (if_then_else (match_operator 0 "comparison_operator"
14231                         [(match_operand 1 "register_operand" "x")
14232                          (match_operand 2 "nonimmediate_operand" "xm")])
14233           (pc)
14234           (label_ref (match_operand 3 "" ""))))
14235    (clobber (reg:CCFP FPSR_REG))
14236    (clobber (reg:CCFP FLAGS_REG))]
14237   "TARGET_SSE_MATH
14238    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14239    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14240    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14241   "#")
14242
14243 (define_insn "*fp_jcc_2_387"
14244   [(set (pc)
14245         (if_then_else (match_operator 0 "comparison_operator"
14246                         [(match_operand 1 "register_operand" "f")
14247                          (match_operand 2 "register_operand" "f")])
14248           (pc)
14249           (label_ref (match_operand 3 "" ""))))
14250    (clobber (reg:CCFP FPSR_REG))
14251    (clobber (reg:CCFP FLAGS_REG))]
14252   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14253    && TARGET_CMOVE
14254    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14255    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14256   "#")
14257
14258 (define_insn "*fp_jcc_3_387"
14259   [(set (pc)
14260         (if_then_else (match_operator 0 "comparison_operator"
14261                         [(match_operand 1 "register_operand" "f")
14262                          (match_operand 2 "nonimmediate_operand" "fm")])
14263           (label_ref (match_operand 3 "" ""))
14264           (pc)))
14265    (clobber (reg:CCFP FPSR_REG))
14266    (clobber (reg:CCFP FLAGS_REG))
14267    (clobber (match_scratch:HI 4 "=a"))]
14268   "TARGET_80387
14269    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14270    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14271    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14272    && SELECT_CC_MODE (GET_CODE (operands[0]),
14273                       operands[1], operands[2]) == CCFPmode
14274    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14275   "#")
14276
14277 (define_insn "*fp_jcc_4_387"
14278   [(set (pc)
14279         (if_then_else (match_operator 0 "comparison_operator"
14280                         [(match_operand 1 "register_operand" "f")
14281                          (match_operand 2 "nonimmediate_operand" "fm")])
14282           (pc)
14283           (label_ref (match_operand 3 "" ""))))
14284    (clobber (reg:CCFP FPSR_REG))
14285    (clobber (reg:CCFP FLAGS_REG))
14286    (clobber (match_scratch:HI 4 "=a"))]
14287   "TARGET_80387
14288    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14289    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14290    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14291    && SELECT_CC_MODE (GET_CODE (operands[0]),
14292                       operands[1], operands[2]) == CCFPmode
14293    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14294   "#")
14295
14296 (define_insn "*fp_jcc_5_387"
14297   [(set (pc)
14298         (if_then_else (match_operator 0 "comparison_operator"
14299                         [(match_operand 1 "register_operand" "f")
14300                          (match_operand 2 "register_operand" "f")])
14301           (label_ref (match_operand 3 "" ""))
14302           (pc)))
14303    (clobber (reg:CCFP FPSR_REG))
14304    (clobber (reg:CCFP FLAGS_REG))
14305    (clobber (match_scratch:HI 4 "=a"))]
14306   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14307    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14308    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14309   "#")
14310
14311 (define_insn "*fp_jcc_6_387"
14312   [(set (pc)
14313         (if_then_else (match_operator 0 "comparison_operator"
14314                         [(match_operand 1 "register_operand" "f")
14315                          (match_operand 2 "register_operand" "f")])
14316           (pc)
14317           (label_ref (match_operand 3 "" ""))))
14318    (clobber (reg:CCFP FPSR_REG))
14319    (clobber (reg:CCFP FLAGS_REG))
14320    (clobber (match_scratch:HI 4 "=a"))]
14321   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14322    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14323    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14324   "#")
14325
14326 (define_insn "*fp_jcc_7_387"
14327   [(set (pc)
14328         (if_then_else (match_operator 0 "comparison_operator"
14329                         [(match_operand 1 "register_operand" "f")
14330                          (match_operand 2 "const0_operand" "X")])
14331           (label_ref (match_operand 3 "" ""))
14332           (pc)))
14333    (clobber (reg:CCFP FPSR_REG))
14334    (clobber (reg:CCFP FLAGS_REG))
14335    (clobber (match_scratch:HI 4 "=a"))]
14336   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14337    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14338    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14339    && SELECT_CC_MODE (GET_CODE (operands[0]),
14340                       operands[1], operands[2]) == CCFPmode
14341    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14342   "#")
14343
14344 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14345 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14346 ;; with a precedence over other operators and is always put in the first
14347 ;; place. Swap condition and operands to match ficom instruction.
14348
14349 (define_insn "*fp_jcc_8<mode>_387"
14350   [(set (pc)
14351         (if_then_else (match_operator 0 "comparison_operator"
14352                         [(match_operator 1 "float_operator"
14353                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14354                            (match_operand 3 "register_operand" "f,f")])
14355           (label_ref (match_operand 4 "" ""))
14356           (pc)))
14357    (clobber (reg:CCFP FPSR_REG))
14358    (clobber (reg:CCFP FLAGS_REG))
14359    (clobber (match_scratch:HI 5 "=a,a"))]
14360   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14361    && TARGET_USE_<MODE>MODE_FIOP
14362    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14363    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14364    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14365    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14366   "#")
14367
14368 (define_split
14369   [(set (pc)
14370         (if_then_else (match_operator 0 "comparison_operator"
14371                         [(match_operand 1 "register_operand" "")
14372                          (match_operand 2 "nonimmediate_operand" "")])
14373           (match_operand 3 "" "")
14374           (match_operand 4 "" "")))
14375    (clobber (reg:CCFP FPSR_REG))
14376    (clobber (reg:CCFP FLAGS_REG))]
14377   "reload_completed"
14378   [(const_int 0)]
14379 {
14380   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14381                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14382   DONE;
14383 })
14384
14385 (define_split
14386   [(set (pc)
14387         (if_then_else (match_operator 0 "comparison_operator"
14388                         [(match_operand 1 "register_operand" "")
14389                          (match_operand 2 "general_operand" "")])
14390           (match_operand 3 "" "")
14391           (match_operand 4 "" "")))
14392    (clobber (reg:CCFP FPSR_REG))
14393    (clobber (reg:CCFP FLAGS_REG))
14394    (clobber (match_scratch:HI 5 "=a"))]
14395   "reload_completed"
14396   [(const_int 0)]
14397 {
14398   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14399                         operands[3], operands[4], operands[5], NULL_RTX);
14400   DONE;
14401 })
14402
14403 (define_split
14404   [(set (pc)
14405         (if_then_else (match_operator 0 "comparison_operator"
14406                         [(match_operator 1 "float_operator"
14407                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14408                            (match_operand 3 "register_operand" "")])
14409           (match_operand 4 "" "")
14410           (match_operand 5 "" "")))
14411    (clobber (reg:CCFP FPSR_REG))
14412    (clobber (reg:CCFP FLAGS_REG))
14413    (clobber (match_scratch:HI 6 "=a"))]
14414   "reload_completed"
14415   [(const_int 0)]
14416 {
14417   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14418   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14419                         operands[3], operands[7],
14420                         operands[4], operands[5], operands[6], NULL_RTX);
14421   DONE;
14422 })
14423
14424 ;; %%% Kill this when reload knows how to do it.
14425 (define_split
14426   [(set (pc)
14427         (if_then_else (match_operator 0 "comparison_operator"
14428                         [(match_operator 1 "float_operator"
14429                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14430                            (match_operand 3 "register_operand" "")])
14431           (match_operand 4 "" "")
14432           (match_operand 5 "" "")))
14433    (clobber (reg:CCFP FPSR_REG))
14434    (clobber (reg:CCFP FLAGS_REG))
14435    (clobber (match_scratch:HI 6 "=a"))]
14436   "reload_completed"
14437   [(const_int 0)]
14438 {
14439   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14440   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14441   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14442                         operands[3], operands[7],
14443                         operands[4], operands[5], operands[6], operands[2]);
14444   DONE;
14445 })
14446 \f
14447 ;; Unconditional and other jump instructions
14448
14449 (define_insn "jump"
14450   [(set (pc)
14451         (label_ref (match_operand 0 "" "")))]
14452   ""
14453   "jmp\t%l0"
14454   [(set_attr "type" "ibr")
14455    (set (attr "length")
14456            (if_then_else (and (ge (minus (match_dup 0) (pc))
14457                                   (const_int -126))
14458                               (lt (minus (match_dup 0) (pc))
14459                                   (const_int 128)))
14460              (const_int 2)
14461              (const_int 5)))
14462    (set_attr "modrm" "0")])
14463
14464 (define_expand "indirect_jump"
14465   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14466   ""
14467   "")
14468
14469 (define_insn "*indirect_jump"
14470   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14471   "!TARGET_64BIT"
14472   "jmp\t%A0"
14473   [(set_attr "type" "ibr")
14474    (set_attr "length_immediate" "0")])
14475
14476 (define_insn "*indirect_jump_rtx64"
14477   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14478   "TARGET_64BIT"
14479   "jmp\t%A0"
14480   [(set_attr "type" "ibr")
14481    (set_attr "length_immediate" "0")])
14482
14483 (define_expand "tablejump"
14484   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14485               (use (label_ref (match_operand 1 "" "")))])]
14486   ""
14487 {
14488   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14489      relative.  Convert the relative address to an absolute address.  */
14490   if (flag_pic)
14491     {
14492       rtx op0, op1;
14493       enum rtx_code code;
14494
14495       /* We can't use @GOTOFF for text labels on VxWorks;
14496          see gotoff_operand.  */
14497       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14498         {
14499           code = PLUS;
14500           op0 = operands[0];
14501           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14502         }
14503       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14504         {
14505           code = PLUS;
14506           op0 = operands[0];
14507           op1 = pic_offset_table_rtx;
14508         }
14509       else
14510         {
14511           code = MINUS;
14512           op0 = pic_offset_table_rtx;
14513           op1 = operands[0];
14514         }
14515
14516       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14517                                          OPTAB_DIRECT);
14518     }
14519 })
14520
14521 (define_insn "*tablejump_1"
14522   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14523    (use (label_ref (match_operand 1 "" "")))]
14524   "!TARGET_64BIT"
14525   "jmp\t%A0"
14526   [(set_attr "type" "ibr")
14527    (set_attr "length_immediate" "0")])
14528
14529 (define_insn "*tablejump_1_rtx64"
14530   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14531    (use (label_ref (match_operand 1 "" "")))]
14532   "TARGET_64BIT"
14533   "jmp\t%A0"
14534   [(set_attr "type" "ibr")
14535    (set_attr "length_immediate" "0")])
14536 \f
14537 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14538
14539 (define_peephole2
14540   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14541    (set (match_operand:QI 1 "register_operand" "")
14542         (match_operator:QI 2 "ix86_comparison_operator"
14543           [(reg FLAGS_REG) (const_int 0)]))
14544    (set (match_operand 3 "q_regs_operand" "")
14545         (zero_extend (match_dup 1)))]
14546   "(peep2_reg_dead_p (3, operands[1])
14547     || operands_match_p (operands[1], operands[3]))
14548    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14549   [(set (match_dup 4) (match_dup 0))
14550    (set (strict_low_part (match_dup 5))
14551         (match_dup 2))]
14552 {
14553   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14554   operands[5] = gen_lowpart (QImode, operands[3]);
14555   ix86_expand_clear (operands[3]);
14556 })
14557
14558 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14559
14560 (define_peephole2
14561   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14562    (set (match_operand:QI 1 "register_operand" "")
14563         (match_operator:QI 2 "ix86_comparison_operator"
14564           [(reg FLAGS_REG) (const_int 0)]))
14565    (parallel [(set (match_operand 3 "q_regs_operand" "")
14566                    (zero_extend (match_dup 1)))
14567               (clobber (reg:CC FLAGS_REG))])]
14568   "(peep2_reg_dead_p (3, operands[1])
14569     || operands_match_p (operands[1], operands[3]))
14570    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14571   [(set (match_dup 4) (match_dup 0))
14572    (set (strict_low_part (match_dup 5))
14573         (match_dup 2))]
14574 {
14575   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14576   operands[5] = gen_lowpart (QImode, operands[3]);
14577   ix86_expand_clear (operands[3]);
14578 })
14579 \f
14580 ;; Call instructions.
14581
14582 ;; The predicates normally associated with named expanders are not properly
14583 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14584 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14585
14586 ;; Call subroutine returning no value.
14587
14588 (define_expand "call_pop"
14589   [(parallel [(call (match_operand:QI 0 "" "")
14590                     (match_operand:SI 1 "" ""))
14591               (set (reg:SI SP_REG)
14592                    (plus:SI (reg:SI SP_REG)
14593                             (match_operand:SI 3 "" "")))])]
14594   "!TARGET_64BIT"
14595 {
14596   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14597   DONE;
14598 })
14599
14600 (define_insn "*call_pop_0"
14601   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14602          (match_operand:SI 1 "" ""))
14603    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14604                             (match_operand:SI 2 "immediate_operand" "")))]
14605   "!TARGET_64BIT"
14606 {
14607   if (SIBLING_CALL_P (insn))
14608     return "jmp\t%P0";
14609   else
14610     return "call\t%P0";
14611 }
14612   [(set_attr "type" "call")])
14613
14614 (define_insn "*call_pop_1"
14615   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14616          (match_operand:SI 1 "" ""))
14617    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14618                             (match_operand:SI 2 "immediate_operand" "i")))]
14619   "!TARGET_64BIT"
14620 {
14621   if (constant_call_address_operand (operands[0], Pmode))
14622     {
14623       if (SIBLING_CALL_P (insn))
14624         return "jmp\t%P0";
14625       else
14626         return "call\t%P0";
14627     }
14628   if (SIBLING_CALL_P (insn))
14629     return "jmp\t%A0";
14630   else
14631     return "call\t%A0";
14632 }
14633   [(set_attr "type" "call")])
14634
14635 (define_expand "call"
14636   [(call (match_operand:QI 0 "" "")
14637          (match_operand 1 "" ""))
14638    (use (match_operand 2 "" ""))]
14639   ""
14640 {
14641   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14642   DONE;
14643 })
14644
14645 (define_expand "sibcall"
14646   [(call (match_operand:QI 0 "" "")
14647          (match_operand 1 "" ""))
14648    (use (match_operand 2 "" ""))]
14649   ""
14650 {
14651   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14652   DONE;
14653 })
14654
14655 (define_insn "*call_0"
14656   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14657          (match_operand 1 "" ""))]
14658   ""
14659 {
14660   if (SIBLING_CALL_P (insn))
14661     return "jmp\t%P0";
14662   else
14663     return "call\t%P0";
14664 }
14665   [(set_attr "type" "call")])
14666
14667 (define_insn "*call_1"
14668   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14669          (match_operand 1 "" ""))]
14670   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14671 {
14672   if (constant_call_address_operand (operands[0], Pmode))
14673     return "call\t%P0";
14674   return "call\t%A0";
14675 }
14676   [(set_attr "type" "call")])
14677
14678 (define_insn "*sibcall_1"
14679   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14680          (match_operand 1 "" ""))]
14681   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14682 {
14683   if (constant_call_address_operand (operands[0], Pmode))
14684     return "jmp\t%P0";
14685   return "jmp\t%A0";
14686 }
14687   [(set_attr "type" "call")])
14688
14689 (define_insn "*call_1_rex64"
14690   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14691          (match_operand 1 "" ""))]
14692   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14693    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14694 {
14695   if (constant_call_address_operand (operands[0], Pmode))
14696     return "call\t%P0";
14697   return "call\t%A0";
14698 }
14699   [(set_attr "type" "call")])
14700
14701 (define_insn "*call_1_rex64_large"
14702   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14703          (match_operand 1 "" ""))]
14704   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14705   "call\t%A0"
14706   [(set_attr "type" "call")])
14707
14708 (define_insn "*sibcall_1_rex64"
14709   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14710          (match_operand 1 "" ""))]
14711   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14712   "jmp\t%P0"
14713   [(set_attr "type" "call")])
14714
14715 (define_insn "*sibcall_1_rex64_v"
14716   [(call (mem:QI (reg:DI R11_REG))
14717          (match_operand 0 "" ""))]
14718   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14719   "jmp\t*%%r11"
14720   [(set_attr "type" "call")])
14721
14722
14723 ;; Call subroutine, returning value in operand 0
14724
14725 (define_expand "call_value_pop"
14726   [(parallel [(set (match_operand 0 "" "")
14727                    (call (match_operand:QI 1 "" "")
14728                          (match_operand:SI 2 "" "")))
14729               (set (reg:SI SP_REG)
14730                    (plus:SI (reg:SI SP_REG)
14731                             (match_operand:SI 4 "" "")))])]
14732   "!TARGET_64BIT"
14733 {
14734   ix86_expand_call (operands[0], operands[1], operands[2],
14735                     operands[3], operands[4], 0);
14736   DONE;
14737 })
14738
14739 (define_expand "call_value"
14740   [(set (match_operand 0 "" "")
14741         (call (match_operand:QI 1 "" "")
14742               (match_operand:SI 2 "" "")))
14743    (use (match_operand:SI 3 "" ""))]
14744   ;; Operand 2 not used on the i386.
14745   ""
14746 {
14747   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14748   DONE;
14749 })
14750
14751 (define_expand "sibcall_value"
14752   [(set (match_operand 0 "" "")
14753         (call (match_operand:QI 1 "" "")
14754               (match_operand:SI 2 "" "")))
14755    (use (match_operand:SI 3 "" ""))]
14756   ;; Operand 2 not used on the i386.
14757   ""
14758 {
14759   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14760   DONE;
14761 })
14762
14763 ;; Call subroutine returning any type.
14764
14765 (define_expand "untyped_call"
14766   [(parallel [(call (match_operand 0 "" "")
14767                     (const_int 0))
14768               (match_operand 1 "" "")
14769               (match_operand 2 "" "")])]
14770   ""
14771 {
14772   int i;
14773
14774   /* In order to give reg-stack an easier job in validating two
14775      coprocessor registers as containing a possible return value,
14776      simply pretend the untyped call returns a complex long double
14777      value.  */
14778
14779   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14780                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14781                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14782                     NULL, 0);
14783
14784   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14785     {
14786       rtx set = XVECEXP (operands[2], 0, i);
14787       emit_move_insn (SET_DEST (set), SET_SRC (set));
14788     }
14789
14790   /* The optimizer does not know that the call sets the function value
14791      registers we stored in the result block.  We avoid problems by
14792      claiming that all hard registers are used and clobbered at this
14793      point.  */
14794   emit_insn (gen_blockage ());
14795
14796   DONE;
14797 })
14798 \f
14799 ;; Prologue and epilogue instructions
14800
14801 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14802 ;; all of memory.  This blocks insns from being moved across this point.
14803
14804 (define_insn "blockage"
14805   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14806   ""
14807   ""
14808   [(set_attr "length" "0")])
14809
14810 ;; As USE insns aren't meaningful after reload, this is used instead
14811 ;; to prevent deleting instructions setting registers for PIC code
14812 (define_insn "prologue_use"
14813   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14814   ""
14815   ""
14816   [(set_attr "length" "0")])
14817
14818 ;; Insn emitted into the body of a function to return from a function.
14819 ;; This is only done if the function's epilogue is known to be simple.
14820 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14821
14822 (define_expand "return"
14823   [(return)]
14824   "ix86_can_use_return_insn_p ()"
14825 {
14826   if (current_function_pops_args)
14827     {
14828       rtx popc = GEN_INT (current_function_pops_args);
14829       emit_jump_insn (gen_return_pop_internal (popc));
14830       DONE;
14831     }
14832 })
14833
14834 (define_insn "return_internal"
14835   [(return)]
14836   "reload_completed"
14837   "ret"
14838   [(set_attr "length" "1")
14839    (set_attr "length_immediate" "0")
14840    (set_attr "modrm" "0")])
14841
14842 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14843 ;; instruction Athlon and K8 have.
14844
14845 (define_insn "return_internal_long"
14846   [(return)
14847    (unspec [(const_int 0)] UNSPEC_REP)]
14848   "reload_completed"
14849   "rep{\;| }ret"
14850   [(set_attr "length" "1")
14851    (set_attr "length_immediate" "0")
14852    (set_attr "prefix_rep" "1")
14853    (set_attr "modrm" "0")])
14854
14855 (define_insn "return_pop_internal"
14856   [(return)
14857    (use (match_operand:SI 0 "const_int_operand" ""))]
14858   "reload_completed"
14859   "ret\t%0"
14860   [(set_attr "length" "3")
14861    (set_attr "length_immediate" "2")
14862    (set_attr "modrm" "0")])
14863
14864 (define_insn "return_indirect_internal"
14865   [(return)
14866    (use (match_operand:SI 0 "register_operand" "r"))]
14867   "reload_completed"
14868   "jmp\t%A0"
14869   [(set_attr "type" "ibr")
14870    (set_attr "length_immediate" "0")])
14871
14872 (define_insn "nop"
14873   [(const_int 0)]
14874   ""
14875   "nop"
14876   [(set_attr "length" "1")
14877    (set_attr "length_immediate" "0")
14878    (set_attr "modrm" "0")])
14879
14880 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14881 ;; branch prediction penalty for the third jump in a 16-byte
14882 ;; block on K8.
14883
14884 (define_insn "align"
14885   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14886   ""
14887 {
14888 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14889   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14890 #else
14891   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14892      The align insn is used to avoid 3 jump instructions in the row to improve
14893      branch prediction and the benefits hardly outweigh the cost of extra 8
14894      nops on the average inserted by full alignment pseudo operation.  */
14895 #endif
14896   return "";
14897 }
14898   [(set_attr "length" "16")])
14899
14900 (define_expand "prologue"
14901   [(const_int 0)]
14902   ""
14903   "ix86_expand_prologue (); DONE;")
14904
14905 (define_insn "set_got"
14906   [(set (match_operand:SI 0 "register_operand" "=r")
14907         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14908    (clobber (reg:CC FLAGS_REG))]
14909   "!TARGET_64BIT"
14910   { return output_set_got (operands[0], NULL_RTX); }
14911   [(set_attr "type" "multi")
14912    (set_attr "length" "12")])
14913
14914 (define_insn "set_got_labelled"
14915   [(set (match_operand:SI 0 "register_operand" "=r")
14916         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14917          UNSPEC_SET_GOT))
14918    (clobber (reg:CC FLAGS_REG))]
14919   "!TARGET_64BIT"
14920   { return output_set_got (operands[0], operands[1]); }
14921   [(set_attr "type" "multi")
14922    (set_attr "length" "12")])
14923
14924 (define_insn "set_got_rex64"
14925   [(set (match_operand:DI 0 "register_operand" "=r")
14926         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14927   "TARGET_64BIT"
14928   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14929   [(set_attr "type" "lea")
14930    (set_attr "length" "6")])
14931
14932 (define_insn "set_rip_rex64"
14933   [(set (match_operand:DI 0 "register_operand" "=r")
14934         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14935   "TARGET_64BIT"
14936   "lea{q}\t%l1(%%rip), %0"
14937   [(set_attr "type" "lea")
14938    (set_attr "length" "6")])
14939
14940 (define_insn "set_got_offset_rex64"
14941   [(set (match_operand:DI 0 "register_operand" "=r")
14942         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14943   "TARGET_64BIT"
14944   "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
14945   [(set_attr "type" "imov")
14946    (set_attr "length" "11")])
14947
14948 (define_expand "epilogue"
14949   [(const_int 0)]
14950   ""
14951   "ix86_expand_epilogue (1); DONE;")
14952
14953 (define_expand "sibcall_epilogue"
14954   [(const_int 0)]
14955   ""
14956   "ix86_expand_epilogue (0); DONE;")
14957
14958 (define_expand "eh_return"
14959   [(use (match_operand 0 "register_operand" ""))]
14960   ""
14961 {
14962   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14963
14964   /* Tricky bit: we write the address of the handler to which we will
14965      be returning into someone else's stack frame, one word below the
14966      stack address we wish to restore.  */
14967   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14968   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14969   tmp = gen_rtx_MEM (Pmode, tmp);
14970   emit_move_insn (tmp, ra);
14971
14972   if (Pmode == SImode)
14973     emit_jump_insn (gen_eh_return_si (sa));
14974   else
14975     emit_jump_insn (gen_eh_return_di (sa));
14976   emit_barrier ();
14977   DONE;
14978 })
14979
14980 (define_insn_and_split "eh_return_si"
14981   [(set (pc)
14982         (unspec [(match_operand:SI 0 "register_operand" "c")]
14983                  UNSPEC_EH_RETURN))]
14984   "!TARGET_64BIT"
14985   "#"
14986   "reload_completed"
14987   [(const_int 0)]
14988   "ix86_expand_epilogue (2); DONE;")
14989
14990 (define_insn_and_split "eh_return_di"
14991   [(set (pc)
14992         (unspec [(match_operand:DI 0 "register_operand" "c")]
14993                  UNSPEC_EH_RETURN))]
14994   "TARGET_64BIT"
14995   "#"
14996   "reload_completed"
14997   [(const_int 0)]
14998   "ix86_expand_epilogue (2); DONE;")
14999
15000 (define_insn "leave"
15001   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15002    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15003    (clobber (mem:BLK (scratch)))]
15004   "!TARGET_64BIT"
15005   "leave"
15006   [(set_attr "type" "leave")])
15007
15008 (define_insn "leave_rex64"
15009   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15010    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15011    (clobber (mem:BLK (scratch)))]
15012   "TARGET_64BIT"
15013   "leave"
15014   [(set_attr "type" "leave")])
15015 \f
15016 (define_expand "ffssi2"
15017   [(parallel
15018      [(set (match_operand:SI 0 "register_operand" "")
15019            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15020       (clobber (match_scratch:SI 2 ""))
15021       (clobber (reg:CC FLAGS_REG))])]
15022   ""
15023 {
15024   if (TARGET_CMOVE)
15025     {
15026       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15027       DONE;
15028     }
15029 })
15030
15031 (define_expand "ffs_cmove"
15032   [(set (match_dup 2) (const_int -1))
15033    (parallel [(set (reg:CCZ FLAGS_REG)
15034                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
15035                                 (const_int 0)))
15036               (set (match_operand:SI 0 "nonimmediate_operand" "")
15037                    (ctz:SI (match_dup 1)))])
15038    (set (match_dup 0) (if_then_else:SI
15039                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15040                         (match_dup 2)
15041                         (match_dup 0)))
15042    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15043               (clobber (reg:CC FLAGS_REG))])]
15044   "TARGET_CMOVE"
15045   "operands[2] = gen_reg_rtx (SImode);")
15046
15047 (define_insn_and_split "*ffs_no_cmove"
15048   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15049         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15050    (clobber (match_scratch:SI 2 "=&q"))
15051    (clobber (reg:CC FLAGS_REG))]
15052   "!TARGET_CMOVE"
15053   "#"
15054   "&& reload_completed"
15055   [(parallel [(set (reg:CCZ FLAGS_REG)
15056                    (compare:CCZ (match_dup 1) (const_int 0)))
15057               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15058    (set (strict_low_part (match_dup 3))
15059         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15060    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15061               (clobber (reg:CC FLAGS_REG))])
15062    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15063               (clobber (reg:CC FLAGS_REG))])
15064    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15065               (clobber (reg:CC FLAGS_REG))])]
15066 {
15067   operands[3] = gen_lowpart (QImode, operands[2]);
15068   ix86_expand_clear (operands[2]);
15069 })
15070
15071 (define_insn "*ffssi_1"
15072   [(set (reg:CCZ FLAGS_REG)
15073         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15074                      (const_int 0)))
15075    (set (match_operand:SI 0 "register_operand" "=r")
15076         (ctz:SI (match_dup 1)))]
15077   ""
15078   "bsf{l}\t{%1, %0|%0, %1}"
15079   [(set_attr "prefix_0f" "1")])
15080
15081 (define_expand "ffsdi2"
15082   [(set (match_dup 2) (const_int -1))
15083    (parallel [(set (reg:CCZ FLAGS_REG)
15084                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
15085                                 (const_int 0)))
15086               (set (match_operand:DI 0 "nonimmediate_operand" "")
15087                    (ctz:DI (match_dup 1)))])
15088    (set (match_dup 0) (if_then_else:DI
15089                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15090                         (match_dup 2)
15091                         (match_dup 0)))
15092    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15093               (clobber (reg:CC FLAGS_REG))])]
15094   "TARGET_64BIT"
15095   "operands[2] = gen_reg_rtx (DImode);")
15096
15097 (define_insn "*ffsdi_1"
15098   [(set (reg:CCZ FLAGS_REG)
15099         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15100                      (const_int 0)))
15101    (set (match_operand:DI 0 "register_operand" "=r")
15102         (ctz:DI (match_dup 1)))]
15103   "TARGET_64BIT"
15104   "bsf{q}\t{%1, %0|%0, %1}"
15105   [(set_attr "prefix_0f" "1")])
15106
15107 (define_insn "ctzsi2"
15108   [(set (match_operand:SI 0 "register_operand" "=r")
15109         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15110    (clobber (reg:CC FLAGS_REG))]
15111   ""
15112   "bsf{l}\t{%1, %0|%0, %1}"
15113   [(set_attr "prefix_0f" "1")])
15114
15115 (define_insn "ctzdi2"
15116   [(set (match_operand:DI 0 "register_operand" "=r")
15117         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15118    (clobber (reg:CC FLAGS_REG))]
15119   "TARGET_64BIT"
15120   "bsf{q}\t{%1, %0|%0, %1}"
15121   [(set_attr "prefix_0f" "1")])
15122
15123 (define_expand "clzsi2"
15124   [(parallel
15125      [(set (match_operand:SI 0 "register_operand" "")
15126            (minus:SI (const_int 31)
15127                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15128       (clobber (reg:CC FLAGS_REG))])
15129    (parallel
15130      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15131       (clobber (reg:CC FLAGS_REG))])]
15132   ""
15133 {
15134   if (TARGET_ABM)
15135     {
15136       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15137       DONE;
15138     }
15139 })
15140
15141 (define_insn "clzsi2_abm"
15142   [(set (match_operand:SI 0 "register_operand" "=r")
15143         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15144    (clobber (reg:CC FLAGS_REG))]
15145   "TARGET_ABM"
15146   "lzcnt{l}\t{%1, %0|%0, %1}"
15147   [(set_attr "prefix_rep" "1")
15148    (set_attr "type" "bitmanip")
15149    (set_attr "mode" "SI")])
15150
15151 (define_insn "*bsr"
15152   [(set (match_operand:SI 0 "register_operand" "=r")
15153         (minus:SI (const_int 31)
15154                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15155    (clobber (reg:CC FLAGS_REG))]
15156   ""
15157   "bsr{l}\t{%1, %0|%0, %1}"
15158   [(set_attr "prefix_0f" "1")
15159    (set_attr "mode" "SI")])
15160
15161 (define_insn "popcountsi2"
15162   [(set (match_operand:SI 0 "register_operand" "=r")
15163         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15164    (clobber (reg:CC FLAGS_REG))]
15165   "TARGET_POPCNT"
15166   "popcnt{l}\t{%1, %0|%0, %1}"
15167   [(set_attr "prefix_rep" "1")
15168    (set_attr "type" "bitmanip")
15169    (set_attr "mode" "SI")])
15170
15171 (define_insn "*popcountsi2_cmp"
15172   [(set (reg FLAGS_REG)
15173         (compare
15174           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15175           (const_int 0)))
15176    (set (match_operand:SI 0 "register_operand" "=r")
15177         (popcount:SI (match_dup 1)))]
15178   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15179   "popcnt{l}\t{%1, %0|%0, %1}"
15180   [(set_attr "prefix_rep" "1")
15181    (set_attr "type" "bitmanip")
15182    (set_attr "mode" "SI")])
15183
15184 (define_insn "*popcountsi2_cmp_zext"
15185   [(set (reg FLAGS_REG)
15186         (compare
15187           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15188           (const_int 0)))
15189    (set (match_operand:DI 0 "register_operand" "=r")
15190         (zero_extend:DI(popcount:SI (match_dup 1))))]
15191   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15192   "popcnt{l}\t{%1, %0|%0, %1}"
15193   [(set_attr "prefix_rep" "1")
15194    (set_attr "type" "bitmanip")
15195    (set_attr "mode" "SI")])
15196
15197 (define_expand "bswapsi2"
15198   [(set (match_operand:SI 0 "register_operand" "")
15199         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15200   ""
15201 {
15202   if (!TARGET_BSWAP)
15203     {
15204       rtx x = operands[0];
15205
15206       emit_move_insn (x, operands[1]);
15207       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15208       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15209       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15210       DONE;
15211     }
15212 })
15213
15214 (define_insn "*bswapsi_1"
15215   [(set (match_operand:SI 0 "register_operand" "=r")
15216         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15217   "TARGET_BSWAP"
15218   "bswap\t%0"
15219   [(set_attr "prefix_0f" "1")
15220    (set_attr "length" "2")])
15221
15222 (define_insn "*bswaphi_lowpart_1"
15223   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15224         (bswap:HI (match_dup 0)))
15225    (clobber (reg:CC FLAGS_REG))]
15226   "TARGET_USE_XCHGB || optimize_size"
15227   "@
15228     xchg{b}\t{%h0, %b0|%b0, %h0}
15229     rol{w}\t{$8, %0|%0, 8}"
15230   [(set_attr "length" "2,4")
15231    (set_attr "mode" "QI,HI")])
15232
15233 (define_insn "bswaphi_lowpart"
15234   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15235         (bswap:HI (match_dup 0)))
15236    (clobber (reg:CC FLAGS_REG))]
15237   ""
15238   "rol{w}\t{$8, %0|%0, 8}"
15239   [(set_attr "length" "4")
15240    (set_attr "mode" "HI")])
15241
15242 (define_insn "bswapdi2"
15243   [(set (match_operand:DI 0 "register_operand" "=r")
15244         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15245   "TARGET_64BIT"
15246   "bswap\t%0"
15247   [(set_attr "prefix_0f" "1")
15248    (set_attr "length" "3")])
15249
15250 (define_expand "clzdi2"
15251   [(parallel
15252      [(set (match_operand:DI 0 "register_operand" "")
15253            (minus:DI (const_int 63)
15254                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15255       (clobber (reg:CC FLAGS_REG))])
15256    (parallel
15257      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15258       (clobber (reg:CC FLAGS_REG))])]
15259   "TARGET_64BIT"
15260 {
15261   if (TARGET_ABM)
15262     {
15263       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15264       DONE;
15265     }
15266 })
15267
15268 (define_insn "clzdi2_abm"
15269   [(set (match_operand:DI 0 "register_operand" "=r")
15270         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15271    (clobber (reg:CC FLAGS_REG))]
15272   "TARGET_64BIT && TARGET_ABM"
15273   "lzcnt{q}\t{%1, %0|%0, %1}"
15274   [(set_attr "prefix_rep" "1")
15275    (set_attr "type" "bitmanip")
15276    (set_attr "mode" "DI")])
15277
15278 (define_insn "*bsr_rex64"
15279   [(set (match_operand:DI 0 "register_operand" "=r")
15280         (minus:DI (const_int 63)
15281                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15282    (clobber (reg:CC FLAGS_REG))]
15283   "TARGET_64BIT"
15284   "bsr{q}\t{%1, %0|%0, %1}"
15285   [(set_attr "prefix_0f" "1")
15286    (set_attr "mode" "DI")])
15287
15288 (define_insn "popcountdi2"
15289   [(set (match_operand:DI 0 "register_operand" "=r")
15290         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15291    (clobber (reg:CC FLAGS_REG))]
15292   "TARGET_64BIT && TARGET_POPCNT"
15293   "popcnt{q}\t{%1, %0|%0, %1}"
15294   [(set_attr "prefix_rep" "1")
15295    (set_attr "type" "bitmanip")
15296    (set_attr "mode" "DI")])
15297
15298 (define_insn "*popcountdi2_cmp"
15299   [(set (reg FLAGS_REG)
15300         (compare
15301           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15302           (const_int 0)))
15303    (set (match_operand:DI 0 "register_operand" "=r")
15304         (popcount:DI (match_dup 1)))]
15305   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15306   "popcnt{q}\t{%1, %0|%0, %1}"
15307   [(set_attr "prefix_rep" "1")
15308    (set_attr "type" "bitmanip")
15309    (set_attr "mode" "DI")])
15310
15311 (define_expand "clzhi2"
15312   [(parallel
15313      [(set (match_operand:HI 0 "register_operand" "")
15314            (minus:HI (const_int 15)
15315                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15316       (clobber (reg:CC FLAGS_REG))])
15317    (parallel
15318      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15319       (clobber (reg:CC FLAGS_REG))])]
15320   ""
15321 {
15322   if (TARGET_ABM)
15323     {
15324       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15325       DONE;
15326     }
15327 })
15328
15329 (define_insn "clzhi2_abm"
15330   [(set (match_operand:HI 0 "register_operand" "=r")
15331         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15332    (clobber (reg:CC FLAGS_REG))]
15333   "TARGET_ABM"
15334   "lzcnt{w}\t{%1, %0|%0, %1}"
15335   [(set_attr "prefix_rep" "1")
15336    (set_attr "type" "bitmanip")
15337    (set_attr "mode" "HI")])
15338
15339 (define_insn "*bsrhi"
15340   [(set (match_operand:HI 0 "register_operand" "=r")
15341         (minus:HI (const_int 15)
15342                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15343    (clobber (reg:CC FLAGS_REG))]
15344   ""
15345   "bsr{w}\t{%1, %0|%0, %1}"
15346   [(set_attr "prefix_0f" "1")
15347    (set_attr "mode" "HI")])
15348
15349 (define_insn "popcounthi2"
15350   [(set (match_operand:HI 0 "register_operand" "=r")
15351         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15352    (clobber (reg:CC FLAGS_REG))]
15353   "TARGET_POPCNT"
15354   "popcnt{w}\t{%1, %0|%0, %1}"
15355   [(set_attr "prefix_rep" "1")
15356    (set_attr "type" "bitmanip")
15357    (set_attr "mode" "HI")])
15358
15359 (define_insn "*popcounthi2_cmp"
15360   [(set (reg FLAGS_REG)
15361         (compare
15362           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15363           (const_int 0)))
15364    (set (match_operand:HI 0 "register_operand" "=r")
15365         (popcount:HI (match_dup 1)))]
15366   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15367   "popcnt{w}\t{%1, %0|%0, %1}"
15368   [(set_attr "prefix_rep" "1")
15369    (set_attr "type" "bitmanip")
15370    (set_attr "mode" "HI")])
15371
15372 (define_expand "paritydi2"
15373   [(set (match_operand:DI 0 "register_operand" "")
15374         (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15375   "! TARGET_POPCNT"
15376 {
15377   rtx scratch = gen_reg_rtx (QImode);
15378   rtx cond;
15379
15380   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15381                                 NULL_RTX, operands[1]));
15382
15383   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15384                          gen_rtx_REG (CCmode, FLAGS_REG),
15385                          const0_rtx);
15386   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15387
15388   if (TARGET_64BIT)
15389     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15390   else
15391     {
15392       rtx tmp = gen_reg_rtx (SImode);
15393
15394       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15395       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15396     }
15397   DONE;
15398 })
15399
15400 (define_insn_and_split "paritydi2_cmp"
15401   [(set (reg:CC FLAGS_REG)
15402         (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15403    (clobber (match_scratch:DI 0 "=r,X"))
15404    (clobber (match_scratch:SI 1 "=r,r"))
15405    (clobber (match_scratch:HI 2 "=Q,Q"))]
15406   "! TARGET_POPCNT"
15407   "#"
15408   "&& reload_completed"
15409   [(parallel
15410      [(set (match_dup 1)
15411            (xor:SI (match_dup 1) (match_dup 4)))
15412       (clobber (reg:CC FLAGS_REG))])
15413    (parallel
15414      [(set (reg:CC FLAGS_REG)
15415            (parity:CC (match_dup 1)))
15416       (clobber (match_dup 1))
15417       (clobber (match_dup 2))])]
15418 {
15419   operands[4] = gen_lowpart (SImode, operands[3]);
15420
15421   if (MEM_P (operands[3]))
15422     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15423   else if (! TARGET_64BIT)
15424     operands[1] = gen_highpart (SImode, operands[3]);
15425   else
15426     {
15427       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15428       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15429     }
15430 })
15431
15432 (define_expand "paritysi2"
15433   [(set (match_operand:SI 0 "register_operand" "")
15434         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15435   "! TARGET_POPCNT"
15436 {
15437   rtx scratch = gen_reg_rtx (QImode);
15438   rtx cond;
15439
15440   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15441
15442   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15443                          gen_rtx_REG (CCmode, FLAGS_REG),
15444                          const0_rtx);
15445   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15446
15447   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15448   DONE;
15449 })
15450
15451 (define_insn_and_split "paritysi2_cmp"
15452   [(set (reg:CC FLAGS_REG)
15453         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15454    (clobber (match_scratch:SI 0 "=r,X"))
15455    (clobber (match_scratch:HI 1 "=Q,Q"))]
15456   "! TARGET_POPCNT"
15457   "#"
15458   "&& reload_completed"
15459   [(parallel
15460      [(set (match_dup 1)
15461            (xor:HI (match_dup 1) (match_dup 3)))
15462       (clobber (reg:CC FLAGS_REG))])
15463    (parallel
15464      [(set (reg:CC FLAGS_REG)
15465            (parity:CC (match_dup 1)))
15466       (clobber (match_dup 1))])]
15467 {
15468   operands[3] = gen_lowpart (HImode, operands[2]);
15469
15470   if (MEM_P (operands[2]))
15471     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15472   else
15473     {
15474       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15475       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15476     }
15477 })
15478
15479 (define_insn "*parityhi2_cmp"
15480   [(set (reg:CC FLAGS_REG)
15481         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15482    (clobber (match_scratch:HI 0 "=Q"))]
15483   "! TARGET_POPCNT"
15484   "xor{b}\t{%h0, %b0|%b0, %h0}"
15485   [(set_attr "length" "2")
15486    (set_attr "mode" "HI")])
15487
15488 (define_insn "*parityqi2_cmp"
15489   [(set (reg:CC FLAGS_REG)
15490         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15491   "! TARGET_POPCNT"
15492   "test{b}\t%0, %0"
15493   [(set_attr "length" "2")
15494    (set_attr "mode" "QI")])
15495 \f
15496 ;; Thread-local storage patterns for ELF.
15497 ;;
15498 ;; Note that these code sequences must appear exactly as shown
15499 ;; in order to allow linker relaxation.
15500
15501 (define_insn "*tls_global_dynamic_32_gnu"
15502   [(set (match_operand:SI 0 "register_operand" "=a")
15503         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15504                     (match_operand:SI 2 "tls_symbolic_operand" "")
15505                     (match_operand:SI 3 "call_insn_operand" "")]
15506                     UNSPEC_TLS_GD))
15507    (clobber (match_scratch:SI 4 "=d"))
15508    (clobber (match_scratch:SI 5 "=c"))
15509    (clobber (reg:CC FLAGS_REG))]
15510   "!TARGET_64BIT && TARGET_GNU_TLS"
15511   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15512   [(set_attr "type" "multi")
15513    (set_attr "length" "12")])
15514
15515 (define_insn "*tls_global_dynamic_32_sun"
15516   [(set (match_operand:SI 0 "register_operand" "=a")
15517         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15518                     (match_operand:SI 2 "tls_symbolic_operand" "")
15519                     (match_operand:SI 3 "call_insn_operand" "")]
15520                     UNSPEC_TLS_GD))
15521    (clobber (match_scratch:SI 4 "=d"))
15522    (clobber (match_scratch:SI 5 "=c"))
15523    (clobber (reg:CC FLAGS_REG))]
15524   "!TARGET_64BIT && TARGET_SUN_TLS"
15525   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15526         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15527   [(set_attr "type" "multi")
15528    (set_attr "length" "14")])
15529
15530 (define_expand "tls_global_dynamic_32"
15531   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15532                    (unspec:SI
15533                     [(match_dup 2)
15534                      (match_operand:SI 1 "tls_symbolic_operand" "")
15535                      (match_dup 3)]
15536                     UNSPEC_TLS_GD))
15537               (clobber (match_scratch:SI 4 ""))
15538               (clobber (match_scratch:SI 5 ""))
15539               (clobber (reg:CC FLAGS_REG))])]
15540   ""
15541 {
15542   if (flag_pic)
15543     operands[2] = pic_offset_table_rtx;
15544   else
15545     {
15546       operands[2] = gen_reg_rtx (Pmode);
15547       emit_insn (gen_set_got (operands[2]));
15548     }
15549   if (TARGET_GNU2_TLS)
15550     {
15551        emit_insn (gen_tls_dynamic_gnu2_32
15552                   (operands[0], operands[1], operands[2]));
15553        DONE;
15554     }
15555   operands[3] = ix86_tls_get_addr ();
15556 })
15557
15558 (define_insn "*tls_global_dynamic_64"
15559   [(set (match_operand:DI 0 "register_operand" "=a")
15560         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15561                  (match_operand:DI 3 "" "")))
15562    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15563               UNSPEC_TLS_GD)]
15564   "TARGET_64BIT"
15565   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15566   [(set_attr "type" "multi")
15567    (set_attr "length" "16")])
15568
15569 (define_expand "tls_global_dynamic_64"
15570   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15571                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15572               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15573                          UNSPEC_TLS_GD)])]
15574   ""
15575 {
15576   if (TARGET_GNU2_TLS)
15577     {
15578        emit_insn (gen_tls_dynamic_gnu2_64
15579                   (operands[0], operands[1]));
15580        DONE;
15581     }
15582   operands[2] = ix86_tls_get_addr ();
15583 })
15584
15585 (define_insn "*tls_local_dynamic_base_32_gnu"
15586   [(set (match_operand:SI 0 "register_operand" "=a")
15587         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15588                     (match_operand:SI 2 "call_insn_operand" "")]
15589                    UNSPEC_TLS_LD_BASE))
15590    (clobber (match_scratch:SI 3 "=d"))
15591    (clobber (match_scratch:SI 4 "=c"))
15592    (clobber (reg:CC FLAGS_REG))]
15593   "!TARGET_64BIT && TARGET_GNU_TLS"
15594   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15595   [(set_attr "type" "multi")
15596    (set_attr "length" "11")])
15597
15598 (define_insn "*tls_local_dynamic_base_32_sun"
15599   [(set (match_operand:SI 0 "register_operand" "=a")
15600         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15601                     (match_operand:SI 2 "call_insn_operand" "")]
15602                    UNSPEC_TLS_LD_BASE))
15603    (clobber (match_scratch:SI 3 "=d"))
15604    (clobber (match_scratch:SI 4 "=c"))
15605    (clobber (reg:CC FLAGS_REG))]
15606   "!TARGET_64BIT && TARGET_SUN_TLS"
15607   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15608         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15609   [(set_attr "type" "multi")
15610    (set_attr "length" "13")])
15611
15612 (define_expand "tls_local_dynamic_base_32"
15613   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15614                    (unspec:SI [(match_dup 1) (match_dup 2)]
15615                               UNSPEC_TLS_LD_BASE))
15616               (clobber (match_scratch:SI 3 ""))
15617               (clobber (match_scratch:SI 4 ""))
15618               (clobber (reg:CC FLAGS_REG))])]
15619   ""
15620 {
15621   if (flag_pic)
15622     operands[1] = pic_offset_table_rtx;
15623   else
15624     {
15625       operands[1] = gen_reg_rtx (Pmode);
15626       emit_insn (gen_set_got (operands[1]));
15627     }
15628   if (TARGET_GNU2_TLS)
15629     {
15630        emit_insn (gen_tls_dynamic_gnu2_32
15631                   (operands[0], ix86_tls_module_base (), operands[1]));
15632        DONE;
15633     }
15634   operands[2] = ix86_tls_get_addr ();
15635 })
15636
15637 (define_insn "*tls_local_dynamic_base_64"
15638   [(set (match_operand:DI 0 "register_operand" "=a")
15639         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15640                  (match_operand:DI 2 "" "")))
15641    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15642   "TARGET_64BIT"
15643   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15644   [(set_attr "type" "multi")
15645    (set_attr "length" "12")])
15646
15647 (define_expand "tls_local_dynamic_base_64"
15648   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15649                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15650               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15651   ""
15652 {
15653   if (TARGET_GNU2_TLS)
15654     {
15655        emit_insn (gen_tls_dynamic_gnu2_64
15656                   (operands[0], ix86_tls_module_base ()));
15657        DONE;
15658     }
15659   operands[1] = ix86_tls_get_addr ();
15660 })
15661
15662 ;; Local dynamic of a single variable is a lose.  Show combine how
15663 ;; to convert that back to global dynamic.
15664
15665 (define_insn_and_split "*tls_local_dynamic_32_once"
15666   [(set (match_operand:SI 0 "register_operand" "=a")
15667         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15668                              (match_operand:SI 2 "call_insn_operand" "")]
15669                             UNSPEC_TLS_LD_BASE)
15670                  (const:SI (unspec:SI
15671                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15672                             UNSPEC_DTPOFF))))
15673    (clobber (match_scratch:SI 4 "=d"))
15674    (clobber (match_scratch:SI 5 "=c"))
15675    (clobber (reg:CC FLAGS_REG))]
15676   ""
15677   "#"
15678   ""
15679   [(parallel [(set (match_dup 0)
15680                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15681                               UNSPEC_TLS_GD))
15682               (clobber (match_dup 4))
15683               (clobber (match_dup 5))
15684               (clobber (reg:CC FLAGS_REG))])]
15685   "")
15686
15687 ;; Load and add the thread base pointer from %gs:0.
15688
15689 (define_insn "*load_tp_si"
15690   [(set (match_operand:SI 0 "register_operand" "=r")
15691         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15692   "!TARGET_64BIT"
15693   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15694   [(set_attr "type" "imov")
15695    (set_attr "modrm" "0")
15696    (set_attr "length" "7")
15697    (set_attr "memory" "load")
15698    (set_attr "imm_disp" "false")])
15699
15700 (define_insn "*add_tp_si"
15701   [(set (match_operand:SI 0 "register_operand" "=r")
15702         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15703                  (match_operand:SI 1 "register_operand" "0")))
15704    (clobber (reg:CC FLAGS_REG))]
15705   "!TARGET_64BIT"
15706   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15707   [(set_attr "type" "alu")
15708    (set_attr "modrm" "0")
15709    (set_attr "length" "7")
15710    (set_attr "memory" "load")
15711    (set_attr "imm_disp" "false")])
15712
15713 (define_insn "*load_tp_di"
15714   [(set (match_operand:DI 0 "register_operand" "=r")
15715         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15716   "TARGET_64BIT"
15717   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15718   [(set_attr "type" "imov")
15719    (set_attr "modrm" "0")
15720    (set_attr "length" "7")
15721    (set_attr "memory" "load")
15722    (set_attr "imm_disp" "false")])
15723
15724 (define_insn "*add_tp_di"
15725   [(set (match_operand:DI 0 "register_operand" "=r")
15726         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15727                  (match_operand:DI 1 "register_operand" "0")))
15728    (clobber (reg:CC FLAGS_REG))]
15729   "TARGET_64BIT"
15730   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15731   [(set_attr "type" "alu")
15732    (set_attr "modrm" "0")
15733    (set_attr "length" "7")
15734    (set_attr "memory" "load")
15735    (set_attr "imm_disp" "false")])
15736
15737 ;; GNU2 TLS patterns can be split.
15738
15739 (define_expand "tls_dynamic_gnu2_32"
15740   [(set (match_dup 3)
15741         (plus:SI (match_operand:SI 2 "register_operand" "")
15742                  (const:SI
15743                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15744                              UNSPEC_TLSDESC))))
15745    (parallel
15746     [(set (match_operand:SI 0 "register_operand" "")
15747           (unspec:SI [(match_dup 1) (match_dup 3)
15748                       (match_dup 2) (reg:SI SP_REG)]
15749                       UNSPEC_TLSDESC))
15750      (clobber (reg:CC FLAGS_REG))])]
15751   "!TARGET_64BIT && TARGET_GNU2_TLS"
15752 {
15753   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15754   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15755 })
15756
15757 (define_insn "*tls_dynamic_lea_32"
15758   [(set (match_operand:SI 0 "register_operand" "=r")
15759         (plus:SI (match_operand:SI 1 "register_operand" "b")
15760                  (const:SI
15761                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15762                               UNSPEC_TLSDESC))))]
15763   "!TARGET_64BIT && TARGET_GNU2_TLS"
15764   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15765   [(set_attr "type" "lea")
15766    (set_attr "mode" "SI")
15767    (set_attr "length" "6")
15768    (set_attr "length_address" "4")])
15769
15770 (define_insn "*tls_dynamic_call_32"
15771   [(set (match_operand:SI 0 "register_operand" "=a")
15772         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15773                     (match_operand:SI 2 "register_operand" "0")
15774                     ;; we have to make sure %ebx still points to the GOT
15775                     (match_operand:SI 3 "register_operand" "b")
15776                     (reg:SI SP_REG)]
15777                    UNSPEC_TLSDESC))
15778    (clobber (reg:CC FLAGS_REG))]
15779   "!TARGET_64BIT && TARGET_GNU2_TLS"
15780   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15781   [(set_attr "type" "call")
15782    (set_attr "length" "2")
15783    (set_attr "length_address" "0")])
15784
15785 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15786   [(set (match_operand:SI 0 "register_operand" "=&a")
15787         (plus:SI
15788          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15789                      (match_operand:SI 4 "" "")
15790                      (match_operand:SI 2 "register_operand" "b")
15791                      (reg:SI SP_REG)]
15792                     UNSPEC_TLSDESC)
15793          (const:SI (unspec:SI
15794                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15795                     UNSPEC_DTPOFF))))
15796    (clobber (reg:CC FLAGS_REG))]
15797   "!TARGET_64BIT && TARGET_GNU2_TLS"
15798   "#"
15799   ""
15800   [(set (match_dup 0) (match_dup 5))]
15801 {
15802   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15803   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15804 })
15805
15806 (define_expand "tls_dynamic_gnu2_64"
15807   [(set (match_dup 2)
15808         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15809                    UNSPEC_TLSDESC))
15810    (parallel
15811     [(set (match_operand:DI 0 "register_operand" "")
15812           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15813                      UNSPEC_TLSDESC))
15814      (clobber (reg:CC FLAGS_REG))])]
15815   "TARGET_64BIT && TARGET_GNU2_TLS"
15816 {
15817   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15818   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15819 })
15820
15821 (define_insn "*tls_dynamic_lea_64"
15822   [(set (match_operand:DI 0 "register_operand" "=r")
15823         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15824                    UNSPEC_TLSDESC))]
15825   "TARGET_64BIT && TARGET_GNU2_TLS"
15826   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15827   [(set_attr "type" "lea")
15828    (set_attr "mode" "DI")
15829    (set_attr "length" "7")
15830    (set_attr "length_address" "4")])
15831
15832 (define_insn "*tls_dynamic_call_64"
15833   [(set (match_operand:DI 0 "register_operand" "=a")
15834         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15835                     (match_operand:DI 2 "register_operand" "0")
15836                     (reg:DI SP_REG)]
15837                    UNSPEC_TLSDESC))
15838    (clobber (reg:CC FLAGS_REG))]
15839   "TARGET_64BIT && TARGET_GNU2_TLS"
15840   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15841   [(set_attr "type" "call")
15842    (set_attr "length" "2")
15843    (set_attr "length_address" "0")])
15844
15845 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15846   [(set (match_operand:DI 0 "register_operand" "=&a")
15847         (plus:DI
15848          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15849                      (match_operand:DI 3 "" "")
15850                      (reg:DI SP_REG)]
15851                     UNSPEC_TLSDESC)
15852          (const:DI (unspec:DI
15853                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15854                     UNSPEC_DTPOFF))))
15855    (clobber (reg:CC FLAGS_REG))]
15856   "TARGET_64BIT && TARGET_GNU2_TLS"
15857   "#"
15858   ""
15859   [(set (match_dup 0) (match_dup 4))]
15860 {
15861   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15862   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15863 })
15864
15865 ;;
15866 \f
15867 ;; These patterns match the binary 387 instructions for addM3, subM3,
15868 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15869 ;; SFmode.  The first is the normal insn, the second the same insn but
15870 ;; with one operand a conversion, and the third the same insn but with
15871 ;; the other operand a conversion.  The conversion may be SFmode or
15872 ;; SImode if the target mode DFmode, but only SImode if the target mode
15873 ;; is SFmode.
15874
15875 ;; Gcc is slightly more smart about handling normal two address instructions
15876 ;; so use special patterns for add and mull.
15877
15878 (define_insn "*fop_sf_comm_mixed"
15879   [(set (match_operand:SF 0 "register_operand" "=f,x")
15880         (match_operator:SF 3 "binary_fp_operator"
15881                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15882                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15883   "TARGET_MIX_SSE_I387
15884    && COMMUTATIVE_ARITH_P (operands[3])
15885    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15886   "* return output_387_binary_op (insn, operands);"
15887   [(set (attr "type")
15888         (if_then_else (eq_attr "alternative" "1")
15889            (if_then_else (match_operand:SF 3 "mult_operator" "")
15890               (const_string "ssemul")
15891               (const_string "sseadd"))
15892            (if_then_else (match_operand:SF 3 "mult_operator" "")
15893               (const_string "fmul")
15894               (const_string "fop"))))
15895    (set_attr "mode" "SF")])
15896
15897 (define_insn "*fop_sf_comm_sse"
15898   [(set (match_operand:SF 0 "register_operand" "=x")
15899         (match_operator:SF 3 "binary_fp_operator"
15900                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15901                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15902   "TARGET_SSE_MATH
15903    && COMMUTATIVE_ARITH_P (operands[3])
15904    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15905   "* return output_387_binary_op (insn, operands);"
15906   [(set (attr "type")
15907         (if_then_else (match_operand:SF 3 "mult_operator" "")
15908            (const_string "ssemul")
15909            (const_string "sseadd")))
15910    (set_attr "mode" "SF")])
15911
15912 (define_insn "*fop_sf_comm_i387"
15913   [(set (match_operand:SF 0 "register_operand" "=f")
15914         (match_operator:SF 3 "binary_fp_operator"
15915                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15916                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15917   "TARGET_80387
15918    && COMMUTATIVE_ARITH_P (operands[3])
15919    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15920   "* return output_387_binary_op (insn, operands);"
15921   [(set (attr "type")
15922         (if_then_else (match_operand:SF 3 "mult_operator" "")
15923            (const_string "fmul")
15924            (const_string "fop")))
15925    (set_attr "mode" "SF")])
15926
15927 (define_insn "*fop_sf_1_mixed"
15928   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15929         (match_operator:SF 3 "binary_fp_operator"
15930                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15931                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15932   "TARGET_MIX_SSE_I387
15933    && !COMMUTATIVE_ARITH_P (operands[3])
15934    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15935   "* return output_387_binary_op (insn, operands);"
15936   [(set (attr "type")
15937         (cond [(and (eq_attr "alternative" "2")
15938                     (match_operand:SF 3 "mult_operator" ""))
15939                  (const_string "ssemul")
15940                (and (eq_attr "alternative" "2")
15941                     (match_operand:SF 3 "div_operator" ""))
15942                  (const_string "ssediv")
15943                (eq_attr "alternative" "2")
15944                  (const_string "sseadd")
15945                (match_operand:SF 3 "mult_operator" "")
15946                  (const_string "fmul")
15947                (match_operand:SF 3 "div_operator" "")
15948                  (const_string "fdiv")
15949               ]
15950               (const_string "fop")))
15951    (set_attr "mode" "SF")])
15952
15953 (define_insn "*rcpsf2_sse"
15954   [(set (match_operand:SF 0 "register_operand" "=x")
15955         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15956                    UNSPEC_RCP))]
15957   "TARGET_SSE_MATH"
15958   "rcpss\t{%1, %0|%0, %1}"
15959   [(set_attr "type" "sse")
15960    (set_attr "mode" "SF")])
15961
15962 (define_insn "*fop_sf_1_sse"
15963   [(set (match_operand:SF 0 "register_operand" "=x")
15964         (match_operator:SF 3 "binary_fp_operator"
15965                         [(match_operand:SF 1 "register_operand" "0")
15966                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15967   "TARGET_SSE_MATH
15968    && !COMMUTATIVE_ARITH_P (operands[3])"
15969   "* return output_387_binary_op (insn, operands);"
15970   [(set (attr "type")
15971         (cond [(match_operand:SF 3 "mult_operator" "")
15972                  (const_string "ssemul")
15973                (match_operand:SF 3 "div_operator" "")
15974                  (const_string "ssediv")
15975               ]
15976               (const_string "sseadd")))
15977    (set_attr "mode" "SF")])
15978
15979 ;; This pattern is not fully shadowed by the pattern above.
15980 (define_insn "*fop_sf_1_i387"
15981   [(set (match_operand:SF 0 "register_operand" "=f,f")
15982         (match_operator:SF 3 "binary_fp_operator"
15983                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15984                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15985   "TARGET_80387 && !TARGET_SSE_MATH
15986    && !COMMUTATIVE_ARITH_P (operands[3])
15987    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15988   "* return output_387_binary_op (insn, operands);"
15989   [(set (attr "type")
15990         (cond [(match_operand:SF 3 "mult_operator" "")
15991                  (const_string "fmul")
15992                (match_operand:SF 3 "div_operator" "")
15993                  (const_string "fdiv")
15994               ]
15995               (const_string "fop")))
15996    (set_attr "mode" "SF")])
15997
15998 ;; ??? Add SSE splitters for these!
15999 (define_insn "*fop_sf_2<mode>_i387"
16000   [(set (match_operand:SF 0 "register_operand" "=f,f")
16001         (match_operator:SF 3 "binary_fp_operator"
16002           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16003            (match_operand:SF 2 "register_operand" "0,0")]))]
16004   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16005   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16006   [(set (attr "type")
16007         (cond [(match_operand:SF 3 "mult_operator" "")
16008                  (const_string "fmul")
16009                (match_operand:SF 3 "div_operator" "")
16010                  (const_string "fdiv")
16011               ]
16012               (const_string "fop")))
16013    (set_attr "fp_int_src" "true")
16014    (set_attr "mode" "<MODE>")])
16015
16016 (define_insn "*fop_sf_3<mode>_i387"
16017   [(set (match_operand:SF 0 "register_operand" "=f,f")
16018         (match_operator:SF 3 "binary_fp_operator"
16019           [(match_operand:SF 1 "register_operand" "0,0")
16020            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16021   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16022   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16023   [(set (attr "type")
16024         (cond [(match_operand:SF 3 "mult_operator" "")
16025                  (const_string "fmul")
16026                (match_operand:SF 3 "div_operator" "")
16027                  (const_string "fdiv")
16028               ]
16029               (const_string "fop")))
16030    (set_attr "fp_int_src" "true")
16031    (set_attr "mode" "<MODE>")])
16032
16033 (define_insn "*fop_df_comm_mixed"
16034   [(set (match_operand:DF 0 "register_operand" "=f,x")
16035         (match_operator:DF 3 "binary_fp_operator"
16036           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16037            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16038   "TARGET_SSE2 && TARGET_MIX_SSE_I387
16039    && COMMUTATIVE_ARITH_P (operands[3])
16040    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16041   "* return output_387_binary_op (insn, operands);"
16042   [(set (attr "type")
16043         (if_then_else (eq_attr "alternative" "1")
16044            (if_then_else (match_operand:DF 3 "mult_operator" "")
16045               (const_string "ssemul")
16046               (const_string "sseadd"))
16047            (if_then_else (match_operand:DF 3 "mult_operator" "")
16048               (const_string "fmul")
16049               (const_string "fop"))))
16050    (set_attr "mode" "DF")])
16051
16052 (define_insn "*fop_df_comm_sse"
16053   [(set (match_operand:DF 0 "register_operand" "=x")
16054         (match_operator:DF 3 "binary_fp_operator"
16055           [(match_operand:DF 1 "nonimmediate_operand" "%0")
16056            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16057   "TARGET_SSE2 && TARGET_SSE_MATH
16058    && COMMUTATIVE_ARITH_P (operands[3])
16059    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16060   "* return output_387_binary_op (insn, operands);"
16061   [(set (attr "type")
16062         (if_then_else (match_operand:DF 3 "mult_operator" "")
16063            (const_string "ssemul")
16064            (const_string "sseadd")))
16065    (set_attr "mode" "DF")])
16066
16067 (define_insn "*fop_df_comm_i387"
16068   [(set (match_operand:DF 0 "register_operand" "=f")
16069         (match_operator:DF 3 "binary_fp_operator"
16070                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
16071                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16072   "TARGET_80387
16073    && COMMUTATIVE_ARITH_P (operands[3])
16074    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16075   "* return output_387_binary_op (insn, operands);"
16076   [(set (attr "type")
16077         (if_then_else (match_operand:DF 3 "mult_operator" "")
16078            (const_string "fmul")
16079            (const_string "fop")))
16080    (set_attr "mode" "DF")])
16081
16082 (define_insn "*fop_df_1_mixed"
16083   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16084         (match_operator:DF 3 "binary_fp_operator"
16085           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16086            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16087   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16088    && !COMMUTATIVE_ARITH_P (operands[3])
16089    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16090   "* return output_387_binary_op (insn, operands);"
16091   [(set (attr "type")
16092         (cond [(and (eq_attr "alternative" "2")
16093                     (match_operand:DF 3 "mult_operator" ""))
16094                  (const_string "ssemul")
16095                (and (eq_attr "alternative" "2")
16096                     (match_operand:DF 3 "div_operator" ""))
16097                  (const_string "ssediv")
16098                (eq_attr "alternative" "2")
16099                  (const_string "sseadd")
16100                (match_operand:DF 3 "mult_operator" "")
16101                  (const_string "fmul")
16102                (match_operand:DF 3 "div_operator" "")
16103                  (const_string "fdiv")
16104               ]
16105               (const_string "fop")))
16106    (set_attr "mode" "DF")])
16107
16108 (define_insn "*fop_df_1_sse"
16109   [(set (match_operand:DF 0 "register_operand" "=x")
16110         (match_operator:DF 3 "binary_fp_operator"
16111           [(match_operand:DF 1 "register_operand" "0")
16112            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16113   "TARGET_SSE2 && TARGET_SSE_MATH
16114    && !COMMUTATIVE_ARITH_P (operands[3])"
16115   "* return output_387_binary_op (insn, operands);"
16116   [(set_attr "mode" "DF")
16117    (set (attr "type")
16118         (cond [(match_operand:DF 3 "mult_operator" "")
16119                  (const_string "ssemul")
16120                (match_operand:DF 3 "div_operator" "")
16121                  (const_string "ssediv")
16122               ]
16123               (const_string "sseadd")))])
16124
16125 ;; This pattern is not fully shadowed by the pattern above.
16126 (define_insn "*fop_df_1_i387"
16127   [(set (match_operand:DF 0 "register_operand" "=f,f")
16128         (match_operator:DF 3 "binary_fp_operator"
16129                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16130                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16131   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16132    && !COMMUTATIVE_ARITH_P (operands[3])
16133    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16134   "* return output_387_binary_op (insn, operands);"
16135   [(set (attr "type")
16136         (cond [(match_operand:DF 3 "mult_operator" "")
16137                  (const_string "fmul")
16138                (match_operand:DF 3 "div_operator" "")
16139                  (const_string "fdiv")
16140               ]
16141               (const_string "fop")))
16142    (set_attr "mode" "DF")])
16143
16144 ;; ??? Add SSE splitters for these!
16145 (define_insn "*fop_df_2<mode>_i387"
16146   [(set (match_operand:DF 0 "register_operand" "=f,f")
16147         (match_operator:DF 3 "binary_fp_operator"
16148            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16149             (match_operand:DF 2 "register_operand" "0,0")]))]
16150   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16151    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16152   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16153   [(set (attr "type")
16154         (cond [(match_operand:DF 3 "mult_operator" "")
16155                  (const_string "fmul")
16156                (match_operand:DF 3 "div_operator" "")
16157                  (const_string "fdiv")
16158               ]
16159               (const_string "fop")))
16160    (set_attr "fp_int_src" "true")
16161    (set_attr "mode" "<MODE>")])
16162
16163 (define_insn "*fop_df_3<mode>_i387"
16164   [(set (match_operand:DF 0 "register_operand" "=f,f")
16165         (match_operator:DF 3 "binary_fp_operator"
16166            [(match_operand:DF 1 "register_operand" "0,0")
16167             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16168   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16169    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16170   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16171   [(set (attr "type")
16172         (cond [(match_operand:DF 3 "mult_operator" "")
16173                  (const_string "fmul")
16174                (match_operand:DF 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_4_i387"
16182   [(set (match_operand:DF 0 "register_operand" "=f,f")
16183         (match_operator:DF 3 "binary_fp_operator"
16184            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16185             (match_operand:DF 2 "register_operand" "0,f")]))]
16186   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16187    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16188   "* return output_387_binary_op (insn, operands);"
16189   [(set (attr "type")
16190         (cond [(match_operand:DF 3 "mult_operator" "")
16191                  (const_string "fmul")
16192                (match_operand:DF 3 "div_operator" "")
16193                  (const_string "fdiv")
16194               ]
16195               (const_string "fop")))
16196    (set_attr "mode" "SF")])
16197
16198 (define_insn "*fop_df_5_i387"
16199   [(set (match_operand:DF 0 "register_operand" "=f,f")
16200         (match_operator:DF 3 "binary_fp_operator"
16201           [(match_operand:DF 1 "register_operand" "0,f")
16202            (float_extend:DF
16203             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16204   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16205   "* return output_387_binary_op (insn, operands);"
16206   [(set (attr "type")
16207         (cond [(match_operand:DF 3 "mult_operator" "")
16208                  (const_string "fmul")
16209                (match_operand:DF 3 "div_operator" "")
16210                  (const_string "fdiv")
16211               ]
16212               (const_string "fop")))
16213    (set_attr "mode" "SF")])
16214
16215 (define_insn "*fop_df_6_i387"
16216   [(set (match_operand:DF 0 "register_operand" "=f,f")
16217         (match_operator:DF 3 "binary_fp_operator"
16218           [(float_extend:DF
16219             (match_operand:SF 1 "register_operand" "0,f"))
16220            (float_extend:DF
16221             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16222   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16223   "* return output_387_binary_op (insn, operands);"
16224   [(set (attr "type")
16225         (cond [(match_operand:DF 3 "mult_operator" "")
16226                  (const_string "fmul")
16227                (match_operand:DF 3 "div_operator" "")
16228                  (const_string "fdiv")
16229               ]
16230               (const_string "fop")))
16231    (set_attr "mode" "SF")])
16232
16233 (define_insn "*fop_xf_comm_i387"
16234   [(set (match_operand:XF 0 "register_operand" "=f")
16235         (match_operator:XF 3 "binary_fp_operator"
16236                         [(match_operand:XF 1 "register_operand" "%0")
16237                          (match_operand:XF 2 "register_operand" "f")]))]
16238   "TARGET_80387
16239    && COMMUTATIVE_ARITH_P (operands[3])"
16240   "* return output_387_binary_op (insn, operands);"
16241   [(set (attr "type")
16242         (if_then_else (match_operand:XF 3 "mult_operator" "")
16243            (const_string "fmul")
16244            (const_string "fop")))
16245    (set_attr "mode" "XF")])
16246
16247 (define_insn "*fop_xf_1_i387"
16248   [(set (match_operand:XF 0 "register_operand" "=f,f")
16249         (match_operator:XF 3 "binary_fp_operator"
16250                         [(match_operand:XF 1 "register_operand" "0,f")
16251                          (match_operand:XF 2 "register_operand" "f,0")]))]
16252   "TARGET_80387
16253    && !COMMUTATIVE_ARITH_P (operands[3])"
16254   "* return output_387_binary_op (insn, operands);"
16255   [(set (attr "type")
16256         (cond [(match_operand:XF 3 "mult_operator" "")
16257                  (const_string "fmul")
16258                (match_operand:XF 3 "div_operator" "")
16259                  (const_string "fdiv")
16260               ]
16261               (const_string "fop")))
16262    (set_attr "mode" "XF")])
16263
16264 (define_insn "*fop_xf_2<mode>_i387"
16265   [(set (match_operand:XF 0 "register_operand" "=f,f")
16266         (match_operator:XF 3 "binary_fp_operator"
16267            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16268             (match_operand:XF 2 "register_operand" "0,0")]))]
16269   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16270   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16271   [(set (attr "type")
16272         (cond [(match_operand:XF 3 "mult_operator" "")
16273                  (const_string "fmul")
16274                (match_operand:XF 3 "div_operator" "")
16275                  (const_string "fdiv")
16276               ]
16277               (const_string "fop")))
16278    (set_attr "fp_int_src" "true")
16279    (set_attr "mode" "<MODE>")])
16280
16281 (define_insn "*fop_xf_3<mode>_i387"
16282   [(set (match_operand:XF 0 "register_operand" "=f,f")
16283         (match_operator:XF 3 "binary_fp_operator"
16284           [(match_operand:XF 1 "register_operand" "0,0")
16285            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16286   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16287   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16288   [(set (attr "type")
16289         (cond [(match_operand:XF 3 "mult_operator" "")
16290                  (const_string "fmul")
16291                (match_operand:XF 3 "div_operator" "")
16292                  (const_string "fdiv")
16293               ]
16294               (const_string "fop")))
16295    (set_attr "fp_int_src" "true")
16296    (set_attr "mode" "<MODE>")])
16297
16298 (define_insn "*fop_xf_4_i387"
16299   [(set (match_operand:XF 0 "register_operand" "=f,f")
16300         (match_operator:XF 3 "binary_fp_operator"
16301            [(float_extend:XF
16302               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16303             (match_operand:XF 2 "register_operand" "0,f")]))]
16304   "TARGET_80387"
16305   "* return output_387_binary_op (insn, operands);"
16306   [(set (attr "type")
16307         (cond [(match_operand:XF 3 "mult_operator" "")
16308                  (const_string "fmul")
16309                (match_operand:XF 3 "div_operator" "")
16310                  (const_string "fdiv")
16311               ]
16312               (const_string "fop")))
16313    (set_attr "mode" "SF")])
16314
16315 (define_insn "*fop_xf_5_i387"
16316   [(set (match_operand:XF 0 "register_operand" "=f,f")
16317         (match_operator:XF 3 "binary_fp_operator"
16318           [(match_operand:XF 1 "register_operand" "0,f")
16319            (float_extend:XF
16320              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16321   "TARGET_80387"
16322   "* return output_387_binary_op (insn, operands);"
16323   [(set (attr "type")
16324         (cond [(match_operand:XF 3 "mult_operator" "")
16325                  (const_string "fmul")
16326                (match_operand:XF 3 "div_operator" "")
16327                  (const_string "fdiv")
16328               ]
16329               (const_string "fop")))
16330    (set_attr "mode" "SF")])
16331
16332 (define_insn "*fop_xf_6_i387"
16333   [(set (match_operand:XF 0 "register_operand" "=f,f")
16334         (match_operator:XF 3 "binary_fp_operator"
16335           [(float_extend:XF
16336              (match_operand:MODEF 1 "register_operand" "0,f"))
16337            (float_extend:XF
16338              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16339   "TARGET_80387"
16340   "* return output_387_binary_op (insn, operands);"
16341   [(set (attr "type")
16342         (cond [(match_operand:XF 3 "mult_operator" "")
16343                  (const_string "fmul")
16344                (match_operand:XF 3 "div_operator" "")
16345                  (const_string "fdiv")
16346               ]
16347               (const_string "fop")))
16348    (set_attr "mode" "SF")])
16349
16350 (define_split
16351   [(set (match_operand 0 "register_operand" "")
16352         (match_operator 3 "binary_fp_operator"
16353            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16354             (match_operand 2 "register_operand" "")]))]
16355   "reload_completed
16356    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16357   [(const_int 0)]
16358 {
16359   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16360   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16361   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16362                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16363                                           GET_MODE (operands[3]),
16364                                           operands[4],
16365                                           operands[2])));
16366   ix86_free_from_memory (GET_MODE (operands[1]));
16367   DONE;
16368 })
16369
16370 (define_split
16371   [(set (match_operand 0 "register_operand" "")
16372         (match_operator 3 "binary_fp_operator"
16373            [(match_operand 1 "register_operand" "")
16374             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16375   "reload_completed
16376    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16377   [(const_int 0)]
16378 {
16379   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16380   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16381   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16382                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16383                                           GET_MODE (operands[3]),
16384                                           operands[1],
16385                                           operands[4])));
16386   ix86_free_from_memory (GET_MODE (operands[2]));
16387   DONE;
16388 })
16389 \f
16390 ;; FPU special functions.
16391
16392 ;; This pattern implements a no-op XFmode truncation for
16393 ;; all fancy i386 XFmode math functions.
16394
16395 (define_insn "truncxf<mode>2_i387_noop_unspec"
16396   [(set (match_operand:MODEF 0 "register_operand" "=f")
16397         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16398         UNSPEC_TRUNC_NOOP))]
16399   "TARGET_USE_FANCY_MATH_387"
16400   "* return output_387_reg_move (insn, operands);"
16401   [(set_attr "type" "fmov")
16402    (set_attr "mode" "<MODE>")])
16403
16404 (define_insn "sqrtxf2"
16405   [(set (match_operand:XF 0 "register_operand" "=f")
16406         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16407   "TARGET_USE_FANCY_MATH_387"
16408   "fsqrt"
16409   [(set_attr "type" "fpspc")
16410    (set_attr "mode" "XF")
16411    (set_attr "athlon_decode" "direct")
16412    (set_attr "amdfam10_decode" "direct")])
16413
16414 (define_insn "sqrt_extend<mode>xf2_i387"
16415   [(set (match_operand:XF 0 "register_operand" "=f")
16416         (sqrt:XF
16417           (float_extend:XF
16418             (match_operand:MODEF 1 "register_operand" "0"))))]
16419   "TARGET_USE_FANCY_MATH_387"
16420   "fsqrt"
16421   [(set_attr "type" "fpspc")
16422    (set_attr "mode" "XF")
16423    (set_attr "athlon_decode" "direct")   
16424    (set_attr "amdfam10_decode" "direct")])
16425
16426 (define_insn "*rsqrtsf2_sse"
16427   [(set (match_operand:SF 0 "register_operand" "=x")
16428         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16429                    UNSPEC_RSQRT))]
16430   "TARGET_SSE_MATH"
16431   "rsqrtss\t{%1, %0|%0, %1}"
16432   [(set_attr "type" "sse")
16433    (set_attr "mode" "SF")])
16434
16435 (define_expand "rsqrtsf2"
16436   [(set (match_operand:SF 0 "register_operand" "")
16437         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16438                    UNSPEC_RSQRT))]
16439   "TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16440    && flag_finite_math_only && !flag_trapping_math
16441    && flag_unsafe_math_optimizations"
16442 {
16443   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16444   DONE;
16445 })
16446
16447 (define_insn "*sqrt<mode>2_sse"
16448   [(set (match_operand:MODEF 0 "register_operand" "=x")
16449         (sqrt:MODEF
16450           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16451   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16452   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16453   [(set_attr "type" "sse")
16454    (set_attr "mode" "<MODE>")
16455    (set_attr "athlon_decode" "*")
16456    (set_attr "amdfam10_decode" "*")])
16457
16458 (define_expand "sqrt<mode>2"
16459   [(set (match_operand:MODEF 0 "register_operand" "")
16460         (sqrt:MODEF
16461           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16462   "TARGET_USE_FANCY_MATH_387
16463    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16464 {
16465   if (<MODE>mode == SFmode
16466       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16467       && flag_finite_math_only && !flag_trapping_math
16468       && flag_unsafe_math_optimizations)
16469     {
16470       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16471       DONE;
16472     }
16473
16474   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16475     {
16476       rtx op0 = gen_reg_rtx (XFmode);
16477       rtx op1 = force_reg (<MODE>mode, operands[1]);
16478
16479       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16480       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16481       DONE;
16482    }
16483 })
16484
16485 (define_insn "fpremxf4_i387"
16486   [(set (match_operand:XF 0 "register_operand" "=f")
16487         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16488                     (match_operand:XF 3 "register_operand" "1")]
16489                    UNSPEC_FPREM_F))
16490    (set (match_operand:XF 1 "register_operand" "=u")
16491         (unspec:XF [(match_dup 2) (match_dup 3)]
16492                    UNSPEC_FPREM_U))
16493    (set (reg:CCFP FPSR_REG)
16494         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16495                      UNSPEC_C2_FLAG))]
16496   "TARGET_USE_FANCY_MATH_387"
16497   "fprem"
16498   [(set_attr "type" "fpspc")
16499    (set_attr "mode" "XF")])
16500
16501 (define_expand "fmodxf3"
16502   [(use (match_operand:XF 0 "register_operand" ""))
16503    (use (match_operand:XF 1 "register_operand" ""))
16504    (use (match_operand:XF 2 "register_operand" ""))]
16505   "TARGET_USE_FANCY_MATH_387"
16506 {
16507   rtx label = gen_label_rtx ();
16508
16509   emit_label (label);
16510
16511   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16512                                 operands[1], operands[2]));
16513   ix86_emit_fp_unordered_jump (label);
16514   LABEL_NUSES (label) = 1;
16515
16516   emit_move_insn (operands[0], operands[1]);
16517   DONE;
16518 })
16519
16520 (define_expand "fmod<mode>3"
16521   [(use (match_operand:MODEF 0 "register_operand" ""))
16522    (use (match_operand:MODEF 1 "general_operand" ""))
16523    (use (match_operand:MODEF 2 "general_operand" ""))]
16524   "TARGET_USE_FANCY_MATH_387"
16525 {
16526   rtx label = gen_label_rtx ();
16527
16528   rtx op1 = gen_reg_rtx (XFmode);
16529   rtx op2 = gen_reg_rtx (XFmode);
16530
16531   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16532   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16533
16534   emit_label (label);
16535   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16536   ix86_emit_fp_unordered_jump (label);
16537   LABEL_NUSES (label) = 1;
16538
16539   /* Truncate the result properly for strict SSE math.  */
16540   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16541       && !TARGET_MIX_SSE_I387)
16542     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16543   else
16544     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16545
16546   DONE;
16547 })
16548
16549 (define_insn "fprem1xf4_i387"
16550   [(set (match_operand:XF 0 "register_operand" "=f")
16551         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16552                     (match_operand:XF 3 "register_operand" "1")]
16553                    UNSPEC_FPREM1_F))
16554    (set (match_operand:XF 1 "register_operand" "=u")
16555         (unspec:XF [(match_dup 2) (match_dup 3)]
16556                    UNSPEC_FPREM1_U))
16557    (set (reg:CCFP FPSR_REG)
16558         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16559                      UNSPEC_C2_FLAG))]
16560   "TARGET_USE_FANCY_MATH_387"
16561   "fprem1"
16562   [(set_attr "type" "fpspc")
16563    (set_attr "mode" "XF")])
16564
16565 (define_expand "remainderxf3"
16566   [(use (match_operand:XF 0 "register_operand" ""))
16567    (use (match_operand:XF 1 "register_operand" ""))
16568    (use (match_operand:XF 2 "register_operand" ""))]
16569   "TARGET_USE_FANCY_MATH_387"
16570 {
16571   rtx label = gen_label_rtx ();
16572
16573   emit_label (label);
16574
16575   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16576                                  operands[1], operands[2]));
16577   ix86_emit_fp_unordered_jump (label);
16578   LABEL_NUSES (label) = 1;
16579
16580   emit_move_insn (operands[0], operands[1]);
16581   DONE;
16582 })
16583
16584 (define_expand "remainder<mode>3"
16585   [(use (match_operand:MODEF 0 "register_operand" ""))
16586    (use (match_operand:MODEF 1 "general_operand" ""))
16587    (use (match_operand:MODEF 2 "general_operand" ""))]
16588   "TARGET_USE_FANCY_MATH_387"
16589 {
16590   rtx label = gen_label_rtx ();
16591
16592   rtx op1 = gen_reg_rtx (XFmode);
16593   rtx op2 = gen_reg_rtx (XFmode);
16594
16595   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16596   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16597
16598   emit_label (label);
16599
16600   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16601   ix86_emit_fp_unordered_jump (label);
16602   LABEL_NUSES (label) = 1;
16603
16604   /* Truncate the result properly for strict SSE math.  */
16605   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16606       && !TARGET_MIX_SSE_I387)
16607     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16608   else
16609     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16610
16611   DONE;
16612 })
16613
16614 (define_insn "*sinxf2_i387"
16615   [(set (match_operand:XF 0 "register_operand" "=f")
16616         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16617   "TARGET_USE_FANCY_MATH_387
16618    && flag_unsafe_math_optimizations"
16619   "fsin"
16620   [(set_attr "type" "fpspc")
16621    (set_attr "mode" "XF")])
16622
16623 (define_insn "*sin_extend<mode>xf2_i387"
16624   [(set (match_operand:XF 0 "register_operand" "=f")
16625         (unspec:XF [(float_extend:XF
16626                       (match_operand:MODEF 1 "register_operand" "0"))]
16627                    UNSPEC_SIN))]
16628   "TARGET_USE_FANCY_MATH_387
16629    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16630        || TARGET_MIX_SSE_I387)
16631    && flag_unsafe_math_optimizations"
16632   "fsin"
16633   [(set_attr "type" "fpspc")
16634    (set_attr "mode" "XF")])
16635
16636 (define_insn "*cosxf2_i387"
16637   [(set (match_operand:XF 0 "register_operand" "=f")
16638         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16639   "TARGET_USE_FANCY_MATH_387
16640    && flag_unsafe_math_optimizations"
16641   "fcos"
16642   [(set_attr "type" "fpspc")
16643    (set_attr "mode" "XF")])
16644
16645 (define_insn "*cos_extend<mode>xf2_i387"
16646   [(set (match_operand:XF 0 "register_operand" "=f")
16647         (unspec:XF [(float_extend:XF
16648                       (match_operand:MODEF 1 "register_operand" "0"))]
16649                    UNSPEC_COS))]
16650   "TARGET_USE_FANCY_MATH_387
16651    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16652        || TARGET_MIX_SSE_I387)
16653    && flag_unsafe_math_optimizations"
16654   "fcos"
16655   [(set_attr "type" "fpspc")
16656    (set_attr "mode" "XF")])
16657
16658 ;; When sincos pattern is defined, sin and cos builtin functions will be
16659 ;; expanded to sincos pattern with one of its outputs left unused.
16660 ;; CSE pass will figure out if two sincos patterns can be combined,
16661 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16662 ;; depending on the unused output.
16663
16664 (define_insn "sincosxf3"
16665   [(set (match_operand:XF 0 "register_operand" "=f")
16666         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16667                    UNSPEC_SINCOS_COS))
16668    (set (match_operand:XF 1 "register_operand" "=u")
16669         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16670   "TARGET_USE_FANCY_MATH_387
16671    && flag_unsafe_math_optimizations"
16672   "fsincos"
16673   [(set_attr "type" "fpspc")
16674    (set_attr "mode" "XF")])
16675
16676 (define_split
16677   [(set (match_operand:XF 0 "register_operand" "")
16678         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16679                    UNSPEC_SINCOS_COS))
16680    (set (match_operand:XF 1 "register_operand" "")
16681         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16682   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16683    && !(reload_completed || reload_in_progress)"
16684   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16685   "")
16686
16687 (define_split
16688   [(set (match_operand:XF 0 "register_operand" "")
16689         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16690                    UNSPEC_SINCOS_COS))
16691    (set (match_operand:XF 1 "register_operand" "")
16692         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16693   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16694    && !(reload_completed || reload_in_progress)"
16695   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16696   "")
16697
16698 (define_insn "sincos_extend<mode>xf3_i387"
16699   [(set (match_operand:XF 0 "register_operand" "=f")
16700         (unspec:XF [(float_extend:XF
16701                       (match_operand:MODEF 2 "register_operand" "0"))]
16702                    UNSPEC_SINCOS_COS))
16703    (set (match_operand:XF 1 "register_operand" "=u")
16704         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16705   "TARGET_USE_FANCY_MATH_387
16706    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16707        || TARGET_MIX_SSE_I387)
16708    && flag_unsafe_math_optimizations"
16709   "fsincos"
16710   [(set_attr "type" "fpspc")
16711    (set_attr "mode" "XF")])
16712
16713 (define_split
16714   [(set (match_operand:XF 0 "register_operand" "")
16715         (unspec:XF [(float_extend:XF
16716                       (match_operand:MODEF 2 "register_operand" ""))]
16717                    UNSPEC_SINCOS_COS))
16718    (set (match_operand:XF 1 "register_operand" "")
16719         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16720   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16721    && !(reload_completed || reload_in_progress)"
16722   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16723   "")
16724
16725 (define_split
16726   [(set (match_operand:XF 0 "register_operand" "")
16727         (unspec:XF [(float_extend:XF
16728                       (match_operand:MODEF 2 "register_operand" ""))]
16729                    UNSPEC_SINCOS_COS))
16730    (set (match_operand:XF 1 "register_operand" "")
16731         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16732   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16733    && !(reload_completed || reload_in_progress)"
16734   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16735   "")
16736
16737 (define_expand "sincos<mode>3"
16738   [(use (match_operand:MODEF 0 "register_operand" ""))
16739    (use (match_operand:MODEF 1 "register_operand" ""))
16740    (use (match_operand:MODEF 2 "register_operand" ""))]
16741   "TARGET_USE_FANCY_MATH_387
16742    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16743        || TARGET_MIX_SSE_I387)
16744    && flag_unsafe_math_optimizations"
16745 {
16746   rtx op0 = gen_reg_rtx (XFmode);
16747   rtx op1 = gen_reg_rtx (XFmode);
16748
16749   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16750   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16751   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16752   DONE;
16753 })
16754
16755 (define_insn "fptanxf4_i387"
16756   [(set (match_operand:XF 0 "register_operand" "=f")
16757         (match_operand:XF 3 "const_double_operand" "F"))
16758    (set (match_operand:XF 1 "register_operand" "=u")
16759         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16760                    UNSPEC_TAN))]
16761   "TARGET_USE_FANCY_MATH_387
16762    && flag_unsafe_math_optimizations
16763    && standard_80387_constant_p (operands[3]) == 2"
16764   "fptan"
16765   [(set_attr "type" "fpspc")
16766    (set_attr "mode" "XF")])
16767
16768 (define_insn "fptan_extend<mode>xf4_i387"
16769   [(set (match_operand:MODEF 0 "register_operand" "=f")
16770         (match_operand:MODEF 3 "const_double_operand" "F"))
16771    (set (match_operand:XF 1 "register_operand" "=u")
16772         (unspec:XF [(float_extend:XF
16773                       (match_operand:MODEF 2 "register_operand" "0"))]
16774                    UNSPEC_TAN))]
16775   "TARGET_USE_FANCY_MATH_387
16776    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16777        || TARGET_MIX_SSE_I387)
16778    && flag_unsafe_math_optimizations
16779    && standard_80387_constant_p (operands[3]) == 2"
16780   "fptan"
16781   [(set_attr "type" "fpspc")
16782    (set_attr "mode" "XF")])
16783
16784 (define_expand "tanxf2"
16785   [(use (match_operand:XF 0 "register_operand" ""))
16786    (use (match_operand:XF 1 "register_operand" ""))]
16787   "TARGET_USE_FANCY_MATH_387
16788    && flag_unsafe_math_optimizations"
16789 {
16790   rtx one = gen_reg_rtx (XFmode);
16791   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16792
16793   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16794   DONE;
16795 })
16796
16797 (define_expand "tan<mode>2"
16798   [(use (match_operand:MODEF 0 "register_operand" ""))
16799    (use (match_operand:MODEF 1 "register_operand" ""))]
16800   "TARGET_USE_FANCY_MATH_387
16801    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16802        || TARGET_MIX_SSE_I387)
16803    && flag_unsafe_math_optimizations"
16804 {
16805   rtx op0 = gen_reg_rtx (XFmode);
16806
16807   rtx one = gen_reg_rtx (<MODE>mode);
16808   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16809
16810   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16811                                              operands[1], op2));
16812   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16813   DONE;
16814 })
16815
16816 (define_insn "*fpatanxf3_i387"
16817   [(set (match_operand:XF 0 "register_operand" "=f")
16818         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16819                     (match_operand:XF 2 "register_operand" "u")]
16820                    UNSPEC_FPATAN))
16821    (clobber (match_scratch:XF 3 "=2"))]
16822   "TARGET_USE_FANCY_MATH_387
16823    && flag_unsafe_math_optimizations"
16824   "fpatan"
16825   [(set_attr "type" "fpspc")
16826    (set_attr "mode" "XF")])
16827
16828 (define_insn "fpatan_extend<mode>xf3_i387"
16829   [(set (match_operand:XF 0 "register_operand" "=f")
16830         (unspec:XF [(float_extend:XF
16831                       (match_operand:MODEF 1 "register_operand" "0"))
16832                     (float_extend:XF
16833                       (match_operand:MODEF 2 "register_operand" "u"))]
16834                    UNSPEC_FPATAN))
16835    (clobber (match_scratch:XF 3 "=2"))]
16836   "TARGET_USE_FANCY_MATH_387
16837    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16838        || TARGET_MIX_SSE_I387)
16839    && flag_unsafe_math_optimizations"
16840   "fpatan"
16841   [(set_attr "type" "fpspc")
16842    (set_attr "mode" "XF")])
16843
16844 (define_expand "atan2xf3"
16845   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16846                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16847                                (match_operand:XF 1 "register_operand" "")]
16848                               UNSPEC_FPATAN))
16849               (clobber (match_scratch:XF 3 ""))])]
16850   "TARGET_USE_FANCY_MATH_387
16851    && flag_unsafe_math_optimizations"
16852   "")
16853
16854 (define_expand "atan2<mode>3"
16855   [(use (match_operand:MODEF 0 "register_operand" ""))
16856    (use (match_operand:MODEF 1 "register_operand" ""))
16857    (use (match_operand:MODEF 2 "register_operand" ""))]
16858   "TARGET_USE_FANCY_MATH_387
16859    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16860        || TARGET_MIX_SSE_I387)
16861    && flag_unsafe_math_optimizations"
16862 {
16863   rtx op0 = gen_reg_rtx (XFmode);
16864
16865   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16866   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16867   DONE;
16868 })
16869
16870 (define_expand "atanxf2"
16871   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16872                    (unspec:XF [(match_dup 2)
16873                                (match_operand:XF 1 "register_operand" "")]
16874                               UNSPEC_FPATAN))
16875               (clobber (match_scratch:XF 3 ""))])]
16876   "TARGET_USE_FANCY_MATH_387
16877    && flag_unsafe_math_optimizations"
16878 {
16879   operands[2] = gen_reg_rtx (XFmode);
16880   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16881 })
16882
16883 (define_expand "atan<mode>2"
16884   [(use (match_operand:MODEF 0 "register_operand" ""))
16885    (use (match_operand:MODEF 1 "register_operand" ""))]
16886   "TARGET_USE_FANCY_MATH_387
16887    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16888        || TARGET_MIX_SSE_I387)
16889    && flag_unsafe_math_optimizations"
16890 {
16891   rtx op0 = gen_reg_rtx (XFmode);
16892
16893   rtx op2 = gen_reg_rtx (<MODE>mode);
16894   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16895
16896   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16897   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16898   DONE;
16899 })
16900
16901 (define_expand "asinxf2"
16902   [(set (match_dup 2)
16903         (mult:XF (match_operand:XF 1 "register_operand" "")
16904                  (match_dup 1)))
16905    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16906    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16907    (parallel [(set (match_operand:XF 0 "register_operand" "")
16908                    (unspec:XF [(match_dup 5) (match_dup 1)]
16909                               UNSPEC_FPATAN))
16910               (clobber (match_scratch:XF 6 ""))])]
16911   "TARGET_USE_FANCY_MATH_387
16912    && flag_unsafe_math_optimizations && !optimize_size"
16913 {
16914   int i;
16915
16916   for (i = 2; i < 6; i++)
16917     operands[i] = gen_reg_rtx (XFmode);
16918
16919   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16920 })
16921
16922 (define_expand "asin<mode>2"
16923   [(use (match_operand:MODEF 0 "register_operand" ""))
16924    (use (match_operand:MODEF 1 "general_operand" ""))]
16925  "TARGET_USE_FANCY_MATH_387
16926    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16927        || TARGET_MIX_SSE_I387)
16928    && flag_unsafe_math_optimizations && !optimize_size"
16929 {
16930   rtx op0 = gen_reg_rtx (XFmode);
16931   rtx op1 = gen_reg_rtx (XFmode);
16932
16933   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16934   emit_insn (gen_asinxf2 (op0, op1));
16935   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16936   DONE;
16937 })
16938
16939 (define_expand "acosxf2"
16940   [(set (match_dup 2)
16941         (mult:XF (match_operand:XF 1 "register_operand" "")
16942                  (match_dup 1)))
16943    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16944    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16945    (parallel [(set (match_operand:XF 0 "register_operand" "")
16946                    (unspec:XF [(match_dup 1) (match_dup 5)]
16947                               UNSPEC_FPATAN))
16948               (clobber (match_scratch:XF 6 ""))])]
16949   "TARGET_USE_FANCY_MATH_387
16950    && flag_unsafe_math_optimizations && !optimize_size"
16951 {
16952   int i;
16953
16954   for (i = 2; i < 6; i++)
16955     operands[i] = gen_reg_rtx (XFmode);
16956
16957   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16958 })
16959
16960 (define_expand "acos<mode>2"
16961   [(use (match_operand:MODEF 0 "register_operand" ""))
16962    (use (match_operand:MODEF 1 "general_operand" ""))]
16963  "TARGET_USE_FANCY_MATH_387
16964    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16965        || TARGET_MIX_SSE_I387)
16966    && flag_unsafe_math_optimizations && !optimize_size"
16967 {
16968   rtx op0 = gen_reg_rtx (XFmode);
16969   rtx op1 = gen_reg_rtx (XFmode);
16970
16971   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16972   emit_insn (gen_acosxf2 (op0, op1));
16973   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16974   DONE;
16975 })
16976
16977 (define_insn "fyl2xxf3_i387"
16978   [(set (match_operand:XF 0 "register_operand" "=f")
16979         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16980                     (match_operand:XF 2 "register_operand" "u")]
16981                    UNSPEC_FYL2X))
16982    (clobber (match_scratch:XF 3 "=2"))]
16983   "TARGET_USE_FANCY_MATH_387
16984    && flag_unsafe_math_optimizations"
16985   "fyl2x"
16986   [(set_attr "type" "fpspc")
16987    (set_attr "mode" "XF")])
16988
16989 (define_insn "fyl2x_extend<mode>xf3_i387"
16990   [(set (match_operand:XF 0 "register_operand" "=f")
16991         (unspec:XF [(float_extend:XF
16992                       (match_operand:MODEF 1 "register_operand" "0"))
16993                     (match_operand:XF 2 "register_operand" "u")]
16994                    UNSPEC_FYL2X))
16995    (clobber (match_scratch:XF 3 "=2"))]
16996   "TARGET_USE_FANCY_MATH_387
16997    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16998        || TARGET_MIX_SSE_I387)
16999    && flag_unsafe_math_optimizations"
17000   "fyl2x"
17001   [(set_attr "type" "fpspc")
17002    (set_attr "mode" "XF")])
17003
17004 (define_expand "logxf2"
17005   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17006                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17007                                (match_dup 2)] UNSPEC_FYL2X))
17008               (clobber (match_scratch:XF 3 ""))])]
17009   "TARGET_USE_FANCY_MATH_387
17010    && flag_unsafe_math_optimizations"
17011 {
17012   operands[2] = gen_reg_rtx (XFmode);
17013   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17014 })
17015
17016 (define_expand "log<mode>2"
17017   [(use (match_operand:MODEF 0 "register_operand" ""))
17018    (use (match_operand:MODEF 1 "register_operand" ""))]
17019   "TARGET_USE_FANCY_MATH_387
17020    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17021        || TARGET_MIX_SSE_I387)
17022    && flag_unsafe_math_optimizations"
17023 {
17024   rtx op0 = gen_reg_rtx (XFmode);
17025
17026   rtx op2 = gen_reg_rtx (XFmode);
17027   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17028
17029   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17030   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17031   DONE;
17032 })
17033
17034 (define_expand "log10xf2"
17035   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17036                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17037                                (match_dup 2)] UNSPEC_FYL2X))
17038               (clobber (match_scratch:XF 3 ""))])]
17039   "TARGET_USE_FANCY_MATH_387
17040    && flag_unsafe_math_optimizations"
17041 {
17042   operands[2] = gen_reg_rtx (XFmode);
17043   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17044 })
17045
17046 (define_expand "log10<mode>2"
17047   [(use (match_operand:MODEF 0 "register_operand" ""))
17048    (use (match_operand:MODEF 1 "register_operand" ""))]
17049   "TARGET_USE_FANCY_MATH_387
17050    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17051        || TARGET_MIX_SSE_I387)
17052    && flag_unsafe_math_optimizations"
17053 {
17054   rtx op0 = gen_reg_rtx (XFmode);
17055
17056   rtx op2 = gen_reg_rtx (XFmode);
17057   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17058
17059   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17060   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17061   DONE;
17062 })
17063
17064 (define_expand "log2xf2"
17065   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17066                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17067                                (match_dup 2)] UNSPEC_FYL2X))
17068               (clobber (match_scratch:XF 3 ""))])]
17069   "TARGET_USE_FANCY_MATH_387
17070    && flag_unsafe_math_optimizations"
17071 {
17072   operands[2] = gen_reg_rtx (XFmode);
17073   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17074 })
17075
17076 (define_expand "log2<mode>2"
17077   [(use (match_operand:MODEF 0 "register_operand" ""))
17078    (use (match_operand:MODEF 1 "register_operand" ""))]
17079   "TARGET_USE_FANCY_MATH_387
17080    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17081        || TARGET_MIX_SSE_I387)
17082    && flag_unsafe_math_optimizations"
17083 {
17084   rtx op0 = gen_reg_rtx (XFmode);
17085
17086   rtx op2 = gen_reg_rtx (XFmode);
17087   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17088
17089   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17090   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17091   DONE;
17092 })
17093
17094 (define_insn "fyl2xp1xf3_i387"
17095   [(set (match_operand:XF 0 "register_operand" "=f")
17096         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17097                     (match_operand:XF 2 "register_operand" "u")]
17098                    UNSPEC_FYL2XP1))
17099    (clobber (match_scratch:XF 3 "=2"))]
17100   "TARGET_USE_FANCY_MATH_387
17101    && flag_unsafe_math_optimizations"
17102   "fyl2xp1"
17103   [(set_attr "type" "fpspc")
17104    (set_attr "mode" "XF")])
17105
17106 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17107   [(set (match_operand:XF 0 "register_operand" "=f")
17108         (unspec:XF [(float_extend:XF
17109                       (match_operand:MODEF 1 "register_operand" "0"))
17110                     (match_operand:XF 2 "register_operand" "u")]
17111                    UNSPEC_FYL2XP1))
17112    (clobber (match_scratch:XF 3 "=2"))]
17113   "TARGET_USE_FANCY_MATH_387
17114    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17115        || TARGET_MIX_SSE_I387)
17116    && flag_unsafe_math_optimizations"
17117   "fyl2xp1"
17118   [(set_attr "type" "fpspc")
17119    (set_attr "mode" "XF")])
17120
17121 (define_expand "log1pxf2"
17122   [(use (match_operand:XF 0 "register_operand" ""))
17123    (use (match_operand:XF 1 "register_operand" ""))]
17124   "TARGET_USE_FANCY_MATH_387
17125    && flag_unsafe_math_optimizations && !optimize_size"
17126 {
17127   ix86_emit_i387_log1p (operands[0], operands[1]);
17128   DONE;
17129 })
17130
17131 (define_expand "log1p<mode>2"
17132   [(use (match_operand:MODEF 0 "register_operand" ""))
17133    (use (match_operand:MODEF 1 "register_operand" ""))]
17134   "TARGET_USE_FANCY_MATH_387
17135    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17136        || TARGET_MIX_SSE_I387)
17137    && flag_unsafe_math_optimizations && !optimize_size"
17138 {
17139   rtx op0 = gen_reg_rtx (XFmode);
17140
17141   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17142
17143   ix86_emit_i387_log1p (op0, operands[1]);
17144   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17145   DONE;
17146 })
17147
17148 (define_insn "fxtractxf3_i387"
17149   [(set (match_operand:XF 0 "register_operand" "=f")
17150         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17151                    UNSPEC_XTRACT_FRACT))
17152    (set (match_operand:XF 1 "register_operand" "=u")
17153         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17154   "TARGET_USE_FANCY_MATH_387
17155    && flag_unsafe_math_optimizations"
17156   "fxtract"
17157   [(set_attr "type" "fpspc")
17158    (set_attr "mode" "XF")])
17159
17160 (define_insn "fxtract_extend<mode>xf3_i387"
17161   [(set (match_operand:XF 0 "register_operand" "=f")
17162         (unspec:XF [(float_extend:XF
17163                       (match_operand:MODEF 2 "register_operand" "0"))]
17164                    UNSPEC_XTRACT_FRACT))
17165    (set (match_operand:XF 1 "register_operand" "=u")
17166         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
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   "fxtract"
17172   [(set_attr "type" "fpspc")
17173    (set_attr "mode" "XF")])
17174
17175 (define_expand "logbxf2"
17176   [(parallel [(set (match_dup 2)
17177                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17178                               UNSPEC_XTRACT_FRACT))
17179               (set (match_operand:XF 0 "register_operand" "")
17180                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17181   "TARGET_USE_FANCY_MATH_387
17182    && flag_unsafe_math_optimizations"
17183 {
17184   operands[2] = gen_reg_rtx (XFmode);
17185 })
17186
17187 (define_expand "logb<mode>2"
17188   [(use (match_operand:MODEF 0 "register_operand" ""))
17189    (use (match_operand:MODEF 1 "register_operand" ""))]
17190   "TARGET_USE_FANCY_MATH_387
17191    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17192        || TARGET_MIX_SSE_I387)
17193    && flag_unsafe_math_optimizations"
17194 {
17195   rtx op0 = gen_reg_rtx (XFmode);
17196   rtx op1 = gen_reg_rtx (XFmode);
17197
17198   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17199   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17200   DONE;
17201 })
17202
17203 (define_expand "ilogbxf2"
17204   [(use (match_operand:SI 0 "register_operand" ""))
17205    (use (match_operand:XF 1 "register_operand" ""))]
17206   "TARGET_USE_FANCY_MATH_387
17207    && flag_unsafe_math_optimizations && !optimize_size"
17208 {
17209   rtx op0 = gen_reg_rtx (XFmode);
17210   rtx op1 = gen_reg_rtx (XFmode);
17211
17212   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17213   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17214   DONE;
17215 })
17216
17217 (define_expand "ilogb<mode>2"
17218   [(use (match_operand:SI 0 "register_operand" ""))
17219    (use (match_operand:MODEF 1 "register_operand" ""))]
17220   "TARGET_USE_FANCY_MATH_387
17221    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17222        || TARGET_MIX_SSE_I387)
17223    && flag_unsafe_math_optimizations && !optimize_size"
17224 {
17225   rtx op0 = gen_reg_rtx (XFmode);
17226   rtx op1 = gen_reg_rtx (XFmode);
17227
17228   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17229   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17230   DONE;
17231 })
17232
17233 (define_insn "*f2xm1xf2_i387"
17234   [(set (match_operand:XF 0 "register_operand" "=f")
17235         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17236                    UNSPEC_F2XM1))]
17237   "TARGET_USE_FANCY_MATH_387
17238    && flag_unsafe_math_optimizations"
17239   "f2xm1"
17240   [(set_attr "type" "fpspc")
17241    (set_attr "mode" "XF")])
17242
17243 (define_insn "*fscalexf4_i387"
17244   [(set (match_operand:XF 0 "register_operand" "=f")
17245         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17246                     (match_operand:XF 3 "register_operand" "1")]
17247                    UNSPEC_FSCALE_FRACT))
17248    (set (match_operand:XF 1 "register_operand" "=u")
17249         (unspec:XF [(match_dup 2) (match_dup 3)]
17250                    UNSPEC_FSCALE_EXP))]
17251   "TARGET_USE_FANCY_MATH_387
17252    && flag_unsafe_math_optimizations"
17253   "fscale"
17254   [(set_attr "type" "fpspc")
17255    (set_attr "mode" "XF")])
17256
17257 (define_expand "expNcorexf3"
17258   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17259                                (match_operand:XF 2 "register_operand" "")))
17260    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17261    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17262    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17263    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17264    (parallel [(set (match_operand:XF 0 "register_operand" "")
17265                    (unspec:XF [(match_dup 8) (match_dup 4)]
17266                               UNSPEC_FSCALE_FRACT))
17267               (set (match_dup 9)
17268                    (unspec:XF [(match_dup 8) (match_dup 4)]
17269                               UNSPEC_FSCALE_EXP))])]
17270   "TARGET_USE_FANCY_MATH_387
17271    && flag_unsafe_math_optimizations && !optimize_size"
17272 {
17273   int i;
17274
17275   for (i = 3; i < 10; i++)
17276     operands[i] = gen_reg_rtx (XFmode);
17277
17278   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17279 })
17280
17281 (define_expand "expxf2"
17282   [(use (match_operand:XF 0 "register_operand" ""))
17283    (use (match_operand:XF 1 "register_operand" ""))]
17284   "TARGET_USE_FANCY_MATH_387
17285    && flag_unsafe_math_optimizations && !optimize_size"
17286 {
17287   rtx op2 = gen_reg_rtx (XFmode);
17288   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17289
17290   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17291   DONE;
17292 })
17293
17294 (define_expand "exp<mode>2"
17295   [(use (match_operand:MODEF 0 "register_operand" ""))
17296    (use (match_operand:MODEF 1 "general_operand" ""))]
17297  "TARGET_USE_FANCY_MATH_387
17298    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17299        || TARGET_MIX_SSE_I387)
17300    && flag_unsafe_math_optimizations && !optimize_size"
17301 {
17302   rtx op0 = gen_reg_rtx (XFmode);
17303   rtx op1 = gen_reg_rtx (XFmode);
17304
17305   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17306   emit_insn (gen_expxf2 (op0, op1));
17307   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17308   DONE;
17309 })
17310
17311 (define_expand "exp10xf2"
17312   [(use (match_operand:XF 0 "register_operand" ""))
17313    (use (match_operand:XF 1 "register_operand" ""))]
17314   "TARGET_USE_FANCY_MATH_387
17315    && flag_unsafe_math_optimizations && !optimize_size"
17316 {
17317   rtx op2 = gen_reg_rtx (XFmode);
17318   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17319
17320   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17321   DONE;
17322 })
17323
17324 (define_expand "exp10<mode>2"
17325   [(use (match_operand:MODEF 0 "register_operand" ""))
17326    (use (match_operand:MODEF 1 "general_operand" ""))]
17327  "TARGET_USE_FANCY_MATH_387
17328    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17329        || TARGET_MIX_SSE_I387)
17330    && flag_unsafe_math_optimizations && !optimize_size"
17331 {
17332   rtx op0 = gen_reg_rtx (XFmode);
17333   rtx op1 = gen_reg_rtx (XFmode);
17334
17335   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17336   emit_insn (gen_exp10xf2 (op0, op1));
17337   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17338   DONE;
17339 })
17340
17341 (define_expand "exp2xf2"
17342   [(use (match_operand:XF 0 "register_operand" ""))
17343    (use (match_operand:XF 1 "register_operand" ""))]
17344   "TARGET_USE_FANCY_MATH_387
17345    && flag_unsafe_math_optimizations && !optimize_size"
17346 {
17347   rtx op2 = gen_reg_rtx (XFmode);
17348   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17349
17350   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17351   DONE;
17352 })
17353
17354 (define_expand "exp2<mode>2"
17355   [(use (match_operand:MODEF 0 "register_operand" ""))
17356    (use (match_operand:MODEF 1 "general_operand" ""))]
17357  "TARGET_USE_FANCY_MATH_387
17358    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17359        || TARGET_MIX_SSE_I387)
17360    && flag_unsafe_math_optimizations && !optimize_size"
17361 {
17362   rtx op0 = gen_reg_rtx (XFmode);
17363   rtx op1 = gen_reg_rtx (XFmode);
17364
17365   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17366   emit_insn (gen_exp2xf2 (op0, op1));
17367   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17368   DONE;
17369 })
17370
17371 (define_expand "expm1xf2"
17372   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17373                                (match_dup 2)))
17374    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17375    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17376    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17377    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17378    (parallel [(set (match_dup 7)
17379                    (unspec:XF [(match_dup 6) (match_dup 4)]
17380                               UNSPEC_FSCALE_FRACT))
17381               (set (match_dup 8)
17382                    (unspec:XF [(match_dup 6) (match_dup 4)]
17383                               UNSPEC_FSCALE_EXP))])
17384    (parallel [(set (match_dup 10)
17385                    (unspec:XF [(match_dup 9) (match_dup 8)]
17386                               UNSPEC_FSCALE_FRACT))
17387               (set (match_dup 11)
17388                    (unspec:XF [(match_dup 9) (match_dup 8)]
17389                               UNSPEC_FSCALE_EXP))])
17390    (set (match_dup 12) (minus:XF (match_dup 10)
17391                                  (float_extend:XF (match_dup 13))))
17392    (set (match_operand:XF 0 "register_operand" "")
17393         (plus:XF (match_dup 12) (match_dup 7)))]
17394   "TARGET_USE_FANCY_MATH_387
17395    && flag_unsafe_math_optimizations && !optimize_size"
17396 {
17397   int i;
17398
17399   for (i = 2; i < 13; i++)
17400     operands[i] = gen_reg_rtx (XFmode);
17401
17402   operands[13]
17403     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17404
17405   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17406 })
17407
17408 (define_expand "expm1<mode>2"
17409   [(use (match_operand:MODEF 0 "register_operand" ""))
17410    (use (match_operand:MODEF 1 "general_operand" ""))]
17411  "TARGET_USE_FANCY_MATH_387
17412    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17413        || TARGET_MIX_SSE_I387)
17414    && flag_unsafe_math_optimizations && !optimize_size"
17415 {
17416   rtx op0 = gen_reg_rtx (XFmode);
17417   rtx op1 = gen_reg_rtx (XFmode);
17418
17419   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17420   emit_insn (gen_expm1xf2 (op0, op1));
17421   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17422   DONE;
17423 })
17424
17425 (define_expand "ldexpxf3"
17426   [(set (match_dup 3)
17427         (float:XF (match_operand:SI 2 "register_operand" "")))
17428    (parallel [(set (match_operand:XF 0 " register_operand" "")
17429                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17430                                (match_dup 3)]
17431                               UNSPEC_FSCALE_FRACT))
17432               (set (match_dup 4)
17433                    (unspec:XF [(match_dup 1) (match_dup 3)]
17434                               UNSPEC_FSCALE_EXP))])]
17435   "TARGET_USE_FANCY_MATH_387
17436    && flag_unsafe_math_optimizations && !optimize_size"
17437 {
17438   operands[3] = gen_reg_rtx (XFmode);
17439   operands[4] = gen_reg_rtx (XFmode);
17440 })
17441
17442 (define_expand "ldexp<mode>3"
17443   [(use (match_operand:MODEF 0 "register_operand" ""))
17444    (use (match_operand:MODEF 1 "general_operand" ""))
17445    (use (match_operand:SI 2 "register_operand" ""))]
17446  "TARGET_USE_FANCY_MATH_387
17447    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17448        || TARGET_MIX_SSE_I387)
17449    && flag_unsafe_math_optimizations && !optimize_size"
17450 {
17451   rtx op0 = gen_reg_rtx (XFmode);
17452   rtx op1 = gen_reg_rtx (XFmode);
17453
17454   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17455   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17456   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17457   DONE;
17458 })
17459
17460 (define_expand "scalbxf3"
17461   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17462                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17463                                (match_operand:XF 2 "register_operand" "")]
17464                               UNSPEC_FSCALE_FRACT))
17465               (set (match_dup 3)
17466                    (unspec:XF [(match_dup 1) (match_dup 2)]
17467                               UNSPEC_FSCALE_EXP))])]
17468   "TARGET_USE_FANCY_MATH_387
17469    && flag_unsafe_math_optimizations && !optimize_size"
17470 {
17471   operands[3] = gen_reg_rtx (XFmode);
17472 })
17473
17474 (define_expand "scalb<mode>3"
17475   [(use (match_operand:MODEF 0 "register_operand" ""))
17476    (use (match_operand:MODEF 1 "general_operand" ""))
17477    (use (match_operand:MODEF 2 "register_operand" ""))]
17478  "TARGET_USE_FANCY_MATH_387
17479    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17480        || TARGET_MIX_SSE_I387)
17481    && flag_unsafe_math_optimizations && !optimize_size"
17482 {
17483   rtx op0 = gen_reg_rtx (XFmode);
17484   rtx op1 = gen_reg_rtx (XFmode);
17485   rtx op2 = gen_reg_rtx (XFmode);
17486
17487   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17488   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17489   emit_insn (gen_scalbxf3 (op0, op1, op2));
17490   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17491   DONE;
17492 })
17493 \f
17494
17495 (define_insn "sse4_1_round<mode>2"
17496   [(set (match_operand:MODEF 0 "register_operand" "=x")
17497         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17498                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17499                       UNSPEC_ROUND))]
17500   "TARGET_SSE4_1"
17501   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17502   [(set_attr "type" "ssecvt")
17503    (set_attr "prefix_extra" "1")
17504    (set_attr "mode" "<MODE>")])
17505
17506 (define_insn "rintxf2"
17507   [(set (match_operand:XF 0 "register_operand" "=f")
17508         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17509                    UNSPEC_FRNDINT))]
17510   "TARGET_USE_FANCY_MATH_387
17511    && flag_unsafe_math_optimizations"
17512   "frndint"
17513   [(set_attr "type" "fpspc")
17514    (set_attr "mode" "XF")])
17515
17516 (define_expand "rint<mode>2"
17517   [(use (match_operand:MODEF 0 "register_operand" ""))
17518    (use (match_operand:MODEF 1 "register_operand" ""))]
17519   "(TARGET_USE_FANCY_MATH_387
17520     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17521         || TARGET_MIX_SSE_I387)
17522     && flag_unsafe_math_optimizations)
17523    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17524        && !flag_trapping_math
17525        && (TARGET_SSE4_1 || !optimize_size))"
17526 {
17527   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17528       && !flag_trapping_math
17529       && (TARGET_SSE4_1 || !optimize_size))
17530     {
17531       if (TARGET_SSE4_1)
17532         emit_insn (gen_sse4_1_round<mode>2
17533                    (operands[0], operands[1], GEN_INT (0x04)));
17534       else
17535         ix86_expand_rint (operand0, operand1);
17536     }
17537   else
17538     {
17539       rtx op0 = gen_reg_rtx (XFmode);
17540       rtx op1 = gen_reg_rtx (XFmode);
17541
17542       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17543       emit_insn (gen_rintxf2 (op0, op1));
17544
17545       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17546     }
17547   DONE;
17548 })
17549
17550 (define_expand "round<mode>2"
17551   [(match_operand:MODEF 0 "register_operand" "")
17552    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17553   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17554    && !flag_trapping_math && !flag_rounding_math
17555    && !optimize_size"
17556 {
17557   if (TARGET_64BIT || (<MODE>mode != DFmode))
17558     ix86_expand_round (operand0, operand1);
17559   else
17560     ix86_expand_rounddf_32 (operand0, operand1);
17561   DONE;
17562 })
17563
17564 (define_insn_and_split "*fistdi2_1"
17565   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17566         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17567                    UNSPEC_FIST))]
17568   "TARGET_USE_FANCY_MATH_387
17569    && !(reload_completed || reload_in_progress)"
17570   "#"
17571   "&& 1"
17572   [(const_int 0)]
17573 {
17574   if (memory_operand (operands[0], VOIDmode))
17575     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17576   else
17577     {
17578       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17579       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17580                                          operands[2]));
17581     }
17582   DONE;
17583 }
17584   [(set_attr "type" "fpspc")
17585    (set_attr "mode" "DI")])
17586
17587 (define_insn "fistdi2"
17588   [(set (match_operand:DI 0 "memory_operand" "=m")
17589         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17590                    UNSPEC_FIST))
17591    (clobber (match_scratch:XF 2 "=&1f"))]
17592   "TARGET_USE_FANCY_MATH_387"
17593   "* return output_fix_trunc (insn, operands, 0);"
17594   [(set_attr "type" "fpspc")
17595    (set_attr "mode" "DI")])
17596
17597 (define_insn "fistdi2_with_temp"
17598   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17599         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17600                    UNSPEC_FIST))
17601    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17602    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17603   "TARGET_USE_FANCY_MATH_387"
17604   "#"
17605   [(set_attr "type" "fpspc")
17606    (set_attr "mode" "DI")])
17607
17608 (define_split
17609   [(set (match_operand:DI 0 "register_operand" "")
17610         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17611                    UNSPEC_FIST))
17612    (clobber (match_operand:DI 2 "memory_operand" ""))
17613    (clobber (match_scratch 3 ""))]
17614   "reload_completed"
17615   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17616               (clobber (match_dup 3))])
17617    (set (match_dup 0) (match_dup 2))]
17618   "")
17619
17620 (define_split
17621   [(set (match_operand:DI 0 "memory_operand" "")
17622         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17623                    UNSPEC_FIST))
17624    (clobber (match_operand:DI 2 "memory_operand" ""))
17625    (clobber (match_scratch 3 ""))]
17626   "reload_completed"
17627   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17628               (clobber (match_dup 3))])]
17629   "")
17630
17631 (define_insn_and_split "*fist<mode>2_1"
17632   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17633         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17634                            UNSPEC_FIST))]
17635   "TARGET_USE_FANCY_MATH_387
17636    && !(reload_completed || reload_in_progress)"
17637   "#"
17638   "&& 1"
17639   [(const_int 0)]
17640 {
17641   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17642   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17643                                         operands[2]));
17644   DONE;
17645 }
17646   [(set_attr "type" "fpspc")
17647    (set_attr "mode" "<MODE>")])
17648
17649 (define_insn "fist<mode>2"
17650   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17651         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17652                            UNSPEC_FIST))]
17653   "TARGET_USE_FANCY_MATH_387"
17654   "* return output_fix_trunc (insn, operands, 0);"
17655   [(set_attr "type" "fpspc")
17656    (set_attr "mode" "<MODE>")])
17657
17658 (define_insn "fist<mode>2_with_temp"
17659   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17660         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17661                            UNSPEC_FIST))
17662    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17663   "TARGET_USE_FANCY_MATH_387"
17664   "#"
17665   [(set_attr "type" "fpspc")
17666    (set_attr "mode" "<MODE>")])
17667
17668 (define_split
17669   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17670         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17671                            UNSPEC_FIST))
17672    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17673   "reload_completed"
17674   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17675    (set (match_dup 0) (match_dup 2))]
17676   "")
17677
17678 (define_split
17679   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17680         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17681                            UNSPEC_FIST))
17682    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17683   "reload_completed"
17684   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17685   "")
17686
17687 (define_expand "lrintxf<mode>2"
17688   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17689      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17690                       UNSPEC_FIST))]
17691   "TARGET_USE_FANCY_MATH_387"
17692   "")
17693
17694 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17695   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17696      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17697                         UNSPEC_FIX_NOTRUNC))]
17698   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17699    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17700   "")
17701
17702 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17703   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17704    (match_operand:MODEF 1 "register_operand" "")]
17705   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17706    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17707    && !flag_trapping_math && !flag_rounding_math
17708    && !optimize_size"
17709 {
17710   ix86_expand_lround (operand0, operand1);
17711   DONE;
17712 })
17713
17714 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17715 (define_insn_and_split "frndintxf2_floor"
17716   [(set (match_operand:XF 0 "register_operand" "")
17717         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17718          UNSPEC_FRNDINT_FLOOR))
17719    (clobber (reg:CC FLAGS_REG))]
17720   "TARGET_USE_FANCY_MATH_387
17721    && flag_unsafe_math_optimizations
17722    && !(reload_completed || reload_in_progress)"
17723   "#"
17724   "&& 1"
17725   [(const_int 0)]
17726 {
17727   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17728
17729   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17730   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17731
17732   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17733                                         operands[2], operands[3]));
17734   DONE;
17735 }
17736   [(set_attr "type" "frndint")
17737    (set_attr "i387_cw" "floor")
17738    (set_attr "mode" "XF")])
17739
17740 (define_insn "frndintxf2_floor_i387"
17741   [(set (match_operand:XF 0 "register_operand" "=f")
17742         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17743          UNSPEC_FRNDINT_FLOOR))
17744    (use (match_operand:HI 2 "memory_operand" "m"))
17745    (use (match_operand:HI 3 "memory_operand" "m"))]
17746   "TARGET_USE_FANCY_MATH_387
17747    && flag_unsafe_math_optimizations"
17748   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17749   [(set_attr "type" "frndint")
17750    (set_attr "i387_cw" "floor")
17751    (set_attr "mode" "XF")])
17752
17753 (define_expand "floorxf2"
17754   [(use (match_operand:XF 0 "register_operand" ""))
17755    (use (match_operand:XF 1 "register_operand" ""))]
17756   "TARGET_USE_FANCY_MATH_387
17757    && flag_unsafe_math_optimizations && !optimize_size"
17758 {
17759   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17760   DONE;
17761 })
17762
17763 (define_expand "floor<mode>2"
17764   [(use (match_operand:MODEF 0 "register_operand" ""))
17765    (use (match_operand:MODEF 1 "register_operand" ""))]
17766   "(TARGET_USE_FANCY_MATH_387
17767     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17768         || TARGET_MIX_SSE_I387)
17769     && flag_unsafe_math_optimizations && !optimize_size)
17770    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17771        && !flag_trapping_math
17772        && (TARGET_SSE4_1 || !optimize_size))"
17773 {
17774   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17775       && !flag_trapping_math
17776       && (TARGET_SSE4_1 || !optimize_size))
17777     {
17778       if (TARGET_SSE4_1)
17779         emit_insn (gen_sse4_1_round<mode>2
17780                    (operands[0], operands[1], GEN_INT (0x01)));
17781       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17782         ix86_expand_floorceil (operand0, operand1, true);
17783       else
17784         ix86_expand_floorceildf_32 (operand0, operand1, true);
17785     }
17786   else
17787     {
17788       rtx op0 = gen_reg_rtx (XFmode);
17789       rtx op1 = gen_reg_rtx (XFmode);
17790
17791       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17792       emit_insn (gen_frndintxf2_floor (op0, op1));
17793
17794       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17795     }
17796   DONE;
17797 })
17798
17799 (define_insn_and_split "*fist<mode>2_floor_1"
17800   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17801         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17802          UNSPEC_FIST_FLOOR))
17803    (clobber (reg:CC FLAGS_REG))]
17804   "TARGET_USE_FANCY_MATH_387
17805    && flag_unsafe_math_optimizations
17806    && !(reload_completed || reload_in_progress)"
17807   "#"
17808   "&& 1"
17809   [(const_int 0)]
17810 {
17811   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17812
17813   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17814   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17815   if (memory_operand (operands[0], VOIDmode))
17816     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17817                                       operands[2], operands[3]));
17818   else
17819     {
17820       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17821       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17822                                                   operands[2], operands[3],
17823                                                   operands[4]));
17824     }
17825   DONE;
17826 }
17827   [(set_attr "type" "fistp")
17828    (set_attr "i387_cw" "floor")
17829    (set_attr "mode" "<MODE>")])
17830
17831 (define_insn "fistdi2_floor"
17832   [(set (match_operand:DI 0 "memory_operand" "=m")
17833         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17834          UNSPEC_FIST_FLOOR))
17835    (use (match_operand:HI 2 "memory_operand" "m"))
17836    (use (match_operand:HI 3 "memory_operand" "m"))
17837    (clobber (match_scratch:XF 4 "=&1f"))]
17838   "TARGET_USE_FANCY_MATH_387
17839    && flag_unsafe_math_optimizations"
17840   "* return output_fix_trunc (insn, operands, 0);"
17841   [(set_attr "type" "fistp")
17842    (set_attr "i387_cw" "floor")
17843    (set_attr "mode" "DI")])
17844
17845 (define_insn "fistdi2_floor_with_temp"
17846   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17847         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17848          UNSPEC_FIST_FLOOR))
17849    (use (match_operand:HI 2 "memory_operand" "m,m"))
17850    (use (match_operand:HI 3 "memory_operand" "m,m"))
17851    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17852    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17853   "TARGET_USE_FANCY_MATH_387
17854    && flag_unsafe_math_optimizations"
17855   "#"
17856   [(set_attr "type" "fistp")
17857    (set_attr "i387_cw" "floor")
17858    (set_attr "mode" "DI")])
17859
17860 (define_split
17861   [(set (match_operand:DI 0 "register_operand" "")
17862         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17863          UNSPEC_FIST_FLOOR))
17864    (use (match_operand:HI 2 "memory_operand" ""))
17865    (use (match_operand:HI 3 "memory_operand" ""))
17866    (clobber (match_operand:DI 4 "memory_operand" ""))
17867    (clobber (match_scratch 5 ""))]
17868   "reload_completed"
17869   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17870               (use (match_dup 2))
17871               (use (match_dup 3))
17872               (clobber (match_dup 5))])
17873    (set (match_dup 0) (match_dup 4))]
17874   "")
17875
17876 (define_split
17877   [(set (match_operand:DI 0 "memory_operand" "")
17878         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17879          UNSPEC_FIST_FLOOR))
17880    (use (match_operand:HI 2 "memory_operand" ""))
17881    (use (match_operand:HI 3 "memory_operand" ""))
17882    (clobber (match_operand:DI 4 "memory_operand" ""))
17883    (clobber (match_scratch 5 ""))]
17884   "reload_completed"
17885   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17886               (use (match_dup 2))
17887               (use (match_dup 3))
17888               (clobber (match_dup 5))])]
17889   "")
17890
17891 (define_insn "fist<mode>2_floor"
17892   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17893         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17894          UNSPEC_FIST_FLOOR))
17895    (use (match_operand:HI 2 "memory_operand" "m"))
17896    (use (match_operand:HI 3 "memory_operand" "m"))]
17897   "TARGET_USE_FANCY_MATH_387
17898    && flag_unsafe_math_optimizations"
17899   "* return output_fix_trunc (insn, operands, 0);"
17900   [(set_attr "type" "fistp")
17901    (set_attr "i387_cw" "floor")
17902    (set_attr "mode" "<MODE>")])
17903
17904 (define_insn "fist<mode>2_floor_with_temp"
17905   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17906         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17907          UNSPEC_FIST_FLOOR))
17908    (use (match_operand:HI 2 "memory_operand" "m,m"))
17909    (use (match_operand:HI 3 "memory_operand" "m,m"))
17910    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17911   "TARGET_USE_FANCY_MATH_387
17912    && flag_unsafe_math_optimizations"
17913   "#"
17914   [(set_attr "type" "fistp")
17915    (set_attr "i387_cw" "floor")
17916    (set_attr "mode" "<MODE>")])
17917
17918 (define_split
17919   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17920         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17921          UNSPEC_FIST_FLOOR))
17922    (use (match_operand:HI 2 "memory_operand" ""))
17923    (use (match_operand:HI 3 "memory_operand" ""))
17924    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17925   "reload_completed"
17926   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17927                                   UNSPEC_FIST_FLOOR))
17928               (use (match_dup 2))
17929               (use (match_dup 3))])
17930    (set (match_dup 0) (match_dup 4))]
17931   "")
17932
17933 (define_split
17934   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17935         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17936          UNSPEC_FIST_FLOOR))
17937    (use (match_operand:HI 2 "memory_operand" ""))
17938    (use (match_operand:HI 3 "memory_operand" ""))
17939    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17940   "reload_completed"
17941   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17942                                   UNSPEC_FIST_FLOOR))
17943               (use (match_dup 2))
17944               (use (match_dup 3))])]
17945   "")
17946
17947 (define_expand "lfloorxf<mode>2"
17948   [(parallel [(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    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17954    && flag_unsafe_math_optimizations"
17955   "")
17956
17957 (define_expand "lfloor<mode>di2"
17958   [(match_operand:DI 0 "nonimmediate_operand" "")
17959    (match_operand:MODEF 1 "register_operand" "")]
17960   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17961    && !flag_trapping_math
17962    && !optimize_size"
17963 {
17964   ix86_expand_lfloorceil (operand0, operand1, true);
17965   DONE;
17966 })
17967
17968 (define_expand "lfloor<mode>si2"
17969   [(match_operand:SI 0 "nonimmediate_operand" "")
17970    (match_operand:MODEF 1 "register_operand" "")]
17971   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17972    && !flag_trapping_math
17973    && (!optimize_size || !TARGET_64BIT)"
17974 {
17975   ix86_expand_lfloorceil (operand0, operand1, true);
17976   DONE;
17977 })
17978
17979 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17980 (define_insn_and_split "frndintxf2_ceil"
17981   [(set (match_operand:XF 0 "register_operand" "")
17982         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17983          UNSPEC_FRNDINT_CEIL))
17984    (clobber (reg:CC FLAGS_REG))]
17985   "TARGET_USE_FANCY_MATH_387
17986    && flag_unsafe_math_optimizations
17987    && !(reload_completed || reload_in_progress)"
17988   "#"
17989   "&& 1"
17990   [(const_int 0)]
17991 {
17992   ix86_optimize_mode_switching[I387_CEIL] = 1;
17993
17994   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17995   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17996
17997   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17998                                        operands[2], operands[3]));
17999   DONE;
18000 }
18001   [(set_attr "type" "frndint")
18002    (set_attr "i387_cw" "ceil")
18003    (set_attr "mode" "XF")])
18004
18005 (define_insn "frndintxf2_ceil_i387"
18006   [(set (match_operand:XF 0 "register_operand" "=f")
18007         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18008          UNSPEC_FRNDINT_CEIL))
18009    (use (match_operand:HI 2 "memory_operand" "m"))
18010    (use (match_operand:HI 3 "memory_operand" "m"))]
18011   "TARGET_USE_FANCY_MATH_387
18012    && flag_unsafe_math_optimizations"
18013   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18014   [(set_attr "type" "frndint")
18015    (set_attr "i387_cw" "ceil")
18016    (set_attr "mode" "XF")])
18017
18018 (define_expand "ceilxf2"
18019   [(use (match_operand:XF 0 "register_operand" ""))
18020    (use (match_operand:XF 1 "register_operand" ""))]
18021   "TARGET_USE_FANCY_MATH_387
18022    && flag_unsafe_math_optimizations && !optimize_size"
18023 {
18024   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18025   DONE;
18026 })
18027
18028 (define_expand "ceil<mode>2"
18029   [(use (match_operand:MODEF 0 "register_operand" ""))
18030    (use (match_operand:MODEF 1 "register_operand" ""))]
18031   "(TARGET_USE_FANCY_MATH_387
18032     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18033         || TARGET_MIX_SSE_I387)
18034     && flag_unsafe_math_optimizations && !optimize_size)
18035    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18036        && !flag_trapping_math
18037        && (TARGET_SSE4_1 || !optimize_size))"
18038 {
18039   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18040       && !flag_trapping_math
18041       && (TARGET_SSE4_1 || !optimize_size))
18042     {
18043       if (TARGET_SSE4_1)
18044         emit_insn (gen_sse4_1_round<mode>2
18045                    (operands[0], operands[1], GEN_INT (0x02)));
18046       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18047         ix86_expand_floorceil (operand0, operand1, false);
18048       else
18049         ix86_expand_floorceildf_32 (operand0, operand1, false);
18050     }
18051   else
18052     {
18053       rtx op0 = gen_reg_rtx (XFmode);
18054       rtx op1 = gen_reg_rtx (XFmode);
18055
18056       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18057       emit_insn (gen_frndintxf2_ceil (op0, op1));
18058
18059       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18060     }
18061   DONE;
18062 })
18063
18064 (define_insn_and_split "*fist<mode>2_ceil_1"
18065   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18066         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18067          UNSPEC_FIST_CEIL))
18068    (clobber (reg:CC FLAGS_REG))]
18069   "TARGET_USE_FANCY_MATH_387
18070    && flag_unsafe_math_optimizations
18071    && !(reload_completed || reload_in_progress)"
18072   "#"
18073   "&& 1"
18074   [(const_int 0)]
18075 {
18076   ix86_optimize_mode_switching[I387_CEIL] = 1;
18077
18078   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18079   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18080   if (memory_operand (operands[0], VOIDmode))
18081     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18082                                      operands[2], operands[3]));
18083   else
18084     {
18085       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18086       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18087                                                  operands[2], operands[3],
18088                                                  operands[4]));
18089     }
18090   DONE;
18091 }
18092   [(set_attr "type" "fistp")
18093    (set_attr "i387_cw" "ceil")
18094    (set_attr "mode" "<MODE>")])
18095
18096 (define_insn "fistdi2_ceil"
18097   [(set (match_operand:DI 0 "memory_operand" "=m")
18098         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18099          UNSPEC_FIST_CEIL))
18100    (use (match_operand:HI 2 "memory_operand" "m"))
18101    (use (match_operand:HI 3 "memory_operand" "m"))
18102    (clobber (match_scratch:XF 4 "=&1f"))]
18103   "TARGET_USE_FANCY_MATH_387
18104    && flag_unsafe_math_optimizations"
18105   "* return output_fix_trunc (insn, operands, 0);"
18106   [(set_attr "type" "fistp")
18107    (set_attr "i387_cw" "ceil")
18108    (set_attr "mode" "DI")])
18109
18110 (define_insn "fistdi2_ceil_with_temp"
18111   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18112         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18113          UNSPEC_FIST_CEIL))
18114    (use (match_operand:HI 2 "memory_operand" "m,m"))
18115    (use (match_operand:HI 3 "memory_operand" "m,m"))
18116    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18117    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18118   "TARGET_USE_FANCY_MATH_387
18119    && flag_unsafe_math_optimizations"
18120   "#"
18121   [(set_attr "type" "fistp")
18122    (set_attr "i387_cw" "ceil")
18123    (set_attr "mode" "DI")])
18124
18125 (define_split
18126   [(set (match_operand:DI 0 "register_operand" "")
18127         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18128          UNSPEC_FIST_CEIL))
18129    (use (match_operand:HI 2 "memory_operand" ""))
18130    (use (match_operand:HI 3 "memory_operand" ""))
18131    (clobber (match_operand:DI 4 "memory_operand" ""))
18132    (clobber (match_scratch 5 ""))]
18133   "reload_completed"
18134   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18135               (use (match_dup 2))
18136               (use (match_dup 3))
18137               (clobber (match_dup 5))])
18138    (set (match_dup 0) (match_dup 4))]
18139   "")
18140
18141 (define_split
18142   [(set (match_operand:DI 0 "memory_operand" "")
18143         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18144          UNSPEC_FIST_CEIL))
18145    (use (match_operand:HI 2 "memory_operand" ""))
18146    (use (match_operand:HI 3 "memory_operand" ""))
18147    (clobber (match_operand:DI 4 "memory_operand" ""))
18148    (clobber (match_scratch 5 ""))]
18149   "reload_completed"
18150   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18151               (use (match_dup 2))
18152               (use (match_dup 3))
18153               (clobber (match_dup 5))])]
18154   "")
18155
18156 (define_insn "fist<mode>2_ceil"
18157   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18158         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18159          UNSPEC_FIST_CEIL))
18160    (use (match_operand:HI 2 "memory_operand" "m"))
18161    (use (match_operand:HI 3 "memory_operand" "m"))]
18162   "TARGET_USE_FANCY_MATH_387
18163    && flag_unsafe_math_optimizations"
18164   "* return output_fix_trunc (insn, operands, 0);"
18165   [(set_attr "type" "fistp")
18166    (set_attr "i387_cw" "ceil")
18167    (set_attr "mode" "<MODE>")])
18168
18169 (define_insn "fist<mode>2_ceil_with_temp"
18170   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18171         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18172          UNSPEC_FIST_CEIL))
18173    (use (match_operand:HI 2 "memory_operand" "m,m"))
18174    (use (match_operand:HI 3 "memory_operand" "m,m"))
18175    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18176   "TARGET_USE_FANCY_MATH_387
18177    && flag_unsafe_math_optimizations"
18178   "#"
18179   [(set_attr "type" "fistp")
18180    (set_attr "i387_cw" "ceil")
18181    (set_attr "mode" "<MODE>")])
18182
18183 (define_split
18184   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18185         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18186          UNSPEC_FIST_CEIL))
18187    (use (match_operand:HI 2 "memory_operand" ""))
18188    (use (match_operand:HI 3 "memory_operand" ""))
18189    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18190   "reload_completed"
18191   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18192                                   UNSPEC_FIST_CEIL))
18193               (use (match_dup 2))
18194               (use (match_dup 3))])
18195    (set (match_dup 0) (match_dup 4))]
18196   "")
18197
18198 (define_split
18199   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18200         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18201          UNSPEC_FIST_CEIL))
18202    (use (match_operand:HI 2 "memory_operand" ""))
18203    (use (match_operand:HI 3 "memory_operand" ""))
18204    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18205   "reload_completed"
18206   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18207                                   UNSPEC_FIST_CEIL))
18208               (use (match_dup 2))
18209               (use (match_dup 3))])]
18210   "")
18211
18212 (define_expand "lceilxf<mode>2"
18213   [(parallel [(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    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18219    && flag_unsafe_math_optimizations"
18220   "")
18221
18222 (define_expand "lceil<mode>di2"
18223   [(match_operand:DI 0 "nonimmediate_operand" "")
18224    (match_operand:MODEF 1 "register_operand" "")]
18225   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18226    && !flag_trapping_math"
18227 {
18228   ix86_expand_lfloorceil (operand0, operand1, false);
18229   DONE;
18230 })
18231
18232 (define_expand "lceil<mode>si2"
18233   [(match_operand:SI 0 "nonimmediate_operand" "")
18234    (match_operand:MODEF 1 "register_operand" "")]
18235   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18236    && !flag_trapping_math"
18237 {
18238   ix86_expand_lfloorceil (operand0, operand1, false);
18239   DONE;
18240 })
18241
18242 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18243 (define_insn_and_split "frndintxf2_trunc"
18244   [(set (match_operand:XF 0 "register_operand" "")
18245         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18246          UNSPEC_FRNDINT_TRUNC))
18247    (clobber (reg:CC FLAGS_REG))]
18248   "TARGET_USE_FANCY_MATH_387
18249    && flag_unsafe_math_optimizations
18250    && !(reload_completed || reload_in_progress)"
18251   "#"
18252   "&& 1"
18253   [(const_int 0)]
18254 {
18255   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18256
18257   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18258   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18259
18260   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18261                                         operands[2], operands[3]));
18262   DONE;
18263 }
18264   [(set_attr "type" "frndint")
18265    (set_attr "i387_cw" "trunc")
18266    (set_attr "mode" "XF")])
18267
18268 (define_insn "frndintxf2_trunc_i387"
18269   [(set (match_operand:XF 0 "register_operand" "=f")
18270         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18271          UNSPEC_FRNDINT_TRUNC))
18272    (use (match_operand:HI 2 "memory_operand" "m"))
18273    (use (match_operand:HI 3 "memory_operand" "m"))]
18274   "TARGET_USE_FANCY_MATH_387
18275    && flag_unsafe_math_optimizations"
18276   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18277   [(set_attr "type" "frndint")
18278    (set_attr "i387_cw" "trunc")
18279    (set_attr "mode" "XF")])
18280
18281 (define_expand "btruncxf2"
18282   [(use (match_operand:XF 0 "register_operand" ""))
18283    (use (match_operand:XF 1 "register_operand" ""))]
18284   "TARGET_USE_FANCY_MATH_387
18285    && flag_unsafe_math_optimizations && !optimize_size"
18286 {
18287   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18288   DONE;
18289 })
18290
18291 (define_expand "btrunc<mode>2"
18292   [(use (match_operand:MODEF 0 "register_operand" ""))
18293    (use (match_operand:MODEF 1 "register_operand" ""))]
18294   "(TARGET_USE_FANCY_MATH_387
18295     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18296         || TARGET_MIX_SSE_I387)
18297     && flag_unsafe_math_optimizations && !optimize_size)
18298    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18299        && !flag_trapping_math
18300        && (TARGET_SSE4_1 || !optimize_size))"
18301 {
18302   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18303       && !flag_trapping_math
18304       && (TARGET_SSE4_1 || !optimize_size))
18305     {
18306       if (TARGET_SSE4_1)
18307         emit_insn (gen_sse4_1_round<mode>2
18308                    (operands[0], operands[1], GEN_INT (0x03)));
18309       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18310         ix86_expand_trunc (operand0, operand1);
18311       else
18312         ix86_expand_truncdf_32 (operand0, operand1);
18313     }
18314   else
18315     {
18316       rtx op0 = gen_reg_rtx (XFmode);
18317       rtx op1 = gen_reg_rtx (XFmode);
18318
18319       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18320       emit_insn (gen_frndintxf2_trunc (op0, op1));
18321
18322       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18323     }
18324   DONE;
18325 })
18326
18327 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18328 (define_insn_and_split "frndintxf2_mask_pm"
18329   [(set (match_operand:XF 0 "register_operand" "")
18330         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18331          UNSPEC_FRNDINT_MASK_PM))
18332    (clobber (reg:CC FLAGS_REG))]
18333   "TARGET_USE_FANCY_MATH_387
18334    && flag_unsafe_math_optimizations
18335    && !(reload_completed || reload_in_progress)"
18336   "#"
18337   "&& 1"
18338   [(const_int 0)]
18339 {
18340   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18341
18342   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18343   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18344
18345   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18346                                           operands[2], operands[3]));
18347   DONE;
18348 }
18349   [(set_attr "type" "frndint")
18350    (set_attr "i387_cw" "mask_pm")
18351    (set_attr "mode" "XF")])
18352
18353 (define_insn "frndintxf2_mask_pm_i387"
18354   [(set (match_operand:XF 0 "register_operand" "=f")
18355         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18356          UNSPEC_FRNDINT_MASK_PM))
18357    (use (match_operand:HI 2 "memory_operand" "m"))
18358    (use (match_operand:HI 3 "memory_operand" "m"))]
18359   "TARGET_USE_FANCY_MATH_387
18360    && flag_unsafe_math_optimizations"
18361   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18362   [(set_attr "type" "frndint")
18363    (set_attr "i387_cw" "mask_pm")
18364    (set_attr "mode" "XF")])
18365
18366 (define_expand "nearbyintxf2"
18367   [(use (match_operand:XF 0 "register_operand" ""))
18368    (use (match_operand:XF 1 "register_operand" ""))]
18369   "TARGET_USE_FANCY_MATH_387
18370    && flag_unsafe_math_optimizations"
18371 {
18372   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18373
18374   DONE;
18375 })
18376
18377 (define_expand "nearbyint<mode>2"
18378   [(use (match_operand:MODEF 0 "register_operand" ""))
18379    (use (match_operand:MODEF 1 "register_operand" ""))]
18380   "TARGET_USE_FANCY_MATH_387
18381    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18382        || TARGET_MIX_SSE_I387)
18383    && flag_unsafe_math_optimizations"
18384 {
18385   rtx op0 = gen_reg_rtx (XFmode);
18386   rtx op1 = gen_reg_rtx (XFmode);
18387
18388   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18389   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18390
18391   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18392   DONE;
18393 })
18394
18395 (define_insn "fxam<mode>2_i387"
18396   [(set (match_operand:HI 0 "register_operand" "=a")
18397         (unspec:HI
18398           [(match_operand:X87MODEF 1 "register_operand" "f")]
18399           UNSPEC_FXAM))]
18400   "TARGET_USE_FANCY_MATH_387"
18401   "fxam\n\tfnstsw\t%0"
18402   [(set_attr "type" "multi")
18403    (set_attr "unit" "i387")
18404    (set_attr "mode" "<MODE>")])
18405
18406 (define_expand "isinf<mode>2"
18407   [(use (match_operand:SI 0 "register_operand" ""))
18408    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18409   "TARGET_USE_FANCY_MATH_387
18410    && TARGET_C99_FUNCTIONS
18411    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18412 {
18413   rtx mask = GEN_INT (0x45);
18414   rtx val = GEN_INT (0x05);
18415
18416   rtx cond;
18417
18418   rtx scratch = gen_reg_rtx (HImode);
18419   rtx res = gen_reg_rtx (QImode);
18420
18421   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18422   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18423   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18424   cond = gen_rtx_fmt_ee (EQ, QImode,
18425                          gen_rtx_REG (CCmode, FLAGS_REG),
18426                          const0_rtx);
18427   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18428   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18429   DONE;
18430 })
18431
18432 (define_expand "signbit<mode>2"
18433   [(use (match_operand:SI 0 "register_operand" ""))
18434    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18435   "TARGET_USE_FANCY_MATH_387
18436    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18437 {
18438   rtx mask = GEN_INT (0x0200);
18439
18440   rtx scratch = gen_reg_rtx (HImode);
18441
18442   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18443   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18444   DONE;
18445 })
18446 \f
18447 ;; Block operation instructions
18448
18449 (define_expand "movmemsi"
18450   [(use (match_operand:BLK 0 "memory_operand" ""))
18451    (use (match_operand:BLK 1 "memory_operand" ""))
18452    (use (match_operand:SI 2 "nonmemory_operand" ""))
18453    (use (match_operand:SI 3 "const_int_operand" ""))
18454    (use (match_operand:SI 4 "const_int_operand" ""))
18455    (use (match_operand:SI 5 "const_int_operand" ""))]
18456   ""
18457 {
18458  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18459                          operands[4], operands[5]))
18460    DONE;
18461  else
18462    FAIL;
18463 })
18464
18465 (define_expand "movmemdi"
18466   [(use (match_operand:BLK 0 "memory_operand" ""))
18467    (use (match_operand:BLK 1 "memory_operand" ""))
18468    (use (match_operand:DI 2 "nonmemory_operand" ""))
18469    (use (match_operand:DI 3 "const_int_operand" ""))
18470    (use (match_operand:SI 4 "const_int_operand" ""))
18471    (use (match_operand:SI 5 "const_int_operand" ""))]
18472   "TARGET_64BIT"
18473 {
18474  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18475                          operands[4], operands[5]))
18476    DONE;
18477  else
18478    FAIL;
18479 })
18480
18481 ;; Most CPUs don't like single string operations
18482 ;; Handle this case here to simplify previous expander.
18483
18484 (define_expand "strmov"
18485   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18486    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18487    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18488               (clobber (reg:CC FLAGS_REG))])
18489    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18490               (clobber (reg:CC FLAGS_REG))])]
18491   ""
18492 {
18493   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18494
18495   /* If .md ever supports :P for Pmode, these can be directly
18496      in the pattern above.  */
18497   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18498   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18499
18500   if (TARGET_SINGLE_STRINGOP || optimize_size)
18501     {
18502       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18503                                       operands[2], operands[3],
18504                                       operands[5], operands[6]));
18505       DONE;
18506     }
18507
18508   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18509 })
18510
18511 (define_expand "strmov_singleop"
18512   [(parallel [(set (match_operand 1 "memory_operand" "")
18513                    (match_operand 3 "memory_operand" ""))
18514               (set (match_operand 0 "register_operand" "")
18515                    (match_operand 4 "" ""))
18516               (set (match_operand 2 "register_operand" "")
18517                    (match_operand 5 "" ""))])]
18518   "TARGET_SINGLE_STRINGOP || optimize_size"
18519   "")
18520
18521 (define_insn "*strmovdi_rex_1"
18522   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18523         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18524    (set (match_operand:DI 0 "register_operand" "=D")
18525         (plus:DI (match_dup 2)
18526                  (const_int 8)))
18527    (set (match_operand:DI 1 "register_operand" "=S")
18528         (plus:DI (match_dup 3)
18529                  (const_int 8)))]
18530   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18531   "movsq"
18532   [(set_attr "type" "str")
18533    (set_attr "mode" "DI")
18534    (set_attr "memory" "both")])
18535
18536 (define_insn "*strmovsi_1"
18537   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18538         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18539    (set (match_operand:SI 0 "register_operand" "=D")
18540         (plus:SI (match_dup 2)
18541                  (const_int 4)))
18542    (set (match_operand:SI 1 "register_operand" "=S")
18543         (plus:SI (match_dup 3)
18544                  (const_int 4)))]
18545   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18546   "{movsl|movsd}"
18547   [(set_attr "type" "str")
18548    (set_attr "mode" "SI")
18549    (set_attr "memory" "both")])
18550
18551 (define_insn "*strmovsi_rex_1"
18552   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18553         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18554    (set (match_operand:DI 0 "register_operand" "=D")
18555         (plus:DI (match_dup 2)
18556                  (const_int 4)))
18557    (set (match_operand:DI 1 "register_operand" "=S")
18558         (plus:DI (match_dup 3)
18559                  (const_int 4)))]
18560   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18561   "{movsl|movsd}"
18562   [(set_attr "type" "str")
18563    (set_attr "mode" "SI")
18564    (set_attr "memory" "both")])
18565
18566 (define_insn "*strmovhi_1"
18567   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18568         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18569    (set (match_operand:SI 0 "register_operand" "=D")
18570         (plus:SI (match_dup 2)
18571                  (const_int 2)))
18572    (set (match_operand:SI 1 "register_operand" "=S")
18573         (plus:SI (match_dup 3)
18574                  (const_int 2)))]
18575   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18576   "movsw"
18577   [(set_attr "type" "str")
18578    (set_attr "memory" "both")
18579    (set_attr "mode" "HI")])
18580
18581 (define_insn "*strmovhi_rex_1"
18582   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18583         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18584    (set (match_operand:DI 0 "register_operand" "=D")
18585         (plus:DI (match_dup 2)
18586                  (const_int 2)))
18587    (set (match_operand:DI 1 "register_operand" "=S")
18588         (plus:DI (match_dup 3)
18589                  (const_int 2)))]
18590   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18591   "movsw"
18592   [(set_attr "type" "str")
18593    (set_attr "memory" "both")
18594    (set_attr "mode" "HI")])
18595
18596 (define_insn "*strmovqi_1"
18597   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18598         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18599    (set (match_operand:SI 0 "register_operand" "=D")
18600         (plus:SI (match_dup 2)
18601                  (const_int 1)))
18602    (set (match_operand:SI 1 "register_operand" "=S")
18603         (plus:SI (match_dup 3)
18604                  (const_int 1)))]
18605   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18606   "movsb"
18607   [(set_attr "type" "str")
18608    (set_attr "memory" "both")
18609    (set_attr "mode" "QI")])
18610
18611 (define_insn "*strmovqi_rex_1"
18612   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18613         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18614    (set (match_operand:DI 0 "register_operand" "=D")
18615         (plus:DI (match_dup 2)
18616                  (const_int 1)))
18617    (set (match_operand:DI 1 "register_operand" "=S")
18618         (plus:DI (match_dup 3)
18619                  (const_int 1)))]
18620   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18621   "movsb"
18622   [(set_attr "type" "str")
18623    (set_attr "memory" "both")
18624    (set_attr "mode" "QI")])
18625
18626 (define_expand "rep_mov"
18627   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18628               (set (match_operand 0 "register_operand" "")
18629                    (match_operand 5 "" ""))
18630               (set (match_operand 2 "register_operand" "")
18631                    (match_operand 6 "" ""))
18632               (set (match_operand 1 "memory_operand" "")
18633                    (match_operand 3 "memory_operand" ""))
18634               (use (match_dup 4))])]
18635   ""
18636   "")
18637
18638 (define_insn "*rep_movdi_rex64"
18639   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18640    (set (match_operand:DI 0 "register_operand" "=D")
18641         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18642                             (const_int 3))
18643                  (match_operand:DI 3 "register_operand" "0")))
18644    (set (match_operand:DI 1 "register_operand" "=S")
18645         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18646                  (match_operand:DI 4 "register_operand" "1")))
18647    (set (mem:BLK (match_dup 3))
18648         (mem:BLK (match_dup 4)))
18649    (use (match_dup 5))]
18650   "TARGET_64BIT"
18651   "rep movsq"
18652   [(set_attr "type" "str")
18653    (set_attr "prefix_rep" "1")
18654    (set_attr "memory" "both")
18655    (set_attr "mode" "DI")])
18656
18657 (define_insn "*rep_movsi"
18658   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18659    (set (match_operand:SI 0 "register_operand" "=D")
18660         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18661                             (const_int 2))
18662                  (match_operand:SI 3 "register_operand" "0")))
18663    (set (match_operand:SI 1 "register_operand" "=S")
18664         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18665                  (match_operand:SI 4 "register_operand" "1")))
18666    (set (mem:BLK (match_dup 3))
18667         (mem:BLK (match_dup 4)))
18668    (use (match_dup 5))]
18669   "!TARGET_64BIT"
18670   "rep movs{l|d}"
18671   [(set_attr "type" "str")
18672    (set_attr "prefix_rep" "1")
18673    (set_attr "memory" "both")
18674    (set_attr "mode" "SI")])
18675
18676 (define_insn "*rep_movsi_rex64"
18677   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18678    (set (match_operand:DI 0 "register_operand" "=D")
18679         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18680                             (const_int 2))
18681                  (match_operand:DI 3 "register_operand" "0")))
18682    (set (match_operand:DI 1 "register_operand" "=S")
18683         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18684                  (match_operand:DI 4 "register_operand" "1")))
18685    (set (mem:BLK (match_dup 3))
18686         (mem:BLK (match_dup 4)))
18687    (use (match_dup 5))]
18688   "TARGET_64BIT"
18689   "rep movs{l|d}"
18690   [(set_attr "type" "str")
18691    (set_attr "prefix_rep" "1")
18692    (set_attr "memory" "both")
18693    (set_attr "mode" "SI")])
18694
18695 (define_insn "*rep_movqi"
18696   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18697    (set (match_operand:SI 0 "register_operand" "=D")
18698         (plus:SI (match_operand:SI 3 "register_operand" "0")
18699                  (match_operand:SI 5 "register_operand" "2")))
18700    (set (match_operand:SI 1 "register_operand" "=S")
18701         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18702    (set (mem:BLK (match_dup 3))
18703         (mem:BLK (match_dup 4)))
18704    (use (match_dup 5))]
18705   "!TARGET_64BIT"
18706   "rep movsb"
18707   [(set_attr "type" "str")
18708    (set_attr "prefix_rep" "1")
18709    (set_attr "memory" "both")
18710    (set_attr "mode" "SI")])
18711
18712 (define_insn "*rep_movqi_rex64"
18713   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18714    (set (match_operand:DI 0 "register_operand" "=D")
18715         (plus:DI (match_operand:DI 3 "register_operand" "0")
18716                  (match_operand:DI 5 "register_operand" "2")))
18717    (set (match_operand:DI 1 "register_operand" "=S")
18718         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18719    (set (mem:BLK (match_dup 3))
18720         (mem:BLK (match_dup 4)))
18721    (use (match_dup 5))]
18722   "TARGET_64BIT"
18723   "rep movsb"
18724   [(set_attr "type" "str")
18725    (set_attr "prefix_rep" "1")
18726    (set_attr "memory" "both")
18727    (set_attr "mode" "SI")])
18728
18729 (define_expand "setmemsi"
18730    [(use (match_operand:BLK 0 "memory_operand" ""))
18731     (use (match_operand:SI 1 "nonmemory_operand" ""))
18732     (use (match_operand 2 "const_int_operand" ""))
18733     (use (match_operand 3 "const_int_operand" ""))
18734     (use (match_operand:SI 4 "const_int_operand" ""))
18735     (use (match_operand:SI 5 "const_int_operand" ""))]
18736   ""
18737 {
18738  if (ix86_expand_setmem (operands[0], operands[1],
18739                          operands[2], operands[3],
18740                          operands[4], operands[5]))
18741    DONE;
18742  else
18743    FAIL;
18744 })
18745
18746 (define_expand "setmemdi"
18747    [(use (match_operand:BLK 0 "memory_operand" ""))
18748     (use (match_operand:DI 1 "nonmemory_operand" ""))
18749     (use (match_operand 2 "const_int_operand" ""))
18750     (use (match_operand 3 "const_int_operand" ""))
18751     (use (match_operand 4 "const_int_operand" ""))
18752     (use (match_operand 5 "const_int_operand" ""))]
18753   "TARGET_64BIT"
18754 {
18755  if (ix86_expand_setmem (operands[0], operands[1],
18756                          operands[2], operands[3],
18757                          operands[4], operands[5]))
18758    DONE;
18759  else
18760    FAIL;
18761 })
18762
18763 ;; Most CPUs don't like single string operations
18764 ;; Handle this case here to simplify previous expander.
18765
18766 (define_expand "strset"
18767   [(set (match_operand 1 "memory_operand" "")
18768         (match_operand 2 "register_operand" ""))
18769    (parallel [(set (match_operand 0 "register_operand" "")
18770                    (match_dup 3))
18771               (clobber (reg:CC FLAGS_REG))])]
18772   ""
18773 {
18774   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18775     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18776
18777   /* If .md ever supports :P for Pmode, this can be directly
18778      in the pattern above.  */
18779   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18780                               GEN_INT (GET_MODE_SIZE (GET_MODE
18781                                                       (operands[2]))));
18782   if (TARGET_SINGLE_STRINGOP || optimize_size)
18783     {
18784       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18785                                       operands[3]));
18786       DONE;
18787     }
18788 })
18789
18790 (define_expand "strset_singleop"
18791   [(parallel [(set (match_operand 1 "memory_operand" "")
18792                    (match_operand 2 "register_operand" ""))
18793               (set (match_operand 0 "register_operand" "")
18794                    (match_operand 3 "" ""))])]
18795   "TARGET_SINGLE_STRINGOP || optimize_size"
18796   "")
18797
18798 (define_insn "*strsetdi_rex_1"
18799   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18800         (match_operand:DI 2 "register_operand" "a"))
18801    (set (match_operand:DI 0 "register_operand" "=D")
18802         (plus:DI (match_dup 1)
18803                  (const_int 8)))]
18804   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18805   "stosq"
18806   [(set_attr "type" "str")
18807    (set_attr "memory" "store")
18808    (set_attr "mode" "DI")])
18809
18810 (define_insn "*strsetsi_1"
18811   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18812         (match_operand:SI 2 "register_operand" "a"))
18813    (set (match_operand:SI 0 "register_operand" "=D")
18814         (plus:SI (match_dup 1)
18815                  (const_int 4)))]
18816   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18817   "{stosl|stosd}"
18818   [(set_attr "type" "str")
18819    (set_attr "memory" "store")
18820    (set_attr "mode" "SI")])
18821
18822 (define_insn "*strsetsi_rex_1"
18823   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18824         (match_operand:SI 2 "register_operand" "a"))
18825    (set (match_operand:DI 0 "register_operand" "=D")
18826         (plus:DI (match_dup 1)
18827                  (const_int 4)))]
18828   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18829   "{stosl|stosd}"
18830   [(set_attr "type" "str")
18831    (set_attr "memory" "store")
18832    (set_attr "mode" "SI")])
18833
18834 (define_insn "*strsethi_1"
18835   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18836         (match_operand:HI 2 "register_operand" "a"))
18837    (set (match_operand:SI 0 "register_operand" "=D")
18838         (plus:SI (match_dup 1)
18839                  (const_int 2)))]
18840   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18841   "stosw"
18842   [(set_attr "type" "str")
18843    (set_attr "memory" "store")
18844    (set_attr "mode" "HI")])
18845
18846 (define_insn "*strsethi_rex_1"
18847   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18848         (match_operand:HI 2 "register_operand" "a"))
18849    (set (match_operand:DI 0 "register_operand" "=D")
18850         (plus:DI (match_dup 1)
18851                  (const_int 2)))]
18852   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18853   "stosw"
18854   [(set_attr "type" "str")
18855    (set_attr "memory" "store")
18856    (set_attr "mode" "HI")])
18857
18858 (define_insn "*strsetqi_1"
18859   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18860         (match_operand:QI 2 "register_operand" "a"))
18861    (set (match_operand:SI 0 "register_operand" "=D")
18862         (plus:SI (match_dup 1)
18863                  (const_int 1)))]
18864   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18865   "stosb"
18866   [(set_attr "type" "str")
18867    (set_attr "memory" "store")
18868    (set_attr "mode" "QI")])
18869
18870 (define_insn "*strsetqi_rex_1"
18871   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18872         (match_operand:QI 2 "register_operand" "a"))
18873    (set (match_operand:DI 0 "register_operand" "=D")
18874         (plus:DI (match_dup 1)
18875                  (const_int 1)))]
18876   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18877   "stosb"
18878   [(set_attr "type" "str")
18879    (set_attr "memory" "store")
18880    (set_attr "mode" "QI")])
18881
18882 (define_expand "rep_stos"
18883   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18884               (set (match_operand 0 "register_operand" "")
18885                    (match_operand 4 "" ""))
18886               (set (match_operand 2 "memory_operand" "") (const_int 0))
18887               (use (match_operand 3 "register_operand" ""))
18888               (use (match_dup 1))])]
18889   ""
18890   "")
18891
18892 (define_insn "*rep_stosdi_rex64"
18893   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18894    (set (match_operand:DI 0 "register_operand" "=D")
18895         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18896                             (const_int 3))
18897                  (match_operand:DI 3 "register_operand" "0")))
18898    (set (mem:BLK (match_dup 3))
18899         (const_int 0))
18900    (use (match_operand:DI 2 "register_operand" "a"))
18901    (use (match_dup 4))]
18902   "TARGET_64BIT"
18903   "rep stosq"
18904   [(set_attr "type" "str")
18905    (set_attr "prefix_rep" "1")
18906    (set_attr "memory" "store")
18907    (set_attr "mode" "DI")])
18908
18909 (define_insn "*rep_stossi"
18910   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18911    (set (match_operand:SI 0 "register_operand" "=D")
18912         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18913                             (const_int 2))
18914                  (match_operand:SI 3 "register_operand" "0")))
18915    (set (mem:BLK (match_dup 3))
18916         (const_int 0))
18917    (use (match_operand:SI 2 "register_operand" "a"))
18918    (use (match_dup 4))]
18919   "!TARGET_64BIT"
18920   "rep stos{l|d}"
18921   [(set_attr "type" "str")
18922    (set_attr "prefix_rep" "1")
18923    (set_attr "memory" "store")
18924    (set_attr "mode" "SI")])
18925
18926 (define_insn "*rep_stossi_rex64"
18927   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18928    (set (match_operand:DI 0 "register_operand" "=D")
18929         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18930                             (const_int 2))
18931                  (match_operand:DI 3 "register_operand" "0")))
18932    (set (mem:BLK (match_dup 3))
18933         (const_int 0))
18934    (use (match_operand:SI 2 "register_operand" "a"))
18935    (use (match_dup 4))]
18936   "TARGET_64BIT"
18937   "rep stos{l|d}"
18938   [(set_attr "type" "str")
18939    (set_attr "prefix_rep" "1")
18940    (set_attr "memory" "store")
18941    (set_attr "mode" "SI")])
18942
18943 (define_insn "*rep_stosqi"
18944   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18945    (set (match_operand:SI 0 "register_operand" "=D")
18946         (plus:SI (match_operand:SI 3 "register_operand" "0")
18947                  (match_operand:SI 4 "register_operand" "1")))
18948    (set (mem:BLK (match_dup 3))
18949         (const_int 0))
18950    (use (match_operand:QI 2 "register_operand" "a"))
18951    (use (match_dup 4))]
18952   "!TARGET_64BIT"
18953   "rep stosb"
18954   [(set_attr "type" "str")
18955    (set_attr "prefix_rep" "1")
18956    (set_attr "memory" "store")
18957    (set_attr "mode" "QI")])
18958
18959 (define_insn "*rep_stosqi_rex64"
18960   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18961    (set (match_operand:DI 0 "register_operand" "=D")
18962         (plus:DI (match_operand:DI 3 "register_operand" "0")
18963                  (match_operand:DI 4 "register_operand" "1")))
18964    (set (mem:BLK (match_dup 3))
18965         (const_int 0))
18966    (use (match_operand:QI 2 "register_operand" "a"))
18967    (use (match_dup 4))]
18968   "TARGET_64BIT"
18969   "rep stosb"
18970   [(set_attr "type" "str")
18971    (set_attr "prefix_rep" "1")
18972    (set_attr "memory" "store")
18973    (set_attr "mode" "QI")])
18974
18975 (define_expand "cmpstrnsi"
18976   [(set (match_operand:SI 0 "register_operand" "")
18977         (compare:SI (match_operand:BLK 1 "general_operand" "")
18978                     (match_operand:BLK 2 "general_operand" "")))
18979    (use (match_operand 3 "general_operand" ""))
18980    (use (match_operand 4 "immediate_operand" ""))]
18981   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18982 {
18983   rtx addr1, addr2, out, outlow, count, countreg, align;
18984
18985   /* Can't use this if the user has appropriated esi or edi.  */
18986   if (global_regs[4] || global_regs[5])
18987     FAIL;
18988
18989   out = operands[0];
18990   if (!REG_P (out))
18991     out = gen_reg_rtx (SImode);
18992
18993   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18994   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18995   if (addr1 != XEXP (operands[1], 0))
18996     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18997   if (addr2 != XEXP (operands[2], 0))
18998     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18999
19000   count = operands[3];
19001   countreg = ix86_zero_extend_to_Pmode (count);
19002
19003   /* %%% Iff we are testing strict equality, we can use known alignment
19004      to good advantage.  This may be possible with combine, particularly
19005      once cc0 is dead.  */
19006   align = operands[4];
19007
19008   if (CONST_INT_P (count))
19009     {
19010       if (INTVAL (count) == 0)
19011         {
19012           emit_move_insn (operands[0], const0_rtx);
19013           DONE;
19014         }
19015       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19016                                      operands[1], operands[2]));
19017     }
19018   else
19019     {
19020       if (TARGET_64BIT)
19021         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19022       else
19023         emit_insn (gen_cmpsi_1 (countreg, countreg));
19024       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19025                                   operands[1], operands[2]));
19026     }
19027
19028   outlow = gen_lowpart (QImode, out);
19029   emit_insn (gen_cmpintqi (outlow));
19030   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19031
19032   if (operands[0] != out)
19033     emit_move_insn (operands[0], out);
19034
19035   DONE;
19036 })
19037
19038 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19039
19040 (define_expand "cmpintqi"
19041   [(set (match_dup 1)
19042         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19043    (set (match_dup 2)
19044         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19045    (parallel [(set (match_operand:QI 0 "register_operand" "")
19046                    (minus:QI (match_dup 1)
19047                              (match_dup 2)))
19048               (clobber (reg:CC FLAGS_REG))])]
19049   ""
19050   "operands[1] = gen_reg_rtx (QImode);
19051    operands[2] = gen_reg_rtx (QImode);")
19052
19053 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19054 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19055
19056 (define_expand "cmpstrnqi_nz_1"
19057   [(parallel [(set (reg:CC FLAGS_REG)
19058                    (compare:CC (match_operand 4 "memory_operand" "")
19059                                (match_operand 5 "memory_operand" "")))
19060               (use (match_operand 2 "register_operand" ""))
19061               (use (match_operand:SI 3 "immediate_operand" ""))
19062               (clobber (match_operand 0 "register_operand" ""))
19063               (clobber (match_operand 1 "register_operand" ""))
19064               (clobber (match_dup 2))])]
19065   ""
19066   "")
19067
19068 (define_insn "*cmpstrnqi_nz_1"
19069   [(set (reg:CC FLAGS_REG)
19070         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19071                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19072    (use (match_operand:SI 6 "register_operand" "2"))
19073    (use (match_operand:SI 3 "immediate_operand" "i"))
19074    (clobber (match_operand:SI 0 "register_operand" "=S"))
19075    (clobber (match_operand:SI 1 "register_operand" "=D"))
19076    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19077   "!TARGET_64BIT"
19078   "repz cmpsb"
19079   [(set_attr "type" "str")
19080    (set_attr "mode" "QI")
19081    (set_attr "prefix_rep" "1")])
19082
19083 (define_insn "*cmpstrnqi_nz_rex_1"
19084   [(set (reg:CC FLAGS_REG)
19085         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19086                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19087    (use (match_operand:DI 6 "register_operand" "2"))
19088    (use (match_operand:SI 3 "immediate_operand" "i"))
19089    (clobber (match_operand:DI 0 "register_operand" "=S"))
19090    (clobber (match_operand:DI 1 "register_operand" "=D"))
19091    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19092   "TARGET_64BIT"
19093   "repz cmpsb"
19094   [(set_attr "type" "str")
19095    (set_attr "mode" "QI")
19096    (set_attr "prefix_rep" "1")])
19097
19098 ;; The same, but the count is not known to not be zero.
19099
19100 (define_expand "cmpstrnqi_1"
19101   [(parallel [(set (reg:CC FLAGS_REG)
19102                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19103                                      (const_int 0))
19104                   (compare:CC (match_operand 4 "memory_operand" "")
19105                               (match_operand 5 "memory_operand" ""))
19106                   (const_int 0)))
19107               (use (match_operand:SI 3 "immediate_operand" ""))
19108               (use (reg:CC FLAGS_REG))
19109               (clobber (match_operand 0 "register_operand" ""))
19110               (clobber (match_operand 1 "register_operand" ""))
19111               (clobber (match_dup 2))])]
19112   ""
19113   "")
19114
19115 (define_insn "*cmpstrnqi_1"
19116   [(set (reg:CC FLAGS_REG)
19117         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19118                              (const_int 0))
19119           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19120                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19121           (const_int 0)))
19122    (use (match_operand:SI 3 "immediate_operand" "i"))
19123    (use (reg:CC FLAGS_REG))
19124    (clobber (match_operand:SI 0 "register_operand" "=S"))
19125    (clobber (match_operand:SI 1 "register_operand" "=D"))
19126    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19127   "!TARGET_64BIT"
19128   "repz cmpsb"
19129   [(set_attr "type" "str")
19130    (set_attr "mode" "QI")
19131    (set_attr "prefix_rep" "1")])
19132
19133 (define_insn "*cmpstrnqi_rex_1"
19134   [(set (reg:CC FLAGS_REG)
19135         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19136                              (const_int 0))
19137           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19138                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19139           (const_int 0)))
19140    (use (match_operand:SI 3 "immediate_operand" "i"))
19141    (use (reg:CC FLAGS_REG))
19142    (clobber (match_operand:DI 0 "register_operand" "=S"))
19143    (clobber (match_operand:DI 1 "register_operand" "=D"))
19144    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19145   "TARGET_64BIT"
19146   "repz cmpsb"
19147   [(set_attr "type" "str")
19148    (set_attr "mode" "QI")
19149    (set_attr "prefix_rep" "1")])
19150
19151 (define_expand "strlensi"
19152   [(set (match_operand:SI 0 "register_operand" "")
19153         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19154                     (match_operand:QI 2 "immediate_operand" "")
19155                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19156   ""
19157 {
19158  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19159    DONE;
19160  else
19161    FAIL;
19162 })
19163
19164 (define_expand "strlendi"
19165   [(set (match_operand:DI 0 "register_operand" "")
19166         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19167                     (match_operand:QI 2 "immediate_operand" "")
19168                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19169   ""
19170 {
19171  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19172    DONE;
19173  else
19174    FAIL;
19175 })
19176
19177 (define_expand "strlenqi_1"
19178   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19179               (clobber (match_operand 1 "register_operand" ""))
19180               (clobber (reg:CC FLAGS_REG))])]
19181   ""
19182   "")
19183
19184 (define_insn "*strlenqi_1"
19185   [(set (match_operand:SI 0 "register_operand" "=&c")
19186         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19187                     (match_operand:QI 2 "register_operand" "a")
19188                     (match_operand:SI 3 "immediate_operand" "i")
19189                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19190    (clobber (match_operand:SI 1 "register_operand" "=D"))
19191    (clobber (reg:CC FLAGS_REG))]
19192   "!TARGET_64BIT"
19193   "repnz scasb"
19194   [(set_attr "type" "str")
19195    (set_attr "mode" "QI")
19196    (set_attr "prefix_rep" "1")])
19197
19198 (define_insn "*strlenqi_rex_1"
19199   [(set (match_operand:DI 0 "register_operand" "=&c")
19200         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19201                     (match_operand:QI 2 "register_operand" "a")
19202                     (match_operand:DI 3 "immediate_operand" "i")
19203                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19204    (clobber (match_operand:DI 1 "register_operand" "=D"))
19205    (clobber (reg:CC FLAGS_REG))]
19206   "TARGET_64BIT"
19207   "repnz scasb"
19208   [(set_attr "type" "str")
19209    (set_attr "mode" "QI")
19210    (set_attr "prefix_rep" "1")])
19211
19212 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19213 ;; handled in combine, but it is not currently up to the task.
19214 ;; When used for their truth value, the cmpstrn* expanders generate
19215 ;; code like this:
19216 ;;
19217 ;;   repz cmpsb
19218 ;;   seta       %al
19219 ;;   setb       %dl
19220 ;;   cmpb       %al, %dl
19221 ;;   jcc        label
19222 ;;
19223 ;; The intermediate three instructions are unnecessary.
19224
19225 ;; This one handles cmpstrn*_nz_1...
19226 (define_peephole2
19227   [(parallel[
19228      (set (reg:CC FLAGS_REG)
19229           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19230                       (mem:BLK (match_operand 5 "register_operand" ""))))
19231      (use (match_operand 6 "register_operand" ""))
19232      (use (match_operand:SI 3 "immediate_operand" ""))
19233      (clobber (match_operand 0 "register_operand" ""))
19234      (clobber (match_operand 1 "register_operand" ""))
19235      (clobber (match_operand 2 "register_operand" ""))])
19236    (set (match_operand:QI 7 "register_operand" "")
19237         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19238    (set (match_operand:QI 8 "register_operand" "")
19239         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19240    (set (reg FLAGS_REG)
19241         (compare (match_dup 7) (match_dup 8)))
19242   ]
19243   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19244   [(parallel[
19245      (set (reg:CC FLAGS_REG)
19246           (compare:CC (mem:BLK (match_dup 4))
19247                       (mem:BLK (match_dup 5))))
19248      (use (match_dup 6))
19249      (use (match_dup 3))
19250      (clobber (match_dup 0))
19251      (clobber (match_dup 1))
19252      (clobber (match_dup 2))])]
19253   "")
19254
19255 ;; ...and this one handles cmpstrn*_1.
19256 (define_peephole2
19257   [(parallel[
19258      (set (reg:CC FLAGS_REG)
19259           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19260                                (const_int 0))
19261             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19262                         (mem:BLK (match_operand 5 "register_operand" "")))
19263             (const_int 0)))
19264      (use (match_operand:SI 3 "immediate_operand" ""))
19265      (use (reg:CC FLAGS_REG))
19266      (clobber (match_operand 0 "register_operand" ""))
19267      (clobber (match_operand 1 "register_operand" ""))
19268      (clobber (match_operand 2 "register_operand" ""))])
19269    (set (match_operand:QI 7 "register_operand" "")
19270         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19271    (set (match_operand:QI 8 "register_operand" "")
19272         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19273    (set (reg FLAGS_REG)
19274         (compare (match_dup 7) (match_dup 8)))
19275   ]
19276   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19277   [(parallel[
19278      (set (reg:CC FLAGS_REG)
19279           (if_then_else:CC (ne (match_dup 6)
19280                                (const_int 0))
19281             (compare:CC (mem:BLK (match_dup 4))
19282                         (mem:BLK (match_dup 5)))
19283             (const_int 0)))
19284      (use (match_dup 3))
19285      (use (reg:CC FLAGS_REG))
19286      (clobber (match_dup 0))
19287      (clobber (match_dup 1))
19288      (clobber (match_dup 2))])]
19289   "")
19290
19291
19292 \f
19293 ;; Conditional move instructions.
19294
19295 (define_expand "movdicc"
19296   [(set (match_operand:DI 0 "register_operand" "")
19297         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19298                          (match_operand:DI 2 "general_operand" "")
19299                          (match_operand:DI 3 "general_operand" "")))]
19300   "TARGET_64BIT"
19301   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19302
19303 (define_insn "x86_movdicc_0_m1_rex64"
19304   [(set (match_operand:DI 0 "register_operand" "=r")
19305         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19306           (const_int -1)
19307           (const_int 0)))
19308    (clobber (reg:CC FLAGS_REG))]
19309   "TARGET_64BIT"
19310   "sbb{q}\t%0, %0"
19311   ; Since we don't have the proper number of operands for an alu insn,
19312   ; fill in all the blanks.
19313   [(set_attr "type" "alu")
19314    (set_attr "pent_pair" "pu")
19315    (set_attr "memory" "none")
19316    (set_attr "imm_disp" "false")
19317    (set_attr "mode" "DI")
19318    (set_attr "length_immediate" "0")])
19319
19320 (define_insn "*movdicc_c_rex64"
19321   [(set (match_operand:DI 0 "register_operand" "=r,r")
19322         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19323                                 [(reg FLAGS_REG) (const_int 0)])
19324                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19325                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19326   "TARGET_64BIT && TARGET_CMOVE
19327    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19328   "@
19329    cmov%O2%C1\t{%2, %0|%0, %2}
19330    cmov%O2%c1\t{%3, %0|%0, %3}"
19331   [(set_attr "type" "icmov")
19332    (set_attr "mode" "DI")])
19333
19334 (define_expand "movsicc"
19335   [(set (match_operand:SI 0 "register_operand" "")
19336         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19337                          (match_operand:SI 2 "general_operand" "")
19338                          (match_operand:SI 3 "general_operand" "")))]
19339   ""
19340   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19341
19342 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19343 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19344 ;; So just document what we're doing explicitly.
19345
19346 (define_insn "x86_movsicc_0_m1"
19347   [(set (match_operand:SI 0 "register_operand" "=r")
19348         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19349           (const_int -1)
19350           (const_int 0)))
19351    (clobber (reg:CC FLAGS_REG))]
19352   ""
19353   "sbb{l}\t%0, %0"
19354   ; Since we don't have the proper number of operands for an alu insn,
19355   ; fill in all the blanks.
19356   [(set_attr "type" "alu")
19357    (set_attr "pent_pair" "pu")
19358    (set_attr "memory" "none")
19359    (set_attr "imm_disp" "false")
19360    (set_attr "mode" "SI")
19361    (set_attr "length_immediate" "0")])
19362
19363 (define_insn "*movsicc_noc"
19364   [(set (match_operand:SI 0 "register_operand" "=r,r")
19365         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19366                                 [(reg FLAGS_REG) (const_int 0)])
19367                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19368                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19369   "TARGET_CMOVE
19370    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19371   "@
19372    cmov%O2%C1\t{%2, %0|%0, %2}
19373    cmov%O2%c1\t{%3, %0|%0, %3}"
19374   [(set_attr "type" "icmov")
19375    (set_attr "mode" "SI")])
19376
19377 (define_expand "movhicc"
19378   [(set (match_operand:HI 0 "register_operand" "")
19379         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19380                          (match_operand:HI 2 "general_operand" "")
19381                          (match_operand:HI 3 "general_operand" "")))]
19382   "TARGET_HIMODE_MATH"
19383   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19384
19385 (define_insn "*movhicc_noc"
19386   [(set (match_operand:HI 0 "register_operand" "=r,r")
19387         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19388                                 [(reg FLAGS_REG) (const_int 0)])
19389                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19390                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19391   "TARGET_CMOVE
19392    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19393   "@
19394    cmov%O2%C1\t{%2, %0|%0, %2}
19395    cmov%O2%c1\t{%3, %0|%0, %3}"
19396   [(set_attr "type" "icmov")
19397    (set_attr "mode" "HI")])
19398
19399 (define_expand "movqicc"
19400   [(set (match_operand:QI 0 "register_operand" "")
19401         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19402                          (match_operand:QI 2 "general_operand" "")
19403                          (match_operand:QI 3 "general_operand" "")))]
19404   "TARGET_QIMODE_MATH"
19405   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19406
19407 (define_insn_and_split "*movqicc_noc"
19408   [(set (match_operand:QI 0 "register_operand" "=r,r")
19409         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19410                                 [(match_operand 4 "flags_reg_operand" "")
19411                                  (const_int 0)])
19412                       (match_operand:QI 2 "register_operand" "r,0")
19413                       (match_operand:QI 3 "register_operand" "0,r")))]
19414   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19415   "#"
19416   "&& reload_completed"
19417   [(set (match_dup 0)
19418         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19419                       (match_dup 2)
19420                       (match_dup 3)))]
19421   "operands[0] = gen_lowpart (SImode, operands[0]);
19422    operands[2] = gen_lowpart (SImode, operands[2]);
19423    operands[3] = gen_lowpart (SImode, operands[3]);"
19424   [(set_attr "type" "icmov")
19425    (set_attr "mode" "SI")])
19426
19427 (define_expand "movsfcc"
19428   [(set (match_operand:SF 0 "register_operand" "")
19429         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19430                          (match_operand:SF 2 "register_operand" "")
19431                          (match_operand:SF 3 "register_operand" "")))]
19432   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19433   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19434
19435 (define_insn "*movsfcc_1_387"
19436   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19437         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19438                                 [(reg FLAGS_REG) (const_int 0)])
19439                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19440                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19441   "TARGET_80387 && TARGET_CMOVE
19442    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19443   "@
19444    fcmov%F1\t{%2, %0|%0, %2}
19445    fcmov%f1\t{%3, %0|%0, %3}
19446    cmov%O2%C1\t{%2, %0|%0, %2}
19447    cmov%O2%c1\t{%3, %0|%0, %3}"
19448   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19449    (set_attr "mode" "SF,SF,SI,SI")])
19450
19451 (define_expand "movdfcc"
19452   [(set (match_operand:DF 0 "register_operand" "")
19453         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19454                          (match_operand:DF 2 "register_operand" "")
19455                          (match_operand:DF 3 "register_operand" "")))]
19456   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19457   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19458
19459 (define_insn "*movdfcc_1"
19460   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19461         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19462                                 [(reg FLAGS_REG) (const_int 0)])
19463                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19464                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19465   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19466    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19467   "@
19468    fcmov%F1\t{%2, %0|%0, %2}
19469    fcmov%f1\t{%3, %0|%0, %3}
19470    #
19471    #"
19472   [(set_attr "type" "fcmov,fcmov,multi,multi")
19473    (set_attr "mode" "DF")])
19474
19475 (define_insn "*movdfcc_1_rex64"
19476   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19477         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19478                                 [(reg FLAGS_REG) (const_int 0)])
19479                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19480                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19481   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19482    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19483   "@
19484    fcmov%F1\t{%2, %0|%0, %2}
19485    fcmov%f1\t{%3, %0|%0, %3}
19486    cmov%O2%C1\t{%2, %0|%0, %2}
19487    cmov%O2%c1\t{%3, %0|%0, %3}"
19488   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19489    (set_attr "mode" "DF")])
19490
19491 (define_split
19492   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19493         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19494                                 [(match_operand 4 "flags_reg_operand" "")
19495                                  (const_int 0)])
19496                       (match_operand:DF 2 "nonimmediate_operand" "")
19497                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19498   "!TARGET_64BIT && reload_completed"
19499   [(set (match_dup 2)
19500         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19501                       (match_dup 5)
19502                       (match_dup 7)))
19503    (set (match_dup 3)
19504         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19505                       (match_dup 6)
19506                       (match_dup 8)))]
19507   "split_di (operands+2, 1, operands+5, operands+6);
19508    split_di (operands+3, 1, operands+7, operands+8);
19509    split_di (operands, 1, operands+2, operands+3);")
19510
19511 (define_expand "movxfcc"
19512   [(set (match_operand:XF 0 "register_operand" "")
19513         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19514                          (match_operand:XF 2 "register_operand" "")
19515                          (match_operand:XF 3 "register_operand" "")))]
19516   "TARGET_80387 && TARGET_CMOVE"
19517   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19518
19519 (define_insn "*movxfcc_1"
19520   [(set (match_operand:XF 0 "register_operand" "=f,f")
19521         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19522                                 [(reg FLAGS_REG) (const_int 0)])
19523                       (match_operand:XF 2 "register_operand" "f,0")
19524                       (match_operand:XF 3 "register_operand" "0,f")))]
19525   "TARGET_80387 && TARGET_CMOVE"
19526   "@
19527    fcmov%F1\t{%2, %0|%0, %2}
19528    fcmov%f1\t{%3, %0|%0, %3}"
19529   [(set_attr "type" "fcmov")
19530    (set_attr "mode" "XF")])
19531
19532 ;; These versions of the min/max patterns are intentionally ignorant of
19533 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19534 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19535 ;; are undefined in this condition, we're certain this is correct.
19536
19537 (define_insn "sminsf3"
19538   [(set (match_operand:SF 0 "register_operand" "=x")
19539         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19540                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19541   "TARGET_SSE_MATH"
19542   "minss\t{%2, %0|%0, %2}"
19543   [(set_attr "type" "sseadd")
19544    (set_attr "mode" "SF")])
19545
19546 (define_insn "smaxsf3"
19547   [(set (match_operand:SF 0 "register_operand" "=x")
19548         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19549                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19550   "TARGET_SSE_MATH"
19551   "maxss\t{%2, %0|%0, %2}"
19552   [(set_attr "type" "sseadd")
19553    (set_attr "mode" "SF")])
19554
19555 (define_insn "smindf3"
19556   [(set (match_operand:DF 0 "register_operand" "=x")
19557         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19558                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19559   "TARGET_SSE2 && TARGET_SSE_MATH"
19560   "minsd\t{%2, %0|%0, %2}"
19561   [(set_attr "type" "sseadd")
19562    (set_attr "mode" "DF")])
19563
19564 (define_insn "smaxdf3"
19565   [(set (match_operand:DF 0 "register_operand" "=x")
19566         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19567                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19568   "TARGET_SSE2 && TARGET_SSE_MATH"
19569   "maxsd\t{%2, %0|%0, %2}"
19570   [(set_attr "type" "sseadd")
19571    (set_attr "mode" "DF")])
19572
19573 ;; These versions of the min/max patterns implement exactly the operations
19574 ;;   min = (op1 < op2 ? op1 : op2)
19575 ;;   max = (!(op1 < op2) ? op1 : op2)
19576 ;; Their operands are not commutative, and thus they may be used in the
19577 ;; presence of -0.0 and NaN.
19578
19579 (define_insn "*ieee_sminsf3"
19580   [(set (match_operand:SF 0 "register_operand" "=x")
19581         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19582                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19583                    UNSPEC_IEEE_MIN))]
19584   "TARGET_SSE_MATH"
19585   "minss\t{%2, %0|%0, %2}"
19586   [(set_attr "type" "sseadd")
19587    (set_attr "mode" "SF")])
19588
19589 (define_insn "*ieee_smaxsf3"
19590   [(set (match_operand:SF 0 "register_operand" "=x")
19591         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19592                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19593                    UNSPEC_IEEE_MAX))]
19594   "TARGET_SSE_MATH"
19595   "maxss\t{%2, %0|%0, %2}"
19596   [(set_attr "type" "sseadd")
19597    (set_attr "mode" "SF")])
19598
19599 (define_insn "*ieee_smindf3"
19600   [(set (match_operand:DF 0 "register_operand" "=x")
19601         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19602                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19603                    UNSPEC_IEEE_MIN))]
19604   "TARGET_SSE2 && TARGET_SSE_MATH"
19605   "minsd\t{%2, %0|%0, %2}"
19606   [(set_attr "type" "sseadd")
19607    (set_attr "mode" "DF")])
19608
19609 (define_insn "*ieee_smaxdf3"
19610   [(set (match_operand:DF 0 "register_operand" "=x")
19611         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19612                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19613                    UNSPEC_IEEE_MAX))]
19614   "TARGET_SSE2 && TARGET_SSE_MATH"
19615   "maxsd\t{%2, %0|%0, %2}"
19616   [(set_attr "type" "sseadd")
19617    (set_attr "mode" "DF")])
19618
19619 ;; Make two stack loads independent:
19620 ;;   fld aa              fld aa
19621 ;;   fld %st(0)     ->   fld bb
19622 ;;   fmul bb             fmul %st(1), %st
19623 ;;
19624 ;; Actually we only match the last two instructions for simplicity.
19625 (define_peephole2
19626   [(set (match_operand 0 "fp_register_operand" "")
19627         (match_operand 1 "fp_register_operand" ""))
19628    (set (match_dup 0)
19629         (match_operator 2 "binary_fp_operator"
19630            [(match_dup 0)
19631             (match_operand 3 "memory_operand" "")]))]
19632   "REGNO (operands[0]) != REGNO (operands[1])"
19633   [(set (match_dup 0) (match_dup 3))
19634    (set (match_dup 0) (match_dup 4))]
19635
19636   ;; The % modifier is not operational anymore in peephole2's, so we have to
19637   ;; swap the operands manually in the case of addition and multiplication.
19638   "if (COMMUTATIVE_ARITH_P (operands[2]))
19639      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19640                                  operands[0], operands[1]);
19641    else
19642      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19643                                  operands[1], operands[0]);")
19644
19645 ;; Conditional addition patterns
19646 (define_expand "addqicc"
19647   [(match_operand:QI 0 "register_operand" "")
19648    (match_operand 1 "comparison_operator" "")
19649    (match_operand:QI 2 "register_operand" "")
19650    (match_operand:QI 3 "const_int_operand" "")]
19651   ""
19652   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19653
19654 (define_expand "addhicc"
19655   [(match_operand:HI 0 "register_operand" "")
19656    (match_operand 1 "comparison_operator" "")
19657    (match_operand:HI 2 "register_operand" "")
19658    (match_operand:HI 3 "const_int_operand" "")]
19659   ""
19660   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19661
19662 (define_expand "addsicc"
19663   [(match_operand:SI 0 "register_operand" "")
19664    (match_operand 1 "comparison_operator" "")
19665    (match_operand:SI 2 "register_operand" "")
19666    (match_operand:SI 3 "const_int_operand" "")]
19667   ""
19668   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19669
19670 (define_expand "adddicc"
19671   [(match_operand:DI 0 "register_operand" "")
19672    (match_operand 1 "comparison_operator" "")
19673    (match_operand:DI 2 "register_operand" "")
19674    (match_operand:DI 3 "const_int_operand" "")]
19675   "TARGET_64BIT"
19676   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19677
19678 \f
19679 ;; Misc patterns (?)
19680
19681 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19682 ;; Otherwise there will be nothing to keep
19683 ;;
19684 ;; [(set (reg ebp) (reg esp))]
19685 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19686 ;;  (clobber (eflags)]
19687 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19688 ;;
19689 ;; in proper program order.
19690 (define_insn "pro_epilogue_adjust_stack_1"
19691   [(set (match_operand:SI 0 "register_operand" "=r,r")
19692         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19693                  (match_operand:SI 2 "immediate_operand" "i,i")))
19694    (clobber (reg:CC FLAGS_REG))
19695    (clobber (mem:BLK (scratch)))]
19696   "!TARGET_64BIT"
19697 {
19698   switch (get_attr_type (insn))
19699     {
19700     case TYPE_IMOV:
19701       return "mov{l}\t{%1, %0|%0, %1}";
19702
19703     case TYPE_ALU:
19704       if (CONST_INT_P (operands[2])
19705           && (INTVAL (operands[2]) == 128
19706               || (INTVAL (operands[2]) < 0
19707                   && INTVAL (operands[2]) != -128)))
19708         {
19709           operands[2] = GEN_INT (-INTVAL (operands[2]));
19710           return "sub{l}\t{%2, %0|%0, %2}";
19711         }
19712       return "add{l}\t{%2, %0|%0, %2}";
19713
19714     case TYPE_LEA:
19715       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19716       return "lea{l}\t{%a2, %0|%0, %a2}";
19717
19718     default:
19719       gcc_unreachable ();
19720     }
19721 }
19722   [(set (attr "type")
19723         (cond [(eq_attr "alternative" "0")
19724                  (const_string "alu")
19725                (match_operand:SI 2 "const0_operand" "")
19726                  (const_string "imov")
19727               ]
19728               (const_string "lea")))
19729    (set_attr "mode" "SI")])
19730
19731 (define_insn "pro_epilogue_adjust_stack_rex64"
19732   [(set (match_operand:DI 0 "register_operand" "=r,r")
19733         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19734                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19735    (clobber (reg:CC FLAGS_REG))
19736    (clobber (mem:BLK (scratch)))]
19737   "TARGET_64BIT"
19738 {
19739   switch (get_attr_type (insn))
19740     {
19741     case TYPE_IMOV:
19742       return "mov{q}\t{%1, %0|%0, %1}";
19743
19744     case TYPE_ALU:
19745       if (CONST_INT_P (operands[2])
19746           /* Avoid overflows.  */
19747           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19748           && (INTVAL (operands[2]) == 128
19749               || (INTVAL (operands[2]) < 0
19750                   && INTVAL (operands[2]) != -128)))
19751         {
19752           operands[2] = GEN_INT (-INTVAL (operands[2]));
19753           return "sub{q}\t{%2, %0|%0, %2}";
19754         }
19755       return "add{q}\t{%2, %0|%0, %2}";
19756
19757     case TYPE_LEA:
19758       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19759       return "lea{q}\t{%a2, %0|%0, %a2}";
19760
19761     default:
19762       gcc_unreachable ();
19763     }
19764 }
19765   [(set (attr "type")
19766         (cond [(eq_attr "alternative" "0")
19767                  (const_string "alu")
19768                (match_operand:DI 2 "const0_operand" "")
19769                  (const_string "imov")
19770               ]
19771               (const_string "lea")))
19772    (set_attr "mode" "DI")])
19773
19774 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19775   [(set (match_operand:DI 0 "register_operand" "=r,r")
19776         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19777                  (match_operand:DI 3 "immediate_operand" "i,i")))
19778    (use (match_operand:DI 2 "register_operand" "r,r"))
19779    (clobber (reg:CC FLAGS_REG))
19780    (clobber (mem:BLK (scratch)))]
19781   "TARGET_64BIT"
19782 {
19783   switch (get_attr_type (insn))
19784     {
19785     case TYPE_ALU:
19786       return "add{q}\t{%2, %0|%0, %2}";
19787
19788     case TYPE_LEA:
19789       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19790       return "lea{q}\t{%a2, %0|%0, %a2}";
19791
19792     default:
19793       gcc_unreachable ();
19794     }
19795 }
19796   [(set_attr "type" "alu,lea")
19797    (set_attr "mode" "DI")])
19798
19799 (define_insn "allocate_stack_worker_32"
19800   [(set (match_operand:SI 0 "register_operand" "+a")
19801         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19802    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19803    (clobber (reg:CC FLAGS_REG))]
19804   "!TARGET_64BIT && TARGET_STACK_PROBE"
19805   "call\t__alloca"
19806   [(set_attr "type" "multi")
19807    (set_attr "length" "5")])
19808
19809 (define_insn "allocate_stack_worker_64"
19810   [(set (match_operand:DI 0 "register_operand" "=a")
19811         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19812    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19813    (clobber (reg:DI R10_REG))
19814    (clobber (reg:DI R11_REG))
19815    (clobber (reg:CC FLAGS_REG))]
19816   "TARGET_64BIT && TARGET_STACK_PROBE"
19817   "call\t___chkstk"
19818   [(set_attr "type" "multi")
19819    (set_attr "length" "5")])
19820
19821 (define_expand "allocate_stack"
19822   [(match_operand 0 "register_operand" "")
19823    (match_operand 1 "general_operand" "")]
19824   "TARGET_STACK_PROBE"
19825 {
19826   rtx x;
19827
19828 #ifndef CHECK_STACK_LIMIT
19829 #define CHECK_STACK_LIMIT 0
19830 #endif
19831
19832   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19833       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19834     {
19835       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19836                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19837       if (x != stack_pointer_rtx)
19838         emit_move_insn (stack_pointer_rtx, x);
19839     }
19840   else
19841     {
19842       x = copy_to_mode_reg (Pmode, operands[1]);
19843       if (TARGET_64BIT)
19844         x = gen_allocate_stack_worker_64 (x);
19845       else
19846         x = gen_allocate_stack_worker_32 (x);
19847       emit_insn (x);
19848     }
19849
19850   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19851   DONE;
19852 })
19853
19854 (define_expand "builtin_setjmp_receiver"
19855   [(label_ref (match_operand 0 "" ""))]
19856   "!TARGET_64BIT && flag_pic"
19857 {
19858   if (TARGET_MACHO)
19859     {
19860       rtx xops[3];
19861       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19862       rtx label_rtx = gen_label_rtx ();
19863       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19864       xops[0] = xops[1] = picreg;
19865       xops[2] = gen_rtx_CONST (SImode,
19866                   gen_rtx_MINUS (SImode,
19867                     gen_rtx_LABEL_REF (SImode, label_rtx),
19868                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19869       ix86_expand_binary_operator (MINUS, SImode, xops);
19870     }
19871   else
19872     emit_insn (gen_set_got (pic_offset_table_rtx));
19873   DONE;
19874 })
19875 \f
19876 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19877
19878 (define_split
19879   [(set (match_operand 0 "register_operand" "")
19880         (match_operator 3 "promotable_binary_operator"
19881            [(match_operand 1 "register_operand" "")
19882             (match_operand 2 "aligned_operand" "")]))
19883    (clobber (reg:CC FLAGS_REG))]
19884   "! TARGET_PARTIAL_REG_STALL && reload_completed
19885    && ((GET_MODE (operands[0]) == HImode
19886         && ((!optimize_size && !TARGET_FAST_PREFIX)
19887             /* ??? next two lines just !satisfies_constraint_K (...) */
19888             || !CONST_INT_P (operands[2])
19889             || satisfies_constraint_K (operands[2])))
19890        || (GET_MODE (operands[0]) == QImode
19891            && (TARGET_PROMOTE_QImode || optimize_size)))"
19892   [(parallel [(set (match_dup 0)
19893                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19894               (clobber (reg:CC FLAGS_REG))])]
19895   "operands[0] = gen_lowpart (SImode, operands[0]);
19896    operands[1] = gen_lowpart (SImode, operands[1]);
19897    if (GET_CODE (operands[3]) != ASHIFT)
19898      operands[2] = gen_lowpart (SImode, operands[2]);
19899    PUT_MODE (operands[3], SImode);")
19900
19901 ; Promote the QImode tests, as i386 has encoding of the AND
19902 ; instruction with 32-bit sign-extended immediate and thus the
19903 ; instruction size is unchanged, except in the %eax case for
19904 ; which it is increased by one byte, hence the ! optimize_size.
19905 (define_split
19906   [(set (match_operand 0 "flags_reg_operand" "")
19907         (match_operator 2 "compare_operator"
19908           [(and (match_operand 3 "aligned_operand" "")
19909                 (match_operand 4 "const_int_operand" ""))
19910            (const_int 0)]))
19911    (set (match_operand 1 "register_operand" "")
19912         (and (match_dup 3) (match_dup 4)))]
19913   "! TARGET_PARTIAL_REG_STALL && reload_completed
19914    && ! optimize_size
19915    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19916        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19917    /* Ensure that the operand will remain sign-extended immediate.  */
19918    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19919   [(parallel [(set (match_dup 0)
19920                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19921                                     (const_int 0)]))
19922               (set (match_dup 1)
19923                    (and:SI (match_dup 3) (match_dup 4)))])]
19924 {
19925   operands[4]
19926     = gen_int_mode (INTVAL (operands[4])
19927                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19928   operands[1] = gen_lowpart (SImode, operands[1]);
19929   operands[3] = gen_lowpart (SImode, operands[3]);
19930 })
19931
19932 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19933 ; the TEST instruction with 32-bit sign-extended immediate and thus
19934 ; the instruction size would at least double, which is not what we
19935 ; want even with ! optimize_size.
19936 (define_split
19937   [(set (match_operand 0 "flags_reg_operand" "")
19938         (match_operator 1 "compare_operator"
19939           [(and (match_operand:HI 2 "aligned_operand" "")
19940                 (match_operand:HI 3 "const_int_operand" ""))
19941            (const_int 0)]))]
19942   "! TARGET_PARTIAL_REG_STALL && reload_completed
19943    && ! TARGET_FAST_PREFIX
19944    && ! optimize_size
19945    /* Ensure that the operand will remain sign-extended immediate.  */
19946    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19947   [(set (match_dup 0)
19948         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19949                          (const_int 0)]))]
19950 {
19951   operands[3]
19952     = gen_int_mode (INTVAL (operands[3])
19953                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19954   operands[2] = gen_lowpart (SImode, operands[2]);
19955 })
19956
19957 (define_split
19958   [(set (match_operand 0 "register_operand" "")
19959         (neg (match_operand 1 "register_operand" "")))
19960    (clobber (reg:CC FLAGS_REG))]
19961   "! TARGET_PARTIAL_REG_STALL && reload_completed
19962    && (GET_MODE (operands[0]) == HImode
19963        || (GET_MODE (operands[0]) == QImode
19964            && (TARGET_PROMOTE_QImode || optimize_size)))"
19965   [(parallel [(set (match_dup 0)
19966                    (neg:SI (match_dup 1)))
19967               (clobber (reg:CC FLAGS_REG))])]
19968   "operands[0] = gen_lowpart (SImode, operands[0]);
19969    operands[1] = gen_lowpart (SImode, operands[1]);")
19970
19971 (define_split
19972   [(set (match_operand 0 "register_operand" "")
19973         (not (match_operand 1 "register_operand" "")))]
19974   "! TARGET_PARTIAL_REG_STALL && reload_completed
19975    && (GET_MODE (operands[0]) == HImode
19976        || (GET_MODE (operands[0]) == QImode
19977            && (TARGET_PROMOTE_QImode || optimize_size)))"
19978   [(set (match_dup 0)
19979         (not:SI (match_dup 1)))]
19980   "operands[0] = gen_lowpart (SImode, operands[0]);
19981    operands[1] = gen_lowpart (SImode, operands[1]);")
19982
19983 (define_split
19984   [(set (match_operand 0 "register_operand" "")
19985         (if_then_else (match_operator 1 "comparison_operator"
19986                                 [(reg FLAGS_REG) (const_int 0)])
19987                       (match_operand 2 "register_operand" "")
19988                       (match_operand 3 "register_operand" "")))]
19989   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19990    && (GET_MODE (operands[0]) == HImode
19991        || (GET_MODE (operands[0]) == QImode
19992            && (TARGET_PROMOTE_QImode || optimize_size)))"
19993   [(set (match_dup 0)
19994         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19995   "operands[0] = gen_lowpart (SImode, operands[0]);
19996    operands[2] = gen_lowpart (SImode, operands[2]);
19997    operands[3] = gen_lowpart (SImode, operands[3]);")
19998
19999 \f
20000 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20001 ;; transform a complex memory operation into two memory to register operations.
20002
20003 ;; Don't push memory operands
20004 (define_peephole2
20005   [(set (match_operand:SI 0 "push_operand" "")
20006         (match_operand:SI 1 "memory_operand" ""))
20007    (match_scratch:SI 2 "r")]
20008   "!optimize_size && !TARGET_PUSH_MEMORY
20009    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20010   [(set (match_dup 2) (match_dup 1))
20011    (set (match_dup 0) (match_dup 2))]
20012   "")
20013
20014 (define_peephole2
20015   [(set (match_operand:DI 0 "push_operand" "")
20016         (match_operand:DI 1 "memory_operand" ""))
20017    (match_scratch:DI 2 "r")]
20018   "!optimize_size && !TARGET_PUSH_MEMORY
20019    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20020   [(set (match_dup 2) (match_dup 1))
20021    (set (match_dup 0) (match_dup 2))]
20022   "")
20023
20024 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20025 ;; SImode pushes.
20026 (define_peephole2
20027   [(set (match_operand:SF 0 "push_operand" "")
20028         (match_operand:SF 1 "memory_operand" ""))
20029    (match_scratch:SF 2 "r")]
20030   "!optimize_size && !TARGET_PUSH_MEMORY
20031    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20032   [(set (match_dup 2) (match_dup 1))
20033    (set (match_dup 0) (match_dup 2))]
20034   "")
20035
20036 (define_peephole2
20037   [(set (match_operand:HI 0 "push_operand" "")
20038         (match_operand:HI 1 "memory_operand" ""))
20039    (match_scratch:HI 2 "r")]
20040   "!optimize_size && !TARGET_PUSH_MEMORY
20041    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20042   [(set (match_dup 2) (match_dup 1))
20043    (set (match_dup 0) (match_dup 2))]
20044   "")
20045
20046 (define_peephole2
20047   [(set (match_operand:QI 0 "push_operand" "")
20048         (match_operand:QI 1 "memory_operand" ""))
20049    (match_scratch:QI 2 "q")]
20050   "!optimize_size && !TARGET_PUSH_MEMORY
20051    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20052   [(set (match_dup 2) (match_dup 1))
20053    (set (match_dup 0) (match_dup 2))]
20054   "")
20055
20056 ;; Don't move an immediate directly to memory when the instruction
20057 ;; gets too big.
20058 (define_peephole2
20059   [(match_scratch:SI 1 "r")
20060    (set (match_operand:SI 0 "memory_operand" "")
20061         (const_int 0))]
20062   "! optimize_size
20063    && ! TARGET_USE_MOV0
20064    && TARGET_SPLIT_LONG_MOVES
20065    && get_attr_length (insn) >= ix86_cost->large_insn
20066    && peep2_regno_dead_p (0, FLAGS_REG)"
20067   [(parallel [(set (match_dup 1) (const_int 0))
20068               (clobber (reg:CC FLAGS_REG))])
20069    (set (match_dup 0) (match_dup 1))]
20070   "")
20071
20072 (define_peephole2
20073   [(match_scratch:HI 1 "r")
20074    (set (match_operand:HI 0 "memory_operand" "")
20075         (const_int 0))]
20076   "! optimize_size
20077    && ! TARGET_USE_MOV0
20078    && TARGET_SPLIT_LONG_MOVES
20079    && get_attr_length (insn) >= ix86_cost->large_insn
20080    && peep2_regno_dead_p (0, FLAGS_REG)"
20081   [(parallel [(set (match_dup 2) (const_int 0))
20082               (clobber (reg:CC FLAGS_REG))])
20083    (set (match_dup 0) (match_dup 1))]
20084   "operands[2] = gen_lowpart (SImode, operands[1]);")
20085
20086 (define_peephole2
20087   [(match_scratch:QI 1 "q")
20088    (set (match_operand:QI 0 "memory_operand" "")
20089         (const_int 0))]
20090   "! optimize_size
20091    && ! TARGET_USE_MOV0
20092    && TARGET_SPLIT_LONG_MOVES
20093    && get_attr_length (insn) >= ix86_cost->large_insn
20094    && peep2_regno_dead_p (0, FLAGS_REG)"
20095   [(parallel [(set (match_dup 2) (const_int 0))
20096               (clobber (reg:CC FLAGS_REG))])
20097    (set (match_dup 0) (match_dup 1))]
20098   "operands[2] = gen_lowpart (SImode, operands[1]);")
20099
20100 (define_peephole2
20101   [(match_scratch:SI 2 "r")
20102    (set (match_operand:SI 0 "memory_operand" "")
20103         (match_operand:SI 1 "immediate_operand" ""))]
20104   "! optimize_size
20105    && TARGET_SPLIT_LONG_MOVES
20106    && get_attr_length (insn) >= ix86_cost->large_insn"
20107   [(set (match_dup 2) (match_dup 1))
20108    (set (match_dup 0) (match_dup 2))]
20109   "")
20110
20111 (define_peephole2
20112   [(match_scratch:HI 2 "r")
20113    (set (match_operand:HI 0 "memory_operand" "")
20114         (match_operand:HI 1 "immediate_operand" ""))]
20115   "! optimize_size
20116    && TARGET_SPLIT_LONG_MOVES
20117    && get_attr_length (insn) >= ix86_cost->large_insn"
20118   [(set (match_dup 2) (match_dup 1))
20119    (set (match_dup 0) (match_dup 2))]
20120   "")
20121
20122 (define_peephole2
20123   [(match_scratch:QI 2 "q")
20124    (set (match_operand:QI 0 "memory_operand" "")
20125         (match_operand:QI 1 "immediate_operand" ""))]
20126   "! optimize_size
20127    && TARGET_SPLIT_LONG_MOVES
20128    && get_attr_length (insn) >= ix86_cost->large_insn"
20129   [(set (match_dup 2) (match_dup 1))
20130    (set (match_dup 0) (match_dup 2))]
20131   "")
20132
20133 ;; Don't compare memory with zero, load and use a test instead.
20134 (define_peephole2
20135   [(set (match_operand 0 "flags_reg_operand" "")
20136         (match_operator 1 "compare_operator"
20137           [(match_operand:SI 2 "memory_operand" "")
20138            (const_int 0)]))
20139    (match_scratch:SI 3 "r")]
20140   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20141   [(set (match_dup 3) (match_dup 2))
20142    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20143   "")
20144
20145 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20146 ;; Don't split NOTs with a displacement operand, because resulting XOR
20147 ;; will not be pairable anyway.
20148 ;;
20149 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20150 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20151 ;; so this split helps here as well.
20152 ;;
20153 ;; Note: Can't do this as a regular split because we can't get proper
20154 ;; lifetime information then.
20155
20156 (define_peephole2
20157   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20158         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20159   "!optimize_size
20160    && ((TARGET_NOT_UNPAIRABLE
20161         && (!MEM_P (operands[0])
20162             || !memory_displacement_operand (operands[0], SImode)))
20163        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20164    && peep2_regno_dead_p (0, FLAGS_REG)"
20165   [(parallel [(set (match_dup 0)
20166                    (xor:SI (match_dup 1) (const_int -1)))
20167               (clobber (reg:CC FLAGS_REG))])]
20168   "")
20169
20170 (define_peephole2
20171   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20172         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20173   "!optimize_size
20174    && ((TARGET_NOT_UNPAIRABLE
20175         && (!MEM_P (operands[0])
20176             || !memory_displacement_operand (operands[0], HImode)))
20177        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20178    && peep2_regno_dead_p (0, FLAGS_REG)"
20179   [(parallel [(set (match_dup 0)
20180                    (xor:HI (match_dup 1) (const_int -1)))
20181               (clobber (reg:CC FLAGS_REG))])]
20182   "")
20183
20184 (define_peephole2
20185   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20186         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20187   "!optimize_size
20188    && ((TARGET_NOT_UNPAIRABLE
20189         && (!MEM_P (operands[0])
20190             || !memory_displacement_operand (operands[0], QImode)))
20191        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20192    && peep2_regno_dead_p (0, FLAGS_REG)"
20193   [(parallel [(set (match_dup 0)
20194                    (xor:QI (match_dup 1) (const_int -1)))
20195               (clobber (reg:CC FLAGS_REG))])]
20196   "")
20197
20198 ;; Non pairable "test imm, reg" instructions can be translated to
20199 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20200 ;; byte opcode instead of two, have a short form for byte operands),
20201 ;; so do it for other CPUs as well.  Given that the value was dead,
20202 ;; this should not create any new dependencies.  Pass on the sub-word
20203 ;; versions if we're concerned about partial register stalls.
20204
20205 (define_peephole2
20206   [(set (match_operand 0 "flags_reg_operand" "")
20207         (match_operator 1 "compare_operator"
20208           [(and:SI (match_operand:SI 2 "register_operand" "")
20209                    (match_operand:SI 3 "immediate_operand" ""))
20210            (const_int 0)]))]
20211   "ix86_match_ccmode (insn, CCNOmode)
20212    && (true_regnum (operands[2]) != 0
20213        || satisfies_constraint_K (operands[3]))
20214    && peep2_reg_dead_p (1, operands[2])"
20215   [(parallel
20216      [(set (match_dup 0)
20217            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20218                             (const_int 0)]))
20219       (set (match_dup 2)
20220            (and:SI (match_dup 2) (match_dup 3)))])]
20221   "")
20222
20223 ;; We don't need to handle HImode case, because it will be promoted to SImode
20224 ;; on ! TARGET_PARTIAL_REG_STALL
20225
20226 (define_peephole2
20227   [(set (match_operand 0 "flags_reg_operand" "")
20228         (match_operator 1 "compare_operator"
20229           [(and:QI (match_operand:QI 2 "register_operand" "")
20230                    (match_operand:QI 3 "immediate_operand" ""))
20231            (const_int 0)]))]
20232   "! TARGET_PARTIAL_REG_STALL
20233    && ix86_match_ccmode (insn, CCNOmode)
20234    && true_regnum (operands[2]) != 0
20235    && peep2_reg_dead_p (1, operands[2])"
20236   [(parallel
20237      [(set (match_dup 0)
20238            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20239                             (const_int 0)]))
20240       (set (match_dup 2)
20241            (and:QI (match_dup 2) (match_dup 3)))])]
20242   "")
20243
20244 (define_peephole2
20245   [(set (match_operand 0 "flags_reg_operand" "")
20246         (match_operator 1 "compare_operator"
20247           [(and:SI
20248              (zero_extract:SI
20249                (match_operand 2 "ext_register_operand" "")
20250                (const_int 8)
20251                (const_int 8))
20252              (match_operand 3 "const_int_operand" ""))
20253            (const_int 0)]))]
20254   "! TARGET_PARTIAL_REG_STALL
20255    && ix86_match_ccmode (insn, CCNOmode)
20256    && true_regnum (operands[2]) != 0
20257    && peep2_reg_dead_p (1, operands[2])"
20258   [(parallel [(set (match_dup 0)
20259                    (match_op_dup 1
20260                      [(and:SI
20261                         (zero_extract:SI
20262                           (match_dup 2)
20263                           (const_int 8)
20264                           (const_int 8))
20265                         (match_dup 3))
20266                       (const_int 0)]))
20267               (set (zero_extract:SI (match_dup 2)
20268                                     (const_int 8)
20269                                     (const_int 8))
20270                    (and:SI
20271                      (zero_extract:SI
20272                        (match_dup 2)
20273                        (const_int 8)
20274                        (const_int 8))
20275                      (match_dup 3)))])]
20276   "")
20277
20278 ;; Don't do logical operations with memory inputs.
20279 (define_peephole2
20280   [(match_scratch:SI 2 "r")
20281    (parallel [(set (match_operand:SI 0 "register_operand" "")
20282                    (match_operator:SI 3 "arith_or_logical_operator"
20283                      [(match_dup 0)
20284                       (match_operand:SI 1 "memory_operand" "")]))
20285               (clobber (reg:CC FLAGS_REG))])]
20286   "! optimize_size && ! TARGET_READ_MODIFY"
20287   [(set (match_dup 2) (match_dup 1))
20288    (parallel [(set (match_dup 0)
20289                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20290               (clobber (reg:CC FLAGS_REG))])]
20291   "")
20292
20293 (define_peephole2
20294   [(match_scratch:SI 2 "r")
20295    (parallel [(set (match_operand:SI 0 "register_operand" "")
20296                    (match_operator:SI 3 "arith_or_logical_operator"
20297                      [(match_operand:SI 1 "memory_operand" "")
20298                       (match_dup 0)]))
20299               (clobber (reg:CC FLAGS_REG))])]
20300   "! optimize_size && ! TARGET_READ_MODIFY"
20301   [(set (match_dup 2) (match_dup 1))
20302    (parallel [(set (match_dup 0)
20303                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20304               (clobber (reg:CC FLAGS_REG))])]
20305   "")
20306
20307 ; Don't do logical operations with memory outputs
20308 ;
20309 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20310 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20311 ; the same decoder scheduling characteristics as the original.
20312
20313 (define_peephole2
20314   [(match_scratch:SI 2 "r")
20315    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20316                    (match_operator:SI 3 "arith_or_logical_operator"
20317                      [(match_dup 0)
20318                       (match_operand:SI 1 "nonmemory_operand" "")]))
20319               (clobber (reg:CC FLAGS_REG))])]
20320   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20321   [(set (match_dup 2) (match_dup 0))
20322    (parallel [(set (match_dup 2)
20323                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20324               (clobber (reg:CC FLAGS_REG))])
20325    (set (match_dup 0) (match_dup 2))]
20326   "")
20327
20328 (define_peephole2
20329   [(match_scratch:SI 2 "r")
20330    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20331                    (match_operator:SI 3 "arith_or_logical_operator"
20332                      [(match_operand:SI 1 "nonmemory_operand" "")
20333                       (match_dup 0)]))
20334               (clobber (reg:CC FLAGS_REG))])]
20335   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20336   [(set (match_dup 2) (match_dup 0))
20337    (parallel [(set (match_dup 2)
20338                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20339               (clobber (reg:CC FLAGS_REG))])
20340    (set (match_dup 0) (match_dup 2))]
20341   "")
20342
20343 ;; Attempt to always use XOR for zeroing registers.
20344 (define_peephole2
20345   [(set (match_operand 0 "register_operand" "")
20346         (match_operand 1 "const0_operand" ""))]
20347   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20348    && (! TARGET_USE_MOV0 || optimize_size)
20349    && GENERAL_REG_P (operands[0])
20350    && peep2_regno_dead_p (0, FLAGS_REG)"
20351   [(parallel [(set (match_dup 0) (const_int 0))
20352               (clobber (reg:CC FLAGS_REG))])]
20353 {
20354   operands[0] = gen_lowpart (word_mode, operands[0]);
20355 })
20356
20357 (define_peephole2
20358   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20359         (const_int 0))]
20360   "(GET_MODE (operands[0]) == QImode
20361     || GET_MODE (operands[0]) == HImode)
20362    && (! TARGET_USE_MOV0 || optimize_size)
20363    && peep2_regno_dead_p (0, FLAGS_REG)"
20364   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20365               (clobber (reg:CC FLAGS_REG))])])
20366
20367 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20368 (define_peephole2
20369   [(set (match_operand 0 "register_operand" "")
20370         (const_int -1))]
20371   "(GET_MODE (operands[0]) == HImode
20372     || GET_MODE (operands[0]) == SImode
20373     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20374    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20375    && peep2_regno_dead_p (0, FLAGS_REG)"
20376   [(parallel [(set (match_dup 0) (const_int -1))
20377               (clobber (reg:CC FLAGS_REG))])]
20378   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20379                               operands[0]);")
20380
20381 ;; Attempt to convert simple leas to adds. These can be created by
20382 ;; move expanders.
20383 (define_peephole2
20384   [(set (match_operand:SI 0 "register_operand" "")
20385         (plus:SI (match_dup 0)
20386                  (match_operand:SI 1 "nonmemory_operand" "")))]
20387   "peep2_regno_dead_p (0, FLAGS_REG)"
20388   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20389               (clobber (reg:CC FLAGS_REG))])]
20390   "")
20391
20392 (define_peephole2
20393   [(set (match_operand:SI 0 "register_operand" "")
20394         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20395                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20396   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20397   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20398               (clobber (reg:CC FLAGS_REG))])]
20399   "operands[2] = gen_lowpart (SImode, operands[2]);")
20400
20401 (define_peephole2
20402   [(set (match_operand:DI 0 "register_operand" "")
20403         (plus:DI (match_dup 0)
20404                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20405   "peep2_regno_dead_p (0, FLAGS_REG)"
20406   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20407               (clobber (reg:CC FLAGS_REG))])]
20408   "")
20409
20410 (define_peephole2
20411   [(set (match_operand:SI 0 "register_operand" "")
20412         (mult:SI (match_dup 0)
20413                  (match_operand:SI 1 "const_int_operand" "")))]
20414   "exact_log2 (INTVAL (operands[1])) >= 0
20415    && peep2_regno_dead_p (0, FLAGS_REG)"
20416   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20417               (clobber (reg:CC FLAGS_REG))])]
20418   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20419
20420 (define_peephole2
20421   [(set (match_operand:DI 0 "register_operand" "")
20422         (mult:DI (match_dup 0)
20423                  (match_operand:DI 1 "const_int_operand" "")))]
20424   "exact_log2 (INTVAL (operands[1])) >= 0
20425    && peep2_regno_dead_p (0, FLAGS_REG)"
20426   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20427               (clobber (reg:CC FLAGS_REG))])]
20428   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20429
20430 (define_peephole2
20431   [(set (match_operand:SI 0 "register_operand" "")
20432         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20433                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20434   "exact_log2 (INTVAL (operands[2])) >= 0
20435    && REGNO (operands[0]) == REGNO (operands[1])
20436    && peep2_regno_dead_p (0, FLAGS_REG)"
20437   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20438               (clobber (reg:CC FLAGS_REG))])]
20439   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20440
20441 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20442 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20443 ;; many CPUs it is also faster, since special hardware to avoid esp
20444 ;; dependencies is present.
20445
20446 ;; While some of these conversions may be done using splitters, we use peepholes
20447 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20448
20449 ;; Convert prologue esp subtractions to push.
20450 ;; We need register to push.  In order to keep verify_flow_info happy we have
20451 ;; two choices
20452 ;; - use scratch and clobber it in order to avoid dependencies
20453 ;; - use already live register
20454 ;; We can't use the second way right now, since there is no reliable way how to
20455 ;; verify that given register is live.  First choice will also most likely in
20456 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20457 ;; call clobbered registers are dead.  We may want to use base pointer as an
20458 ;; alternative when no register is available later.
20459
20460 (define_peephole2
20461   [(match_scratch:SI 0 "r")
20462    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20463               (clobber (reg:CC FLAGS_REG))
20464               (clobber (mem:BLK (scratch)))])]
20465   "optimize_size || !TARGET_SUB_ESP_4"
20466   [(clobber (match_dup 0))
20467    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20468               (clobber (mem:BLK (scratch)))])])
20469
20470 (define_peephole2
20471   [(match_scratch:SI 0 "r")
20472    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20473               (clobber (reg:CC FLAGS_REG))
20474               (clobber (mem:BLK (scratch)))])]
20475   "optimize_size || !TARGET_SUB_ESP_8"
20476   [(clobber (match_dup 0))
20477    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20478    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20479               (clobber (mem:BLK (scratch)))])])
20480
20481 ;; Convert esp subtractions to push.
20482 (define_peephole2
20483   [(match_scratch:SI 0 "r")
20484    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20485               (clobber (reg:CC FLAGS_REG))])]
20486   "optimize_size || !TARGET_SUB_ESP_4"
20487   [(clobber (match_dup 0))
20488    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20489
20490 (define_peephole2
20491   [(match_scratch:SI 0 "r")
20492    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20493               (clobber (reg:CC FLAGS_REG))])]
20494   "optimize_size || !TARGET_SUB_ESP_8"
20495   [(clobber (match_dup 0))
20496    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20497    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20498
20499 ;; Convert epilogue deallocator to pop.
20500 (define_peephole2
20501   [(match_scratch:SI 0 "r")
20502    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20503               (clobber (reg:CC FLAGS_REG))
20504               (clobber (mem:BLK (scratch)))])]
20505   "optimize_size || !TARGET_ADD_ESP_4"
20506   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20507               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20508               (clobber (mem:BLK (scratch)))])]
20509   "")
20510
20511 ;; Two pops case is tricky, since pop causes dependency on destination register.
20512 ;; We use two registers if available.
20513 (define_peephole2
20514   [(match_scratch:SI 0 "r")
20515    (match_scratch:SI 1 "r")
20516    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20517               (clobber (reg:CC FLAGS_REG))
20518               (clobber (mem:BLK (scratch)))])]
20519   "optimize_size || !TARGET_ADD_ESP_8"
20520   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20521               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20522               (clobber (mem:BLK (scratch)))])
20523    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20524               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20525   "")
20526
20527 (define_peephole2
20528   [(match_scratch:SI 0 "r")
20529    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20530               (clobber (reg:CC FLAGS_REG))
20531               (clobber (mem:BLK (scratch)))])]
20532   "optimize_size"
20533   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20534               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20535               (clobber (mem:BLK (scratch)))])
20536    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20537               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20538   "")
20539
20540 ;; Convert esp additions to pop.
20541 (define_peephole2
20542   [(match_scratch:SI 0 "r")
20543    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20544               (clobber (reg:CC FLAGS_REG))])]
20545   ""
20546   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20547               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20548   "")
20549
20550 ;; Two pops case is tricky, since pop causes dependency on destination register.
20551 ;; We use two registers if available.
20552 (define_peephole2
20553   [(match_scratch:SI 0 "r")
20554    (match_scratch:SI 1 "r")
20555    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20556               (clobber (reg:CC FLAGS_REG))])]
20557   ""
20558   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20559               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20560    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20561               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20562   "")
20563
20564 (define_peephole2
20565   [(match_scratch:SI 0 "r")
20566    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20567               (clobber (reg:CC FLAGS_REG))])]
20568   "optimize_size"
20569   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20570               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20571    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20572               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20573   "")
20574 \f
20575 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20576 ;; required and register dies.  Similarly for 128 to plus -128.
20577 (define_peephole2
20578   [(set (match_operand 0 "flags_reg_operand" "")
20579         (match_operator 1 "compare_operator"
20580           [(match_operand 2 "register_operand" "")
20581            (match_operand 3 "const_int_operand" "")]))]
20582   "(INTVAL (operands[3]) == -1
20583     || INTVAL (operands[3]) == 1
20584     || INTVAL (operands[3]) == 128)
20585    && ix86_match_ccmode (insn, CCGCmode)
20586    && peep2_reg_dead_p (1, operands[2])"
20587   [(parallel [(set (match_dup 0)
20588                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20589               (clobber (match_dup 2))])]
20590   "")
20591 \f
20592 (define_peephole2
20593   [(match_scratch:DI 0 "r")
20594    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20595               (clobber (reg:CC FLAGS_REG))
20596               (clobber (mem:BLK (scratch)))])]
20597   "optimize_size || !TARGET_SUB_ESP_4"
20598   [(clobber (match_dup 0))
20599    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20600               (clobber (mem:BLK (scratch)))])])
20601
20602 (define_peephole2
20603   [(match_scratch:DI 0 "r")
20604    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20605               (clobber (reg:CC FLAGS_REG))
20606               (clobber (mem:BLK (scratch)))])]
20607   "optimize_size || !TARGET_SUB_ESP_8"
20608   [(clobber (match_dup 0))
20609    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20610    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20611               (clobber (mem:BLK (scratch)))])])
20612
20613 ;; Convert esp subtractions to push.
20614 (define_peephole2
20615   [(match_scratch:DI 0 "r")
20616    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20617               (clobber (reg:CC FLAGS_REG))])]
20618   "optimize_size || !TARGET_SUB_ESP_4"
20619   [(clobber (match_dup 0))
20620    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20621
20622 (define_peephole2
20623   [(match_scratch:DI 0 "r")
20624    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20625               (clobber (reg:CC FLAGS_REG))])]
20626   "optimize_size || !TARGET_SUB_ESP_8"
20627   [(clobber (match_dup 0))
20628    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20629    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20630
20631 ;; Convert epilogue deallocator to pop.
20632 (define_peephole2
20633   [(match_scratch:DI 0 "r")
20634    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20635               (clobber (reg:CC FLAGS_REG))
20636               (clobber (mem:BLK (scratch)))])]
20637   "optimize_size || !TARGET_ADD_ESP_4"
20638   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20639               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20640               (clobber (mem:BLK (scratch)))])]
20641   "")
20642
20643 ;; Two pops case is tricky, since pop causes dependency on destination register.
20644 ;; We use two registers if available.
20645 (define_peephole2
20646   [(match_scratch:DI 0 "r")
20647    (match_scratch:DI 1 "r")
20648    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20649               (clobber (reg:CC FLAGS_REG))
20650               (clobber (mem:BLK (scratch)))])]
20651   "optimize_size || !TARGET_ADD_ESP_8"
20652   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20653               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20654               (clobber (mem:BLK (scratch)))])
20655    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20656               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20657   "")
20658
20659 (define_peephole2
20660   [(match_scratch:DI 0 "r")
20661    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20662               (clobber (reg:CC FLAGS_REG))
20663               (clobber (mem:BLK (scratch)))])]
20664   "optimize_size"
20665   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20666               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20667               (clobber (mem:BLK (scratch)))])
20668    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20669               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20670   "")
20671
20672 ;; Convert esp additions to pop.
20673 (define_peephole2
20674   [(match_scratch:DI 0 "r")
20675    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20676               (clobber (reg:CC FLAGS_REG))])]
20677   ""
20678   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20679               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20680   "")
20681
20682 ;; Two pops case is tricky, since pop causes dependency on destination register.
20683 ;; We use two registers if available.
20684 (define_peephole2
20685   [(match_scratch:DI 0 "r")
20686    (match_scratch:DI 1 "r")
20687    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20688               (clobber (reg:CC FLAGS_REG))])]
20689   ""
20690   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20691               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20692    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20693               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20694   "")
20695
20696 (define_peephole2
20697   [(match_scratch:DI 0 "r")
20698    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20699               (clobber (reg:CC FLAGS_REG))])]
20700   "optimize_size"
20701   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20702               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20703    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20704               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20705   "")
20706 \f
20707 ;; Convert imul by three, five and nine into lea
20708 (define_peephole2
20709   [(parallel
20710     [(set (match_operand:SI 0 "register_operand" "")
20711           (mult:SI (match_operand:SI 1 "register_operand" "")
20712                    (match_operand:SI 2 "const_int_operand" "")))
20713      (clobber (reg:CC FLAGS_REG))])]
20714   "INTVAL (operands[2]) == 3
20715    || INTVAL (operands[2]) == 5
20716    || INTVAL (operands[2]) == 9"
20717   [(set (match_dup 0)
20718         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20719                  (match_dup 1)))]
20720   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20721
20722 (define_peephole2
20723   [(parallel
20724     [(set (match_operand:SI 0 "register_operand" "")
20725           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20726                    (match_operand:SI 2 "const_int_operand" "")))
20727      (clobber (reg:CC FLAGS_REG))])]
20728   "!optimize_size
20729    && (INTVAL (operands[2]) == 3
20730        || INTVAL (operands[2]) == 5
20731        || INTVAL (operands[2]) == 9)"
20732   [(set (match_dup 0) (match_dup 1))
20733    (set (match_dup 0)
20734         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20735                  (match_dup 0)))]
20736   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20737
20738 (define_peephole2
20739   [(parallel
20740     [(set (match_operand:DI 0 "register_operand" "")
20741           (mult:DI (match_operand:DI 1 "register_operand" "")
20742                    (match_operand:DI 2 "const_int_operand" "")))
20743      (clobber (reg:CC FLAGS_REG))])]
20744   "TARGET_64BIT
20745    && (INTVAL (operands[2]) == 3
20746        || INTVAL (operands[2]) == 5
20747        || INTVAL (operands[2]) == 9)"
20748   [(set (match_dup 0)
20749         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20750                  (match_dup 1)))]
20751   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20752
20753 (define_peephole2
20754   [(parallel
20755     [(set (match_operand:DI 0 "register_operand" "")
20756           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20757                    (match_operand:DI 2 "const_int_operand" "")))
20758      (clobber (reg:CC FLAGS_REG))])]
20759   "TARGET_64BIT
20760    && !optimize_size
20761    && (INTVAL (operands[2]) == 3
20762        || INTVAL (operands[2]) == 5
20763        || INTVAL (operands[2]) == 9)"
20764   [(set (match_dup 0) (match_dup 1))
20765    (set (match_dup 0)
20766         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20767                  (match_dup 0)))]
20768   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20769
20770 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20771 ;; imul $32bit_imm, reg, reg is direct decoded.
20772 (define_peephole2
20773   [(match_scratch:DI 3 "r")
20774    (parallel [(set (match_operand:DI 0 "register_operand" "")
20775                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20776                             (match_operand:DI 2 "immediate_operand" "")))
20777               (clobber (reg:CC FLAGS_REG))])]
20778   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20779    && !satisfies_constraint_K (operands[2])"
20780   [(set (match_dup 3) (match_dup 1))
20781    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20782               (clobber (reg:CC FLAGS_REG))])]
20783 "")
20784
20785 (define_peephole2
20786   [(match_scratch:SI 3 "r")
20787    (parallel [(set (match_operand:SI 0 "register_operand" "")
20788                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20789                             (match_operand:SI 2 "immediate_operand" "")))
20790               (clobber (reg:CC FLAGS_REG))])]
20791   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20792    && !satisfies_constraint_K (operands[2])"
20793   [(set (match_dup 3) (match_dup 1))
20794    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20795               (clobber (reg:CC FLAGS_REG))])]
20796 "")
20797
20798 (define_peephole2
20799   [(match_scratch:SI 3 "r")
20800    (parallel [(set (match_operand:DI 0 "register_operand" "")
20801                    (zero_extend:DI
20802                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20803                               (match_operand:SI 2 "immediate_operand" ""))))
20804               (clobber (reg:CC FLAGS_REG))])]
20805   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20806    && !satisfies_constraint_K (operands[2])"
20807   [(set (match_dup 3) (match_dup 1))
20808    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20809               (clobber (reg:CC FLAGS_REG))])]
20810 "")
20811
20812 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20813 ;; Convert it into imul reg, reg
20814 ;; It would be better to force assembler to encode instruction using long
20815 ;; immediate, but there is apparently no way to do so.
20816 (define_peephole2
20817   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20818                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20819                             (match_operand:DI 2 "const_int_operand" "")))
20820               (clobber (reg:CC FLAGS_REG))])
20821    (match_scratch:DI 3 "r")]
20822   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20823    && satisfies_constraint_K (operands[2])"
20824   [(set (match_dup 3) (match_dup 2))
20825    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20826               (clobber (reg:CC FLAGS_REG))])]
20827 {
20828   if (!rtx_equal_p (operands[0], operands[1]))
20829     emit_move_insn (operands[0], operands[1]);
20830 })
20831
20832 (define_peephole2
20833   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20834                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20835                             (match_operand:SI 2 "const_int_operand" "")))
20836               (clobber (reg:CC FLAGS_REG))])
20837    (match_scratch:SI 3 "r")]
20838   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20839    && satisfies_constraint_K (operands[2])"
20840   [(set (match_dup 3) (match_dup 2))
20841    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20842               (clobber (reg:CC FLAGS_REG))])]
20843 {
20844   if (!rtx_equal_p (operands[0], operands[1]))
20845     emit_move_insn (operands[0], operands[1]);
20846 })
20847
20848 (define_peephole2
20849   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20850                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20851                             (match_operand:HI 2 "immediate_operand" "")))
20852               (clobber (reg:CC FLAGS_REG))])
20853    (match_scratch:HI 3 "r")]
20854   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20855   [(set (match_dup 3) (match_dup 2))
20856    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20857               (clobber (reg:CC FLAGS_REG))])]
20858 {
20859   if (!rtx_equal_p (operands[0], operands[1]))
20860     emit_move_insn (operands[0], operands[1]);
20861 })
20862
20863 ;; After splitting up read-modify operations, array accesses with memory
20864 ;; operands might end up in form:
20865 ;;  sall    $2, %eax
20866 ;;  movl    4(%esp), %edx
20867 ;;  addl    %edx, %eax
20868 ;; instead of pre-splitting:
20869 ;;  sall    $2, %eax
20870 ;;  addl    4(%esp), %eax
20871 ;; Turn it into:
20872 ;;  movl    4(%esp), %edx
20873 ;;  leal    (%edx,%eax,4), %eax
20874
20875 (define_peephole2
20876   [(parallel [(set (match_operand 0 "register_operand" "")
20877                    (ashift (match_operand 1 "register_operand" "")
20878                            (match_operand 2 "const_int_operand" "")))
20879                (clobber (reg:CC FLAGS_REG))])
20880    (set (match_operand 3 "register_operand")
20881         (match_operand 4 "x86_64_general_operand" ""))
20882    (parallel [(set (match_operand 5 "register_operand" "")
20883                    (plus (match_operand 6 "register_operand" "")
20884                          (match_operand 7 "register_operand" "")))
20885                    (clobber (reg:CC FLAGS_REG))])]
20886   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20887    /* Validate MODE for lea.  */
20888    && ((!TARGET_PARTIAL_REG_STALL
20889         && (GET_MODE (operands[0]) == QImode
20890             || GET_MODE (operands[0]) == HImode))
20891        || GET_MODE (operands[0]) == SImode
20892        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20893    /* We reorder load and the shift.  */
20894    && !rtx_equal_p (operands[1], operands[3])
20895    && !reg_overlap_mentioned_p (operands[0], operands[4])
20896    /* Last PLUS must consist of operand 0 and 3.  */
20897    && !rtx_equal_p (operands[0], operands[3])
20898    && (rtx_equal_p (operands[3], operands[6])
20899        || rtx_equal_p (operands[3], operands[7]))
20900    && (rtx_equal_p (operands[0], operands[6])
20901        || rtx_equal_p (operands[0], operands[7]))
20902    /* The intermediate operand 0 must die or be same as output.  */
20903    && (rtx_equal_p (operands[0], operands[5])
20904        || peep2_reg_dead_p (3, operands[0]))"
20905   [(set (match_dup 3) (match_dup 4))
20906    (set (match_dup 0) (match_dup 1))]
20907 {
20908   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20909   int scale = 1 << INTVAL (operands[2]);
20910   rtx index = gen_lowpart (Pmode, operands[1]);
20911   rtx base = gen_lowpart (Pmode, operands[3]);
20912   rtx dest = gen_lowpart (mode, operands[5]);
20913
20914   operands[1] = gen_rtx_PLUS (Pmode, base,
20915                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20916   if (mode != Pmode)
20917     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20918   operands[0] = dest;
20919 })
20920 \f
20921 ;; Call-value patterns last so that the wildcard operand does not
20922 ;; disrupt insn-recog's switch tables.
20923
20924 (define_insn "*call_value_pop_0"
20925   [(set (match_operand 0 "" "")
20926         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20927               (match_operand:SI 2 "" "")))
20928    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20929                             (match_operand:SI 3 "immediate_operand" "")))]
20930   "!TARGET_64BIT"
20931 {
20932   if (SIBLING_CALL_P (insn))
20933     return "jmp\t%P1";
20934   else
20935     return "call\t%P1";
20936 }
20937   [(set_attr "type" "callv")])
20938
20939 (define_insn "*call_value_pop_1"
20940   [(set (match_operand 0 "" "")
20941         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20942               (match_operand:SI 2 "" "")))
20943    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20944                             (match_operand:SI 3 "immediate_operand" "i")))]
20945   "!TARGET_64BIT"
20946 {
20947   if (constant_call_address_operand (operands[1], Pmode))
20948     {
20949       if (SIBLING_CALL_P (insn))
20950         return "jmp\t%P1";
20951       else
20952         return "call\t%P1";
20953     }
20954   if (SIBLING_CALL_P (insn))
20955     return "jmp\t%A1";
20956   else
20957     return "call\t%A1";
20958 }
20959   [(set_attr "type" "callv")])
20960
20961 (define_insn "*call_value_0"
20962   [(set (match_operand 0 "" "")
20963         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20964               (match_operand:SI 2 "" "")))]
20965   "!TARGET_64BIT"
20966 {
20967   if (SIBLING_CALL_P (insn))
20968     return "jmp\t%P1";
20969   else
20970     return "call\t%P1";
20971 }
20972   [(set_attr "type" "callv")])
20973
20974 (define_insn "*call_value_0_rex64"
20975   [(set (match_operand 0 "" "")
20976         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20977               (match_operand:DI 2 "const_int_operand" "")))]
20978   "TARGET_64BIT"
20979 {
20980   if (SIBLING_CALL_P (insn))
20981     return "jmp\t%P1";
20982   else
20983     return "call\t%P1";
20984 }
20985   [(set_attr "type" "callv")])
20986
20987 (define_insn "*call_value_1"
20988   [(set (match_operand 0 "" "")
20989         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20990               (match_operand:SI 2 "" "")))]
20991   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20992 {
20993   if (constant_call_address_operand (operands[1], Pmode))
20994     return "call\t%P1";
20995   return "call\t%A1";
20996 }
20997   [(set_attr "type" "callv")])
20998
20999 (define_insn "*sibcall_value_1"
21000   [(set (match_operand 0 "" "")
21001         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21002               (match_operand:SI 2 "" "")))]
21003   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21004 {
21005   if (constant_call_address_operand (operands[1], Pmode))
21006     return "jmp\t%P1";
21007   return "jmp\t%A1";
21008 }
21009   [(set_attr "type" "callv")])
21010
21011 (define_insn "*call_value_1_rex64"
21012   [(set (match_operand 0 "" "")
21013         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21014               (match_operand:DI 2 "" "")))]
21015   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21016    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21017 {
21018   if (constant_call_address_operand (operands[1], Pmode))
21019     return "call\t%P1";
21020   return "call\t%A1";
21021 }
21022   [(set_attr "type" "callv")])
21023
21024 (define_insn "*call_value_1_rex64_large"
21025   [(set (match_operand 0 "" "")
21026         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21027               (match_operand:DI 2 "" "")))]
21028   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21029   "call\t%A1"
21030   [(set_attr "type" "callv")])
21031
21032 (define_insn "*sibcall_value_1_rex64"
21033   [(set (match_operand 0 "" "")
21034         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21035               (match_operand:DI 2 "" "")))]
21036   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21037   "jmp\t%P1"
21038   [(set_attr "type" "callv")])
21039
21040 (define_insn "*sibcall_value_1_rex64_v"
21041   [(set (match_operand 0 "" "")
21042         (call (mem:QI (reg:DI R11_REG))
21043               (match_operand:DI 1 "" "")))]
21044   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21045   "jmp\t*%%r11"
21046   [(set_attr "type" "callv")])
21047 \f
21048 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21049 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21050 ;; caught for use by garbage collectors and the like.  Using an insn that
21051 ;; maps to SIGILL makes it more likely the program will rightfully die.
21052 ;; Keeping with tradition, "6" is in honor of #UD.
21053 (define_insn "trap"
21054   [(trap_if (const_int 1) (const_int 6))]
21055   ""
21056   { return ASM_SHORT "0x0b0f"; }
21057   [(set_attr "length" "2")])
21058
21059 (define_expand "sse_prologue_save"
21060   [(parallel [(set (match_operand:BLK 0 "" "")
21061                    (unspec:BLK [(reg:DI 21)
21062                                 (reg:DI 22)
21063                                 (reg:DI 23)
21064                                 (reg:DI 24)
21065                                 (reg:DI 25)
21066                                 (reg:DI 26)
21067                                 (reg:DI 27)
21068                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21069               (use (match_operand:DI 1 "register_operand" ""))
21070               (use (match_operand:DI 2 "immediate_operand" ""))
21071               (use (label_ref:DI (match_operand 3 "" "")))])]
21072   "TARGET_64BIT"
21073   "")
21074
21075 (define_insn "*sse_prologue_save_insn"
21076   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21077                           (match_operand:DI 4 "const_int_operand" "n")))
21078         (unspec:BLK [(reg:DI 21)
21079                      (reg:DI 22)
21080                      (reg:DI 23)
21081                      (reg:DI 24)
21082                      (reg:DI 25)
21083                      (reg:DI 26)
21084                      (reg:DI 27)
21085                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21086    (use (match_operand:DI 1 "register_operand" "r"))
21087    (use (match_operand:DI 2 "const_int_operand" "i"))
21088    (use (label_ref:DI (match_operand 3 "" "X")))]
21089   "TARGET_64BIT
21090    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21091    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21092   "*
21093 {
21094   int i;
21095   operands[0] = gen_rtx_MEM (Pmode,
21096                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21097   output_asm_insn (\"jmp\\t%A1\", operands);
21098   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21099     {
21100       operands[4] = adjust_address (operands[0], DImode, i*16);
21101       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21102       PUT_MODE (operands[4], TImode);
21103       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21104         output_asm_insn (\"rex\", operands);
21105       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21106     }
21107   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21108                              CODE_LABEL_NUMBER (operands[3]));
21109   return \"\";
21110 }
21111   "
21112   [(set_attr "type" "other")
21113    (set_attr "length_immediate" "0")
21114    (set_attr "length_address" "0")
21115    (set_attr "length" "135")
21116    (set_attr "memory" "store")
21117    (set_attr "modrm" "0")
21118    (set_attr "mode" "DI")])
21119
21120 (define_expand "prefetch"
21121   [(prefetch (match_operand 0 "address_operand" "")
21122              (match_operand:SI 1 "const_int_operand" "")
21123              (match_operand:SI 2 "const_int_operand" ""))]
21124   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21125 {
21126   int rw = INTVAL (operands[1]);
21127   int locality = INTVAL (operands[2]);
21128
21129   gcc_assert (rw == 0 || rw == 1);
21130   gcc_assert (locality >= 0 && locality <= 3);
21131   gcc_assert (GET_MODE (operands[0]) == Pmode
21132               || GET_MODE (operands[0]) == VOIDmode);
21133
21134   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21135      supported by SSE counterpart or the SSE prefetch is not available
21136      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21137      of locality.  */
21138   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21139     operands[2] = GEN_INT (3);
21140   else
21141     operands[1] = const0_rtx;
21142 })
21143
21144 (define_insn "*prefetch_sse"
21145   [(prefetch (match_operand:SI 0 "address_operand" "p")
21146              (const_int 0)
21147              (match_operand:SI 1 "const_int_operand" ""))]
21148   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21149 {
21150   static const char * const patterns[4] = {
21151    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21152   };
21153
21154   int locality = INTVAL (operands[1]);
21155   gcc_assert (locality >= 0 && locality <= 3);
21156
21157   return patterns[locality];
21158 }
21159   [(set_attr "type" "sse")
21160    (set_attr "memory" "none")])
21161
21162 (define_insn "*prefetch_sse_rex"
21163   [(prefetch (match_operand:DI 0 "address_operand" "p")
21164              (const_int 0)
21165              (match_operand:SI 1 "const_int_operand" ""))]
21166   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21167 {
21168   static const char * const patterns[4] = {
21169    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21170   };
21171
21172   int locality = INTVAL (operands[1]);
21173   gcc_assert (locality >= 0 && locality <= 3);
21174
21175   return patterns[locality];
21176 }
21177   [(set_attr "type" "sse")
21178    (set_attr "memory" "none")])
21179
21180 (define_insn "*prefetch_3dnow"
21181   [(prefetch (match_operand:SI 0 "address_operand" "p")
21182              (match_operand:SI 1 "const_int_operand" "n")
21183              (const_int 3))]
21184   "TARGET_3DNOW && !TARGET_64BIT"
21185 {
21186   if (INTVAL (operands[1]) == 0)
21187     return "prefetch\t%a0";
21188   else
21189     return "prefetchw\t%a0";
21190 }
21191   [(set_attr "type" "mmx")
21192    (set_attr "memory" "none")])
21193
21194 (define_insn "*prefetch_3dnow_rex"
21195   [(prefetch (match_operand:DI 0 "address_operand" "p")
21196              (match_operand:SI 1 "const_int_operand" "n")
21197              (const_int 3))]
21198   "TARGET_3DNOW && TARGET_64BIT"
21199 {
21200   if (INTVAL (operands[1]) == 0)
21201     return "prefetch\t%a0";
21202   else
21203     return "prefetchw\t%a0";
21204 }
21205   [(set_attr "type" "mmx")
21206    (set_attr "memory" "none")])
21207
21208 (define_expand "stack_protect_set"
21209   [(match_operand 0 "memory_operand" "")
21210    (match_operand 1 "memory_operand" "")]
21211   ""
21212 {
21213 #ifdef TARGET_THREAD_SSP_OFFSET
21214   if (TARGET_64BIT)
21215     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21216                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21217   else
21218     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21219                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21220 #else
21221   if (TARGET_64BIT)
21222     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21223   else
21224     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21225 #endif
21226   DONE;
21227 })
21228
21229 (define_insn "stack_protect_set_si"
21230   [(set (match_operand:SI 0 "memory_operand" "=m")
21231         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21232    (set (match_scratch:SI 2 "=&r") (const_int 0))
21233    (clobber (reg:CC FLAGS_REG))]
21234   ""
21235   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21236   [(set_attr "type" "multi")])
21237
21238 (define_insn "stack_protect_set_di"
21239   [(set (match_operand:DI 0 "memory_operand" "=m")
21240         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21241    (set (match_scratch:DI 2 "=&r") (const_int 0))
21242    (clobber (reg:CC FLAGS_REG))]
21243   "TARGET_64BIT"
21244   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21245   [(set_attr "type" "multi")])
21246
21247 (define_insn "stack_tls_protect_set_si"
21248   [(set (match_operand:SI 0 "memory_operand" "=m")
21249         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21250    (set (match_scratch:SI 2 "=&r") (const_int 0))
21251    (clobber (reg:CC FLAGS_REG))]
21252   ""
21253   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21254   [(set_attr "type" "multi")])
21255
21256 (define_insn "stack_tls_protect_set_di"
21257   [(set (match_operand:DI 0 "memory_operand" "=m")
21258         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21259    (set (match_scratch:DI 2 "=&r") (const_int 0))
21260    (clobber (reg:CC FLAGS_REG))]
21261   "TARGET_64BIT"
21262   {
21263      /* The kernel uses a different segment register for performance reasons; a
21264         system call would not have to trash the userspace segment register,
21265         which would be expensive */
21266      if (ix86_cmodel != CM_KERNEL)
21267         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21268      else
21269         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21270   }
21271   [(set_attr "type" "multi")])
21272
21273 (define_expand "stack_protect_test"
21274   [(match_operand 0 "memory_operand" "")
21275    (match_operand 1 "memory_operand" "")
21276    (match_operand 2 "" "")]
21277   ""
21278 {
21279   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21280   ix86_compare_op0 = operands[0];
21281   ix86_compare_op1 = operands[1];
21282   ix86_compare_emitted = flags;
21283
21284 #ifdef TARGET_THREAD_SSP_OFFSET
21285   if (TARGET_64BIT)
21286     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21287                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21288   else
21289     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21290                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21291 #else
21292   if (TARGET_64BIT)
21293     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21294   else
21295     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21296 #endif
21297   emit_jump_insn (gen_beq (operands[2]));
21298   DONE;
21299 })
21300
21301 (define_insn "stack_protect_test_si"
21302   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21303         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21304                      (match_operand:SI 2 "memory_operand" "m")]
21305                     UNSPEC_SP_TEST))
21306    (clobber (match_scratch:SI 3 "=&r"))]
21307   ""
21308   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21309   [(set_attr "type" "multi")])
21310
21311 (define_insn "stack_protect_test_di"
21312   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21313         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21314                      (match_operand:DI 2 "memory_operand" "m")]
21315                     UNSPEC_SP_TEST))
21316    (clobber (match_scratch:DI 3 "=&r"))]
21317   "TARGET_64BIT"
21318   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21319   [(set_attr "type" "multi")])
21320
21321 (define_insn "stack_tls_protect_test_si"
21322   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21323         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21324                      (match_operand:SI 2 "const_int_operand" "i")]
21325                     UNSPEC_SP_TLS_TEST))
21326    (clobber (match_scratch:SI 3 "=r"))]
21327   ""
21328   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21329   [(set_attr "type" "multi")])
21330
21331 (define_insn "stack_tls_protect_test_di"
21332   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21333         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21334                      (match_operand:DI 2 "const_int_operand" "i")]
21335                     UNSPEC_SP_TLS_TEST))
21336    (clobber (match_scratch:DI 3 "=r"))]
21337   "TARGET_64BIT"
21338   {
21339      /* The kernel uses a different segment register for performance reasons; a
21340         system call would not have to trash the userspace segment register,
21341         which would be expensive */
21342      if (ix86_cmodel != CM_KERNEL)
21343         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21344      else
21345         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21346   }
21347   [(set_attr "type" "multi")])
21348
21349 (define_mode_iterator CRC32MODE [QI HI SI])
21350 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21351 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21352
21353 (define_insn "sse4_2_crc32<mode>"
21354   [(set (match_operand:SI 0 "register_operand" "=r")
21355         (unspec:SI
21356           [(match_operand:SI 1 "register_operand" "0")
21357            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21358           UNSPEC_CRC32))]
21359   "TARGET_SSE4_2"
21360   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21361   [(set_attr "type" "sselog1")
21362    (set_attr "prefix_rep" "1")
21363    (set_attr "prefix_extra" "1")
21364    (set_attr "mode" "SI")])
21365
21366 (define_insn "sse4_2_crc32di"
21367   [(set (match_operand:DI 0 "register_operand" "=r")
21368         (unspec:DI
21369           [(match_operand:DI 1 "register_operand" "0")
21370            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21371           UNSPEC_CRC32))]
21372   "TARGET_SSE4_2 && TARGET_64BIT"
21373   "crc32q\t{%2, %0|%0, %2}"
21374   [(set_attr "type" "sselog1")
21375    (set_attr "prefix_rep" "1")
21376    (set_attr "prefix_extra" "1")
21377    (set_attr "mode" "DI")])
21378
21379 (include "mmx.md")
21380 (include "sse.md")
21381 (include "sync.md")