OSDN Git Service

* config/i386/i386.md (standard sse constant splitter): Handle TFmode.
[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 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; The special asm out single letter directives following a '%' are:
31 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;;     operands[1].
33 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
34 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
35 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
36 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
37 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
38 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
39 ;; 'J' Print the appropriate jump operand.
40 ;;
41 ;; 'b' Print the QImode name of the register for the indicated operand.
42 ;;     %b0 would print %al if operands[0] is reg 0.
43 ;; 'w' Likewise, print the HImode name of the register.
44 ;; 'k' Likewise, print the SImode name of the register.
45 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
46 ;; 'y' Print "st(0)" instead of "st" as a register.
47
48 ;; UNSPEC usage:
49
50 (define_constants
51   [; Relocation specifiers
52    (UNSPEC_GOT                  0)
53    (UNSPEC_GOTOFF               1)
54    (UNSPEC_GOTPCREL             2)
55    (UNSPEC_GOTTPOFF             3)
56    (UNSPEC_TPOFF                4)
57    (UNSPEC_NTPOFF               5)
58    (UNSPEC_DTPOFF               6)
59    (UNSPEC_GOTNTPOFF            7)
60    (UNSPEC_INDNTPOFF            8)
61    (UNSPEC_PLTOFF               9)
62
63    ; Prologue support
64    (UNSPEC_STACK_ALLOC          11)
65    (UNSPEC_SET_GOT              12)
66    (UNSPEC_SSE_PROLOGUE_SAVE    13)
67    (UNSPEC_REG_SAVE             14)
68    (UNSPEC_DEF_CFA              15)
69    (UNSPEC_SET_RIP              16)
70    (UNSPEC_SET_GOT_OFFSET       17)
71
72    ; TLS support
73    (UNSPEC_TP                   18)
74    (UNSPEC_TLS_GD               19)
75    (UNSPEC_TLS_LD_BASE          20)
76    (UNSPEC_TLSDESC              21)
77
78    ; Other random patterns
79    (UNSPEC_SCAS                 30)
80    (UNSPEC_FNSTSW               31)
81    (UNSPEC_SAHF                 32)
82    (UNSPEC_FSTCW                33)
83    (UNSPEC_ADD_CARRY            34)
84    (UNSPEC_FLDCW                35)
85    (UNSPEC_REP                  36)
86    (UNSPEC_EH_RETURN            37)
87    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
88    (UNSPEC_TRUNC_NOOP           39)
89
90    ; For SSE/MMX support:
91    (UNSPEC_FIX_NOTRUNC          40)
92    (UNSPEC_MASKMOV              41)
93    (UNSPEC_MOVMSK               42)
94    (UNSPEC_MOVNT                43)
95    (UNSPEC_MOVU                 44)
96    (UNSPEC_RCP                  45)
97    (UNSPEC_RSQRT                46)
98    (UNSPEC_SFENCE               47)
99    (UNSPEC_NOP                  48)     ; prevents combiner cleverness
100    (UNSPEC_PFRCP                49)
101    (UNSPEC_PFRCPIT1             40)
102    (UNSPEC_PFRCPIT2             41)
103    (UNSPEC_PFRSQRT              42)
104    (UNSPEC_PFRSQIT1             43)
105    (UNSPEC_MFENCE               44)
106    (UNSPEC_LFENCE               45)
107    (UNSPEC_PSADBW               46)
108    (UNSPEC_LDDQU                47)
109
110    ; Generic math support
111    (UNSPEC_COPYSIGN             50)
112    (UNSPEC_IEEE_MIN             51)     ; not commutative
113    (UNSPEC_IEEE_MAX             52)     ; not commutative
114
115    ; x87 Floating point
116    (UNSPEC_SIN                  60)
117    (UNSPEC_COS                  61)
118    (UNSPEC_FPATAN               62)
119    (UNSPEC_FYL2X                63)
120    (UNSPEC_FYL2XP1              64)
121    (UNSPEC_FRNDINT              65)
122    (UNSPEC_FIST                 66)
123    (UNSPEC_F2XM1                67)
124    (UNSPEC_TAN                  68)
125    (UNSPEC_FXAM                 69)
126
127    ; x87 Rounding
128    (UNSPEC_FRNDINT_FLOOR        70)
129    (UNSPEC_FRNDINT_CEIL         71)
130    (UNSPEC_FRNDINT_TRUNC        72)
131    (UNSPEC_FRNDINT_MASK_PM      73)
132    (UNSPEC_FIST_FLOOR           74)
133    (UNSPEC_FIST_CEIL            75)
134
135    ; x87 Double output FP
136    (UNSPEC_SINCOS_COS           80)
137    (UNSPEC_SINCOS_SIN           81)
138    (UNSPEC_XTRACT_FRACT         84)
139    (UNSPEC_XTRACT_EXP           85)
140    (UNSPEC_FSCALE_FRACT         86)
141    (UNSPEC_FSCALE_EXP           87)
142    (UNSPEC_FPREM_F              88)
143    (UNSPEC_FPREM_U              89)
144    (UNSPEC_FPREM1_F             90)
145    (UNSPEC_FPREM1_U             91)
146
147    (UNSPEC_C2_FLAG              95)
148
149    ; SSP patterns
150    (UNSPEC_SP_SET               100)
151    (UNSPEC_SP_TEST              101)
152    (UNSPEC_SP_TLS_SET           102)
153    (UNSPEC_SP_TLS_TEST          103)
154
155    ; SSSE3
156    (UNSPEC_PSHUFB               120)
157    (UNSPEC_PSIGN                121)
158    (UNSPEC_PALIGNR              122)
159
160    ; For SSE4A support
161    (UNSPEC_EXTRQI               130)
162    (UNSPEC_EXTRQ                131)   
163    (UNSPEC_INSERTQI             132)
164    (UNSPEC_INSERTQ              133)
165
166    ; For SSE4.1 support
167    (UNSPEC_BLENDV               134)
168    (UNSPEC_INSERTPS             135)
169    (UNSPEC_DP                   136)
170    (UNSPEC_MOVNTDQA             137)
171    (UNSPEC_MPSADBW              138)
172    (UNSPEC_PHMINPOSUW           139)
173    (UNSPEC_PTEST                140)
174    (UNSPEC_ROUND                141)
175
176    ; For SSE4.2 support
177    (UNSPEC_CRC32                143)
178    (UNSPEC_PCMPESTR             144)
179    (UNSPEC_PCMPISTR             145)
180   ])
181
182 (define_constants
183   [(UNSPECV_BLOCKAGE            0)
184    (UNSPECV_STACK_PROBE         1)
185    (UNSPECV_EMMS                2)
186    (UNSPECV_LDMXCSR             3)
187    (UNSPECV_STMXCSR             4)
188    (UNSPECV_FEMMS               5)
189    (UNSPECV_CLFLUSH             6)
190    (UNSPECV_ALIGN               7)
191    (UNSPECV_MONITOR             8)
192    (UNSPECV_MWAIT               9)
193    (UNSPECV_CMPXCHG_1           10)
194    (UNSPECV_CMPXCHG_2           11)
195    (UNSPECV_XCHG                12)
196    (UNSPECV_LOCK                13)
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 ;; All x87 floating point modes
492 (define_mode_macro X87MODEF [SF DF XF])
493
494 ;; x87 SFmode and DFMode floating point modes
495 (define_mode_macro X87MODEF12 [SF DF])
496
497 ;; All integer modes handled by x87 fisttp operator.
498 (define_mode_macro X87MODEI [HI SI DI])
499
500 ;; All integer modes handled by integer x87 operators.
501 (define_mode_macro X87MODEI12 [HI SI])
502
503 ;; All SSE floating point modes
504 (define_mode_macro SSEMODEF [SF DF])
505
506 ;; All integer modes handled by SSE cvtts?2si* operators.
507 (define_mode_macro SSEMODEI24 [SI DI])
508
509 ;; SSE asm suffix for floating point modes
510 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
511
512 ;; SSE vector mode corresponding to a scalar mode
513 (define_mode_attr ssevecmode
514   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
515 \f
516 ;; Scheduling descriptions
517
518 (include "pentium.md")
519 (include "ppro.md")
520 (include "k6.md")
521 (include "athlon.md")
522 (include "geode.md")
523
524 \f
525 ;; Operand and operator predicates and constraints
526
527 (include "predicates.md")
528 (include "constraints.md")
529
530 \f
531 ;; Compare instructions.
532
533 ;; All compare insns have expanders that save the operands away without
534 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
535 ;; after the cmp) will actually emit the cmpM.
536
537 (define_expand "cmpti"
538   [(set (reg:CC FLAGS_REG)
539         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
540                     (match_operand:TI 1 "x86_64_general_operand" "")))]
541   "TARGET_64BIT"
542 {
543   if (MEM_P (operands[0]) && MEM_P (operands[1]))
544     operands[0] = force_reg (TImode, operands[0]);
545   ix86_compare_op0 = operands[0];
546   ix86_compare_op1 = operands[1];
547   DONE;
548 })
549
550 (define_expand "cmpdi"
551   [(set (reg:CC FLAGS_REG)
552         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
553                     (match_operand:DI 1 "x86_64_general_operand" "")))]
554   ""
555 {
556   if (MEM_P (operands[0]) && MEM_P (operands[1]))
557     operands[0] = force_reg (DImode, operands[0]);
558   ix86_compare_op0 = operands[0];
559   ix86_compare_op1 = operands[1];
560   DONE;
561 })
562
563 (define_expand "cmpsi"
564   [(set (reg:CC FLAGS_REG)
565         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
566                     (match_operand:SI 1 "general_operand" "")))]
567   ""
568 {
569   if (MEM_P (operands[0]) && MEM_P (operands[1]))
570     operands[0] = force_reg (SImode, operands[0]);
571   ix86_compare_op0 = operands[0];
572   ix86_compare_op1 = operands[1];
573   DONE;
574 })
575
576 (define_expand "cmphi"
577   [(set (reg:CC FLAGS_REG)
578         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
579                     (match_operand:HI 1 "general_operand" "")))]
580   ""
581 {
582   if (MEM_P (operands[0]) && MEM_P (operands[1]))
583     operands[0] = force_reg (HImode, operands[0]);
584   ix86_compare_op0 = operands[0];
585   ix86_compare_op1 = operands[1];
586   DONE;
587 })
588
589 (define_expand "cmpqi"
590   [(set (reg:CC FLAGS_REG)
591         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
592                     (match_operand:QI 1 "general_operand" "")))]
593   "TARGET_QIMODE_MATH"
594 {
595   if (MEM_P (operands[0]) && MEM_P (operands[1]))
596     operands[0] = force_reg (QImode, operands[0]);
597   ix86_compare_op0 = operands[0];
598   ix86_compare_op1 = operands[1];
599   DONE;
600 })
601
602 (define_insn "cmpdi_ccno_1_rex64"
603   [(set (reg FLAGS_REG)
604         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
605                  (match_operand:DI 1 "const0_operand" "n,n")))]
606   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
607   "@
608    test{q}\t%0, %0
609    cmp{q}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "test,icmp")
611    (set_attr "length_immediate" "0,1")
612    (set_attr "mode" "DI")])
613
614 (define_insn "*cmpdi_minus_1_rex64"
615   [(set (reg FLAGS_REG)
616         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
617                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
618                  (const_int 0)))]
619   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
620   "cmp{q}\t{%1, %0|%0, %1}"
621   [(set_attr "type" "icmp")
622    (set_attr "mode" "DI")])
623
624 (define_expand "cmpdi_1_rex64"
625   [(set (reg:CC FLAGS_REG)
626         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
627                     (match_operand:DI 1 "general_operand" "")))]
628   "TARGET_64BIT"
629   "")
630
631 (define_insn "cmpdi_1_insn_rex64"
632   [(set (reg FLAGS_REG)
633         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
634                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
635   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
636   "cmp{q}\t{%1, %0|%0, %1}"
637   [(set_attr "type" "icmp")
638    (set_attr "mode" "DI")])
639
640
641 (define_insn "*cmpsi_ccno_1"
642   [(set (reg FLAGS_REG)
643         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
644                  (match_operand:SI 1 "const0_operand" "n,n")))]
645   "ix86_match_ccmode (insn, CCNOmode)"
646   "@
647    test{l}\t%0, %0
648    cmp{l}\t{%1, %0|%0, %1}"
649   [(set_attr "type" "test,icmp")
650    (set_attr "length_immediate" "0,1")
651    (set_attr "mode" "SI")])
652
653 (define_insn "*cmpsi_minus_1"
654   [(set (reg FLAGS_REG)
655         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
656                            (match_operand:SI 1 "general_operand" "ri,mr"))
657                  (const_int 0)))]
658   "ix86_match_ccmode (insn, CCGOCmode)"
659   "cmp{l}\t{%1, %0|%0, %1}"
660   [(set_attr "type" "icmp")
661    (set_attr "mode" "SI")])
662
663 (define_expand "cmpsi_1"
664   [(set (reg:CC FLAGS_REG)
665         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
666                     (match_operand:SI 1 "general_operand" "ri,mr")))]
667   ""
668   "")
669
670 (define_insn "*cmpsi_1_insn"
671   [(set (reg FLAGS_REG)
672         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
673                  (match_operand:SI 1 "general_operand" "ri,mr")))]
674   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
675     && ix86_match_ccmode (insn, CCmode)"
676   "cmp{l}\t{%1, %0|%0, %1}"
677   [(set_attr "type" "icmp")
678    (set_attr "mode" "SI")])
679
680 (define_insn "*cmphi_ccno_1"
681   [(set (reg FLAGS_REG)
682         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
683                  (match_operand:HI 1 "const0_operand" "n,n")))]
684   "ix86_match_ccmode (insn, CCNOmode)"
685   "@
686    test{w}\t%0, %0
687    cmp{w}\t{%1, %0|%0, %1}"
688   [(set_attr "type" "test,icmp")
689    (set_attr "length_immediate" "0,1")
690    (set_attr "mode" "HI")])
691
692 (define_insn "*cmphi_minus_1"
693   [(set (reg FLAGS_REG)
694         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
695                            (match_operand:HI 1 "general_operand" "ri,mr"))
696                  (const_int 0)))]
697   "ix86_match_ccmode (insn, CCGOCmode)"
698   "cmp{w}\t{%1, %0|%0, %1}"
699   [(set_attr "type" "icmp")
700    (set_attr "mode" "HI")])
701
702 (define_insn "*cmphi_1"
703   [(set (reg FLAGS_REG)
704         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
705                  (match_operand:HI 1 "general_operand" "ri,mr")))]
706   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
707    && ix86_match_ccmode (insn, CCmode)"
708   "cmp{w}\t{%1, %0|%0, %1}"
709   [(set_attr "type" "icmp")
710    (set_attr "mode" "HI")])
711
712 (define_insn "*cmpqi_ccno_1"
713   [(set (reg FLAGS_REG)
714         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
715                  (match_operand:QI 1 "const0_operand" "n,n")))]
716   "ix86_match_ccmode (insn, CCNOmode)"
717   "@
718    test{b}\t%0, %0
719    cmp{b}\t{$0, %0|%0, 0}"
720   [(set_attr "type" "test,icmp")
721    (set_attr "length_immediate" "0,1")
722    (set_attr "mode" "QI")])
723
724 (define_insn "*cmpqi_1"
725   [(set (reg FLAGS_REG)
726         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
727                  (match_operand:QI 1 "general_operand" "qi,mq")))]
728   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
729     && ix86_match_ccmode (insn, CCmode)"
730   "cmp{b}\t{%1, %0|%0, %1}"
731   [(set_attr "type" "icmp")
732    (set_attr "mode" "QI")])
733
734 (define_insn "*cmpqi_minus_1"
735   [(set (reg FLAGS_REG)
736         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
737                            (match_operand:QI 1 "general_operand" "qi,mq"))
738                  (const_int 0)))]
739   "ix86_match_ccmode (insn, CCGOCmode)"
740   "cmp{b}\t{%1, %0|%0, %1}"
741   [(set_attr "type" "icmp")
742    (set_attr "mode" "QI")])
743
744 (define_insn "*cmpqi_ext_1"
745   [(set (reg FLAGS_REG)
746         (compare
747           (match_operand:QI 0 "general_operand" "Qm")
748           (subreg:QI
749             (zero_extract:SI
750               (match_operand 1 "ext_register_operand" "Q")
751               (const_int 8)
752               (const_int 8)) 0)))]
753   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
754   "cmp{b}\t{%h1, %0|%0, %h1}"
755   [(set_attr "type" "icmp")
756    (set_attr "mode" "QI")])
757
758 (define_insn "*cmpqi_ext_1_rex64"
759   [(set (reg FLAGS_REG)
760         (compare
761           (match_operand:QI 0 "register_operand" "Q")
762           (subreg:QI
763             (zero_extract:SI
764               (match_operand 1 "ext_register_operand" "Q")
765               (const_int 8)
766               (const_int 8)) 0)))]
767   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
768   "cmp{b}\t{%h1, %0|%0, %h1}"
769   [(set_attr "type" "icmp")
770    (set_attr "mode" "QI")])
771
772 (define_insn "*cmpqi_ext_2"
773   [(set (reg FLAGS_REG)
774         (compare
775           (subreg:QI
776             (zero_extract:SI
777               (match_operand 0 "ext_register_operand" "Q")
778               (const_int 8)
779               (const_int 8)) 0)
780           (match_operand:QI 1 "const0_operand" "n")))]
781   "ix86_match_ccmode (insn, CCNOmode)"
782   "test{b}\t%h0, %h0"
783   [(set_attr "type" "test")
784    (set_attr "length_immediate" "0")
785    (set_attr "mode" "QI")])
786
787 (define_expand "cmpqi_ext_3"
788   [(set (reg:CC FLAGS_REG)
789         (compare:CC
790           (subreg:QI
791             (zero_extract:SI
792               (match_operand 0 "ext_register_operand" "")
793               (const_int 8)
794               (const_int 8)) 0)
795           (match_operand:QI 1 "general_operand" "")))]
796   ""
797   "")
798
799 (define_insn "cmpqi_ext_3_insn"
800   [(set (reg FLAGS_REG)
801         (compare
802           (subreg:QI
803             (zero_extract:SI
804               (match_operand 0 "ext_register_operand" "Q")
805               (const_int 8)
806               (const_int 8)) 0)
807           (match_operand:QI 1 "general_operand" "Qmn")))]
808   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
809   "cmp{b}\t{%1, %h0|%h0, %1}"
810   [(set_attr "type" "icmp")
811    (set_attr "mode" "QI")])
812
813 (define_insn "cmpqi_ext_3_insn_rex64"
814   [(set (reg FLAGS_REG)
815         (compare
816           (subreg:QI
817             (zero_extract:SI
818               (match_operand 0 "ext_register_operand" "Q")
819               (const_int 8)
820               (const_int 8)) 0)
821           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
822   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
823   "cmp{b}\t{%1, %h0|%h0, %1}"
824   [(set_attr "type" "icmp")
825    (set_attr "mode" "QI")])
826
827 (define_insn "*cmpqi_ext_4"
828   [(set (reg FLAGS_REG)
829         (compare
830           (subreg:QI
831             (zero_extract:SI
832               (match_operand 0 "ext_register_operand" "Q")
833               (const_int 8)
834               (const_int 8)) 0)
835           (subreg:QI
836             (zero_extract:SI
837               (match_operand 1 "ext_register_operand" "Q")
838               (const_int 8)
839               (const_int 8)) 0)))]
840   "ix86_match_ccmode (insn, CCmode)"
841   "cmp{b}\t{%h1, %h0|%h0, %h1}"
842   [(set_attr "type" "icmp")
843    (set_attr "mode" "QI")])
844
845 ;; These implement float point compares.
846 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
847 ;; which would allow mix and match FP modes on the compares.  Which is what
848 ;; the old patterns did, but with many more of them.
849
850 (define_expand "cmpxf"
851   [(set (reg:CC FLAGS_REG)
852         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
853                     (match_operand:XF 1 "nonmemory_operand" "")))]
854   "TARGET_80387"
855 {
856   ix86_compare_op0 = operands[0];
857   ix86_compare_op1 = operands[1];
858   DONE;
859 })
860
861 (define_expand "cmp<mode>"
862   [(set (reg:CC FLAGS_REG)
863         (compare:CC (match_operand:SSEMODEF 0 "cmp_fp_expander_operand" "")
864                     (match_operand:SSEMODEF 1 "cmp_fp_expander_operand" "")))]
865   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
866 {
867   ix86_compare_op0 = operands[0];
868   ix86_compare_op1 = operands[1];
869   DONE;
870 })
871
872 ;; FP compares, step 1:
873 ;; Set the FP condition codes.
874 ;;
875 ;; CCFPmode     compare with exceptions
876 ;; CCFPUmode    compare with no exceptions
877
878 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
879 ;; used to manage the reg stack popping would not be preserved.
880
881 (define_insn "*cmpfp_0"
882   [(set (match_operand:HI 0 "register_operand" "=a")
883         (unspec:HI
884           [(compare:CCFP
885              (match_operand 1 "register_operand" "f")
886              (match_operand 2 "const0_operand" "X"))]
887         UNSPEC_FNSTSW))]
888   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
889    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
890   "* return output_fp_compare (insn, operands, 0, 0);"
891   [(set_attr "type" "multi")
892    (set_attr "unit" "i387")
893    (set (attr "mode")
894      (cond [(match_operand:SF 1 "" "")
895               (const_string "SF")
896             (match_operand:DF 1 "" "")
897               (const_string "DF")
898            ]
899            (const_string "XF")))])
900
901 (define_insn "*cmpfp_xf"
902   [(set (match_operand:HI 0 "register_operand" "=a")
903         (unspec:HI
904           [(compare:CCFP
905              (match_operand:XF 1 "register_operand" "f")
906              (match_operand:XF 2 "register_operand" "f"))]
907           UNSPEC_FNSTSW))]
908   "TARGET_80387"
909   "* return output_fp_compare (insn, operands, 0, 0);"
910   [(set_attr "type" "multi")
911    (set_attr "unit" "i387")
912    (set_attr "mode" "XF")])
913
914 (define_insn "*cmpfp_<mode>"
915   [(set (match_operand:HI 0 "register_operand" "=a")
916         (unspec:HI
917           [(compare:CCFP
918              (match_operand:X87MODEF12 1 "register_operand" "f")
919              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm"))]
920           UNSPEC_FNSTSW))]
921   "TARGET_80387"
922   "* return output_fp_compare (insn, operands, 0, 0);"
923   [(set_attr "type" "multi")
924    (set_attr "unit" "i387")
925    (set_attr "mode" "<MODE>")])
926
927 (define_insn "*cmpfp_u"
928   [(set (match_operand:HI 0 "register_operand" "=a")
929         (unspec:HI
930           [(compare:CCFPU
931              (match_operand 1 "register_operand" "f")
932              (match_operand 2 "register_operand" "f"))]
933           UNSPEC_FNSTSW))]
934   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
935    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
936   "* return output_fp_compare (insn, operands, 0, 1);"
937   [(set_attr "type" "multi")
938    (set_attr "unit" "i387")
939    (set (attr "mode")
940      (cond [(match_operand:SF 1 "" "")
941               (const_string "SF")
942             (match_operand:DF 1 "" "")
943               (const_string "DF")
944            ]
945            (const_string "XF")))])
946
947 (define_insn "*cmpfp_<mode>"
948   [(set (match_operand:HI 0 "register_operand" "=a")
949         (unspec:HI
950           [(compare:CCFP
951              (match_operand 1 "register_operand" "f")
952              (match_operator 3 "float_operator"
953                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
954           UNSPEC_FNSTSW))]
955   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
956    && TARGET_USE_<MODE>MODE_FIOP
957    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
958   "* return output_fp_compare (insn, operands, 0, 0);"
959   [(set_attr "type" "multi")
960    (set_attr "unit" "i387")
961    (set_attr "fp_int_src" "true")
962    (set_attr "mode" "<MODE>")])
963
964 ;; FP compares, step 2
965 ;; Move the fpsw to ax.
966
967 (define_insn "x86_fnstsw_1"
968   [(set (match_operand:HI 0 "register_operand" "=a")
969         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
970   "TARGET_80387"
971   "fnstsw\t%0"
972   [(set_attr "length" "2")
973    (set_attr "mode" "SI")
974    (set_attr "unit" "i387")])
975
976 ;; FP compares, step 3
977 ;; Get ax into flags, general case.
978
979 (define_insn "x86_sahf_1"
980   [(set (reg:CC FLAGS_REG)
981         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
982                    UNSPEC_SAHF))]
983   "TARGET_SAHF"
984 {
985 #ifdef HAVE_AS_IX86_SAHF
986   return "sahf";
987 #else
988   return ".byte\t0x9e";
989 #endif
990 }
991   [(set_attr "length" "1")
992    (set_attr "athlon_decode" "vector")
993    (set_attr "amdfam10_decode" "direct")
994    (set_attr "mode" "SI")])
995
996 ;; Pentium Pro can do steps 1 through 3 in one go.
997 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
998 (define_insn "*cmpfp_i_mixed"
999   [(set (reg:CCFP FLAGS_REG)
1000         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1001                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1002   "TARGET_MIX_SSE_I387
1003    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1004    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1005   "* return output_fp_compare (insn, operands, 1, 0);"
1006   [(set_attr "type" "fcmp,ssecomi")
1007    (set (attr "mode")
1008      (if_then_else (match_operand:SF 1 "" "")
1009         (const_string "SF")
1010         (const_string "DF")))
1011    (set_attr "athlon_decode" "vector")
1012    (set_attr "amdfam10_decode" "direct")])
1013
1014 (define_insn "*cmpfp_i_sse"
1015   [(set (reg:CCFP FLAGS_REG)
1016         (compare:CCFP (match_operand 0 "register_operand" "x")
1017                       (match_operand 1 "nonimmediate_operand" "xm")))]
1018   "TARGET_SSE_MATH
1019    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1020    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1021   "* return output_fp_compare (insn, operands, 1, 0);"
1022   [(set_attr "type" "ssecomi")
1023    (set (attr "mode")
1024      (if_then_else (match_operand:SF 1 "" "")
1025         (const_string "SF")
1026         (const_string "DF")))
1027    (set_attr "athlon_decode" "vector")
1028    (set_attr "amdfam10_decode" "direct")])
1029
1030 (define_insn "*cmpfp_i_i387"
1031   [(set (reg:CCFP FLAGS_REG)
1032         (compare:CCFP (match_operand 0 "register_operand" "f")
1033                       (match_operand 1 "register_operand" "f")))]
1034   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1035    && TARGET_CMOVE
1036    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1037    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1038   "* return output_fp_compare (insn, operands, 1, 0);"
1039   [(set_attr "type" "fcmp")
1040    (set (attr "mode")
1041      (cond [(match_operand:SF 1 "" "")
1042               (const_string "SF")
1043             (match_operand:DF 1 "" "")
1044               (const_string "DF")
1045            ]
1046            (const_string "XF")))
1047    (set_attr "athlon_decode" "vector")
1048    (set_attr "amdfam10_decode" "direct")])
1049
1050 (define_insn "*cmpfp_iu_mixed"
1051   [(set (reg:CCFPU FLAGS_REG)
1052         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1053                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1054   "TARGET_MIX_SSE_I387
1055    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1056    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1057   "* return output_fp_compare (insn, operands, 1, 1);"
1058   [(set_attr "type" "fcmp,ssecomi")
1059    (set (attr "mode")
1060      (if_then_else (match_operand:SF 1 "" "")
1061         (const_string "SF")
1062         (const_string "DF")))
1063    (set_attr "athlon_decode" "vector")
1064    (set_attr "amdfam10_decode" "direct")])
1065
1066 (define_insn "*cmpfp_iu_sse"
1067   [(set (reg:CCFPU FLAGS_REG)
1068         (compare:CCFPU (match_operand 0 "register_operand" "x")
1069                        (match_operand 1 "nonimmediate_operand" "xm")))]
1070   "TARGET_SSE_MATH
1071    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1072    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1073   "* return output_fp_compare (insn, operands, 1, 1);"
1074   [(set_attr "type" "ssecomi")
1075    (set (attr "mode")
1076      (if_then_else (match_operand:SF 1 "" "")
1077         (const_string "SF")
1078         (const_string "DF")))
1079    (set_attr "athlon_decode" "vector")
1080    (set_attr "amdfam10_decode" "direct")])
1081
1082 (define_insn "*cmpfp_iu_387"
1083   [(set (reg:CCFPU FLAGS_REG)
1084         (compare:CCFPU (match_operand 0 "register_operand" "f")
1085                        (match_operand 1 "register_operand" "f")))]
1086   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1087    && TARGET_CMOVE
1088    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1089    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1090   "* return output_fp_compare (insn, operands, 1, 1);"
1091   [(set_attr "type" "fcmp")
1092    (set (attr "mode")
1093      (cond [(match_operand:SF 1 "" "")
1094               (const_string "SF")
1095             (match_operand:DF 1 "" "")
1096               (const_string "DF")
1097            ]
1098            (const_string "XF")))
1099    (set_attr "athlon_decode" "vector")
1100    (set_attr "amdfam10_decode" "direct")])
1101 \f
1102 ;; Move instructions.
1103
1104 ;; General case of fullword move.
1105
1106 (define_expand "movsi"
1107   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1108         (match_operand:SI 1 "general_operand" ""))]
1109   ""
1110   "ix86_expand_move (SImode, operands); DONE;")
1111
1112 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1113 ;; general_operand.
1114 ;;
1115 ;; %%% We don't use a post-inc memory reference because x86 is not a
1116 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1117 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1118 ;; targets without our curiosities, and it is just as easy to represent
1119 ;; this differently.
1120
1121 (define_insn "*pushsi2"
1122   [(set (match_operand:SI 0 "push_operand" "=<")
1123         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1124   "!TARGET_64BIT"
1125   "push{l}\t%1"
1126   [(set_attr "type" "push")
1127    (set_attr "mode" "SI")])
1128
1129 ;; For 64BIT abi we always round up to 8 bytes.
1130 (define_insn "*pushsi2_rex64"
1131   [(set (match_operand:SI 0 "push_operand" "=X")
1132         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1133   "TARGET_64BIT"
1134   "push{q}\t%q1"
1135   [(set_attr "type" "push")
1136    (set_attr "mode" "SI")])
1137
1138 (define_insn "*pushsi2_prologue"
1139   [(set (match_operand:SI 0 "push_operand" "=<")
1140         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1141    (clobber (mem:BLK (scratch)))]
1142   "!TARGET_64BIT"
1143   "push{l}\t%1"
1144   [(set_attr "type" "push")
1145    (set_attr "mode" "SI")])
1146
1147 (define_insn "*popsi1_epilogue"
1148   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1149         (mem:SI (reg:SI SP_REG)))
1150    (set (reg:SI SP_REG)
1151         (plus:SI (reg:SI SP_REG) (const_int 4)))
1152    (clobber (mem:BLK (scratch)))]
1153   "!TARGET_64BIT"
1154   "pop{l}\t%0"
1155   [(set_attr "type" "pop")
1156    (set_attr "mode" "SI")])
1157
1158 (define_insn "popsi1"
1159   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1160         (mem:SI (reg:SI SP_REG)))
1161    (set (reg:SI SP_REG)
1162         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1163   "!TARGET_64BIT"
1164   "pop{l}\t%0"
1165   [(set_attr "type" "pop")
1166    (set_attr "mode" "SI")])
1167
1168 (define_insn "*movsi_xor"
1169   [(set (match_operand:SI 0 "register_operand" "=r")
1170         (match_operand:SI 1 "const0_operand" "i"))
1171    (clobber (reg:CC FLAGS_REG))]
1172   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1173   "xor{l}\t%0, %0"
1174   [(set_attr "type" "alu1")
1175    (set_attr "mode" "SI")
1176    (set_attr "length_immediate" "0")])
1177
1178 (define_insn "*movsi_or"
1179   [(set (match_operand:SI 0 "register_operand" "=r")
1180         (match_operand:SI 1 "immediate_operand" "i"))
1181    (clobber (reg:CC FLAGS_REG))]
1182   "reload_completed
1183    && operands[1] == constm1_rtx
1184    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1185 {
1186   operands[1] = constm1_rtx;
1187   return "or{l}\t{%1, %0|%0, %1}";
1188 }
1189   [(set_attr "type" "alu1")
1190    (set_attr "mode" "SI")
1191    (set_attr "length_immediate" "1")])
1192
1193 (define_insn "*movsi_1"
1194   [(set (match_operand:SI 0 "nonimmediate_operand"
1195                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1196         (match_operand:SI 1 "general_operand"
1197                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1198   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1199 {
1200   switch (get_attr_type (insn))
1201     {
1202     case TYPE_SSELOG1:
1203       if (get_attr_mode (insn) == MODE_TI)
1204         return "pxor\t%0, %0";
1205       return "xorps\t%0, %0";
1206
1207     case TYPE_SSEMOV:
1208       switch (get_attr_mode (insn))
1209         {
1210         case MODE_TI:
1211           return "movdqa\t{%1, %0|%0, %1}";
1212         case MODE_V4SF:
1213           return "movaps\t{%1, %0|%0, %1}";
1214         case MODE_SI:
1215           return "movd\t{%1, %0|%0, %1}";
1216         case MODE_SF:
1217           return "movss\t{%1, %0|%0, %1}";
1218         default:
1219           gcc_unreachable ();
1220         }
1221
1222     case TYPE_MMXADD:
1223       return "pxor\t%0, %0";
1224
1225     case TYPE_MMXMOV:
1226       if (get_attr_mode (insn) == MODE_DI)
1227         return "movq\t{%1, %0|%0, %1}";
1228       return "movd\t{%1, %0|%0, %1}";
1229
1230     case TYPE_LEA:
1231       return "lea{l}\t{%1, %0|%0, %1}";
1232
1233     default:
1234       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1235       return "mov{l}\t{%1, %0|%0, %1}";
1236     }
1237 }
1238   [(set (attr "type")
1239      (cond [(eq_attr "alternative" "2")
1240               (const_string "mmxadd")
1241             (eq_attr "alternative" "3,4,5")
1242               (const_string "mmxmov")
1243             (eq_attr "alternative" "6")
1244               (const_string "sselog1")
1245             (eq_attr "alternative" "7,8,9,10,11")
1246               (const_string "ssemov")
1247             (match_operand:DI 1 "pic_32bit_operand" "")
1248               (const_string "lea")
1249            ]
1250            (const_string "imov")))
1251    (set (attr "mode")
1252      (cond [(eq_attr "alternative" "2,3")
1253               (const_string "DI")
1254             (eq_attr "alternative" "6,7")
1255               (if_then_else
1256                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1257                 (const_string "V4SF")
1258                 (const_string "TI"))
1259             (and (eq_attr "alternative" "8,9,10,11")
1260                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1261               (const_string "SF")
1262            ]
1263            (const_string "SI")))])
1264
1265 ;; Stores and loads of ax to arbitrary constant address.
1266 ;; We fake an second form of instruction to force reload to load address
1267 ;; into register when rax is not available
1268 (define_insn "*movabssi_1_rex64"
1269   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1270         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1271   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1272   "@
1273    movabs{l}\t{%1, %P0|%P0, %1}
1274    mov{l}\t{%1, %a0|%a0, %1}"
1275   [(set_attr "type" "imov")
1276    (set_attr "modrm" "0,*")
1277    (set_attr "length_address" "8,0")
1278    (set_attr "length_immediate" "0,*")
1279    (set_attr "memory" "store")
1280    (set_attr "mode" "SI")])
1281
1282 (define_insn "*movabssi_2_rex64"
1283   [(set (match_operand:SI 0 "register_operand" "=a,r")
1284         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1285   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1286   "@
1287    movabs{l}\t{%P1, %0|%0, %P1}
1288    mov{l}\t{%a1, %0|%0, %a1}"
1289   [(set_attr "type" "imov")
1290    (set_attr "modrm" "0,*")
1291    (set_attr "length_address" "8,0")
1292    (set_attr "length_immediate" "0")
1293    (set_attr "memory" "load")
1294    (set_attr "mode" "SI")])
1295
1296 (define_insn "*swapsi"
1297   [(set (match_operand:SI 0 "register_operand" "+r")
1298         (match_operand:SI 1 "register_operand" "+r"))
1299    (set (match_dup 1)
1300         (match_dup 0))]
1301   ""
1302   "xchg{l}\t%1, %0"
1303   [(set_attr "type" "imov")
1304    (set_attr "mode" "SI")
1305    (set_attr "pent_pair" "np")
1306    (set_attr "athlon_decode" "vector")
1307    (set_attr "amdfam10_decode" "double")])   
1308
1309 (define_expand "movhi"
1310   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1311         (match_operand:HI 1 "general_operand" ""))]
1312   ""
1313   "ix86_expand_move (HImode, operands); DONE;")
1314
1315 (define_insn "*pushhi2"
1316   [(set (match_operand:HI 0 "push_operand" "=X")
1317         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1318   "!TARGET_64BIT"
1319   "push{l}\t%k1"
1320   [(set_attr "type" "push")
1321    (set_attr "mode" "SI")])
1322
1323 ;; For 64BIT abi we always round up to 8 bytes.
1324 (define_insn "*pushhi2_rex64"
1325   [(set (match_operand:HI 0 "push_operand" "=X")
1326         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1327   "TARGET_64BIT"
1328   "push{q}\t%q1"
1329   [(set_attr "type" "push")
1330    (set_attr "mode" "DI")])
1331
1332 (define_insn "*movhi_1"
1333   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1334         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1335   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1336 {
1337   switch (get_attr_type (insn))
1338     {
1339     case TYPE_IMOVX:
1340       /* movzwl is faster than movw on p2 due to partial word stalls,
1341          though not as fast as an aligned movl.  */
1342       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1343     default:
1344       if (get_attr_mode (insn) == MODE_SI)
1345         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1346       else
1347         return "mov{w}\t{%1, %0|%0, %1}";
1348     }
1349 }
1350   [(set (attr "type")
1351      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1352               (const_string "imov")
1353             (and (eq_attr "alternative" "0")
1354                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1355                           (const_int 0))
1356                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1357                           (const_int 0))))
1358               (const_string "imov")
1359             (and (eq_attr "alternative" "1,2")
1360                  (match_operand:HI 1 "aligned_operand" ""))
1361               (const_string "imov")
1362             (and (ne (symbol_ref "TARGET_MOVX")
1363                      (const_int 0))
1364                  (eq_attr "alternative" "0,2"))
1365               (const_string "imovx")
1366            ]
1367            (const_string "imov")))
1368     (set (attr "mode")
1369       (cond [(eq_attr "type" "imovx")
1370                (const_string "SI")
1371              (and (eq_attr "alternative" "1,2")
1372                   (match_operand:HI 1 "aligned_operand" ""))
1373                (const_string "SI")
1374              (and (eq_attr "alternative" "0")
1375                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1376                            (const_int 0))
1377                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1378                            (const_int 0))))
1379                (const_string "SI")
1380             ]
1381             (const_string "HI")))])
1382
1383 ;; Stores and loads of ax to arbitrary constant address.
1384 ;; We fake an second form of instruction to force reload to load address
1385 ;; into register when rax is not available
1386 (define_insn "*movabshi_1_rex64"
1387   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1388         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1389   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1390   "@
1391    movabs{w}\t{%1, %P0|%P0, %1}
1392    mov{w}\t{%1, %a0|%a0, %1}"
1393   [(set_attr "type" "imov")
1394    (set_attr "modrm" "0,*")
1395    (set_attr "length_address" "8,0")
1396    (set_attr "length_immediate" "0,*")
1397    (set_attr "memory" "store")
1398    (set_attr "mode" "HI")])
1399
1400 (define_insn "*movabshi_2_rex64"
1401   [(set (match_operand:HI 0 "register_operand" "=a,r")
1402         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1403   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1404   "@
1405    movabs{w}\t{%P1, %0|%0, %P1}
1406    mov{w}\t{%a1, %0|%0, %a1}"
1407   [(set_attr "type" "imov")
1408    (set_attr "modrm" "0,*")
1409    (set_attr "length_address" "8,0")
1410    (set_attr "length_immediate" "0")
1411    (set_attr "memory" "load")
1412    (set_attr "mode" "HI")])
1413
1414 (define_insn "*swaphi_1"
1415   [(set (match_operand:HI 0 "register_operand" "+r")
1416         (match_operand:HI 1 "register_operand" "+r"))
1417    (set (match_dup 1)
1418         (match_dup 0))]
1419   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1420   "xchg{l}\t%k1, %k0"
1421   [(set_attr "type" "imov")
1422    (set_attr "mode" "SI")
1423    (set_attr "pent_pair" "np")
1424    (set_attr "athlon_decode" "vector")
1425    (set_attr "amdfam10_decode" "double")])   
1426
1427 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1428 (define_insn "*swaphi_2"
1429   [(set (match_operand:HI 0 "register_operand" "+r")
1430         (match_operand:HI 1 "register_operand" "+r"))
1431    (set (match_dup 1)
1432         (match_dup 0))]
1433   "TARGET_PARTIAL_REG_STALL"
1434   "xchg{w}\t%1, %0"
1435   [(set_attr "type" "imov")
1436    (set_attr "mode" "HI")
1437    (set_attr "pent_pair" "np")
1438    (set_attr "athlon_decode" "vector")])
1439
1440 (define_expand "movstricthi"
1441   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1442         (match_operand:HI 1 "general_operand" ""))]
1443   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1444 {
1445   /* Don't generate memory->memory moves, go through a register */
1446   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1447     operands[1] = force_reg (HImode, operands[1]);
1448 })
1449
1450 (define_insn "*movstricthi_1"
1451   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1452         (match_operand:HI 1 "general_operand" "rn,m"))]
1453   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1454    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1455   "mov{w}\t{%1, %0|%0, %1}"
1456   [(set_attr "type" "imov")
1457    (set_attr "mode" "HI")])
1458
1459 (define_insn "*movstricthi_xor"
1460   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1461         (match_operand:HI 1 "const0_operand" "i"))
1462    (clobber (reg:CC FLAGS_REG))]
1463   "reload_completed
1464    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1465   "xor{w}\t%0, %0"
1466   [(set_attr "type" "alu1")
1467    (set_attr "mode" "HI")
1468    (set_attr "length_immediate" "0")])
1469
1470 (define_expand "movqi"
1471   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1472         (match_operand:QI 1 "general_operand" ""))]
1473   ""
1474   "ix86_expand_move (QImode, operands); DONE;")
1475
1476 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1477 ;; "push a byte".  But actually we use pushl, which has the effect
1478 ;; of rounding the amount pushed up to a word.
1479
1480 (define_insn "*pushqi2"
1481   [(set (match_operand:QI 0 "push_operand" "=X")
1482         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1483   "!TARGET_64BIT"
1484   "push{l}\t%k1"
1485   [(set_attr "type" "push")
1486    (set_attr "mode" "SI")])
1487
1488 ;; For 64BIT abi we always round up to 8 bytes.
1489 (define_insn "*pushqi2_rex64"
1490   [(set (match_operand:QI 0 "push_operand" "=X")
1491         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1492   "TARGET_64BIT"
1493   "push{q}\t%q1"
1494   [(set_attr "type" "push")
1495    (set_attr "mode" "DI")])
1496
1497 ;; Situation is quite tricky about when to choose full sized (SImode) move
1498 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1499 ;; partial register dependency machines (such as AMD Athlon), where QImode
1500 ;; moves issue extra dependency and for partial register stalls machines
1501 ;; that don't use QImode patterns (and QImode move cause stall on the next
1502 ;; instruction).
1503 ;;
1504 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1505 ;; register stall machines with, where we use QImode instructions, since
1506 ;; partial register stall can be caused there.  Then we use movzx.
1507 (define_insn "*movqi_1"
1508   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1509         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1510   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1511 {
1512   switch (get_attr_type (insn))
1513     {
1514     case TYPE_IMOVX:
1515       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1516       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1517     default:
1518       if (get_attr_mode (insn) == MODE_SI)
1519         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1520       else
1521         return "mov{b}\t{%1, %0|%0, %1}";
1522     }
1523 }
1524   [(set (attr "type")
1525      (cond [(and (eq_attr "alternative" "5")
1526                  (not (match_operand:QI 1 "aligned_operand" "")))
1527               (const_string "imovx")
1528             (ne (symbol_ref "optimize_size") (const_int 0))
1529               (const_string "imov")
1530             (and (eq_attr "alternative" "3")
1531                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1532                           (const_int 0))
1533                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1534                           (const_int 0))))
1535               (const_string "imov")
1536             (eq_attr "alternative" "3,5")
1537               (const_string "imovx")
1538             (and (ne (symbol_ref "TARGET_MOVX")
1539                      (const_int 0))
1540                  (eq_attr "alternative" "2"))
1541               (const_string "imovx")
1542            ]
1543            (const_string "imov")))
1544    (set (attr "mode")
1545       (cond [(eq_attr "alternative" "3,4,5")
1546                (const_string "SI")
1547              (eq_attr "alternative" "6")
1548                (const_string "QI")
1549              (eq_attr "type" "imovx")
1550                (const_string "SI")
1551              (and (eq_attr "type" "imov")
1552                   (and (eq_attr "alternative" "0,1")
1553                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1554                                 (const_int 0))
1555                             (and (eq (symbol_ref "optimize_size")
1556                                      (const_int 0))
1557                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1558                                      (const_int 0))))))
1559                (const_string "SI")
1560              ;; Avoid partial register stalls when not using QImode arithmetic
1561              (and (eq_attr "type" "imov")
1562                   (and (eq_attr "alternative" "0,1")
1563                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1564                                 (const_int 0))
1565                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1566                                 (const_int 0)))))
1567                (const_string "SI")
1568            ]
1569            (const_string "QI")))])
1570
1571 (define_expand "reload_outqi"
1572   [(parallel [(match_operand:QI 0 "" "=m")
1573               (match_operand:QI 1 "register_operand" "r")
1574               (match_operand:QI 2 "register_operand" "=&q")])]
1575   ""
1576 {
1577   rtx op0, op1, op2;
1578   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1579
1580   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1581   if (! q_regs_operand (op1, QImode))
1582     {
1583       emit_insn (gen_movqi (op2, op1));
1584       op1 = op2;
1585     }
1586   emit_insn (gen_movqi (op0, op1));
1587   DONE;
1588 })
1589
1590 (define_insn "*swapqi_1"
1591   [(set (match_operand:QI 0 "register_operand" "+r")
1592         (match_operand:QI 1 "register_operand" "+r"))
1593    (set (match_dup 1)
1594         (match_dup 0))]
1595   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1596   "xchg{l}\t%k1, %k0"
1597   [(set_attr "type" "imov")
1598    (set_attr "mode" "SI")
1599    (set_attr "pent_pair" "np")
1600    (set_attr "athlon_decode" "vector")
1601    (set_attr "amdfam10_decode" "vector")])   
1602
1603 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1604 (define_insn "*swapqi_2"
1605   [(set (match_operand:QI 0 "register_operand" "+q")
1606         (match_operand:QI 1 "register_operand" "+q"))
1607    (set (match_dup 1)
1608         (match_dup 0))]
1609   "TARGET_PARTIAL_REG_STALL"
1610   "xchg{b}\t%1, %0"
1611   [(set_attr "type" "imov")
1612    (set_attr "mode" "QI")
1613    (set_attr "pent_pair" "np")
1614    (set_attr "athlon_decode" "vector")])
1615
1616 (define_expand "movstrictqi"
1617   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1618         (match_operand:QI 1 "general_operand" ""))]
1619   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1620 {
1621   /* Don't generate memory->memory moves, go through a register.  */
1622   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1623     operands[1] = force_reg (QImode, operands[1]);
1624 })
1625
1626 (define_insn "*movstrictqi_1"
1627   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1628         (match_operand:QI 1 "general_operand" "*qn,m"))]
1629   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1630    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1631   "mov{b}\t{%1, %0|%0, %1}"
1632   [(set_attr "type" "imov")
1633    (set_attr "mode" "QI")])
1634
1635 (define_insn "*movstrictqi_xor"
1636   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1637         (match_operand:QI 1 "const0_operand" "i"))
1638    (clobber (reg:CC FLAGS_REG))]
1639   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1640   "xor{b}\t%0, %0"
1641   [(set_attr "type" "alu1")
1642    (set_attr "mode" "QI")
1643    (set_attr "length_immediate" "0")])
1644
1645 (define_insn "*movsi_extv_1"
1646   [(set (match_operand:SI 0 "register_operand" "=R")
1647         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1648                          (const_int 8)
1649                          (const_int 8)))]
1650   ""
1651   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1652   [(set_attr "type" "imovx")
1653    (set_attr "mode" "SI")])
1654
1655 (define_insn "*movhi_extv_1"
1656   [(set (match_operand:HI 0 "register_operand" "=R")
1657         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1658                          (const_int 8)
1659                          (const_int 8)))]
1660   ""
1661   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1662   [(set_attr "type" "imovx")
1663    (set_attr "mode" "SI")])
1664
1665 (define_insn "*movqi_extv_1"
1666   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1667         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1668                          (const_int 8)
1669                          (const_int 8)))]
1670   "!TARGET_64BIT"
1671 {
1672   switch (get_attr_type (insn))
1673     {
1674     case TYPE_IMOVX:
1675       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1676     default:
1677       return "mov{b}\t{%h1, %0|%0, %h1}";
1678     }
1679 }
1680   [(set (attr "type")
1681      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1682                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1683                              (ne (symbol_ref "TARGET_MOVX")
1684                                  (const_int 0))))
1685         (const_string "imovx")
1686         (const_string "imov")))
1687    (set (attr "mode")
1688      (if_then_else (eq_attr "type" "imovx")
1689         (const_string "SI")
1690         (const_string "QI")))])
1691
1692 (define_insn "*movqi_extv_1_rex64"
1693   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1694         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1695                          (const_int 8)
1696                          (const_int 8)))]
1697   "TARGET_64BIT"
1698 {
1699   switch (get_attr_type (insn))
1700     {
1701     case TYPE_IMOVX:
1702       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1703     default:
1704       return "mov{b}\t{%h1, %0|%0, %h1}";
1705     }
1706 }
1707   [(set (attr "type")
1708      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1709                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1710                              (ne (symbol_ref "TARGET_MOVX")
1711                                  (const_int 0))))
1712         (const_string "imovx")
1713         (const_string "imov")))
1714    (set (attr "mode")
1715      (if_then_else (eq_attr "type" "imovx")
1716         (const_string "SI")
1717         (const_string "QI")))])
1718
1719 ;; Stores and loads of ax to arbitrary constant address.
1720 ;; We fake an second form of instruction to force reload to load address
1721 ;; into register when rax is not available
1722 (define_insn "*movabsqi_1_rex64"
1723   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1724         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1725   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1726   "@
1727    movabs{b}\t{%1, %P0|%P0, %1}
1728    mov{b}\t{%1, %a0|%a0, %1}"
1729   [(set_attr "type" "imov")
1730    (set_attr "modrm" "0,*")
1731    (set_attr "length_address" "8,0")
1732    (set_attr "length_immediate" "0,*")
1733    (set_attr "memory" "store")
1734    (set_attr "mode" "QI")])
1735
1736 (define_insn "*movabsqi_2_rex64"
1737   [(set (match_operand:QI 0 "register_operand" "=a,r")
1738         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1739   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1740   "@
1741    movabs{b}\t{%P1, %0|%0, %P1}
1742    mov{b}\t{%a1, %0|%0, %a1}"
1743   [(set_attr "type" "imov")
1744    (set_attr "modrm" "0,*")
1745    (set_attr "length_address" "8,0")
1746    (set_attr "length_immediate" "0")
1747    (set_attr "memory" "load")
1748    (set_attr "mode" "QI")])
1749
1750 (define_insn "*movdi_extzv_1"
1751   [(set (match_operand:DI 0 "register_operand" "=R")
1752         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1753                          (const_int 8)
1754                          (const_int 8)))]
1755   "TARGET_64BIT"
1756   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1757   [(set_attr "type" "imovx")
1758    (set_attr "mode" "DI")])
1759
1760 (define_insn "*movsi_extzv_1"
1761   [(set (match_operand:SI 0 "register_operand" "=R")
1762         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1763                          (const_int 8)
1764                          (const_int 8)))]
1765   ""
1766   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1767   [(set_attr "type" "imovx")
1768    (set_attr "mode" "SI")])
1769
1770 (define_insn "*movqi_extzv_2"
1771   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1772         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1773                                     (const_int 8)
1774                                     (const_int 8)) 0))]
1775   "!TARGET_64BIT"
1776 {
1777   switch (get_attr_type (insn))
1778     {
1779     case TYPE_IMOVX:
1780       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1781     default:
1782       return "mov{b}\t{%h1, %0|%0, %h1}";
1783     }
1784 }
1785   [(set (attr "type")
1786      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1787                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1788                              (ne (symbol_ref "TARGET_MOVX")
1789                                  (const_int 0))))
1790         (const_string "imovx")
1791         (const_string "imov")))
1792    (set (attr "mode")
1793      (if_then_else (eq_attr "type" "imovx")
1794         (const_string "SI")
1795         (const_string "QI")))])
1796
1797 (define_insn "*movqi_extzv_2_rex64"
1798   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1799         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1800                                     (const_int 8)
1801                                     (const_int 8)) 0))]
1802   "TARGET_64BIT"
1803 {
1804   switch (get_attr_type (insn))
1805     {
1806     case TYPE_IMOVX:
1807       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1808     default:
1809       return "mov{b}\t{%h1, %0|%0, %h1}";
1810     }
1811 }
1812   [(set (attr "type")
1813      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1814                         (ne (symbol_ref "TARGET_MOVX")
1815                             (const_int 0)))
1816         (const_string "imovx")
1817         (const_string "imov")))
1818    (set (attr "mode")
1819      (if_then_else (eq_attr "type" "imovx")
1820         (const_string "SI")
1821         (const_string "QI")))])
1822
1823 (define_insn "movsi_insv_1"
1824   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1825                          (const_int 8)
1826                          (const_int 8))
1827         (match_operand:SI 1 "general_operand" "Qmn"))]
1828   "!TARGET_64BIT"
1829   "mov{b}\t{%b1, %h0|%h0, %b1}"
1830   [(set_attr "type" "imov")
1831    (set_attr "mode" "QI")])
1832
1833 (define_insn "*movsi_insv_1_rex64"
1834   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1835                          (const_int 8)
1836                          (const_int 8))
1837         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1838   "TARGET_64BIT"
1839   "mov{b}\t{%b1, %h0|%h0, %b1}"
1840   [(set_attr "type" "imov")
1841    (set_attr "mode" "QI")])
1842
1843 (define_insn "movdi_insv_1_rex64"
1844   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1845                          (const_int 8)
1846                          (const_int 8))
1847         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1848   "TARGET_64BIT"
1849   "mov{b}\t{%b1, %h0|%h0, %b1}"
1850   [(set_attr "type" "imov")
1851    (set_attr "mode" "QI")])
1852
1853 (define_insn "*movqi_insv_2"
1854   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1855                          (const_int 8)
1856                          (const_int 8))
1857         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1858                      (const_int 8)))]
1859   ""
1860   "mov{b}\t{%h1, %h0|%h0, %h1}"
1861   [(set_attr "type" "imov")
1862    (set_attr "mode" "QI")])
1863
1864 (define_expand "movdi"
1865   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1866         (match_operand:DI 1 "general_operand" ""))]
1867   ""
1868   "ix86_expand_move (DImode, operands); DONE;")
1869
1870 (define_insn "*pushdi"
1871   [(set (match_operand:DI 0 "push_operand" "=<")
1872         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1873   "!TARGET_64BIT"
1874   "#")
1875
1876 (define_insn "*pushdi2_rex64"
1877   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1878         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1879   "TARGET_64BIT"
1880   "@
1881    push{q}\t%1
1882    #"
1883   [(set_attr "type" "push,multi")
1884    (set_attr "mode" "DI")])
1885
1886 ;; Convert impossible pushes of immediate to existing instructions.
1887 ;; First try to get scratch register and go through it.  In case this
1888 ;; fails, push sign extended lower part first and then overwrite
1889 ;; upper part by 32bit move.
1890 (define_peephole2
1891   [(match_scratch:DI 2 "r")
1892    (set (match_operand:DI 0 "push_operand" "")
1893         (match_operand:DI 1 "immediate_operand" ""))]
1894   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1895    && !x86_64_immediate_operand (operands[1], DImode)"
1896   [(set (match_dup 2) (match_dup 1))
1897    (set (match_dup 0) (match_dup 2))]
1898   "")
1899
1900 ;; We need to define this as both peepholer and splitter for case
1901 ;; peephole2 pass is not run.
1902 ;; "&& 1" is needed to keep it from matching the previous pattern.
1903 (define_peephole2
1904   [(set (match_operand:DI 0 "push_operand" "")
1905         (match_operand:DI 1 "immediate_operand" ""))]
1906   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1907    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1908   [(set (match_dup 0) (match_dup 1))
1909    (set (match_dup 2) (match_dup 3))]
1910   "split_di (operands + 1, 1, operands + 2, operands + 3);
1911    operands[1] = gen_lowpart (DImode, operands[2]);
1912    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1913                                                     GEN_INT (4)));
1914   ")
1915
1916 (define_split
1917   [(set (match_operand:DI 0 "push_operand" "")
1918         (match_operand:DI 1 "immediate_operand" ""))]
1919   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1920                     ? flow2_completed : reload_completed)
1921    && !symbolic_operand (operands[1], DImode)
1922    && !x86_64_immediate_operand (operands[1], DImode)"
1923   [(set (match_dup 0) (match_dup 1))
1924    (set (match_dup 2) (match_dup 3))]
1925   "split_di (operands + 1, 1, operands + 2, operands + 3);
1926    operands[1] = gen_lowpart (DImode, operands[2]);
1927    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1928                                                     GEN_INT (4)));
1929   ")
1930
1931 (define_insn "*pushdi2_prologue_rex64"
1932   [(set (match_operand:DI 0 "push_operand" "=<")
1933         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1934    (clobber (mem:BLK (scratch)))]
1935   "TARGET_64BIT"
1936   "push{q}\t%1"
1937   [(set_attr "type" "push")
1938    (set_attr "mode" "DI")])
1939
1940 (define_insn "*popdi1_epilogue_rex64"
1941   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1942         (mem:DI (reg:DI SP_REG)))
1943    (set (reg:DI SP_REG)
1944         (plus:DI (reg:DI SP_REG) (const_int 8)))
1945    (clobber (mem:BLK (scratch)))]
1946   "TARGET_64BIT"
1947   "pop{q}\t%0"
1948   [(set_attr "type" "pop")
1949    (set_attr "mode" "DI")])
1950
1951 (define_insn "popdi1"
1952   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1953         (mem:DI (reg:DI SP_REG)))
1954    (set (reg:DI SP_REG)
1955         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1956   "TARGET_64BIT"
1957   "pop{q}\t%0"
1958   [(set_attr "type" "pop")
1959    (set_attr "mode" "DI")])
1960
1961 (define_insn "*movdi_xor_rex64"
1962   [(set (match_operand:DI 0 "register_operand" "=r")
1963         (match_operand:DI 1 "const0_operand" "i"))
1964    (clobber (reg:CC FLAGS_REG))]
1965   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1966    && reload_completed"
1967   "xor{l}\t%k0, %k0";
1968   [(set_attr "type" "alu1")
1969    (set_attr "mode" "SI")
1970    (set_attr "length_immediate" "0")])
1971
1972 (define_insn "*movdi_or_rex64"
1973   [(set (match_operand:DI 0 "register_operand" "=r")
1974         (match_operand:DI 1 "const_int_operand" "i"))
1975    (clobber (reg:CC FLAGS_REG))]
1976   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
1977    && reload_completed
1978    && operands[1] == constm1_rtx"
1979 {
1980   operands[1] = constm1_rtx;
1981   return "or{q}\t{%1, %0|%0, %1}";
1982 }
1983   [(set_attr "type" "alu1")
1984    (set_attr "mode" "DI")
1985    (set_attr "length_immediate" "1")])
1986
1987 (define_insn "*movdi_2"
1988   [(set (match_operand:DI 0 "nonimmediate_operand"
1989                         "=r  ,o  ,*y,m*y,*y,*Yt,m  ,*Yt,*Yt,*x,m ,*x,*x")
1990         (match_operand:DI 1 "general_operand"
1991                         "riFo,riF,C ,*y ,m ,C  ,*Yt,*Yt,m  ,C ,*x,*x,m "))]
1992   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1993   "@
1994    #
1995    #
1996    pxor\t%0, %0
1997    movq\t{%1, %0|%0, %1}
1998    movq\t{%1, %0|%0, %1}
1999    pxor\t%0, %0
2000    movq\t{%1, %0|%0, %1}
2001    movdqa\t{%1, %0|%0, %1}
2002    movq\t{%1, %0|%0, %1}
2003    xorps\t%0, %0
2004    movlps\t{%1, %0|%0, %1}
2005    movaps\t{%1, %0|%0, %1}
2006    movlps\t{%1, %0|%0, %1}"
2007   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2008    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2009
2010 (define_split
2011   [(set (match_operand:DI 0 "push_operand" "")
2012         (match_operand:DI 1 "general_operand" ""))]
2013   "!TARGET_64BIT && reload_completed
2014    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2015   [(const_int 0)]
2016   "ix86_split_long_move (operands); DONE;")
2017
2018 ;; %%% This multiword shite has got to go.
2019 (define_split
2020   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2021         (match_operand:DI 1 "general_operand" ""))]
2022   "!TARGET_64BIT && reload_completed
2023    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2024    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2025   [(const_int 0)]
2026   "ix86_split_long_move (operands); DONE;")
2027
2028 (define_insn "*movdi_1_rex64"
2029   [(set (match_operand:DI 0 "nonimmediate_operand"
2030           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2031         (match_operand:DI 1 "general_operand"
2032           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2033   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2034 {
2035   switch (get_attr_type (insn))
2036     {
2037     case TYPE_SSECVT:
2038       if (SSE_REG_P (operands[0]))
2039         return "movq2dq\t{%1, %0|%0, %1}";
2040       else
2041         return "movdq2q\t{%1, %0|%0, %1}";
2042
2043     case TYPE_SSEMOV:
2044       if (get_attr_mode (insn) == MODE_TI)
2045         return "movdqa\t{%1, %0|%0, %1}";
2046       /* FALLTHRU */
2047
2048     case TYPE_MMXMOV:
2049       /* Moves from and into integer register is done using movd
2050          opcode with REX prefix.  */
2051       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2052         return "movd\t{%1, %0|%0, %1}";
2053       return "movq\t{%1, %0|%0, %1}";
2054
2055     case TYPE_SSELOG1:
2056     case TYPE_MMXADD:
2057       return "pxor\t%0, %0";
2058
2059     case TYPE_MULTI:
2060       return "#";
2061
2062     case TYPE_LEA:
2063       return "lea{q}\t{%a1, %0|%0, %a1}";
2064
2065     default:
2066       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2067       if (get_attr_mode (insn) == MODE_SI)
2068         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2069       else if (which_alternative == 2)
2070         return "movabs{q}\t{%1, %0|%0, %1}";
2071       else
2072         return "mov{q}\t{%1, %0|%0, %1}";
2073     }
2074 }
2075   [(set (attr "type")
2076      (cond [(eq_attr "alternative" "5")
2077               (const_string "mmxadd")
2078             (eq_attr "alternative" "6,7,8,9,10")
2079               (const_string "mmxmov")
2080             (eq_attr "alternative" "11")
2081               (const_string "sselog1")
2082             (eq_attr "alternative" "12,13,14,15,16")
2083               (const_string "ssemov")
2084             (eq_attr "alternative" "17,18")
2085               (const_string "ssecvt")
2086             (eq_attr "alternative" "4")
2087               (const_string "multi")
2088             (match_operand:DI 1 "pic_32bit_operand" "")
2089               (const_string "lea")
2090            ]
2091            (const_string "imov")))
2092    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2093    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2094    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2095
2096 ;; Stores and loads of ax to arbitrary constant address.
2097 ;; We fake an second form of instruction to force reload to load address
2098 ;; into register when rax is not available
2099 (define_insn "*movabsdi_1_rex64"
2100   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2101         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2102   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2103   "@
2104    movabs{q}\t{%1, %P0|%P0, %1}
2105    mov{q}\t{%1, %a0|%a0, %1}"
2106   [(set_attr "type" "imov")
2107    (set_attr "modrm" "0,*")
2108    (set_attr "length_address" "8,0")
2109    (set_attr "length_immediate" "0,*")
2110    (set_attr "memory" "store")
2111    (set_attr "mode" "DI")])
2112
2113 (define_insn "*movabsdi_2_rex64"
2114   [(set (match_operand:DI 0 "register_operand" "=a,r")
2115         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2116   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2117   "@
2118    movabs{q}\t{%P1, %0|%0, %P1}
2119    mov{q}\t{%a1, %0|%0, %a1}"
2120   [(set_attr "type" "imov")
2121    (set_attr "modrm" "0,*")
2122    (set_attr "length_address" "8,0")
2123    (set_attr "length_immediate" "0")
2124    (set_attr "memory" "load")
2125    (set_attr "mode" "DI")])
2126
2127 ;; Convert impossible stores of immediate to existing instructions.
2128 ;; First try to get scratch register and go through it.  In case this
2129 ;; fails, move by 32bit parts.
2130 (define_peephole2
2131   [(match_scratch:DI 2 "r")
2132    (set (match_operand:DI 0 "memory_operand" "")
2133         (match_operand:DI 1 "immediate_operand" ""))]
2134   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2135    && !x86_64_immediate_operand (operands[1], DImode)"
2136   [(set (match_dup 2) (match_dup 1))
2137    (set (match_dup 0) (match_dup 2))]
2138   "")
2139
2140 ;; We need to define this as both peepholer and splitter for case
2141 ;; peephole2 pass is not run.
2142 ;; "&& 1" is needed to keep it from matching the previous pattern.
2143 (define_peephole2
2144   [(set (match_operand:DI 0 "memory_operand" "")
2145         (match_operand:DI 1 "immediate_operand" ""))]
2146   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2147    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2148   [(set (match_dup 2) (match_dup 3))
2149    (set (match_dup 4) (match_dup 5))]
2150   "split_di (operands, 2, operands + 2, operands + 4);")
2151
2152 (define_split
2153   [(set (match_operand:DI 0 "memory_operand" "")
2154         (match_operand:DI 1 "immediate_operand" ""))]
2155   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2156                     ? flow2_completed : reload_completed)
2157    && !symbolic_operand (operands[1], DImode)
2158    && !x86_64_immediate_operand (operands[1], DImode)"
2159   [(set (match_dup 2) (match_dup 3))
2160    (set (match_dup 4) (match_dup 5))]
2161   "split_di (operands, 2, operands + 2, operands + 4);")
2162
2163 (define_insn "*swapdi_rex64"
2164   [(set (match_operand:DI 0 "register_operand" "+r")
2165         (match_operand:DI 1 "register_operand" "+r"))
2166    (set (match_dup 1)
2167         (match_dup 0))]
2168   "TARGET_64BIT"
2169   "xchg{q}\t%1, %0"
2170   [(set_attr "type" "imov")
2171    (set_attr "mode" "DI")
2172    (set_attr "pent_pair" "np")
2173    (set_attr "athlon_decode" "vector")
2174    (set_attr "amdfam10_decode" "double")])   
2175
2176 (define_expand "movti"
2177   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2178         (match_operand:TI 1 "nonimmediate_operand" ""))]
2179   "TARGET_SSE || TARGET_64BIT"
2180 {
2181   if (TARGET_64BIT)
2182     ix86_expand_move (TImode, operands);
2183   else if (push_operand (operands[0], TImode))
2184     ix86_expand_push (TImode, operands[1]);
2185   else
2186     ix86_expand_vector_move (TImode, operands);
2187   DONE;
2188 })
2189
2190 (define_insn "*movti_internal"
2191   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2192         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2193   "TARGET_SSE && !TARGET_64BIT
2194    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2195 {
2196   switch (which_alternative)
2197     {
2198     case 0:
2199       if (get_attr_mode (insn) == MODE_V4SF)
2200         return "xorps\t%0, %0";
2201       else
2202         return "pxor\t%0, %0";
2203     case 1:
2204     case 2:
2205       if (get_attr_mode (insn) == MODE_V4SF)
2206         return "movaps\t{%1, %0|%0, %1}";
2207       else
2208         return "movdqa\t{%1, %0|%0, %1}";
2209     default:
2210       gcc_unreachable ();
2211     }
2212 }
2213   [(set_attr "type" "sselog1,ssemov,ssemov")
2214    (set (attr "mode")
2215         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2216                     (ne (symbol_ref "optimize_size") (const_int 0)))
2217                  (const_string "V4SF")
2218                (and (eq_attr "alternative" "2")
2219                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2220                         (const_int 0)))
2221                  (const_string "V4SF")]
2222               (const_string "TI")))])
2223
2224 (define_insn "*movti_rex64"
2225   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2226         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2227   "TARGET_64BIT
2228    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2229 {
2230   switch (which_alternative)
2231     {
2232     case 0:
2233     case 1:
2234       return "#";
2235     case 2:
2236       if (get_attr_mode (insn) == MODE_V4SF)
2237         return "xorps\t%0, %0";
2238       else
2239         return "pxor\t%0, %0";
2240     case 3:
2241     case 4:
2242       if (get_attr_mode (insn) == MODE_V4SF)
2243         return "movaps\t{%1, %0|%0, %1}";
2244       else
2245         return "movdqa\t{%1, %0|%0, %1}";
2246     default:
2247       gcc_unreachable ();
2248     }
2249 }
2250   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2251    (set (attr "mode")
2252         (cond [(eq_attr "alternative" "2,3")
2253                  (if_then_else
2254                    (ne (symbol_ref "optimize_size")
2255                        (const_int 0))
2256                    (const_string "V4SF")
2257                    (const_string "TI"))
2258                (eq_attr "alternative" "4")
2259                  (if_then_else
2260                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2261                             (const_int 0))
2262                         (ne (symbol_ref "optimize_size")
2263                             (const_int 0)))
2264                    (const_string "V4SF")
2265                    (const_string "TI"))]
2266                (const_string "DI")))])
2267
2268 (define_split
2269   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2270         (match_operand:TI 1 "general_operand" ""))]
2271   "reload_completed && !SSE_REG_P (operands[0])
2272    && !SSE_REG_P (operands[1])"
2273   [(const_int 0)]
2274   "ix86_split_long_move (operands); DONE;")
2275
2276 ;; This expands to what emit_move_complex would generate if we didn't
2277 ;; have a movti pattern.  Having this avoids problems with reload on
2278 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2279 ;; to have around all the time.
2280 (define_expand "movcdi"
2281   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2282         (match_operand:CDI 1 "general_operand" ""))]
2283   ""
2284 {
2285   if (push_operand (operands[0], CDImode))
2286     emit_move_complex_push (CDImode, operands[0], operands[1]);
2287   else
2288     emit_move_complex_parts (operands[0], operands[1]);
2289   DONE;
2290 })
2291
2292 (define_expand "movsf"
2293   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2294         (match_operand:SF 1 "general_operand" ""))]
2295   ""
2296   "ix86_expand_move (SFmode, operands); DONE;")
2297
2298 (define_insn "*pushsf"
2299   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2300         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2301   "!TARGET_64BIT"
2302 {
2303   /* Anything else should be already split before reg-stack.  */
2304   gcc_assert (which_alternative == 1);
2305   return "push{l}\t%1";
2306 }
2307   [(set_attr "type" "multi,push,multi")
2308    (set_attr "unit" "i387,*,*")
2309    (set_attr "mode" "SF,SI,SF")])
2310
2311 (define_insn "*pushsf_rex64"
2312   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2313         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2314   "TARGET_64BIT"
2315 {
2316   /* Anything else should be already split before reg-stack.  */
2317   gcc_assert (which_alternative == 1);
2318   return "push{q}\t%q1";
2319 }
2320   [(set_attr "type" "multi,push,multi")
2321    (set_attr "unit" "i387,*,*")
2322    (set_attr "mode" "SF,DI,SF")])
2323
2324 (define_split
2325   [(set (match_operand:SF 0 "push_operand" "")
2326         (match_operand:SF 1 "memory_operand" ""))]
2327   "reload_completed
2328    && MEM_P (operands[1])
2329    && (operands[2] = find_constant_src (insn))"
2330   [(set (match_dup 0)
2331         (match_dup 2))])
2332
2333
2334 ;; %%% Kill this when call knows how to work this out.
2335 (define_split
2336   [(set (match_operand:SF 0 "push_operand" "")
2337         (match_operand:SF 1 "any_fp_register_operand" ""))]
2338   "!TARGET_64BIT"
2339   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2340    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2341
2342 (define_split
2343   [(set (match_operand:SF 0 "push_operand" "")
2344         (match_operand:SF 1 "any_fp_register_operand" ""))]
2345   "TARGET_64BIT"
2346   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2347    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2348
2349 (define_insn "*movsf_1"
2350   [(set (match_operand:SF 0 "nonimmediate_operand"
2351           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2352         (match_operand:SF 1 "general_operand"
2353           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2354   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2355    && (reload_in_progress || reload_completed
2356        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2357        || (!TARGET_SSE_MATH && optimize_size
2358            && standard_80387_constant_p (operands[1]))
2359        || GET_CODE (operands[1]) != CONST_DOUBLE
2360        || memory_operand (operands[0], SFmode))"
2361 {
2362   switch (which_alternative)
2363     {
2364     case 0:
2365     case 1:
2366       return output_387_reg_move (insn, operands);
2367
2368     case 2:
2369       return standard_80387_constant_opcode (operands[1]);
2370
2371     case 3:
2372     case 4:
2373       return "mov{l}\t{%1, %0|%0, %1}";
2374     case 5:
2375       if (get_attr_mode (insn) == MODE_TI)
2376         return "pxor\t%0, %0";
2377       else
2378         return "xorps\t%0, %0";
2379     case 6:
2380       if (get_attr_mode (insn) == MODE_V4SF)
2381         return "movaps\t{%1, %0|%0, %1}";
2382       else
2383         return "movss\t{%1, %0|%0, %1}";
2384     case 7: case 8:
2385       return "movss\t{%1, %0|%0, %1}";
2386
2387     case 9: case 10:
2388     case 12: case 13: case 14: case 15:
2389       return "movd\t{%1, %0|%0, %1}";
2390
2391     case 11:
2392       return "movq\t{%1, %0|%0, %1}";
2393
2394     default:
2395       gcc_unreachable ();
2396     }
2397 }
2398   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2399    (set (attr "mode")
2400         (cond [(eq_attr "alternative" "3,4,9,10")
2401                  (const_string "SI")
2402                (eq_attr "alternative" "5")
2403                  (if_then_else
2404                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2405                                  (const_int 0))
2406                              (ne (symbol_ref "TARGET_SSE2")
2407                                  (const_int 0)))
2408                         (eq (symbol_ref "optimize_size")
2409                             (const_int 0)))
2410                    (const_string "TI")
2411                    (const_string "V4SF"))
2412                /* For architectures resolving dependencies on
2413                   whole SSE registers use APS move to break dependency
2414                   chains, otherwise use short move to avoid extra work.
2415
2416                   Do the same for architectures resolving dependencies on
2417                   the parts.  While in DF mode it is better to always handle
2418                   just register parts, the SF mode is different due to lack
2419                   of instructions to load just part of the register.  It is
2420                   better to maintain the whole registers in single format
2421                   to avoid problems on using packed logical operations.  */
2422                (eq_attr "alternative" "6")
2423                  (if_then_else
2424                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2425                             (const_int 0))
2426                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2427                             (const_int 0)))
2428                    (const_string "V4SF")
2429                    (const_string "SF"))
2430                (eq_attr "alternative" "11")
2431                  (const_string "DI")]
2432                (const_string "SF")))])
2433
2434 (define_insn "*swapsf"
2435   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2436         (match_operand:SF 1 "fp_register_operand" "+f"))
2437    (set (match_dup 1)
2438         (match_dup 0))]
2439   "reload_completed || TARGET_80387"
2440 {
2441   if (STACK_TOP_P (operands[0]))
2442     return "fxch\t%1";
2443   else
2444     return "fxch\t%0";
2445 }
2446   [(set_attr "type" "fxch")
2447    (set_attr "mode" "SF")])
2448
2449 (define_expand "movdf"
2450   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2451         (match_operand:DF 1 "general_operand" ""))]
2452   ""
2453   "ix86_expand_move (DFmode, operands); DONE;")
2454
2455 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2456 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2457 ;; On the average, pushdf using integers can be still shorter.  Allow this
2458 ;; pattern for optimize_size too.
2459
2460 (define_insn "*pushdf_nointeger"
2461   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2462         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Yt"))]
2463   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2464 {
2465   /* This insn should be already split before reg-stack.  */
2466   gcc_unreachable ();
2467 }
2468   [(set_attr "type" "multi")
2469    (set_attr "unit" "i387,*,*,*")
2470    (set_attr "mode" "DF,SI,SI,DF")])
2471
2472 (define_insn "*pushdf_integer"
2473   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2474         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Yt"))]
2475   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2476 {
2477   /* This insn should be already split before reg-stack.  */
2478   gcc_unreachable ();
2479 }
2480   [(set_attr "type" "multi")
2481    (set_attr "unit" "i387,*,*")
2482    (set_attr "mode" "DF,SI,DF")])
2483
2484 ;; %%% Kill this when call knows how to work this out.
2485 (define_split
2486   [(set (match_operand:DF 0 "push_operand" "")
2487         (match_operand:DF 1 "any_fp_register_operand" ""))]
2488   "!TARGET_64BIT && reload_completed"
2489   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2490    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2491   "")
2492
2493 (define_split
2494   [(set (match_operand:DF 0 "push_operand" "")
2495         (match_operand:DF 1 "any_fp_register_operand" ""))]
2496   "TARGET_64BIT && reload_completed"
2497   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2498    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2499   "")
2500
2501 (define_split
2502   [(set (match_operand:DF 0 "push_operand" "")
2503         (match_operand:DF 1 "general_operand" ""))]
2504   "reload_completed"
2505   [(const_int 0)]
2506   "ix86_split_long_move (operands); DONE;")
2507
2508 ;; Moving is usually shorter when only FP registers are used. This separate
2509 ;; movdf pattern avoids the use of integer registers for FP operations
2510 ;; when optimizing for size.
2511
2512 (define_insn "*movdf_nointeger"
2513   [(set (match_operand:DF 0 "nonimmediate_operand"
2514                         "=f,m,f,*r  ,o  ,Yt*x,Yt*x,Yt*x ,m  ")
2515         (match_operand:DF 1 "general_operand"
2516                         "fm,f,G,*roF,F*r,C   ,Yt*x,mYt*x,Yt*x"))]
2517   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2518    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2519    && (reload_in_progress || reload_completed
2520        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2521        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2522            && standard_80387_constant_p (operands[1]))
2523        || GET_CODE (operands[1]) != CONST_DOUBLE
2524        || memory_operand (operands[0], DFmode))"
2525 {
2526   switch (which_alternative)
2527     {
2528     case 0:
2529     case 1:
2530       return output_387_reg_move (insn, operands);
2531
2532     case 2:
2533       return standard_80387_constant_opcode (operands[1]);
2534
2535     case 3:
2536     case 4:
2537       return "#";
2538     case 5:
2539       switch (get_attr_mode (insn))
2540         {
2541         case MODE_V4SF:
2542           return "xorps\t%0, %0";
2543         case MODE_V2DF:
2544           return "xorpd\t%0, %0";
2545         case MODE_TI:
2546           return "pxor\t%0, %0";
2547         default:
2548           gcc_unreachable ();
2549         }
2550     case 6:
2551     case 7:
2552     case 8:
2553       switch (get_attr_mode (insn))
2554         {
2555         case MODE_V4SF:
2556           return "movaps\t{%1, %0|%0, %1}";
2557         case MODE_V2DF:
2558           return "movapd\t{%1, %0|%0, %1}";
2559         case MODE_TI:
2560           return "movdqa\t{%1, %0|%0, %1}";
2561         case MODE_DI:
2562           return "movq\t{%1, %0|%0, %1}";
2563         case MODE_DF:
2564           return "movsd\t{%1, %0|%0, %1}";
2565         case MODE_V1DF:
2566           return "movlpd\t{%1, %0|%0, %1}";
2567         case MODE_V2SF:
2568           return "movlps\t{%1, %0|%0, %1}";
2569         default:
2570           gcc_unreachable ();
2571         }
2572
2573     default:
2574       gcc_unreachable ();
2575     }
2576 }
2577   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2578    (set (attr "mode")
2579         (cond [(eq_attr "alternative" "0,1,2")
2580                  (const_string "DF")
2581                (eq_attr "alternative" "3,4")
2582                  (const_string "SI")
2583
2584                /* For SSE1, we have many fewer alternatives.  */
2585                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2586                  (cond [(eq_attr "alternative" "5,6")
2587                           (const_string "V4SF")
2588                        ]
2589                    (const_string "V2SF"))
2590
2591                /* xorps is one byte shorter.  */
2592                (eq_attr "alternative" "5")
2593                  (cond [(ne (symbol_ref "optimize_size")
2594                             (const_int 0))
2595                           (const_string "V4SF")
2596                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2597                             (const_int 0))
2598                           (const_string "TI")
2599                        ]
2600                        (const_string "V2DF"))
2601
2602                /* For architectures resolving dependencies on
2603                   whole SSE registers use APD move to break dependency
2604                   chains, otherwise use short move to avoid extra work.
2605
2606                   movaps encodes one byte shorter.  */
2607                (eq_attr "alternative" "6")
2608                  (cond
2609                    [(ne (symbol_ref "optimize_size")
2610                         (const_int 0))
2611                       (const_string "V4SF")
2612                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2613                         (const_int 0))
2614                       (const_string "V2DF")
2615                    ]
2616                    (const_string "DF"))
2617                /* For architectures resolving dependencies on register
2618                   parts we may avoid extra work to zero out upper part
2619                   of register.  */
2620                (eq_attr "alternative" "7")
2621                  (if_then_else
2622                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2623                        (const_int 0))
2624                    (const_string "V1DF")
2625                    (const_string "DF"))
2626               ]
2627               (const_string "DF")))])
2628
2629 (define_insn "*movdf_integer_rex64"
2630   [(set (match_operand:DF 0 "nonimmediate_operand"
2631                 "=f,m,f,r  ,m ,Yt*x,Yt*x,Yt*x,m   ,Yi,r ")
2632         (match_operand:DF 1 "general_operand"
2633                 "fm,f,G,rmF,Fr,C   ,Yt*x,m   ,Yt*x,r ,Yi"))]
2634   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2635    && (reload_in_progress || reload_completed
2636        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2637        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2638            && standard_80387_constant_p (operands[1]))
2639        || GET_CODE (operands[1]) != CONST_DOUBLE
2640        || memory_operand (operands[0], DFmode))"
2641 {
2642   switch (which_alternative)
2643     {
2644     case 0:
2645     case 1:
2646       return output_387_reg_move (insn, operands);
2647
2648     case 2:
2649       return standard_80387_constant_opcode (operands[1]);
2650
2651     case 3:
2652     case 4:
2653       return "#";
2654
2655     case 5:
2656       switch (get_attr_mode (insn))
2657         {
2658         case MODE_V4SF:
2659           return "xorps\t%0, %0";
2660         case MODE_V2DF:
2661           return "xorpd\t%0, %0";
2662         case MODE_TI:
2663           return "pxor\t%0, %0";
2664         default:
2665           gcc_unreachable ();
2666         }
2667     case 6:
2668     case 7:
2669     case 8:
2670       switch (get_attr_mode (insn))
2671         {
2672         case MODE_V4SF:
2673           return "movaps\t{%1, %0|%0, %1}";
2674         case MODE_V2DF:
2675           return "movapd\t{%1, %0|%0, %1}";
2676         case MODE_TI:
2677           return "movdqa\t{%1, %0|%0, %1}";
2678         case MODE_DI:
2679           return "movq\t{%1, %0|%0, %1}";
2680         case MODE_DF:
2681           return "movsd\t{%1, %0|%0, %1}";
2682         case MODE_V1DF:
2683           return "movlpd\t{%1, %0|%0, %1}";
2684         case MODE_V2SF:
2685           return "movlps\t{%1, %0|%0, %1}";
2686         default:
2687           gcc_unreachable ();
2688         }
2689
2690     case 9:
2691     case 10:
2692       return "movd\t{%1, %0|%0, %1}";
2693
2694     default:
2695       gcc_unreachable();
2696     }
2697 }
2698   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2699    (set (attr "mode")
2700         (cond [(eq_attr "alternative" "0,1,2")
2701                  (const_string "DF")
2702                (eq_attr "alternative" "3,4,9,10")
2703                  (const_string "DI")
2704
2705                /* For SSE1, we have many fewer alternatives.  */
2706                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2707                  (cond [(eq_attr "alternative" "5,6")
2708                           (const_string "V4SF")
2709                        ]
2710                    (const_string "V2SF"))
2711
2712                /* xorps is one byte shorter.  */
2713                (eq_attr "alternative" "5")
2714                  (cond [(ne (symbol_ref "optimize_size")
2715                             (const_int 0))
2716                           (const_string "V4SF")
2717                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2718                             (const_int 0))
2719                           (const_string "TI")
2720                        ]
2721                        (const_string "V2DF"))
2722
2723                /* For architectures resolving dependencies on
2724                   whole SSE registers use APD move to break dependency
2725                   chains, otherwise use short move to avoid extra work.
2726
2727                   movaps encodes one byte shorter.  */
2728                (eq_attr "alternative" "6")
2729                  (cond
2730                    [(ne (symbol_ref "optimize_size")
2731                         (const_int 0))
2732                       (const_string "V4SF")
2733                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2734                         (const_int 0))
2735                       (const_string "V2DF")
2736                    ]
2737                    (const_string "DF"))
2738                /* For architectures resolving dependencies on register
2739                   parts we may avoid extra work to zero out upper part
2740                   of register.  */
2741                (eq_attr "alternative" "7")
2742                  (if_then_else
2743                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2744                        (const_int 0))
2745                    (const_string "V1DF")
2746                    (const_string "DF"))
2747               ]
2748               (const_string "DF")))])
2749
2750 (define_insn "*movdf_integer"
2751   [(set (match_operand:DF 0 "nonimmediate_operand"
2752                 "=f,m,f,r  ,o ,Yt*x,Yt*x,Yt*x,m   ")
2753         (match_operand:DF 1 "general_operand"
2754                 "fm,f,G,roF,Fr,C   ,Yt*x,m   ,Yt*x"))]
2755   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2756    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2757    && (reload_in_progress || reload_completed
2758        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2759        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2760            && standard_80387_constant_p (operands[1]))
2761        || GET_CODE (operands[1]) != CONST_DOUBLE
2762        || memory_operand (operands[0], DFmode))"
2763 {
2764   switch (which_alternative)
2765     {
2766     case 0:
2767     case 1:
2768       return output_387_reg_move (insn, operands);
2769
2770     case 2:
2771       return standard_80387_constant_opcode (operands[1]);
2772
2773     case 3:
2774     case 4:
2775       return "#";
2776
2777     case 5:
2778       switch (get_attr_mode (insn))
2779         {
2780         case MODE_V4SF:
2781           return "xorps\t%0, %0";
2782         case MODE_V2DF:
2783           return "xorpd\t%0, %0";
2784         case MODE_TI:
2785           return "pxor\t%0, %0";
2786         default:
2787           gcc_unreachable ();
2788         }
2789     case 6:
2790     case 7:
2791     case 8:
2792       switch (get_attr_mode (insn))
2793         {
2794         case MODE_V4SF:
2795           return "movaps\t{%1, %0|%0, %1}";
2796         case MODE_V2DF:
2797           return "movapd\t{%1, %0|%0, %1}";
2798         case MODE_TI:
2799           return "movdqa\t{%1, %0|%0, %1}";
2800         case MODE_DI:
2801           return "movq\t{%1, %0|%0, %1}";
2802         case MODE_DF:
2803           return "movsd\t{%1, %0|%0, %1}";
2804         case MODE_V1DF:
2805           return "movlpd\t{%1, %0|%0, %1}";
2806         case MODE_V2SF:
2807           return "movlps\t{%1, %0|%0, %1}";
2808         default:
2809           gcc_unreachable ();
2810         }
2811
2812     default:
2813       gcc_unreachable();
2814     }
2815 }
2816   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2817    (set (attr "mode")
2818         (cond [(eq_attr "alternative" "0,1,2")
2819                  (const_string "DF")
2820                (eq_attr "alternative" "3,4")
2821                  (const_string "SI")
2822
2823                /* For SSE1, we have many fewer alternatives.  */
2824                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2825                  (cond [(eq_attr "alternative" "5,6")
2826                           (const_string "V4SF")
2827                        ]
2828                    (const_string "V2SF"))
2829
2830                /* xorps is one byte shorter.  */
2831                (eq_attr "alternative" "5")
2832                  (cond [(ne (symbol_ref "optimize_size")
2833                             (const_int 0))
2834                           (const_string "V4SF")
2835                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2836                             (const_int 0))
2837                           (const_string "TI")
2838                        ]
2839                        (const_string "V2DF"))
2840
2841                /* For architectures resolving dependencies on
2842                   whole SSE registers use APD move to break dependency
2843                   chains, otherwise use short move to avoid extra work.
2844
2845                   movaps encodes one byte shorter.  */
2846                (eq_attr "alternative" "6")
2847                  (cond
2848                    [(ne (symbol_ref "optimize_size")
2849                         (const_int 0))
2850                       (const_string "V4SF")
2851                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2852                         (const_int 0))
2853                       (const_string "V2DF")
2854                    ]
2855                    (const_string "DF"))
2856                /* For architectures resolving dependencies on register
2857                   parts we may avoid extra work to zero out upper part
2858                   of register.  */
2859                (eq_attr "alternative" "7")
2860                  (if_then_else
2861                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2862                        (const_int 0))
2863                    (const_string "V1DF")
2864                    (const_string "DF"))
2865               ]
2866               (const_string "DF")))])
2867
2868 (define_split
2869   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2870         (match_operand:DF 1 "general_operand" ""))]
2871   "reload_completed
2872    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2873    && ! (ANY_FP_REG_P (operands[0]) ||
2874          (GET_CODE (operands[0]) == SUBREG
2875           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2876    && ! (ANY_FP_REG_P (operands[1]) ||
2877          (GET_CODE (operands[1]) == SUBREG
2878           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2879   [(const_int 0)]
2880   "ix86_split_long_move (operands); DONE;")
2881
2882 (define_insn "*swapdf"
2883   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2884         (match_operand:DF 1 "fp_register_operand" "+f"))
2885    (set (match_dup 1)
2886         (match_dup 0))]
2887   "reload_completed || TARGET_80387"
2888 {
2889   if (STACK_TOP_P (operands[0]))
2890     return "fxch\t%1";
2891   else
2892     return "fxch\t%0";
2893 }
2894   [(set_attr "type" "fxch")
2895    (set_attr "mode" "DF")])
2896
2897 (define_expand "movxf"
2898   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2899         (match_operand:XF 1 "general_operand" ""))]
2900   ""
2901   "ix86_expand_move (XFmode, operands); DONE;")
2902
2903 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2904 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2905 ;; Pushing using integer instructions is longer except for constants
2906 ;; and direct memory references.
2907 ;; (assuming that any given constant is pushed only once, but this ought to be
2908 ;;  handled elsewhere).
2909
2910 (define_insn "*pushxf_nointeger"
2911   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2912         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2913   "optimize_size"
2914 {
2915   /* This insn should be already split before reg-stack.  */
2916   gcc_unreachable ();
2917 }
2918   [(set_attr "type" "multi")
2919    (set_attr "unit" "i387,*,*")
2920    (set_attr "mode" "XF,SI,SI")])
2921
2922 (define_insn "*pushxf_integer"
2923   [(set (match_operand:XF 0 "push_operand" "=<,<")
2924         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2925   "!optimize_size"
2926 {
2927   /* This insn should be already split before reg-stack.  */
2928   gcc_unreachable ();
2929 }
2930   [(set_attr "type" "multi")
2931    (set_attr "unit" "i387,*")
2932    (set_attr "mode" "XF,SI")])
2933
2934 (define_split
2935   [(set (match_operand 0 "push_operand" "")
2936         (match_operand 1 "general_operand" ""))]
2937   "reload_completed
2938    && (GET_MODE (operands[0]) == XFmode
2939        || GET_MODE (operands[0]) == DFmode)
2940    && !ANY_FP_REG_P (operands[1])"
2941   [(const_int 0)]
2942   "ix86_split_long_move (operands); DONE;")
2943
2944 (define_split
2945   [(set (match_operand:XF 0 "push_operand" "")
2946         (match_operand:XF 1 "any_fp_register_operand" ""))]
2947   "!TARGET_64BIT"
2948   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2949    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2950   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2951
2952 (define_split
2953   [(set (match_operand:XF 0 "push_operand" "")
2954         (match_operand:XF 1 "any_fp_register_operand" ""))]
2955   "TARGET_64BIT"
2956   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2957    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2958   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2959
2960 ;; Do not use integer registers when optimizing for size
2961 (define_insn "*movxf_nointeger"
2962   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2963         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2964   "optimize_size
2965    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2966    && (reload_in_progress || reload_completed
2967        || (optimize_size && standard_80387_constant_p (operands[1]))
2968        || GET_CODE (operands[1]) != CONST_DOUBLE
2969        || memory_operand (operands[0], XFmode))"
2970 {
2971   switch (which_alternative)
2972     {
2973     case 0:
2974     case 1:
2975       return output_387_reg_move (insn, operands);
2976
2977     case 2:
2978       return standard_80387_constant_opcode (operands[1]);
2979
2980     case 3: case 4:
2981       return "#";
2982     default:
2983       gcc_unreachable ();
2984     }
2985 }
2986   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2987    (set_attr "mode" "XF,XF,XF,SI,SI")])
2988
2989 (define_insn "*movxf_integer"
2990   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2991         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2992   "!optimize_size
2993    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2994    && (reload_in_progress || reload_completed
2995        || (optimize_size && standard_80387_constant_p (operands[1]))
2996        || GET_CODE (operands[1]) != CONST_DOUBLE
2997        || memory_operand (operands[0], XFmode))"
2998 {
2999   switch (which_alternative)
3000     {
3001     case 0:
3002     case 1:
3003       return output_387_reg_move (insn, operands);
3004
3005     case 2:
3006       return standard_80387_constant_opcode (operands[1]);
3007
3008     case 3: case 4:
3009       return "#";
3010
3011     default:
3012       gcc_unreachable ();
3013     }
3014 }
3015   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3016    (set_attr "mode" "XF,XF,XF,SI,SI")])
3017
3018 (define_split
3019   [(set (match_operand 0 "nonimmediate_operand" "")
3020         (match_operand 1 "general_operand" ""))]
3021   "reload_completed
3022    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3023    && GET_MODE (operands[0]) == XFmode
3024    && ! (ANY_FP_REG_P (operands[0]) ||
3025          (GET_CODE (operands[0]) == SUBREG
3026           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3027    && ! (ANY_FP_REG_P (operands[1]) ||
3028          (GET_CODE (operands[1]) == SUBREG
3029           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3030   [(const_int 0)]
3031   "ix86_split_long_move (operands); DONE;")
3032
3033 (define_split
3034   [(set (match_operand 0 "register_operand" "")
3035         (match_operand 1 "memory_operand" ""))]
3036   "reload_completed
3037    && MEM_P (operands[1])
3038    && (GET_MODE (operands[0]) == TFmode
3039        || GET_MODE (operands[0]) == XFmode
3040        || GET_MODE (operands[0]) == SFmode
3041        || GET_MODE (operands[0]) == DFmode)
3042    && (operands[2] = find_constant_src (insn))"
3043   [(set (match_dup 0) (match_dup 2))]
3044 {
3045   rtx c = operands[2];
3046   rtx r = operands[0];
3047
3048   if (GET_CODE (r) == SUBREG)
3049     r = SUBREG_REG (r);
3050
3051   if (SSE_REG_P (r))
3052     {
3053       if (!standard_sse_constant_p (c))
3054         FAIL;
3055     }
3056   else if (FP_REG_P (r))
3057     {
3058       if (!standard_80387_constant_p (c))
3059         FAIL;
3060     }
3061   else if (MMX_REG_P (r))
3062     FAIL;
3063 })
3064
3065 (define_split
3066   [(set (match_operand 0 "register_operand" "")
3067         (float_extend (match_operand 1 "memory_operand" "")))]
3068   "reload_completed
3069    && MEM_P (operands[1])
3070    && (GET_MODE (operands[0]) == XFmode
3071        || GET_MODE (operands[0]) == SFmode
3072        || GET_MODE (operands[0]) == DFmode)
3073    && (operands[2] = find_constant_src (insn))"
3074   [(set (match_dup 0) (match_dup 2))]
3075 {
3076   rtx c = operands[2];
3077   rtx r = operands[0];
3078
3079   if (GET_CODE (r) == SUBREG)
3080     r = SUBREG_REG (r);
3081
3082   if (SSE_REG_P (r))
3083     {
3084       if (!standard_sse_constant_p (c))
3085         FAIL;
3086     }
3087   else if (FP_REG_P (r))
3088     {
3089       if (!standard_80387_constant_p (c))
3090         FAIL;
3091     }
3092   else if (MMX_REG_P (r))
3093     FAIL;
3094 })
3095
3096 (define_insn "swapxf"
3097   [(set (match_operand:XF 0 "register_operand" "+f")
3098         (match_operand:XF 1 "register_operand" "+f"))
3099    (set (match_dup 1)
3100         (match_dup 0))]
3101   "TARGET_80387"
3102 {
3103   if (STACK_TOP_P (operands[0]))
3104     return "fxch\t%1";
3105   else
3106     return "fxch\t%0";
3107 }
3108   [(set_attr "type" "fxch")
3109    (set_attr "mode" "XF")])
3110
3111 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3112 (define_split
3113   [(set (match_operand:X87MODEF 0 "register_operand" "")
3114         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3115   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3116    && (standard_80387_constant_p (operands[1]) == 8
3117        || standard_80387_constant_p (operands[1]) == 9)"
3118   [(set (match_dup 0)(match_dup 1))
3119    (set (match_dup 0)
3120         (neg:X87MODEF (match_dup 0)))]
3121 {
3122   REAL_VALUE_TYPE r;
3123
3124   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3125   if (real_isnegzero (&r))
3126     operands[1] = CONST0_RTX (<MODE>mode);
3127   else
3128     operands[1] = CONST1_RTX (<MODE>mode);
3129 })
3130
3131 (define_expand "movtf"
3132   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3133         (match_operand:TF 1 "nonimmediate_operand" ""))]
3134   "TARGET_64BIT"
3135 {
3136   ix86_expand_move (TFmode, operands);
3137   DONE;
3138 })
3139
3140 (define_insn "*movtf_internal"
3141   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3142         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3143   "TARGET_64BIT
3144    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3145 {
3146   switch (which_alternative)
3147     {
3148     case 0:
3149     case 1:
3150       return "#";
3151     case 2:
3152       if (get_attr_mode (insn) == MODE_V4SF)
3153         return "xorps\t%0, %0";
3154       else
3155         return "pxor\t%0, %0";
3156     case 3:
3157     case 4:
3158       if (get_attr_mode (insn) == MODE_V4SF)
3159         return "movaps\t{%1, %0|%0, %1}";
3160       else
3161         return "movdqa\t{%1, %0|%0, %1}";
3162     default:
3163       gcc_unreachable ();
3164     }
3165 }
3166   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3167    (set (attr "mode")
3168         (cond [(eq_attr "alternative" "2,3")
3169                  (if_then_else
3170                    (ne (symbol_ref "optimize_size")
3171                        (const_int 0))
3172                    (const_string "V4SF")
3173                    (const_string "TI"))
3174                (eq_attr "alternative" "4")
3175                  (if_then_else
3176                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3177                             (const_int 0))
3178                         (ne (symbol_ref "optimize_size")
3179                             (const_int 0)))
3180                    (const_string "V4SF")
3181                    (const_string "TI"))]
3182                (const_string "DI")))])
3183
3184 (define_split
3185   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3186         (match_operand:TF 1 "general_operand" ""))]
3187   "reload_completed && !SSE_REG_P (operands[0])
3188    && !SSE_REG_P (operands[1])"
3189   [(const_int 0)]
3190   "ix86_split_long_move (operands); DONE;")
3191 \f
3192 ;; Zero extension instructions
3193
3194 (define_expand "zero_extendhisi2"
3195   [(set (match_operand:SI 0 "register_operand" "")
3196      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3197   ""
3198 {
3199   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3200     {
3201       operands[1] = force_reg (HImode, operands[1]);
3202       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3203       DONE;
3204     }
3205 })
3206
3207 (define_insn "zero_extendhisi2_and"
3208   [(set (match_operand:SI 0 "register_operand" "=r")
3209      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3210    (clobber (reg:CC FLAGS_REG))]
3211   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3212   "#"
3213   [(set_attr "type" "alu1")
3214    (set_attr "mode" "SI")])
3215
3216 (define_split
3217   [(set (match_operand:SI 0 "register_operand" "")
3218         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3219    (clobber (reg:CC FLAGS_REG))]
3220   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3221   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3222               (clobber (reg:CC FLAGS_REG))])]
3223   "")
3224
3225 (define_insn "*zero_extendhisi2_movzwl"
3226   [(set (match_operand:SI 0 "register_operand" "=r")
3227      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3228   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3229   "movz{wl|x}\t{%1, %0|%0, %1}"
3230   [(set_attr "type" "imovx")
3231    (set_attr "mode" "SI")])
3232
3233 (define_expand "zero_extendqihi2"
3234   [(parallel
3235     [(set (match_operand:HI 0 "register_operand" "")
3236        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3237      (clobber (reg:CC FLAGS_REG))])]
3238   ""
3239   "")
3240
3241 (define_insn "*zero_extendqihi2_and"
3242   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3243      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3244    (clobber (reg:CC FLAGS_REG))]
3245   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3246   "#"
3247   [(set_attr "type" "alu1")
3248    (set_attr "mode" "HI")])
3249
3250 (define_insn "*zero_extendqihi2_movzbw_and"
3251   [(set (match_operand:HI 0 "register_operand" "=r,r")
3252      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3253    (clobber (reg:CC FLAGS_REG))]
3254   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3255   "#"
3256   [(set_attr "type" "imovx,alu1")
3257    (set_attr "mode" "HI")])
3258
3259 ; zero extend to SImode here to avoid partial register stalls
3260 (define_insn "*zero_extendqihi2_movzbl"
3261   [(set (match_operand:HI 0 "register_operand" "=r")
3262      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3263   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3264   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3265   [(set_attr "type" "imovx")
3266    (set_attr "mode" "SI")])
3267
3268 ;; For the movzbw case strip only the clobber
3269 (define_split
3270   [(set (match_operand:HI 0 "register_operand" "")
3271         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3272    (clobber (reg:CC FLAGS_REG))]
3273   "reload_completed
3274    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3275    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3276   [(set (match_operand:HI 0 "register_operand" "")
3277         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3278
3279 ;; When source and destination does not overlap, clear destination
3280 ;; first and then do the movb
3281 (define_split
3282   [(set (match_operand:HI 0 "register_operand" "")
3283         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3284    (clobber (reg:CC FLAGS_REG))]
3285   "reload_completed
3286    && ANY_QI_REG_P (operands[0])
3287    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3288    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3289   [(set (match_dup 0) (const_int 0))
3290    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3291   "operands[2] = gen_lowpart (QImode, operands[0]);")
3292
3293 ;; Rest is handled by single and.
3294 (define_split
3295   [(set (match_operand:HI 0 "register_operand" "")
3296         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3297    (clobber (reg:CC FLAGS_REG))]
3298   "reload_completed
3299    && true_regnum (operands[0]) == true_regnum (operands[1])"
3300   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3301               (clobber (reg:CC FLAGS_REG))])]
3302   "")
3303
3304 (define_expand "zero_extendqisi2"
3305   [(parallel
3306     [(set (match_operand:SI 0 "register_operand" "")
3307        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3308      (clobber (reg:CC FLAGS_REG))])]
3309   ""
3310   "")
3311
3312 (define_insn "*zero_extendqisi2_and"
3313   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3314      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3315    (clobber (reg:CC FLAGS_REG))]
3316   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3317   "#"
3318   [(set_attr "type" "alu1")
3319    (set_attr "mode" "SI")])
3320
3321 (define_insn "*zero_extendqisi2_movzbw_and"
3322   [(set (match_operand:SI 0 "register_operand" "=r,r")
3323      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3324    (clobber (reg:CC FLAGS_REG))]
3325   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3326   "#"
3327   [(set_attr "type" "imovx,alu1")
3328    (set_attr "mode" "SI")])
3329
3330 (define_insn "*zero_extendqisi2_movzbw"
3331   [(set (match_operand:SI 0 "register_operand" "=r")
3332      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3333   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3334   "movz{bl|x}\t{%1, %0|%0, %1}"
3335   [(set_attr "type" "imovx")
3336    (set_attr "mode" "SI")])
3337
3338 ;; For the movzbl case strip only the clobber
3339 (define_split
3340   [(set (match_operand:SI 0 "register_operand" "")
3341         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3342    (clobber (reg:CC FLAGS_REG))]
3343   "reload_completed
3344    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3345    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3346   [(set (match_dup 0)
3347         (zero_extend:SI (match_dup 1)))])
3348
3349 ;; When source and destination does not overlap, clear destination
3350 ;; first and then do the movb
3351 (define_split
3352   [(set (match_operand:SI 0 "register_operand" "")
3353         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3354    (clobber (reg:CC FLAGS_REG))]
3355   "reload_completed
3356    && ANY_QI_REG_P (operands[0])
3357    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3358    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3359    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3360   [(set (match_dup 0) (const_int 0))
3361    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3362   "operands[2] = gen_lowpart (QImode, operands[0]);")
3363
3364 ;; Rest is handled by single and.
3365 (define_split
3366   [(set (match_operand:SI 0 "register_operand" "")
3367         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3368    (clobber (reg:CC FLAGS_REG))]
3369   "reload_completed
3370    && true_regnum (operands[0]) == true_regnum (operands[1])"
3371   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3372               (clobber (reg:CC FLAGS_REG))])]
3373   "")
3374
3375 ;; %%% Kill me once multi-word ops are sane.
3376 (define_expand "zero_extendsidi2"
3377   [(set (match_operand:DI 0 "register_operand" "=r")
3378      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3379   ""
3380 {
3381   if (!TARGET_64BIT)
3382     {
3383       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3384       DONE;
3385     }
3386 })
3387
3388 (define_insn "zero_extendsidi2_32"
3389   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Yt")
3390         (zero_extend:DI
3391          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3392    (clobber (reg:CC FLAGS_REG))]
3393   "!TARGET_64BIT"
3394   "@
3395    #
3396    #
3397    #
3398    movd\t{%1, %0|%0, %1}
3399    movd\t{%1, %0|%0, %1}
3400    movd\t{%1, %0|%0, %1}
3401    movd\t{%1, %0|%0, %1}"
3402   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3403    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3404
3405 (define_insn "zero_extendsidi2_rex64"
3406   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Yt")
3407      (zero_extend:DI
3408        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3409   "TARGET_64BIT"
3410   "@
3411    mov\t{%k1, %k0|%k0, %k1}
3412    #
3413    movd\t{%1, %0|%0, %1}
3414    movd\t{%1, %0|%0, %1}
3415    movd\t{%1, %0|%0, %1}
3416    movd\t{%1, %0|%0, %1}"
3417   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3418    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3419
3420 (define_split
3421   [(set (match_operand:DI 0 "memory_operand" "")
3422      (zero_extend:DI (match_dup 0)))]
3423   "TARGET_64BIT"
3424   [(set (match_dup 4) (const_int 0))]
3425   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3426
3427 (define_split
3428   [(set (match_operand:DI 0 "register_operand" "")
3429         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3430    (clobber (reg:CC FLAGS_REG))]
3431   "!TARGET_64BIT && reload_completed
3432    && true_regnum (operands[0]) == true_regnum (operands[1])"
3433   [(set (match_dup 4) (const_int 0))]
3434   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3435
3436 (define_split
3437   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3438         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3439    (clobber (reg:CC FLAGS_REG))]
3440   "!TARGET_64BIT && reload_completed
3441    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3442   [(set (match_dup 3) (match_dup 1))
3443    (set (match_dup 4) (const_int 0))]
3444   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3445
3446 (define_insn "zero_extendhidi2"
3447   [(set (match_operand:DI 0 "register_operand" "=r")
3448      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3449   "TARGET_64BIT"
3450   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3451   [(set_attr "type" "imovx")
3452    (set_attr "mode" "DI")])
3453
3454 (define_insn "zero_extendqidi2"
3455   [(set (match_operand:DI 0 "register_operand" "=r")
3456      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3457   "TARGET_64BIT"
3458   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3459   [(set_attr "type" "imovx")
3460    (set_attr "mode" "DI")])
3461 \f
3462 ;; Sign extension instructions
3463
3464 (define_expand "extendsidi2"
3465   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3466                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3467               (clobber (reg:CC FLAGS_REG))
3468               (clobber (match_scratch:SI 2 ""))])]
3469   ""
3470 {
3471   if (TARGET_64BIT)
3472     {
3473       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3474       DONE;
3475     }
3476 })
3477
3478 (define_insn "*extendsidi2_1"
3479   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3480         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3481    (clobber (reg:CC FLAGS_REG))
3482    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3483   "!TARGET_64BIT"
3484   "#")
3485
3486 (define_insn "extendsidi2_rex64"
3487   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3488         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3489   "TARGET_64BIT"
3490   "@
3491    {cltq|cdqe}
3492    movs{lq|x}\t{%1,%0|%0, %1}"
3493   [(set_attr "type" "imovx")
3494    (set_attr "mode" "DI")
3495    (set_attr "prefix_0f" "0")
3496    (set_attr "modrm" "0,1")])
3497
3498 (define_insn "extendhidi2"
3499   [(set (match_operand:DI 0 "register_operand" "=r")
3500         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3501   "TARGET_64BIT"
3502   "movs{wq|x}\t{%1,%0|%0, %1}"
3503   [(set_attr "type" "imovx")
3504    (set_attr "mode" "DI")])
3505
3506 (define_insn "extendqidi2"
3507   [(set (match_operand:DI 0 "register_operand" "=r")
3508         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3509   "TARGET_64BIT"
3510   "movs{bq|x}\t{%1,%0|%0, %1}"
3511    [(set_attr "type" "imovx")
3512     (set_attr "mode" "DI")])
3513
3514 ;; Extend to memory case when source register does die.
3515 (define_split
3516   [(set (match_operand:DI 0 "memory_operand" "")
3517         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3518    (clobber (reg:CC FLAGS_REG))
3519    (clobber (match_operand:SI 2 "register_operand" ""))]
3520   "(reload_completed
3521     && dead_or_set_p (insn, operands[1])
3522     && !reg_mentioned_p (operands[1], operands[0]))"
3523   [(set (match_dup 3) (match_dup 1))
3524    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3525               (clobber (reg:CC FLAGS_REG))])
3526    (set (match_dup 4) (match_dup 1))]
3527   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3528
3529 ;; Extend to memory case when source register does not die.
3530 (define_split
3531   [(set (match_operand:DI 0 "memory_operand" "")
3532         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3533    (clobber (reg:CC FLAGS_REG))
3534    (clobber (match_operand:SI 2 "register_operand" ""))]
3535   "reload_completed"
3536   [(const_int 0)]
3537 {
3538   split_di (&operands[0], 1, &operands[3], &operands[4]);
3539
3540   emit_move_insn (operands[3], operands[1]);
3541
3542   /* Generate a cltd if possible and doing so it profitable.  */
3543   if (true_regnum (operands[1]) == 0
3544       && true_regnum (operands[2]) == 1
3545       && (optimize_size || TARGET_USE_CLTD))
3546     {
3547       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3548     }
3549   else
3550     {
3551       emit_move_insn (operands[2], operands[1]);
3552       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3553     }
3554   emit_move_insn (operands[4], operands[2]);
3555   DONE;
3556 })
3557
3558 ;; Extend to register case.  Optimize case where source and destination
3559 ;; registers match and cases where we can use cltd.
3560 (define_split
3561   [(set (match_operand:DI 0 "register_operand" "")
3562         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3563    (clobber (reg:CC FLAGS_REG))
3564    (clobber (match_scratch:SI 2 ""))]
3565   "reload_completed"
3566   [(const_int 0)]
3567 {
3568   split_di (&operands[0], 1, &operands[3], &operands[4]);
3569
3570   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3571     emit_move_insn (operands[3], operands[1]);
3572
3573   /* Generate a cltd if possible and doing so it profitable.  */
3574   if (true_regnum (operands[3]) == 0
3575       && (optimize_size || TARGET_USE_CLTD))
3576     {
3577       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3578       DONE;
3579     }
3580
3581   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3582     emit_move_insn (operands[4], operands[1]);
3583
3584   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3585   DONE;
3586 })
3587
3588 (define_insn "extendhisi2"
3589   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3590         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3591   ""
3592 {
3593   switch (get_attr_prefix_0f (insn))
3594     {
3595     case 0:
3596       return "{cwtl|cwde}";
3597     default:
3598       return "movs{wl|x}\t{%1,%0|%0, %1}";
3599     }
3600 }
3601   [(set_attr "type" "imovx")
3602    (set_attr "mode" "SI")
3603    (set (attr "prefix_0f")
3604      ;; movsx is short decodable while cwtl is vector decoded.
3605      (if_then_else (and (eq_attr "cpu" "!k6")
3606                         (eq_attr "alternative" "0"))
3607         (const_string "0")
3608         (const_string "1")))
3609    (set (attr "modrm")
3610      (if_then_else (eq_attr "prefix_0f" "0")
3611         (const_string "0")
3612         (const_string "1")))])
3613
3614 (define_insn "*extendhisi2_zext"
3615   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3616         (zero_extend:DI
3617           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3618   "TARGET_64BIT"
3619 {
3620   switch (get_attr_prefix_0f (insn))
3621     {
3622     case 0:
3623       return "{cwtl|cwde}";
3624     default:
3625       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3626     }
3627 }
3628   [(set_attr "type" "imovx")
3629    (set_attr "mode" "SI")
3630    (set (attr "prefix_0f")
3631      ;; movsx is short decodable while cwtl is vector decoded.
3632      (if_then_else (and (eq_attr "cpu" "!k6")
3633                         (eq_attr "alternative" "0"))
3634         (const_string "0")
3635         (const_string "1")))
3636    (set (attr "modrm")
3637      (if_then_else (eq_attr "prefix_0f" "0")
3638         (const_string "0")
3639         (const_string "1")))])
3640
3641 (define_insn "extendqihi2"
3642   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3643         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3644   ""
3645 {
3646   switch (get_attr_prefix_0f (insn))
3647     {
3648     case 0:
3649       return "{cbtw|cbw}";
3650     default:
3651       return "movs{bw|x}\t{%1,%0|%0, %1}";
3652     }
3653 }
3654   [(set_attr "type" "imovx")
3655    (set_attr "mode" "HI")
3656    (set (attr "prefix_0f")
3657      ;; movsx is short decodable while cwtl is vector decoded.
3658      (if_then_else (and (eq_attr "cpu" "!k6")
3659                         (eq_attr "alternative" "0"))
3660         (const_string "0")
3661         (const_string "1")))
3662    (set (attr "modrm")
3663      (if_then_else (eq_attr "prefix_0f" "0")
3664         (const_string "0")
3665         (const_string "1")))])
3666
3667 (define_insn "extendqisi2"
3668   [(set (match_operand:SI 0 "register_operand" "=r")
3669         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3670   ""
3671   "movs{bl|x}\t{%1,%0|%0, %1}"
3672    [(set_attr "type" "imovx")
3673     (set_attr "mode" "SI")])
3674
3675 (define_insn "*extendqisi2_zext"
3676   [(set (match_operand:DI 0 "register_operand" "=r")
3677         (zero_extend:DI
3678           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3679   "TARGET_64BIT"
3680   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3681    [(set_attr "type" "imovx")
3682     (set_attr "mode" "SI")])
3683 \f
3684 ;; Conversions between float and double.
3685
3686 ;; These are all no-ops in the model used for the 80387.  So just
3687 ;; emit moves.
3688
3689 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3690 (define_insn "*dummy_extendsfdf2"
3691   [(set (match_operand:DF 0 "push_operand" "=<")
3692         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3693   "0"
3694   "#")
3695
3696 (define_split
3697   [(set (match_operand:DF 0 "push_operand" "")
3698         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3699   "!TARGET_64BIT"
3700   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3701    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3702
3703 (define_split
3704   [(set (match_operand:DF 0 "push_operand" "")
3705         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3706   "TARGET_64BIT"
3707   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3708    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3709
3710 (define_insn "*dummy_extendsfxf2"
3711   [(set (match_operand:XF 0 "push_operand" "=<")
3712         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3713   "0"
3714   "#")
3715
3716 (define_split
3717   [(set (match_operand:XF 0 "push_operand" "")
3718         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3719   ""
3720   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3721    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3722   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3723
3724 (define_split
3725   [(set (match_operand:XF 0 "push_operand" "")
3726         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3727   "TARGET_64BIT"
3728   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3729    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3730   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3731
3732 (define_split
3733   [(set (match_operand:XF 0 "push_operand" "")
3734         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3735   ""
3736   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3737    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3738   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3739
3740 (define_split
3741   [(set (match_operand:XF 0 "push_operand" "")
3742         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3743   "TARGET_64BIT"
3744   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3745    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3746   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3747
3748 (define_expand "extendsfdf2"
3749   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3750         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3751   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3752 {
3753   /* ??? Needed for compress_float_constant since all fp constants
3754      are LEGITIMATE_CONSTANT_P.  */
3755   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3756     {
3757       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3758           && standard_80387_constant_p (operands[1]) > 0)
3759         {
3760           operands[1] = simplify_const_unary_operation
3761             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3762           emit_move_insn_1 (operands[0], operands[1]);
3763           DONE;
3764         }
3765       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3766     }
3767 })
3768
3769 (define_insn "*extendsfdf2_mixed"
3770   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3771         (float_extend:DF
3772           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3773   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3774 {
3775   switch (which_alternative)
3776     {
3777     case 0:
3778     case 1:
3779       return output_387_reg_move (insn, operands);
3780
3781     case 2:
3782       return "cvtss2sd\t{%1, %0|%0, %1}";
3783
3784     default:
3785       gcc_unreachable ();
3786     }
3787 }
3788   [(set_attr "type" "fmov,fmov,ssecvt")
3789    (set_attr "mode" "SF,XF,DF")])
3790
3791 (define_insn "*extendsfdf2_sse"
3792   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3793         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3794   "TARGET_SSE2 && TARGET_SSE_MATH"
3795   "cvtss2sd\t{%1, %0|%0, %1}"
3796   [(set_attr "type" "ssecvt")
3797    (set_attr "mode" "DF")])
3798
3799 (define_insn "*extendsfdf2_i387"
3800   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3801         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3802   "TARGET_80387"
3803   "* return output_387_reg_move (insn, operands);"
3804   [(set_attr "type" "fmov")
3805    (set_attr "mode" "SF,XF")])
3806
3807 (define_expand "extend<mode>xf2"
3808   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3809         (float_extend:XF (match_operand:X87MODEF12 1 "general_operand" "")))]
3810   "TARGET_80387"
3811 {
3812   /* ??? Needed for compress_float_constant since all fp constants
3813      are LEGITIMATE_CONSTANT_P.  */
3814   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3815     {
3816       if (standard_80387_constant_p (operands[1]) > 0)
3817         {
3818           operands[1] = simplify_const_unary_operation
3819             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3820           emit_move_insn_1 (operands[0], operands[1]);
3821           DONE;
3822         }
3823       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3824     }
3825 })
3826
3827 (define_insn "*extend<mode>xf2_i387"
3828   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3829         (float_extend:XF
3830           (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,f")))]
3831   "TARGET_80387"
3832   "* return output_387_reg_move (insn, operands);"
3833   [(set_attr "type" "fmov")
3834    (set_attr "mode" "<MODE>,XF")])
3835
3836 ;; %%% This seems bad bad news.
3837 ;; This cannot output into an f-reg because there is no way to be sure
3838 ;; of truncating in that case.  Otherwise this is just like a simple move
3839 ;; insn.  So we pretend we can output to a reg in order to get better
3840 ;; register preferencing, but we really use a stack slot.
3841
3842 ;; Conversion from DFmode to SFmode.
3843
3844 (define_expand "truncdfsf2"
3845   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3846         (float_truncate:SF
3847           (match_operand:DF 1 "nonimmediate_operand" "")))]
3848   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3849 {
3850   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3851     ;
3852   else if (flag_unsafe_math_optimizations)
3853     ;
3854   else
3855     {
3856       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3857       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3858       DONE;
3859     }
3860 })
3861
3862 (define_expand "truncdfsf2_with_temp"
3863   [(parallel [(set (match_operand:SF 0 "" "")
3864                    (float_truncate:SF (match_operand:DF 1 "" "")))
3865               (clobber (match_operand:SF 2 "" ""))])]
3866   "")
3867
3868 (define_insn "*truncdfsf_fast_mixed"
3869   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
3870         (float_truncate:SF
3871           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3872   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3873 {
3874   switch (which_alternative)
3875     {
3876     case 0:
3877     case 1:
3878       return output_387_reg_move (insn, operands);
3879     case 2:
3880       return "cvtsd2ss\t{%1, %0|%0, %1}";
3881     default:
3882       gcc_unreachable ();
3883     }
3884 }
3885   [(set_attr "type" "fmov,fmov,ssecvt")
3886    (set_attr "mode" "SF")])
3887
3888 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3889 ;; because nothing we do here is unsafe.
3890 (define_insn "*truncdfsf_fast_sse"
3891   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
3892         (float_truncate:SF
3893           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3894   "TARGET_SSE2 && TARGET_SSE_MATH"
3895   "cvtsd2ss\t{%1, %0|%0, %1}"
3896   [(set_attr "type" "ssecvt")
3897    (set_attr "mode" "SF")])
3898
3899 (define_insn "*truncdfsf_fast_i387"
3900   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3901         (float_truncate:SF
3902           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3903   "TARGET_80387 && flag_unsafe_math_optimizations"
3904   "* return output_387_reg_move (insn, operands);"
3905   [(set_attr "type" "fmov")
3906    (set_attr "mode" "SF")])
3907
3908 (define_insn "*truncdfsf_mixed"
3909   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Yt")
3910         (float_truncate:SF
3911           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ytm")))
3912    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3913   "TARGET_MIX_SSE_I387"
3914 {
3915   switch (which_alternative)
3916     {
3917     case 0:
3918       return output_387_reg_move (insn, operands);
3919
3920     case 1:
3921       return "#";
3922     case 2:
3923       return "cvtsd2ss\t{%1, %0|%0, %1}";
3924     default:
3925       gcc_unreachable ();
3926     }
3927 }
3928   [(set_attr "type" "fmov,multi,ssecvt")
3929    (set_attr "unit" "*,i387,*")
3930    (set_attr "mode" "SF")])
3931
3932 (define_insn "*truncdfsf_i387"
3933   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3934         (float_truncate:SF
3935           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3936    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3937   "TARGET_80387"
3938 {
3939   switch (which_alternative)
3940     {
3941     case 0:
3942       return output_387_reg_move (insn, operands);
3943
3944     case 1:
3945       return "#";
3946     default:
3947       gcc_unreachable ();
3948     }
3949 }
3950   [(set_attr "type" "fmov,multi")
3951    (set_attr "unit" "*,i387")
3952    (set_attr "mode" "SF")])
3953
3954 (define_insn "*truncdfsf2_i387_1"
3955   [(set (match_operand:SF 0 "memory_operand" "=m")
3956         (float_truncate:SF
3957           (match_operand:DF 1 "register_operand" "f")))]
3958   "TARGET_80387
3959    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3960    && !TARGET_MIX_SSE_I387"
3961   "* return output_387_reg_move (insn, operands);"
3962   [(set_attr "type" "fmov")
3963    (set_attr "mode" "SF")])
3964
3965 (define_split
3966   [(set (match_operand:SF 0 "register_operand" "")
3967         (float_truncate:SF
3968          (match_operand:DF 1 "fp_register_operand" "")))
3969    (clobber (match_operand 2 "" ""))]
3970   "reload_completed"
3971   [(set (match_dup 2) (match_dup 1))
3972    (set (match_dup 0) (match_dup 2))]
3973 {
3974   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3975 })
3976
3977 ;; Conversion from XFmode to {SF,DF}mode
3978
3979 (define_expand "truncxf<mode>2"
3980   [(parallel [(set (match_operand:X87MODEF12 0 "nonimmediate_operand" "")
3981                    (float_truncate:X87MODEF12
3982                      (match_operand:XF 1 "register_operand" "")))
3983               (clobber (match_dup 2))])]
3984   "TARGET_80387"
3985 {
3986   if (flag_unsafe_math_optimizations)
3987     {
3988       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
3989       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
3990       if (reg != operands[0])
3991         emit_move_insn (operands[0], reg);
3992       DONE;
3993     }
3994   else
3995     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
3996 })
3997
3998 (define_insn "*truncxfsf2_mixed"
3999   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4000         (float_truncate:SF
4001           (match_operand:XF 1 "register_operand" "f,f")))
4002    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4003   "TARGET_80387"
4004 {
4005   gcc_assert (!which_alternative);
4006   return output_387_reg_move (insn, operands);
4007 }
4008   [(set_attr "type" "fmov,multi")
4009    (set_attr "unit" "*,i387")
4010    (set_attr "mode" "SF")])
4011
4012 (define_insn "*truncxfdf2_mixed"
4013   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fYt*r")
4014         (float_truncate:DF
4015           (match_operand:XF 1 "register_operand" "f,f")))
4016    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4017   "TARGET_80387"
4018 {
4019   gcc_assert (!which_alternative);
4020   return output_387_reg_move (insn, operands);
4021 }
4022   [(set_attr "type" "fmov,multi")
4023    (set_attr "unit" "*,i387")
4024    (set_attr "mode" "DF")])
4025
4026 (define_insn "truncxf<mode>2_i387_noop"
4027   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
4028         (float_truncate:X87MODEF12
4029           (match_operand:XF 1 "register_operand" "f")))]
4030   "TARGET_80387 && flag_unsafe_math_optimizations"
4031   "* return output_387_reg_move (insn, operands);"
4032   [(set_attr "type" "fmov")
4033    (set_attr "mode" "<MODE>")])
4034
4035 (define_insn "*truncxf<mode>2_i387"
4036   [(set (match_operand:X87MODEF12 0 "memory_operand" "=m")
4037         (float_truncate:X87MODEF12
4038           (match_operand:XF 1 "register_operand" "f")))]
4039   "TARGET_80387"
4040   "* return output_387_reg_move (insn, operands);"
4041   [(set_attr "type" "fmov")
4042    (set_attr "mode" "<MODE>")])
4043
4044 (define_split
4045   [(set (match_operand:X87MODEF12 0 "register_operand" "")
4046         (float_truncate:X87MODEF12
4047           (match_operand:XF 1 "register_operand" "")))
4048    (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4049   "TARGET_80387 && reload_completed"
4050   [(set (match_dup 2) (float_truncate:X87MODEF12 (match_dup 1)))
4051    (set (match_dup 0) (match_dup 2))]
4052   "")
4053
4054 (define_split
4055   [(set (match_operand:X87MODEF12 0 "memory_operand" "")
4056         (float_truncate:X87MODEF12
4057           (match_operand:XF 1 "register_operand" "")))
4058    (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4059   "TARGET_80387"
4060   [(set (match_dup 0) (float_truncate:X87MODEF12 (match_dup 1)))]
4061   "")
4062 \f
4063 ;; Signed conversion to DImode.
4064
4065 (define_expand "fix_truncxfdi2"
4066   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4067                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4068               (clobber (reg:CC FLAGS_REG))])]
4069   "TARGET_80387"
4070 {
4071   if (TARGET_FISTTP)
4072    {
4073      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4074      DONE;
4075    }
4076 })
4077
4078 (define_expand "fix_trunc<mode>di2"
4079   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4080                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4081               (clobber (reg:CC FLAGS_REG))])]
4082   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4083 {
4084   if (TARGET_FISTTP
4085       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4086    {
4087      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4088      DONE;
4089    }
4090   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4091    {
4092      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4093      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4094      if (out != operands[0])
4095         emit_move_insn (operands[0], out);
4096      DONE;
4097    }
4098 })
4099
4100 ;; Signed conversion to SImode.
4101
4102 (define_expand "fix_truncxfsi2"
4103   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4104                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4105               (clobber (reg:CC FLAGS_REG))])]
4106   "TARGET_80387"
4107 {
4108   if (TARGET_FISTTP)
4109    {
4110      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4111      DONE;
4112    }
4113 })
4114
4115 (define_expand "fix_trunc<mode>si2"
4116   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4117                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4118               (clobber (reg:CC FLAGS_REG))])]
4119   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4120 {
4121   if (TARGET_FISTTP
4122       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4123    {
4124      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4125      DONE;
4126    }
4127   if (SSE_FLOAT_MODE_P (<MODE>mode))
4128    {
4129      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4130      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4131      if (out != operands[0])
4132         emit_move_insn (operands[0], out);
4133      DONE;
4134    }
4135 })
4136
4137 ;; Signed conversion to HImode.
4138
4139 (define_expand "fix_trunc<mode>hi2"
4140   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4141                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4142               (clobber (reg:CC FLAGS_REG))])]
4143   "TARGET_80387
4144    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4145 {
4146   if (TARGET_FISTTP)
4147    {
4148      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4149      DONE;
4150    }
4151 })
4152
4153 ;; Unsigned conversion to SImode.
4154
4155 (define_expand "fixuns_trunc<mode>si2"
4156   [(parallel
4157     [(set (match_operand:SI 0 "register_operand" "")
4158           (unsigned_fix:SI
4159             (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4160      (use (match_dup 2))
4161      (clobber (match_scratch:<ssevecmode> 3 ""))
4162      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4163   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4164 {
4165   enum machine_mode mode = <MODE>mode;
4166   enum machine_mode vecmode = <ssevecmode>mode;
4167   REAL_VALUE_TYPE TWO31r;
4168   rtx two31;
4169
4170   real_ldexp (&TWO31r, &dconst1, 31);
4171   two31 = const_double_from_real_value (TWO31r, mode);
4172   two31 = ix86_build_const_vector (mode, true, two31);
4173   operands[2] = force_reg (vecmode, two31);
4174 })
4175
4176 (define_insn_and_split "*fixuns_trunc<mode>_1"
4177   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4178         (unsigned_fix:SI
4179           (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4180    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4181    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4182    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4183   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4184   "#"
4185   "&& reload_completed"
4186   [(const_int 0)]
4187 {
4188   ix86_split_convert_uns_si_sse (operands);
4189   DONE;
4190 })
4191
4192 ;; Unsigned conversion to HImode.
4193 ;; Without these patterns, we'll try the unsigned SI conversion which
4194 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4195
4196 (define_expand "fixuns_trunc<mode>hi2"
4197   [(set (match_dup 2)
4198         (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4199    (set (match_operand:HI 0 "nonimmediate_operand" "")
4200         (subreg:HI (match_dup 2) 0))]
4201   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4202   "operands[2] = gen_reg_rtx (SImode);")
4203
4204 ;; When SSE is available, it is always faster to use it!
4205 (define_insn "fix_trunc<mode>di_sse"
4206   [(set (match_operand:DI 0 "register_operand" "=r,r")
4207         (fix:DI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4208   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4209    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4210   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4211   [(set_attr "type" "sseicvt")
4212    (set_attr "mode" "<MODE>")
4213    (set_attr "athlon_decode" "double,vector")
4214    (set_attr "amdfam10_decode" "double,double")])
4215
4216 (define_insn "fix_trunc<mode>si_sse"
4217   [(set (match_operand:SI 0 "register_operand" "=r,r")
4218         (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4219   "SSE_FLOAT_MODE_P (<MODE>mode)
4220    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4221   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4222   [(set_attr "type" "sseicvt")
4223    (set_attr "mode" "<MODE>")
4224    (set_attr "athlon_decode" "double,vector")
4225    (set_attr "amdfam10_decode" "double,double")])
4226
4227 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4228 (define_peephole2
4229   [(set (match_operand:SSEMODEF 0 "register_operand" "")
4230         (match_operand:SSEMODEF 1 "memory_operand" ""))
4231    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4232         (fix:SSEMODEI24 (match_dup 0)))]
4233   "TARGET_SHORTEN_X87_SSE
4234    && peep2_reg_dead_p (2, operands[0])"
4235   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4236   "")
4237
4238 ;; Avoid vector decoded forms of the instruction.
4239 (define_peephole2
4240   [(match_scratch:DF 2 "Yt")
4241    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4242         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4243   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4244   [(set (match_dup 2) (match_dup 1))
4245    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4246   "")
4247
4248 (define_peephole2
4249   [(match_scratch:SF 2 "x")
4250    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4251         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4252   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4253   [(set (match_dup 2) (match_dup 1))
4254    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4255   "")
4256
4257 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4258   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4259         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4260   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4261    && TARGET_FISTTP
4262    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4263          && (TARGET_64BIT || <MODE>mode != DImode))
4264         && TARGET_SSE_MATH)
4265    && !(reload_completed || reload_in_progress)"
4266   "#"
4267   "&& 1"
4268   [(const_int 0)]
4269 {
4270   if (memory_operand (operands[0], VOIDmode))
4271     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4272   else
4273     {
4274       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4275       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4276                                                             operands[1],
4277                                                             operands[2]));
4278     }
4279   DONE;
4280 }
4281   [(set_attr "type" "fisttp")
4282    (set_attr "mode" "<MODE>")])
4283
4284 (define_insn "fix_trunc<mode>_i387_fisttp"
4285   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4286         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4287    (clobber (match_scratch:XF 2 "=&1f"))]
4288   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4289    && TARGET_FISTTP
4290    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4291          && (TARGET_64BIT || <MODE>mode != DImode))
4292         && TARGET_SSE_MATH)"
4293   "* return output_fix_trunc (insn, operands, 1);"
4294   [(set_attr "type" "fisttp")
4295    (set_attr "mode" "<MODE>")])
4296
4297 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4298   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4299         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4300    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4301    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4302   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4303    && TARGET_FISTTP
4304    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4305         && (TARGET_64BIT || <MODE>mode != DImode))
4306         && TARGET_SSE_MATH)"
4307   "#"
4308   [(set_attr "type" "fisttp")
4309    (set_attr "mode" "<MODE>")])
4310
4311 (define_split
4312   [(set (match_operand:X87MODEI 0 "register_operand" "")
4313         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4314    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4315    (clobber (match_scratch 3 ""))]
4316   "reload_completed"
4317   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4318               (clobber (match_dup 3))])
4319    (set (match_dup 0) (match_dup 2))]
4320   "")
4321
4322 (define_split
4323   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4324         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4325    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4326    (clobber (match_scratch 3 ""))]
4327   "reload_completed"
4328   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4329               (clobber (match_dup 3))])]
4330   "")
4331
4332 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4333 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4334 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4335 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4336 ;; function in i386.c.
4337 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4338   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4339         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4340    (clobber (reg:CC FLAGS_REG))]
4341   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4342    && !TARGET_FISTTP
4343    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4344          && (TARGET_64BIT || <MODE>mode != DImode))
4345    && !(reload_completed || reload_in_progress)"
4346   "#"
4347   "&& 1"
4348   [(const_int 0)]
4349 {
4350   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4351
4352   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4353   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4354   if (memory_operand (operands[0], VOIDmode))
4355     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4356                                          operands[2], operands[3]));
4357   else
4358     {
4359       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4360       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4361                                                      operands[2], operands[3],
4362                                                      operands[4]));
4363     }
4364   DONE;
4365 }
4366   [(set_attr "type" "fistp")
4367    (set_attr "i387_cw" "trunc")
4368    (set_attr "mode" "<MODE>")])
4369
4370 (define_insn "fix_truncdi_i387"
4371   [(set (match_operand:DI 0 "memory_operand" "=m")
4372         (fix:DI (match_operand 1 "register_operand" "f")))
4373    (use (match_operand:HI 2 "memory_operand" "m"))
4374    (use (match_operand:HI 3 "memory_operand" "m"))
4375    (clobber (match_scratch:XF 4 "=&1f"))]
4376   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4377    && !TARGET_FISTTP
4378    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4379   "* return output_fix_trunc (insn, operands, 0);"
4380   [(set_attr "type" "fistp")
4381    (set_attr "i387_cw" "trunc")
4382    (set_attr "mode" "DI")])
4383
4384 (define_insn "fix_truncdi_i387_with_temp"
4385   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4386         (fix:DI (match_operand 1 "register_operand" "f,f")))
4387    (use (match_operand:HI 2 "memory_operand" "m,m"))
4388    (use (match_operand:HI 3 "memory_operand" "m,m"))
4389    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4390    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4391   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4392    && !TARGET_FISTTP
4393    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4394   "#"
4395   [(set_attr "type" "fistp")
4396    (set_attr "i387_cw" "trunc")
4397    (set_attr "mode" "DI")])
4398
4399 (define_split
4400   [(set (match_operand:DI 0 "register_operand" "")
4401         (fix:DI (match_operand 1 "register_operand" "")))
4402    (use (match_operand:HI 2 "memory_operand" ""))
4403    (use (match_operand:HI 3 "memory_operand" ""))
4404    (clobber (match_operand:DI 4 "memory_operand" ""))
4405    (clobber (match_scratch 5 ""))]
4406   "reload_completed"
4407   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4408               (use (match_dup 2))
4409               (use (match_dup 3))
4410               (clobber (match_dup 5))])
4411    (set (match_dup 0) (match_dup 4))]
4412   "")
4413
4414 (define_split
4415   [(set (match_operand:DI 0 "memory_operand" "")
4416         (fix:DI (match_operand 1 "register_operand" "")))
4417    (use (match_operand:HI 2 "memory_operand" ""))
4418    (use (match_operand:HI 3 "memory_operand" ""))
4419    (clobber (match_operand:DI 4 "memory_operand" ""))
4420    (clobber (match_scratch 5 ""))]
4421   "reload_completed"
4422   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4423               (use (match_dup 2))
4424               (use (match_dup 3))
4425               (clobber (match_dup 5))])]
4426   "")
4427
4428 (define_insn "fix_trunc<mode>_i387"
4429   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4430         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4431    (use (match_operand:HI 2 "memory_operand" "m"))
4432    (use (match_operand:HI 3 "memory_operand" "m"))]
4433   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4434    && !TARGET_FISTTP
4435    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4436   "* return output_fix_trunc (insn, operands, 0);"
4437   [(set_attr "type" "fistp")
4438    (set_attr "i387_cw" "trunc")
4439    (set_attr "mode" "<MODE>")])
4440
4441 (define_insn "fix_trunc<mode>_i387_with_temp"
4442   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4443         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4444    (use (match_operand:HI 2 "memory_operand" "m,m"))
4445    (use (match_operand:HI 3 "memory_operand" "m,m"))
4446    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4447   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4448    && !TARGET_FISTTP
4449    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4450   "#"
4451   [(set_attr "type" "fistp")
4452    (set_attr "i387_cw" "trunc")
4453    (set_attr "mode" "<MODE>")])
4454
4455 (define_split
4456   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4457         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4458    (use (match_operand:HI 2 "memory_operand" ""))
4459    (use (match_operand:HI 3 "memory_operand" ""))
4460    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4461   "reload_completed"
4462   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4463               (use (match_dup 2))
4464               (use (match_dup 3))])
4465    (set (match_dup 0) (match_dup 4))]
4466   "")
4467
4468 (define_split
4469   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4470         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4471    (use (match_operand:HI 2 "memory_operand" ""))
4472    (use (match_operand:HI 3 "memory_operand" ""))
4473    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4474   "reload_completed"
4475   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4476               (use (match_dup 2))
4477               (use (match_dup 3))])]
4478   "")
4479
4480 (define_insn "x86_fnstcw_1"
4481   [(set (match_operand:HI 0 "memory_operand" "=m")
4482         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4483   "TARGET_80387"
4484   "fnstcw\t%0"
4485   [(set_attr "length" "2")
4486    (set_attr "mode" "HI")
4487    (set_attr "unit" "i387")])
4488
4489 (define_insn "x86_fldcw_1"
4490   [(set (reg:HI FPCR_REG)
4491         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4492   "TARGET_80387"
4493   "fldcw\t%0"
4494   [(set_attr "length" "2")
4495    (set_attr "mode" "HI")
4496    (set_attr "unit" "i387")
4497    (set_attr "athlon_decode" "vector")
4498    (set_attr "amdfam10_decode" "vector")])   
4499 \f
4500 ;; Conversion between fixed point and floating point.
4501
4502 ;; Even though we only accept memory inputs, the backend _really_
4503 ;; wants to be able to do this between registers.
4504
4505 (define_expand "floathi<mode>2"
4506   [(set (match_operand:SSEMODEF 0 "register_operand" "")
4507         (float:SSEMODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4508   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4509 {
4510   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4511     {
4512       emit_insn
4513         (gen_floatsi<mode>2 (operands[0],
4514                              convert_to_mode (SImode, operands[1], 0)));
4515       DONE;
4516     }
4517 })
4518
4519 (define_insn "*floathi<mode>2_i387"
4520   [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4521         (float:X87MODEF12
4522           (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4523   "TARGET_80387
4524    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4525        || TARGET_MIX_SSE_I387)"
4526   "@
4527    fild%z1\t%1
4528    #"
4529   [(set_attr "type" "fmov,multi")
4530    (set_attr "mode" "<MODE>")
4531    (set_attr "unit" "*,i387")
4532    (set_attr "fp_int_src" "true")])
4533
4534 (define_expand "floatsi<mode>2"
4535   [(set (match_operand:SSEMODEF 0 "register_operand" "")
4536         (float:SSEMODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4537   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4538   "")
4539
4540 (define_insn "*floatsisf2_mixed"
4541   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4542         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4543   "TARGET_MIX_SSE_I387"
4544   "@
4545    fild%z1\t%1
4546    #
4547    cvtsi2ss\t{%1, %0|%0, %1}
4548    cvtsi2ss\t{%1, %0|%0, %1}"
4549   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4550    (set_attr "mode" "SF")
4551    (set_attr "unit" "*,i387,*,*")
4552    (set_attr "athlon_decode" "*,*,vector,double")
4553    (set_attr "amdfam10_decode" "*,*,vector,double")
4554    (set_attr "fp_int_src" "true")])
4555
4556 (define_insn "*floatsisf2_sse"
4557   [(set (match_operand:SF 0 "register_operand" "=x,x")
4558         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4559   "TARGET_SSE_MATH"
4560   "cvtsi2ss\t{%1, %0|%0, %1}"
4561   [(set_attr "type" "sseicvt")
4562    (set_attr "mode" "SF")
4563    (set_attr "athlon_decode" "vector,double")
4564    (set_attr "amdfam10_decode" "vector,double")
4565    (set_attr "fp_int_src" "true")])
4566
4567 (define_insn "*floatsidf2_mixed"
4568   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4569         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4570   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4571   "@
4572    fild%z1\t%1
4573    #
4574    cvtsi2sd\t{%1, %0|%0, %1}
4575    cvtsi2sd\t{%1, %0|%0, %1}"
4576   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4577    (set_attr "mode" "DF")
4578    (set_attr "unit" "*,i387,*,*")
4579    (set_attr "athlon_decode" "*,*,double,direct")
4580    (set_attr "amdfam10_decode" "*,*,vector,double")
4581    (set_attr "fp_int_src" "true")])
4582
4583 (define_insn "*floatsidf2_sse"
4584   [(set (match_operand:DF 0 "register_operand" "=x,x")
4585         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4586   "TARGET_SSE2 && TARGET_SSE_MATH"
4587   "cvtsi2sd\t{%1, %0|%0, %1}"
4588   [(set_attr "type" "sseicvt")
4589    (set_attr "mode" "DF")
4590    (set_attr "athlon_decode" "double,direct")
4591    (set_attr "amdfam10_decode" "vector,double")
4592    (set_attr "fp_int_src" "true")])
4593
4594 (define_insn "*floatsi<mode>2_i387"
4595   [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4596         (float:X87MODEF12
4597           (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4598   "TARGET_80387"
4599   "@
4600    fild%z1\t%1
4601    #"
4602   [(set_attr "type" "fmov,multi")
4603    (set_attr "mode" "<MODE>")
4604    (set_attr "unit" "*,i387")
4605    (set_attr "fp_int_src" "true")])
4606
4607 (define_expand "floatdisf2"
4608   [(set (match_operand:SF 0 "register_operand" "")
4609         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4610   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4611   "")
4612
4613 (define_insn "*floatdisf2_mixed"
4614   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4615         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4616   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4617   "@
4618    fild%z1\t%1
4619    #
4620    cvtsi2ss{q}\t{%1, %0|%0, %1}
4621    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4622   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4623    (set_attr "mode" "SF")
4624    (set_attr "unit" "*,i387,*,*")
4625    (set_attr "athlon_decode" "*,*,vector,double")
4626    (set_attr "amdfam10_decode" "*,*,vector,double")
4627    (set_attr "fp_int_src" "true")])
4628
4629 (define_insn "*floatdisf2_sse"
4630   [(set (match_operand:SF 0 "register_operand" "=x,x")
4631         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4632   "TARGET_64BIT && TARGET_SSE_MATH"
4633   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4634   [(set_attr "type" "sseicvt")
4635    (set_attr "mode" "SF")
4636    (set_attr "athlon_decode" "vector,double")
4637    (set_attr "amdfam10_decode" "vector,double")
4638    (set_attr "fp_int_src" "true")])
4639
4640 (define_expand "floatdidf2"
4641   [(set (match_operand:DF 0 "register_operand" "")
4642         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4643   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4644 {
4645   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4646     {
4647       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4648       DONE;
4649     }
4650 })
4651
4652 (define_insn "*floatdidf2_mixed"
4653   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4654         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4655   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4656   "@
4657    fild%z1\t%1
4658    #
4659    cvtsi2sd{q}\t{%1, %0|%0, %1}
4660    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4661   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4662    (set_attr "mode" "DF")
4663    (set_attr "unit" "*,i387,*,*")
4664    (set_attr "athlon_decode" "*,*,double,direct")
4665    (set_attr "amdfam10_decode" "*,*,vector,double")
4666    (set_attr "fp_int_src" "true")])
4667
4668 (define_insn "*floatdidf2_sse"
4669   [(set (match_operand:DF 0 "register_operand" "=x,x")
4670         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4671   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4672   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4673   [(set_attr "type" "sseicvt")
4674    (set_attr "mode" "DF")
4675    (set_attr "athlon_decode" "double,direct")
4676    (set_attr "amdfam10_decode" "vector,double")
4677    (set_attr "fp_int_src" "true")])
4678
4679 (define_insn "*floatdi<mode>2_i387"
4680   [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4681         (float:X87MODEF12
4682           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4683   "TARGET_80387"
4684   "@
4685    fild%z1\t%1
4686    #"
4687   [(set_attr "type" "fmov,multi")
4688    (set_attr "mode" "<MODE>")
4689    (set_attr "unit" "*,i387")
4690    (set_attr "fp_int_src" "true")])
4691
4692 (define_insn "float<mode>xf2"
4693   [(set (match_operand:XF 0 "register_operand" "=f,f")
4694         (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
4695   "TARGET_80387"
4696   "@
4697    fild%z1\t%1
4698    #"
4699   [(set_attr "type" "fmov,multi")
4700    (set_attr "mode" "XF")
4701    (set_attr "unit" "*,i387")
4702    (set_attr "fp_int_src" "true")])
4703
4704 ;; %%% Kill these when reload knows how to do it.
4705 (define_split
4706   [(set (match_operand 0 "fp_register_operand" "")
4707         (float (match_operand 1 "register_operand" "")))]
4708   "reload_completed
4709    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
4710   [(const_int 0)]
4711 {
4712   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4713   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4714   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4715   ix86_free_from_memory (GET_MODE (operands[1]));
4716   DONE;
4717 })
4718
4719 (define_expand "floatunssisf2"
4720   [(use (match_operand:SF 0 "register_operand" ""))
4721    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4722   "!TARGET_64BIT"
4723 {
4724   if (TARGET_SSE_MATH && TARGET_SSE2)
4725     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
4726   else
4727     x86_emit_floatuns (operands);
4728   DONE;
4729 })
4730
4731 (define_expand "floatunssidf2"
4732   [(use (match_operand:DF 0 "register_operand" ""))
4733    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4734   "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
4735   "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
4736
4737 (define_expand "floatunsdisf2"
4738   [(use (match_operand:SF 0 "register_operand" ""))
4739    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4740   "TARGET_64BIT && TARGET_SSE_MATH"
4741   "x86_emit_floatuns (operands); DONE;")
4742
4743 (define_expand "floatunsdidf2"
4744   [(use (match_operand:DF 0 "register_operand" ""))
4745    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4746   "TARGET_SSE_MATH && TARGET_SSE2
4747    && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
4748 {
4749   if (TARGET_64BIT)
4750     x86_emit_floatuns (operands);
4751   else
4752     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
4753   DONE;
4754 })
4755 \f
4756 ;; Add instructions
4757
4758 ;; %%% splits for addditi3
4759
4760 (define_expand "addti3"
4761   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4762         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4763                  (match_operand:TI 2 "x86_64_general_operand" "")))
4764    (clobber (reg:CC FLAGS_REG))]
4765   "TARGET_64BIT"
4766   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4767
4768 (define_insn "*addti3_1"
4769   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4770         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4771                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4772    (clobber (reg:CC FLAGS_REG))]
4773   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4774   "#")
4775
4776 (define_split
4777   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4778         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4779                  (match_operand:TI 2 "x86_64_general_operand" "")))
4780    (clobber (reg:CC FLAGS_REG))]
4781   "TARGET_64BIT && reload_completed"
4782   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4783                                           UNSPEC_ADD_CARRY))
4784               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4785    (parallel [(set (match_dup 3)
4786                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4787                                      (match_dup 4))
4788                             (match_dup 5)))
4789               (clobber (reg:CC FLAGS_REG))])]
4790   "split_ti (operands+0, 1, operands+0, operands+3);
4791    split_ti (operands+1, 1, operands+1, operands+4);
4792    split_ti (operands+2, 1, operands+2, operands+5);")
4793
4794 ;; %%% splits for addsidi3
4795 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4796 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4797 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4798
4799 (define_expand "adddi3"
4800   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4801         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4802                  (match_operand:DI 2 "x86_64_general_operand" "")))
4803    (clobber (reg:CC FLAGS_REG))]
4804   ""
4805   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4806
4807 (define_insn "*adddi3_1"
4808   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4809         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4810                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4811    (clobber (reg:CC FLAGS_REG))]
4812   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4813   "#")
4814
4815 (define_split
4816   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4817         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4818                  (match_operand:DI 2 "general_operand" "")))
4819    (clobber (reg:CC FLAGS_REG))]
4820   "!TARGET_64BIT && reload_completed"
4821   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4822                                           UNSPEC_ADD_CARRY))
4823               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4824    (parallel [(set (match_dup 3)
4825                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4826                                      (match_dup 4))
4827                             (match_dup 5)))
4828               (clobber (reg:CC FLAGS_REG))])]
4829   "split_di (operands+0, 1, operands+0, operands+3);
4830    split_di (operands+1, 1, operands+1, operands+4);
4831    split_di (operands+2, 1, operands+2, operands+5);")
4832
4833 (define_insn "adddi3_carry_rex64"
4834   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4835           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4836                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4837                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4838    (clobber (reg:CC FLAGS_REG))]
4839   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4840   "adc{q}\t{%2, %0|%0, %2}"
4841   [(set_attr "type" "alu")
4842    (set_attr "pent_pair" "pu")
4843    (set_attr "mode" "DI")])
4844
4845 (define_insn "*adddi3_cc_rex64"
4846   [(set (reg:CC FLAGS_REG)
4847         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4848                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4849                    UNSPEC_ADD_CARRY))
4850    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4851         (plus:DI (match_dup 1) (match_dup 2)))]
4852   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4853   "add{q}\t{%2, %0|%0, %2}"
4854   [(set_attr "type" "alu")
4855    (set_attr "mode" "DI")])
4856
4857 (define_insn "addqi3_carry"
4858   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4859           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4860                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4861                    (match_operand:QI 2 "general_operand" "qi,qm")))
4862    (clobber (reg:CC FLAGS_REG))]
4863   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4864   "adc{b}\t{%2, %0|%0, %2}"
4865   [(set_attr "type" "alu")
4866    (set_attr "pent_pair" "pu")
4867    (set_attr "mode" "QI")])
4868
4869 (define_insn "addhi3_carry"
4870   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4871           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4872                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4873                    (match_operand:HI 2 "general_operand" "ri,rm")))
4874    (clobber (reg:CC FLAGS_REG))]
4875   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4876   "adc{w}\t{%2, %0|%0, %2}"
4877   [(set_attr "type" "alu")
4878    (set_attr "pent_pair" "pu")
4879    (set_attr "mode" "HI")])
4880
4881 (define_insn "addsi3_carry"
4882   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4883           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4884                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4885                    (match_operand:SI 2 "general_operand" "ri,rm")))
4886    (clobber (reg:CC FLAGS_REG))]
4887   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4888   "adc{l}\t{%2, %0|%0, %2}"
4889   [(set_attr "type" "alu")
4890    (set_attr "pent_pair" "pu")
4891    (set_attr "mode" "SI")])
4892
4893 (define_insn "*addsi3_carry_zext"
4894   [(set (match_operand:DI 0 "register_operand" "=r")
4895           (zero_extend:DI
4896             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4897                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4898                      (match_operand:SI 2 "general_operand" "rim"))))
4899    (clobber (reg:CC FLAGS_REG))]
4900   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4901   "adc{l}\t{%2, %k0|%k0, %2}"
4902   [(set_attr "type" "alu")
4903    (set_attr "pent_pair" "pu")
4904    (set_attr "mode" "SI")])
4905
4906 (define_insn "*addsi3_cc"
4907   [(set (reg:CC FLAGS_REG)
4908         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4909                     (match_operand:SI 2 "general_operand" "ri,rm")]
4910                    UNSPEC_ADD_CARRY))
4911    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4912         (plus:SI (match_dup 1) (match_dup 2)))]
4913   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4914   "add{l}\t{%2, %0|%0, %2}"
4915   [(set_attr "type" "alu")
4916    (set_attr "mode" "SI")])
4917
4918 (define_insn "addqi3_cc"
4919   [(set (reg:CC FLAGS_REG)
4920         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4921                     (match_operand:QI 2 "general_operand" "qi,qm")]
4922                    UNSPEC_ADD_CARRY))
4923    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4924         (plus:QI (match_dup 1) (match_dup 2)))]
4925   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4926   "add{b}\t{%2, %0|%0, %2}"
4927   [(set_attr "type" "alu")
4928    (set_attr "mode" "QI")])
4929
4930 (define_expand "addsi3"
4931   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4932                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4933                             (match_operand:SI 2 "general_operand" "")))
4934               (clobber (reg:CC FLAGS_REG))])]
4935   ""
4936   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4937
4938 (define_insn "*lea_1"
4939   [(set (match_operand:SI 0 "register_operand" "=r")
4940         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4941   "!TARGET_64BIT"
4942   "lea{l}\t{%a1, %0|%0, %a1}"
4943   [(set_attr "type" "lea")
4944    (set_attr "mode" "SI")])
4945
4946 (define_insn "*lea_1_rex64"
4947   [(set (match_operand:SI 0 "register_operand" "=r")
4948         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4949   "TARGET_64BIT"
4950   "lea{l}\t{%a1, %0|%0, %a1}"
4951   [(set_attr "type" "lea")
4952    (set_attr "mode" "SI")])
4953
4954 (define_insn "*lea_1_zext"
4955   [(set (match_operand:DI 0 "register_operand" "=r")
4956         (zero_extend:DI
4957          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4958   "TARGET_64BIT"
4959   "lea{l}\t{%a1, %k0|%k0, %a1}"
4960   [(set_attr "type" "lea")
4961    (set_attr "mode" "SI")])
4962
4963 (define_insn "*lea_2_rex64"
4964   [(set (match_operand:DI 0 "register_operand" "=r")
4965         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4966   "TARGET_64BIT"
4967   "lea{q}\t{%a1, %0|%0, %a1}"
4968   [(set_attr "type" "lea")
4969    (set_attr "mode" "DI")])
4970
4971 ;; The lea patterns for non-Pmodes needs to be matched by several
4972 ;; insns converted to real lea by splitters.
4973
4974 (define_insn_and_split "*lea_general_1"
4975   [(set (match_operand 0 "register_operand" "=r")
4976         (plus (plus (match_operand 1 "index_register_operand" "l")
4977                     (match_operand 2 "register_operand" "r"))
4978               (match_operand 3 "immediate_operand" "i")))]
4979   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4980     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4981    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4982    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4983    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4984    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4985        || GET_MODE (operands[3]) == VOIDmode)"
4986   "#"
4987   "&& reload_completed"
4988   [(const_int 0)]
4989 {
4990   rtx pat;
4991   operands[0] = gen_lowpart (SImode, operands[0]);
4992   operands[1] = gen_lowpart (Pmode, operands[1]);
4993   operands[2] = gen_lowpart (Pmode, operands[2]);
4994   operands[3] = gen_lowpart (Pmode, operands[3]);
4995   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4996                       operands[3]);
4997   if (Pmode != SImode)
4998     pat = gen_rtx_SUBREG (SImode, pat, 0);
4999   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5000   DONE;
5001 }
5002   [(set_attr "type" "lea")
5003    (set_attr "mode" "SI")])
5004
5005 (define_insn_and_split "*lea_general_1_zext"
5006   [(set (match_operand:DI 0 "register_operand" "=r")
5007         (zero_extend:DI
5008           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5009                             (match_operand:SI 2 "register_operand" "r"))
5010                    (match_operand:SI 3 "immediate_operand" "i"))))]
5011   "TARGET_64BIT"
5012   "#"
5013   "&& reload_completed"
5014   [(set (match_dup 0)
5015         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5016                                                      (match_dup 2))
5017                                             (match_dup 3)) 0)))]
5018 {
5019   operands[1] = gen_lowpart (Pmode, operands[1]);
5020   operands[2] = gen_lowpart (Pmode, operands[2]);
5021   operands[3] = gen_lowpart (Pmode, operands[3]);
5022 }
5023   [(set_attr "type" "lea")
5024    (set_attr "mode" "SI")])
5025
5026 (define_insn_and_split "*lea_general_2"
5027   [(set (match_operand 0 "register_operand" "=r")
5028         (plus (mult (match_operand 1 "index_register_operand" "l")
5029                     (match_operand 2 "const248_operand" "i"))
5030               (match_operand 3 "nonmemory_operand" "ri")))]
5031   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5032     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5033    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5034    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5035    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5036        || GET_MODE (operands[3]) == VOIDmode)"
5037   "#"
5038   "&& reload_completed"
5039   [(const_int 0)]
5040 {
5041   rtx pat;
5042   operands[0] = gen_lowpart (SImode, operands[0]);
5043   operands[1] = gen_lowpart (Pmode, operands[1]);
5044   operands[3] = gen_lowpart (Pmode, operands[3]);
5045   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5046                       operands[3]);
5047   if (Pmode != SImode)
5048     pat = gen_rtx_SUBREG (SImode, pat, 0);
5049   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5050   DONE;
5051 }
5052   [(set_attr "type" "lea")
5053    (set_attr "mode" "SI")])
5054
5055 (define_insn_and_split "*lea_general_2_zext"
5056   [(set (match_operand:DI 0 "register_operand" "=r")
5057         (zero_extend:DI
5058           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5059                             (match_operand:SI 2 "const248_operand" "n"))
5060                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5061   "TARGET_64BIT"
5062   "#"
5063   "&& reload_completed"
5064   [(set (match_dup 0)
5065         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5066                                                      (match_dup 2))
5067                                             (match_dup 3)) 0)))]
5068 {
5069   operands[1] = gen_lowpart (Pmode, operands[1]);
5070   operands[3] = gen_lowpart (Pmode, operands[3]);
5071 }
5072   [(set_attr "type" "lea")
5073    (set_attr "mode" "SI")])
5074
5075 (define_insn_and_split "*lea_general_3"
5076   [(set (match_operand 0 "register_operand" "=r")
5077         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5078                           (match_operand 2 "const248_operand" "i"))
5079                     (match_operand 3 "register_operand" "r"))
5080               (match_operand 4 "immediate_operand" "i")))]
5081   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5082     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5083    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5084    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5085    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5086   "#"
5087   "&& reload_completed"
5088   [(const_int 0)]
5089 {
5090   rtx pat;
5091   operands[0] = gen_lowpart (SImode, operands[0]);
5092   operands[1] = gen_lowpart (Pmode, operands[1]);
5093   operands[3] = gen_lowpart (Pmode, operands[3]);
5094   operands[4] = gen_lowpart (Pmode, operands[4]);
5095   pat = gen_rtx_PLUS (Pmode,
5096                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5097                                                          operands[2]),
5098                                     operands[3]),
5099                       operands[4]);
5100   if (Pmode != SImode)
5101     pat = gen_rtx_SUBREG (SImode, pat, 0);
5102   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5103   DONE;
5104 }
5105   [(set_attr "type" "lea")
5106    (set_attr "mode" "SI")])
5107
5108 (define_insn_and_split "*lea_general_3_zext"
5109   [(set (match_operand:DI 0 "register_operand" "=r")
5110         (zero_extend:DI
5111           (plus:SI (plus:SI (mult:SI
5112                               (match_operand:SI 1 "index_register_operand" "l")
5113                               (match_operand:SI 2 "const248_operand" "n"))
5114                             (match_operand:SI 3 "register_operand" "r"))
5115                    (match_operand:SI 4 "immediate_operand" "i"))))]
5116   "TARGET_64BIT"
5117   "#"
5118   "&& reload_completed"
5119   [(set (match_dup 0)
5120         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5121                                                               (match_dup 2))
5122                                                      (match_dup 3))
5123                                             (match_dup 4)) 0)))]
5124 {
5125   operands[1] = gen_lowpart (Pmode, operands[1]);
5126   operands[3] = gen_lowpart (Pmode, operands[3]);
5127   operands[4] = gen_lowpart (Pmode, operands[4]);
5128 }
5129   [(set_attr "type" "lea")
5130    (set_attr "mode" "SI")])
5131
5132 (define_insn "*adddi_1_rex64"
5133   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5134         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5135                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5136    (clobber (reg:CC FLAGS_REG))]
5137   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5138 {
5139   switch (get_attr_type (insn))
5140     {
5141     case TYPE_LEA:
5142       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5143       return "lea{q}\t{%a2, %0|%0, %a2}";
5144
5145     case TYPE_INCDEC:
5146       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5147       if (operands[2] == const1_rtx)
5148         return "inc{q}\t%0";
5149       else
5150         {
5151           gcc_assert (operands[2] == constm1_rtx);
5152           return "dec{q}\t%0";
5153         }
5154
5155     default:
5156       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5157
5158       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5159          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5160       if (CONST_INT_P (operands[2])
5161           /* Avoid overflows.  */
5162           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5163           && (INTVAL (operands[2]) == 128
5164               || (INTVAL (operands[2]) < 0
5165                   && INTVAL (operands[2]) != -128)))
5166         {
5167           operands[2] = GEN_INT (-INTVAL (operands[2]));
5168           return "sub{q}\t{%2, %0|%0, %2}";
5169         }
5170       return "add{q}\t{%2, %0|%0, %2}";
5171     }
5172 }
5173   [(set (attr "type")
5174      (cond [(eq_attr "alternative" "2")
5175               (const_string "lea")
5176             ; Current assemblers are broken and do not allow @GOTOFF in
5177             ; ought but a memory context.
5178             (match_operand:DI 2 "pic_symbolic_operand" "")
5179               (const_string "lea")
5180             (match_operand:DI 2 "incdec_operand" "")
5181               (const_string "incdec")
5182            ]
5183            (const_string "alu")))
5184    (set_attr "mode" "DI")])
5185
5186 ;; Convert lea to the lea pattern to avoid flags dependency.
5187 (define_split
5188   [(set (match_operand:DI 0 "register_operand" "")
5189         (plus:DI (match_operand:DI 1 "register_operand" "")
5190                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5191    (clobber (reg:CC FLAGS_REG))]
5192   "TARGET_64BIT && reload_completed
5193    && true_regnum (operands[0]) != true_regnum (operands[1])"
5194   [(set (match_dup 0)
5195         (plus:DI (match_dup 1)
5196                  (match_dup 2)))]
5197   "")
5198
5199 (define_insn "*adddi_2_rex64"
5200   [(set (reg FLAGS_REG)
5201         (compare
5202           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5203                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5204           (const_int 0)))
5205    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5206         (plus:DI (match_dup 1) (match_dup 2)))]
5207   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5208    && ix86_binary_operator_ok (PLUS, DImode, operands)
5209    /* Current assemblers are broken and do not allow @GOTOFF in
5210       ought but a memory context.  */
5211    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5212 {
5213   switch (get_attr_type (insn))
5214     {
5215     case TYPE_INCDEC:
5216       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5217       if (operands[2] == const1_rtx)
5218         return "inc{q}\t%0";
5219       else
5220         {
5221           gcc_assert (operands[2] == constm1_rtx);
5222           return "dec{q}\t%0";
5223         }
5224
5225     default:
5226       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5227       /* ???? We ought to handle there the 32bit case too
5228          - do we need new constraint?  */
5229       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5230          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5231       if (CONST_INT_P (operands[2])
5232           /* Avoid overflows.  */
5233           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5234           && (INTVAL (operands[2]) == 128
5235               || (INTVAL (operands[2]) < 0
5236                   && INTVAL (operands[2]) != -128)))
5237         {
5238           operands[2] = GEN_INT (-INTVAL (operands[2]));
5239           return "sub{q}\t{%2, %0|%0, %2}";
5240         }
5241       return "add{q}\t{%2, %0|%0, %2}";
5242     }
5243 }
5244   [(set (attr "type")
5245      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5246         (const_string "incdec")
5247         (const_string "alu")))
5248    (set_attr "mode" "DI")])
5249
5250 (define_insn "*adddi_3_rex64"
5251   [(set (reg FLAGS_REG)
5252         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5253                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5254    (clobber (match_scratch:DI 0 "=r"))]
5255   "TARGET_64BIT
5256    && ix86_match_ccmode (insn, CCZmode)
5257    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5258    /* Current assemblers are broken and do not allow @GOTOFF in
5259       ought but a memory context.  */
5260    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5261 {
5262   switch (get_attr_type (insn))
5263     {
5264     case TYPE_INCDEC:
5265       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5266       if (operands[2] == const1_rtx)
5267         return "inc{q}\t%0";
5268       else
5269         {
5270           gcc_assert (operands[2] == constm1_rtx);
5271           return "dec{q}\t%0";
5272         }
5273
5274     default:
5275       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5276       /* ???? We ought to handle there the 32bit case too
5277          - do we need new constraint?  */
5278       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5279          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5280       if (CONST_INT_P (operands[2])
5281           /* Avoid overflows.  */
5282           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5283           && (INTVAL (operands[2]) == 128
5284               || (INTVAL (operands[2]) < 0
5285                   && INTVAL (operands[2]) != -128)))
5286         {
5287           operands[2] = GEN_INT (-INTVAL (operands[2]));
5288           return "sub{q}\t{%2, %0|%0, %2}";
5289         }
5290       return "add{q}\t{%2, %0|%0, %2}";
5291     }
5292 }
5293   [(set (attr "type")
5294      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5295         (const_string "incdec")
5296         (const_string "alu")))
5297    (set_attr "mode" "DI")])
5298
5299 ; For comparisons against 1, -1 and 128, we may generate better code
5300 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5301 ; is matched then.  We can't accept general immediate, because for
5302 ; case of overflows,  the result is messed up.
5303 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5304 ; when negated.
5305 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5306 ; only for comparisons not depending on it.
5307 (define_insn "*adddi_4_rex64"
5308   [(set (reg FLAGS_REG)
5309         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5310                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5311    (clobber (match_scratch:DI 0 "=rm"))]
5312   "TARGET_64BIT
5313    &&  ix86_match_ccmode (insn, CCGCmode)"
5314 {
5315   switch (get_attr_type (insn))
5316     {
5317     case TYPE_INCDEC:
5318       if (operands[2] == constm1_rtx)
5319         return "inc{q}\t%0";
5320       else
5321         {
5322           gcc_assert (operands[2] == const1_rtx);
5323           return "dec{q}\t%0";
5324         }
5325
5326     default:
5327       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5328       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5329          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5330       if ((INTVAL (operands[2]) == -128
5331            || (INTVAL (operands[2]) > 0
5332                && INTVAL (operands[2]) != 128))
5333           /* Avoid overflows.  */
5334           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5335         return "sub{q}\t{%2, %0|%0, %2}";
5336       operands[2] = GEN_INT (-INTVAL (operands[2]));
5337       return "add{q}\t{%2, %0|%0, %2}";
5338     }
5339 }
5340   [(set (attr "type")
5341      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5342         (const_string "incdec")
5343         (const_string "alu")))
5344    (set_attr "mode" "DI")])
5345
5346 (define_insn "*adddi_5_rex64"
5347   [(set (reg FLAGS_REG)
5348         (compare
5349           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5350                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5351           (const_int 0)))
5352    (clobber (match_scratch:DI 0 "=r"))]
5353   "TARGET_64BIT
5354    && ix86_match_ccmode (insn, CCGOCmode)
5355    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5356    /* Current assemblers are broken and do not allow @GOTOFF in
5357       ought but a memory context.  */
5358    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5359 {
5360   switch (get_attr_type (insn))
5361     {
5362     case TYPE_INCDEC:
5363       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5364       if (operands[2] == const1_rtx)
5365         return "inc{q}\t%0";
5366       else
5367         {
5368           gcc_assert (operands[2] == constm1_rtx);
5369           return "dec{q}\t%0";
5370         }
5371
5372     default:
5373       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5374       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5375          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5376       if (CONST_INT_P (operands[2])
5377           /* Avoid overflows.  */
5378           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5379           && (INTVAL (operands[2]) == 128
5380               || (INTVAL (operands[2]) < 0
5381                   && INTVAL (operands[2]) != -128)))
5382         {
5383           operands[2] = GEN_INT (-INTVAL (operands[2]));
5384           return "sub{q}\t{%2, %0|%0, %2}";
5385         }
5386       return "add{q}\t{%2, %0|%0, %2}";
5387     }
5388 }
5389   [(set (attr "type")
5390      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5391         (const_string "incdec")
5392         (const_string "alu")))
5393    (set_attr "mode" "DI")])
5394
5395
5396 (define_insn "*addsi_1"
5397   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5398         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5399                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5400    (clobber (reg:CC FLAGS_REG))]
5401   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5402 {
5403   switch (get_attr_type (insn))
5404     {
5405     case TYPE_LEA:
5406       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5407       return "lea{l}\t{%a2, %0|%0, %a2}";
5408
5409     case TYPE_INCDEC:
5410       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5411       if (operands[2] == const1_rtx)
5412         return "inc{l}\t%0";
5413       else
5414         {
5415           gcc_assert (operands[2] == constm1_rtx);
5416           return "dec{l}\t%0";
5417         }
5418
5419     default:
5420       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5421
5422       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5423          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5424       if (CONST_INT_P (operands[2])
5425           && (INTVAL (operands[2]) == 128
5426               || (INTVAL (operands[2]) < 0
5427                   && INTVAL (operands[2]) != -128)))
5428         {
5429           operands[2] = GEN_INT (-INTVAL (operands[2]));
5430           return "sub{l}\t{%2, %0|%0, %2}";
5431         }
5432       return "add{l}\t{%2, %0|%0, %2}";
5433     }
5434 }
5435   [(set (attr "type")
5436      (cond [(eq_attr "alternative" "2")
5437               (const_string "lea")
5438             ; Current assemblers are broken and do not allow @GOTOFF in
5439             ; ought but a memory context.
5440             (match_operand:SI 2 "pic_symbolic_operand" "")
5441               (const_string "lea")
5442             (match_operand:SI 2 "incdec_operand" "")
5443               (const_string "incdec")
5444            ]
5445            (const_string "alu")))
5446    (set_attr "mode" "SI")])
5447
5448 ;; Convert lea to the lea pattern to avoid flags dependency.
5449 (define_split
5450   [(set (match_operand 0 "register_operand" "")
5451         (plus (match_operand 1 "register_operand" "")
5452               (match_operand 2 "nonmemory_operand" "")))
5453    (clobber (reg:CC FLAGS_REG))]
5454   "reload_completed
5455    && true_regnum (operands[0]) != true_regnum (operands[1])"
5456   [(const_int 0)]
5457 {
5458   rtx pat;
5459   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5460      may confuse gen_lowpart.  */
5461   if (GET_MODE (operands[0]) != Pmode)
5462     {
5463       operands[1] = gen_lowpart (Pmode, operands[1]);
5464       operands[2] = gen_lowpart (Pmode, operands[2]);
5465     }
5466   operands[0] = gen_lowpart (SImode, operands[0]);
5467   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5468   if (Pmode != SImode)
5469     pat = gen_rtx_SUBREG (SImode, pat, 0);
5470   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5471   DONE;
5472 })
5473
5474 ;; It may seem that nonimmediate operand is proper one for operand 1.
5475 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5476 ;; we take care in ix86_binary_operator_ok to not allow two memory
5477 ;; operands so proper swapping will be done in reload.  This allow
5478 ;; patterns constructed from addsi_1 to match.
5479 (define_insn "addsi_1_zext"
5480   [(set (match_operand:DI 0 "register_operand" "=r,r")
5481         (zero_extend:DI
5482           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5483                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5484    (clobber (reg:CC FLAGS_REG))]
5485   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5486 {
5487   switch (get_attr_type (insn))
5488     {
5489     case TYPE_LEA:
5490       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5491       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5492
5493     case TYPE_INCDEC:
5494       if (operands[2] == const1_rtx)
5495         return "inc{l}\t%k0";
5496       else
5497         {
5498           gcc_assert (operands[2] == constm1_rtx);
5499           return "dec{l}\t%k0";
5500         }
5501
5502     default:
5503       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5504          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5505       if (CONST_INT_P (operands[2])
5506           && (INTVAL (operands[2]) == 128
5507               || (INTVAL (operands[2]) < 0
5508                   && INTVAL (operands[2]) != -128)))
5509         {
5510           operands[2] = GEN_INT (-INTVAL (operands[2]));
5511           return "sub{l}\t{%2, %k0|%k0, %2}";
5512         }
5513       return "add{l}\t{%2, %k0|%k0, %2}";
5514     }
5515 }
5516   [(set (attr "type")
5517      (cond [(eq_attr "alternative" "1")
5518               (const_string "lea")
5519             ; Current assemblers are broken and do not allow @GOTOFF in
5520             ; ought but a memory context.
5521             (match_operand:SI 2 "pic_symbolic_operand" "")
5522               (const_string "lea")
5523             (match_operand:SI 2 "incdec_operand" "")
5524               (const_string "incdec")
5525            ]
5526            (const_string "alu")))
5527    (set_attr "mode" "SI")])
5528
5529 ;; Convert lea to the lea pattern to avoid flags dependency.
5530 (define_split
5531   [(set (match_operand:DI 0 "register_operand" "")
5532         (zero_extend:DI
5533           (plus:SI (match_operand:SI 1 "register_operand" "")
5534                    (match_operand:SI 2 "nonmemory_operand" ""))))
5535    (clobber (reg:CC FLAGS_REG))]
5536   "TARGET_64BIT && reload_completed
5537    && true_regnum (operands[0]) != true_regnum (operands[1])"
5538   [(set (match_dup 0)
5539         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5540 {
5541   operands[1] = gen_lowpart (Pmode, operands[1]);
5542   operands[2] = gen_lowpart (Pmode, operands[2]);
5543 })
5544
5545 (define_insn "*addsi_2"
5546   [(set (reg FLAGS_REG)
5547         (compare
5548           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5549                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5550           (const_int 0)))
5551    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5552         (plus:SI (match_dup 1) (match_dup 2)))]
5553   "ix86_match_ccmode (insn, CCGOCmode)
5554    && ix86_binary_operator_ok (PLUS, SImode, operands)
5555    /* Current assemblers are broken and do not allow @GOTOFF in
5556       ought but a memory context.  */
5557    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5558 {
5559   switch (get_attr_type (insn))
5560     {
5561     case TYPE_INCDEC:
5562       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5563       if (operands[2] == const1_rtx)
5564         return "inc{l}\t%0";
5565       else
5566         {
5567           gcc_assert (operands[2] == constm1_rtx);
5568           return "dec{l}\t%0";
5569         }
5570
5571     default:
5572       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5573       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5574          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5575       if (CONST_INT_P (operands[2])
5576           && (INTVAL (operands[2]) == 128
5577               || (INTVAL (operands[2]) < 0
5578                   && INTVAL (operands[2]) != -128)))
5579         {
5580           operands[2] = GEN_INT (-INTVAL (operands[2]));
5581           return "sub{l}\t{%2, %0|%0, %2}";
5582         }
5583       return "add{l}\t{%2, %0|%0, %2}";
5584     }
5585 }
5586   [(set (attr "type")
5587      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5588         (const_string "incdec")
5589         (const_string "alu")))
5590    (set_attr "mode" "SI")])
5591
5592 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5593 (define_insn "*addsi_2_zext"
5594   [(set (reg FLAGS_REG)
5595         (compare
5596           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5597                    (match_operand:SI 2 "general_operand" "rmni"))
5598           (const_int 0)))
5599    (set (match_operand:DI 0 "register_operand" "=r")
5600         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5601   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5602    && ix86_binary_operator_ok (PLUS, SImode, operands)
5603    /* Current assemblers are broken and do not allow @GOTOFF in
5604       ought but a memory context.  */
5605    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5606 {
5607   switch (get_attr_type (insn))
5608     {
5609     case TYPE_INCDEC:
5610       if (operands[2] == const1_rtx)
5611         return "inc{l}\t%k0";
5612       else
5613         {
5614           gcc_assert (operands[2] == constm1_rtx);
5615           return "dec{l}\t%k0";
5616         }
5617
5618     default:
5619       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5620          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5621       if (CONST_INT_P (operands[2])
5622           && (INTVAL (operands[2]) == 128
5623               || (INTVAL (operands[2]) < 0
5624                   && INTVAL (operands[2]) != -128)))
5625         {
5626           operands[2] = GEN_INT (-INTVAL (operands[2]));
5627           return "sub{l}\t{%2, %k0|%k0, %2}";
5628         }
5629       return "add{l}\t{%2, %k0|%k0, %2}";
5630     }
5631 }
5632   [(set (attr "type")
5633      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5634         (const_string "incdec")
5635         (const_string "alu")))
5636    (set_attr "mode" "SI")])
5637
5638 (define_insn "*addsi_3"
5639   [(set (reg FLAGS_REG)
5640         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5641                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5642    (clobber (match_scratch:SI 0 "=r"))]
5643   "ix86_match_ccmode (insn, CCZmode)
5644    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5645    /* Current assemblers are broken and do not allow @GOTOFF in
5646       ought but a memory context.  */
5647    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5648 {
5649   switch (get_attr_type (insn))
5650     {
5651     case TYPE_INCDEC:
5652       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5653       if (operands[2] == const1_rtx)
5654         return "inc{l}\t%0";
5655       else
5656         {
5657           gcc_assert (operands[2] == constm1_rtx);
5658           return "dec{l}\t%0";
5659         }
5660
5661     default:
5662       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5663       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5664          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5665       if (CONST_INT_P (operands[2])
5666           && (INTVAL (operands[2]) == 128
5667               || (INTVAL (operands[2]) < 0
5668                   && INTVAL (operands[2]) != -128)))
5669         {
5670           operands[2] = GEN_INT (-INTVAL (operands[2]));
5671           return "sub{l}\t{%2, %0|%0, %2}";
5672         }
5673       return "add{l}\t{%2, %0|%0, %2}";
5674     }
5675 }
5676   [(set (attr "type")
5677      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5678         (const_string "incdec")
5679         (const_string "alu")))
5680    (set_attr "mode" "SI")])
5681
5682 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5683 (define_insn "*addsi_3_zext"
5684   [(set (reg FLAGS_REG)
5685         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5686                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5687    (set (match_operand:DI 0 "register_operand" "=r")
5688         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5689   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5690    && ix86_binary_operator_ok (PLUS, SImode, operands)
5691    /* Current assemblers are broken and do not allow @GOTOFF in
5692       ought but a memory context.  */
5693    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5694 {
5695   switch (get_attr_type (insn))
5696     {
5697     case TYPE_INCDEC:
5698       if (operands[2] == const1_rtx)
5699         return "inc{l}\t%k0";
5700       else
5701         {
5702           gcc_assert (operands[2] == constm1_rtx);
5703           return "dec{l}\t%k0";
5704         }
5705
5706     default:
5707       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5708          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5709       if (CONST_INT_P (operands[2])
5710           && (INTVAL (operands[2]) == 128
5711               || (INTVAL (operands[2]) < 0
5712                   && INTVAL (operands[2]) != -128)))
5713         {
5714           operands[2] = GEN_INT (-INTVAL (operands[2]));
5715           return "sub{l}\t{%2, %k0|%k0, %2}";
5716         }
5717       return "add{l}\t{%2, %k0|%k0, %2}";
5718     }
5719 }
5720   [(set (attr "type")
5721      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5722         (const_string "incdec")
5723         (const_string "alu")))
5724    (set_attr "mode" "SI")])
5725
5726 ; For comparisons against 1, -1 and 128, we may generate better code
5727 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5728 ; is matched then.  We can't accept general immediate, because for
5729 ; case of overflows,  the result is messed up.
5730 ; This pattern also don't hold of 0x80000000, since the value overflows
5731 ; when negated.
5732 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5733 ; only for comparisons not depending on it.
5734 (define_insn "*addsi_4"
5735   [(set (reg FLAGS_REG)
5736         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5737                  (match_operand:SI 2 "const_int_operand" "n")))
5738    (clobber (match_scratch:SI 0 "=rm"))]
5739   "ix86_match_ccmode (insn, CCGCmode)
5740    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5741 {
5742   switch (get_attr_type (insn))
5743     {
5744     case TYPE_INCDEC:
5745       if (operands[2] == constm1_rtx)
5746         return "inc{l}\t%0";
5747       else
5748         {
5749           gcc_assert (operands[2] == const1_rtx);
5750           return "dec{l}\t%0";
5751         }
5752
5753     default:
5754       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5755       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5756          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5757       if ((INTVAL (operands[2]) == -128
5758            || (INTVAL (operands[2]) > 0
5759                && INTVAL (operands[2]) != 128)))
5760         return "sub{l}\t{%2, %0|%0, %2}";
5761       operands[2] = GEN_INT (-INTVAL (operands[2]));
5762       return "add{l}\t{%2, %0|%0, %2}";
5763     }
5764 }
5765   [(set (attr "type")
5766      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5767         (const_string "incdec")
5768         (const_string "alu")))
5769    (set_attr "mode" "SI")])
5770
5771 (define_insn "*addsi_5"
5772   [(set (reg FLAGS_REG)
5773         (compare
5774           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5775                    (match_operand:SI 2 "general_operand" "rmni"))
5776           (const_int 0)))
5777    (clobber (match_scratch:SI 0 "=r"))]
5778   "ix86_match_ccmode (insn, CCGOCmode)
5779    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5780    /* Current assemblers are broken and do not allow @GOTOFF in
5781       ought but a memory context.  */
5782    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5783 {
5784   switch (get_attr_type (insn))
5785     {
5786     case TYPE_INCDEC:
5787       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5788       if (operands[2] == const1_rtx)
5789         return "inc{l}\t%0";
5790       else
5791         {
5792           gcc_assert (operands[2] == constm1_rtx);
5793           return "dec{l}\t%0";
5794         }
5795
5796     default:
5797       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5798       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5799          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5800       if (CONST_INT_P (operands[2])
5801           && (INTVAL (operands[2]) == 128
5802               || (INTVAL (operands[2]) < 0
5803                   && INTVAL (operands[2]) != -128)))
5804         {
5805           operands[2] = GEN_INT (-INTVAL (operands[2]));
5806           return "sub{l}\t{%2, %0|%0, %2}";
5807         }
5808       return "add{l}\t{%2, %0|%0, %2}";
5809     }
5810 }
5811   [(set (attr "type")
5812      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5813         (const_string "incdec")
5814         (const_string "alu")))
5815    (set_attr "mode" "SI")])
5816
5817 (define_expand "addhi3"
5818   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5819                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5820                             (match_operand:HI 2 "general_operand" "")))
5821               (clobber (reg:CC FLAGS_REG))])]
5822   "TARGET_HIMODE_MATH"
5823   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5824
5825 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5826 ;; type optimizations enabled by define-splits.  This is not important
5827 ;; for PII, and in fact harmful because of partial register stalls.
5828
5829 (define_insn "*addhi_1_lea"
5830   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5831         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5832                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5833    (clobber (reg:CC FLAGS_REG))]
5834   "!TARGET_PARTIAL_REG_STALL
5835    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5836 {
5837   switch (get_attr_type (insn))
5838     {
5839     case TYPE_LEA:
5840       return "#";
5841     case TYPE_INCDEC:
5842       if (operands[2] == const1_rtx)
5843         return "inc{w}\t%0";
5844       else
5845         {
5846           gcc_assert (operands[2] == constm1_rtx);
5847           return "dec{w}\t%0";
5848         }
5849
5850     default:
5851       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5852          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5853       if (CONST_INT_P (operands[2])
5854           && (INTVAL (operands[2]) == 128
5855               || (INTVAL (operands[2]) < 0
5856                   && INTVAL (operands[2]) != -128)))
5857         {
5858           operands[2] = GEN_INT (-INTVAL (operands[2]));
5859           return "sub{w}\t{%2, %0|%0, %2}";
5860         }
5861       return "add{w}\t{%2, %0|%0, %2}";
5862     }
5863 }
5864   [(set (attr "type")
5865      (if_then_else (eq_attr "alternative" "2")
5866         (const_string "lea")
5867         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5868            (const_string "incdec")
5869            (const_string "alu"))))
5870    (set_attr "mode" "HI,HI,SI")])
5871
5872 (define_insn "*addhi_1"
5873   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5874         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5875                  (match_operand:HI 2 "general_operand" "ri,rm")))
5876    (clobber (reg:CC FLAGS_REG))]
5877   "TARGET_PARTIAL_REG_STALL
5878    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5879 {
5880   switch (get_attr_type (insn))
5881     {
5882     case TYPE_INCDEC:
5883       if (operands[2] == const1_rtx)
5884         return "inc{w}\t%0";
5885       else
5886         {
5887           gcc_assert (operands[2] == constm1_rtx);
5888           return "dec{w}\t%0";
5889         }
5890
5891     default:
5892       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5893          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5894       if (CONST_INT_P (operands[2])
5895           && (INTVAL (operands[2]) == 128
5896               || (INTVAL (operands[2]) < 0
5897                   && INTVAL (operands[2]) != -128)))
5898         {
5899           operands[2] = GEN_INT (-INTVAL (operands[2]));
5900           return "sub{w}\t{%2, %0|%0, %2}";
5901         }
5902       return "add{w}\t{%2, %0|%0, %2}";
5903     }
5904 }
5905   [(set (attr "type")
5906      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5907         (const_string "incdec")
5908         (const_string "alu")))
5909    (set_attr "mode" "HI")])
5910
5911 (define_insn "*addhi_2"
5912   [(set (reg FLAGS_REG)
5913         (compare
5914           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5915                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5916           (const_int 0)))
5917    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5918         (plus:HI (match_dup 1) (match_dup 2)))]
5919   "ix86_match_ccmode (insn, CCGOCmode)
5920    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5921 {
5922   switch (get_attr_type (insn))
5923     {
5924     case TYPE_INCDEC:
5925       if (operands[2] == const1_rtx)
5926         return "inc{w}\t%0";
5927       else
5928         {
5929           gcc_assert (operands[2] == constm1_rtx);
5930           return "dec{w}\t%0";
5931         }
5932
5933     default:
5934       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5935          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5936       if (CONST_INT_P (operands[2])
5937           && (INTVAL (operands[2]) == 128
5938               || (INTVAL (operands[2]) < 0
5939                   && INTVAL (operands[2]) != -128)))
5940         {
5941           operands[2] = GEN_INT (-INTVAL (operands[2]));
5942           return "sub{w}\t{%2, %0|%0, %2}";
5943         }
5944       return "add{w}\t{%2, %0|%0, %2}";
5945     }
5946 }
5947   [(set (attr "type")
5948      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5949         (const_string "incdec")
5950         (const_string "alu")))
5951    (set_attr "mode" "HI")])
5952
5953 (define_insn "*addhi_3"
5954   [(set (reg FLAGS_REG)
5955         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5956                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5957    (clobber (match_scratch:HI 0 "=r"))]
5958   "ix86_match_ccmode (insn, CCZmode)
5959    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5960 {
5961   switch (get_attr_type (insn))
5962     {
5963     case TYPE_INCDEC:
5964       if (operands[2] == const1_rtx)
5965         return "inc{w}\t%0";
5966       else
5967         {
5968           gcc_assert (operands[2] == constm1_rtx);
5969           return "dec{w}\t%0";
5970         }
5971
5972     default:
5973       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5974          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5975       if (CONST_INT_P (operands[2])
5976           && (INTVAL (operands[2]) == 128
5977               || (INTVAL (operands[2]) < 0
5978                   && INTVAL (operands[2]) != -128)))
5979         {
5980           operands[2] = GEN_INT (-INTVAL (operands[2]));
5981           return "sub{w}\t{%2, %0|%0, %2}";
5982         }
5983       return "add{w}\t{%2, %0|%0, %2}";
5984     }
5985 }
5986   [(set (attr "type")
5987      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5988         (const_string "incdec")
5989         (const_string "alu")))
5990    (set_attr "mode" "HI")])
5991
5992 ; See comments above addsi_4 for details.
5993 (define_insn "*addhi_4"
5994   [(set (reg FLAGS_REG)
5995         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5996                  (match_operand:HI 2 "const_int_operand" "n")))
5997    (clobber (match_scratch:HI 0 "=rm"))]
5998   "ix86_match_ccmode (insn, CCGCmode)
5999    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6000 {
6001   switch (get_attr_type (insn))
6002     {
6003     case TYPE_INCDEC:
6004       if (operands[2] == constm1_rtx)
6005         return "inc{w}\t%0";
6006       else
6007         {
6008           gcc_assert (operands[2] == const1_rtx);
6009           return "dec{w}\t%0";
6010         }
6011
6012     default:
6013       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6014       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6015          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6016       if ((INTVAL (operands[2]) == -128
6017            || (INTVAL (operands[2]) > 0
6018                && INTVAL (operands[2]) != 128)))
6019         return "sub{w}\t{%2, %0|%0, %2}";
6020       operands[2] = GEN_INT (-INTVAL (operands[2]));
6021       return "add{w}\t{%2, %0|%0, %2}";
6022     }
6023 }
6024   [(set (attr "type")
6025      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6026         (const_string "incdec")
6027         (const_string "alu")))
6028    (set_attr "mode" "SI")])
6029
6030
6031 (define_insn "*addhi_5"
6032   [(set (reg FLAGS_REG)
6033         (compare
6034           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6035                    (match_operand:HI 2 "general_operand" "rmni"))
6036           (const_int 0)))
6037    (clobber (match_scratch:HI 0 "=r"))]
6038   "ix86_match_ccmode (insn, CCGOCmode)
6039    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6040 {
6041   switch (get_attr_type (insn))
6042     {
6043     case TYPE_INCDEC:
6044       if (operands[2] == const1_rtx)
6045         return "inc{w}\t%0";
6046       else
6047         {
6048           gcc_assert (operands[2] == constm1_rtx);
6049           return "dec{w}\t%0";
6050         }
6051
6052     default:
6053       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6054          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6055       if (CONST_INT_P (operands[2])
6056           && (INTVAL (operands[2]) == 128
6057               || (INTVAL (operands[2]) < 0
6058                   && INTVAL (operands[2]) != -128)))
6059         {
6060           operands[2] = GEN_INT (-INTVAL (operands[2]));
6061           return "sub{w}\t{%2, %0|%0, %2}";
6062         }
6063       return "add{w}\t{%2, %0|%0, %2}";
6064     }
6065 }
6066   [(set (attr "type")
6067      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6068         (const_string "incdec")
6069         (const_string "alu")))
6070    (set_attr "mode" "HI")])
6071
6072 (define_expand "addqi3"
6073   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6074                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6075                             (match_operand:QI 2 "general_operand" "")))
6076               (clobber (reg:CC FLAGS_REG))])]
6077   "TARGET_QIMODE_MATH"
6078   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6079
6080 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6081 (define_insn "*addqi_1_lea"
6082   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6083         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6084                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6085    (clobber (reg:CC FLAGS_REG))]
6086   "!TARGET_PARTIAL_REG_STALL
6087    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6088 {
6089   int widen = (which_alternative == 2);
6090   switch (get_attr_type (insn))
6091     {
6092     case TYPE_LEA:
6093       return "#";
6094     case TYPE_INCDEC:
6095       if (operands[2] == const1_rtx)
6096         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6097       else
6098         {
6099           gcc_assert (operands[2] == constm1_rtx);
6100           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6101         }
6102
6103     default:
6104       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6105          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6106       if (CONST_INT_P (operands[2])
6107           && (INTVAL (operands[2]) == 128
6108               || (INTVAL (operands[2]) < 0
6109                   && INTVAL (operands[2]) != -128)))
6110         {
6111           operands[2] = GEN_INT (-INTVAL (operands[2]));
6112           if (widen)
6113             return "sub{l}\t{%2, %k0|%k0, %2}";
6114           else
6115             return "sub{b}\t{%2, %0|%0, %2}";
6116         }
6117       if (widen)
6118         return "add{l}\t{%k2, %k0|%k0, %k2}";
6119       else
6120         return "add{b}\t{%2, %0|%0, %2}";
6121     }
6122 }
6123   [(set (attr "type")
6124      (if_then_else (eq_attr "alternative" "3")
6125         (const_string "lea")
6126         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6127            (const_string "incdec")
6128            (const_string "alu"))))
6129    (set_attr "mode" "QI,QI,SI,SI")])
6130
6131 (define_insn "*addqi_1"
6132   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6133         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6134                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6135    (clobber (reg:CC FLAGS_REG))]
6136   "TARGET_PARTIAL_REG_STALL
6137    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6138 {
6139   int widen = (which_alternative == 2);
6140   switch (get_attr_type (insn))
6141     {
6142     case TYPE_INCDEC:
6143       if (operands[2] == const1_rtx)
6144         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6145       else
6146         {
6147           gcc_assert (operands[2] == constm1_rtx);
6148           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6149         }
6150
6151     default:
6152       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6153          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6154       if (CONST_INT_P (operands[2])
6155           && (INTVAL (operands[2]) == 128
6156               || (INTVAL (operands[2]) < 0
6157                   && INTVAL (operands[2]) != -128)))
6158         {
6159           operands[2] = GEN_INT (-INTVAL (operands[2]));
6160           if (widen)
6161             return "sub{l}\t{%2, %k0|%k0, %2}";
6162           else
6163             return "sub{b}\t{%2, %0|%0, %2}";
6164         }
6165       if (widen)
6166         return "add{l}\t{%k2, %k0|%k0, %k2}";
6167       else
6168         return "add{b}\t{%2, %0|%0, %2}";
6169     }
6170 }
6171   [(set (attr "type")
6172      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6173         (const_string "incdec")
6174         (const_string "alu")))
6175    (set_attr "mode" "QI,QI,SI")])
6176
6177 (define_insn "*addqi_1_slp"
6178   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6179         (plus:QI (match_dup 0)
6180                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6181    (clobber (reg:CC FLAGS_REG))]
6182   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6183    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6184 {
6185   switch (get_attr_type (insn))
6186     {
6187     case TYPE_INCDEC:
6188       if (operands[1] == const1_rtx)
6189         return "inc{b}\t%0";
6190       else
6191         {
6192           gcc_assert (operands[1] == constm1_rtx);
6193           return "dec{b}\t%0";
6194         }
6195
6196     default:
6197       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6198       if (CONST_INT_P (operands[1])
6199           && INTVAL (operands[1]) < 0)
6200         {
6201           operands[1] = GEN_INT (-INTVAL (operands[1]));
6202           return "sub{b}\t{%1, %0|%0, %1}";
6203         }
6204       return "add{b}\t{%1, %0|%0, %1}";
6205     }
6206 }
6207   [(set (attr "type")
6208      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6209         (const_string "incdec")
6210         (const_string "alu1")))
6211    (set (attr "memory")
6212      (if_then_else (match_operand 1 "memory_operand" "")
6213         (const_string "load")
6214         (const_string "none")))
6215    (set_attr "mode" "QI")])
6216
6217 (define_insn "*addqi_2"
6218   [(set (reg FLAGS_REG)
6219         (compare
6220           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6221                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6222           (const_int 0)))
6223    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6224         (plus:QI (match_dup 1) (match_dup 2)))]
6225   "ix86_match_ccmode (insn, CCGOCmode)
6226    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6227 {
6228   switch (get_attr_type (insn))
6229     {
6230     case TYPE_INCDEC:
6231       if (operands[2] == const1_rtx)
6232         return "inc{b}\t%0";
6233       else
6234         {
6235           gcc_assert (operands[2] == constm1_rtx
6236                       || (CONST_INT_P (operands[2])
6237                           && INTVAL (operands[2]) == 255));
6238           return "dec{b}\t%0";
6239         }
6240
6241     default:
6242       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6243       if (CONST_INT_P (operands[2])
6244           && INTVAL (operands[2]) < 0)
6245         {
6246           operands[2] = GEN_INT (-INTVAL (operands[2]));
6247           return "sub{b}\t{%2, %0|%0, %2}";
6248         }
6249       return "add{b}\t{%2, %0|%0, %2}";
6250     }
6251 }
6252   [(set (attr "type")
6253      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6254         (const_string "incdec")
6255         (const_string "alu")))
6256    (set_attr "mode" "QI")])
6257
6258 (define_insn "*addqi_3"
6259   [(set (reg FLAGS_REG)
6260         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6261                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6262    (clobber (match_scratch:QI 0 "=q"))]
6263   "ix86_match_ccmode (insn, CCZmode)
6264    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6265 {
6266   switch (get_attr_type (insn))
6267     {
6268     case TYPE_INCDEC:
6269       if (operands[2] == const1_rtx)
6270         return "inc{b}\t%0";
6271       else
6272         {
6273           gcc_assert (operands[2] == constm1_rtx
6274                       || (CONST_INT_P (operands[2])
6275                           && INTVAL (operands[2]) == 255));
6276           return "dec{b}\t%0";
6277         }
6278
6279     default:
6280       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6281       if (CONST_INT_P (operands[2])
6282           && INTVAL (operands[2]) < 0)
6283         {
6284           operands[2] = GEN_INT (-INTVAL (operands[2]));
6285           return "sub{b}\t{%2, %0|%0, %2}";
6286         }
6287       return "add{b}\t{%2, %0|%0, %2}";
6288     }
6289 }
6290   [(set (attr "type")
6291      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6292         (const_string "incdec")
6293         (const_string "alu")))
6294    (set_attr "mode" "QI")])
6295
6296 ; See comments above addsi_4 for details.
6297 (define_insn "*addqi_4"
6298   [(set (reg FLAGS_REG)
6299         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6300                  (match_operand:QI 2 "const_int_operand" "n")))
6301    (clobber (match_scratch:QI 0 "=qm"))]
6302   "ix86_match_ccmode (insn, CCGCmode)
6303    && (INTVAL (operands[2]) & 0xff) != 0x80"
6304 {
6305   switch (get_attr_type (insn))
6306     {
6307     case TYPE_INCDEC:
6308       if (operands[2] == constm1_rtx
6309           || (CONST_INT_P (operands[2])
6310               && INTVAL (operands[2]) == 255))
6311         return "inc{b}\t%0";
6312       else
6313         {
6314           gcc_assert (operands[2] == const1_rtx);
6315           return "dec{b}\t%0";
6316         }
6317
6318     default:
6319       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6320       if (INTVAL (operands[2]) < 0)
6321         {
6322           operands[2] = GEN_INT (-INTVAL (operands[2]));
6323           return "add{b}\t{%2, %0|%0, %2}";
6324         }
6325       return "sub{b}\t{%2, %0|%0, %2}";
6326     }
6327 }
6328   [(set (attr "type")
6329      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6330         (const_string "incdec")
6331         (const_string "alu")))
6332    (set_attr "mode" "QI")])
6333
6334
6335 (define_insn "*addqi_5"
6336   [(set (reg FLAGS_REG)
6337         (compare
6338           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6339                    (match_operand:QI 2 "general_operand" "qmni"))
6340           (const_int 0)))
6341    (clobber (match_scratch:QI 0 "=q"))]
6342   "ix86_match_ccmode (insn, CCGOCmode)
6343    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6344 {
6345   switch (get_attr_type (insn))
6346     {
6347     case TYPE_INCDEC:
6348       if (operands[2] == const1_rtx)
6349         return "inc{b}\t%0";
6350       else
6351         {
6352           gcc_assert (operands[2] == constm1_rtx
6353                       || (CONST_INT_P (operands[2])
6354                           && INTVAL (operands[2]) == 255));
6355           return "dec{b}\t%0";
6356         }
6357
6358     default:
6359       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6360       if (CONST_INT_P (operands[2])
6361           && INTVAL (operands[2]) < 0)
6362         {
6363           operands[2] = GEN_INT (-INTVAL (operands[2]));
6364           return "sub{b}\t{%2, %0|%0, %2}";
6365         }
6366       return "add{b}\t{%2, %0|%0, %2}";
6367     }
6368 }
6369   [(set (attr "type")
6370      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6371         (const_string "incdec")
6372         (const_string "alu")))
6373    (set_attr "mode" "QI")])
6374
6375
6376 (define_insn "addqi_ext_1"
6377   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6378                          (const_int 8)
6379                          (const_int 8))
6380         (plus:SI
6381           (zero_extract:SI
6382             (match_operand 1 "ext_register_operand" "0")
6383             (const_int 8)
6384             (const_int 8))
6385           (match_operand:QI 2 "general_operand" "Qmn")))
6386    (clobber (reg:CC FLAGS_REG))]
6387   "!TARGET_64BIT"
6388 {
6389   switch (get_attr_type (insn))
6390     {
6391     case TYPE_INCDEC:
6392       if (operands[2] == const1_rtx)
6393         return "inc{b}\t%h0";
6394       else
6395         {
6396           gcc_assert (operands[2] == constm1_rtx
6397                       || (CONST_INT_P (operands[2])
6398                           && INTVAL (operands[2]) == 255));
6399           return "dec{b}\t%h0";
6400         }
6401
6402     default:
6403       return "add{b}\t{%2, %h0|%h0, %2}";
6404     }
6405 }
6406   [(set (attr "type")
6407      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6408         (const_string "incdec")
6409         (const_string "alu")))
6410    (set_attr "mode" "QI")])
6411
6412 (define_insn "*addqi_ext_1_rex64"
6413   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6414                          (const_int 8)
6415                          (const_int 8))
6416         (plus:SI
6417           (zero_extract:SI
6418             (match_operand 1 "ext_register_operand" "0")
6419             (const_int 8)
6420             (const_int 8))
6421           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6422    (clobber (reg:CC FLAGS_REG))]
6423   "TARGET_64BIT"
6424 {
6425   switch (get_attr_type (insn))
6426     {
6427     case TYPE_INCDEC:
6428       if (operands[2] == const1_rtx)
6429         return "inc{b}\t%h0";
6430       else
6431         {
6432           gcc_assert (operands[2] == constm1_rtx
6433                       || (CONST_INT_P (operands[2])
6434                           && INTVAL (operands[2]) == 255));
6435           return "dec{b}\t%h0";
6436         }
6437
6438     default:
6439       return "add{b}\t{%2, %h0|%h0, %2}";
6440     }
6441 }
6442   [(set (attr "type")
6443      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6444         (const_string "incdec")
6445         (const_string "alu")))
6446    (set_attr "mode" "QI")])
6447
6448 (define_insn "*addqi_ext_2"
6449   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6450                          (const_int 8)
6451                          (const_int 8))
6452         (plus:SI
6453           (zero_extract:SI
6454             (match_operand 1 "ext_register_operand" "%0")
6455             (const_int 8)
6456             (const_int 8))
6457           (zero_extract:SI
6458             (match_operand 2 "ext_register_operand" "Q")
6459             (const_int 8)
6460             (const_int 8))))
6461    (clobber (reg:CC FLAGS_REG))]
6462   ""
6463   "add{b}\t{%h2, %h0|%h0, %h2}"
6464   [(set_attr "type" "alu")
6465    (set_attr "mode" "QI")])
6466
6467 ;; The patterns that match these are at the end of this file.
6468
6469 (define_expand "addxf3"
6470   [(set (match_operand:XF 0 "register_operand" "")
6471         (plus:XF (match_operand:XF 1 "register_operand" "")
6472                  (match_operand:XF 2 "register_operand" "")))]
6473   "TARGET_80387"
6474   "")
6475
6476 (define_expand "adddf3"
6477   [(set (match_operand:DF 0 "register_operand" "")
6478         (plus:DF (match_operand:DF 1 "register_operand" "")
6479                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6480   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6481   "")
6482
6483 (define_expand "addsf3"
6484   [(set (match_operand:SF 0 "register_operand" "")
6485         (plus:SF (match_operand:SF 1 "register_operand" "")
6486                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6487   "TARGET_80387 || TARGET_SSE_MATH"
6488   "")
6489 \f
6490 ;; Subtract instructions
6491
6492 ;; %%% splits for subditi3
6493
6494 (define_expand "subti3"
6495   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6496                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6497                              (match_operand:TI 2 "x86_64_general_operand" "")))
6498               (clobber (reg:CC FLAGS_REG))])]
6499   "TARGET_64BIT"
6500   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6501
6502 (define_insn "*subti3_1"
6503   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6504         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6505                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6506    (clobber (reg:CC FLAGS_REG))]
6507   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6508   "#")
6509
6510 (define_split
6511   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6512         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6513                   (match_operand:TI 2 "x86_64_general_operand" "")))
6514    (clobber (reg:CC FLAGS_REG))]
6515   "TARGET_64BIT && reload_completed"
6516   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6517               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6518    (parallel [(set (match_dup 3)
6519                    (minus:DI (match_dup 4)
6520                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6521                                       (match_dup 5))))
6522               (clobber (reg:CC FLAGS_REG))])]
6523   "split_ti (operands+0, 1, operands+0, operands+3);
6524    split_ti (operands+1, 1, operands+1, operands+4);
6525    split_ti (operands+2, 1, operands+2, operands+5);")
6526
6527 ;; %%% splits for subsidi3
6528
6529 (define_expand "subdi3"
6530   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6531                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6532                              (match_operand:DI 2 "x86_64_general_operand" "")))
6533               (clobber (reg:CC FLAGS_REG))])]
6534   ""
6535   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6536
6537 (define_insn "*subdi3_1"
6538   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6539         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6540                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6541    (clobber (reg:CC FLAGS_REG))]
6542   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6543   "#")
6544
6545 (define_split
6546   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6547         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6548                   (match_operand:DI 2 "general_operand" "")))
6549    (clobber (reg:CC FLAGS_REG))]
6550   "!TARGET_64BIT && reload_completed"
6551   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6552               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6553    (parallel [(set (match_dup 3)
6554                    (minus:SI (match_dup 4)
6555                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6556                                       (match_dup 5))))
6557               (clobber (reg:CC FLAGS_REG))])]
6558   "split_di (operands+0, 1, operands+0, operands+3);
6559    split_di (operands+1, 1, operands+1, operands+4);
6560    split_di (operands+2, 1, operands+2, operands+5);")
6561
6562 (define_insn "subdi3_carry_rex64"
6563   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6564           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6565             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6566                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6567    (clobber (reg:CC FLAGS_REG))]
6568   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6569   "sbb{q}\t{%2, %0|%0, %2}"
6570   [(set_attr "type" "alu")
6571    (set_attr "pent_pair" "pu")
6572    (set_attr "mode" "DI")])
6573
6574 (define_insn "*subdi_1_rex64"
6575   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6576         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6577                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6578    (clobber (reg:CC FLAGS_REG))]
6579   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6580   "sub{q}\t{%2, %0|%0, %2}"
6581   [(set_attr "type" "alu")
6582    (set_attr "mode" "DI")])
6583
6584 (define_insn "*subdi_2_rex64"
6585   [(set (reg FLAGS_REG)
6586         (compare
6587           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6588                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6589           (const_int 0)))
6590    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6591         (minus:DI (match_dup 1) (match_dup 2)))]
6592   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6593    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6594   "sub{q}\t{%2, %0|%0, %2}"
6595   [(set_attr "type" "alu")
6596    (set_attr "mode" "DI")])
6597
6598 (define_insn "*subdi_3_rex63"
6599   [(set (reg FLAGS_REG)
6600         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6601                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6602    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6603         (minus:DI (match_dup 1) (match_dup 2)))]
6604   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6605    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6606   "sub{q}\t{%2, %0|%0, %2}"
6607   [(set_attr "type" "alu")
6608    (set_attr "mode" "DI")])
6609
6610 (define_insn "subqi3_carry"
6611   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6612           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6613             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6614                (match_operand:QI 2 "general_operand" "qi,qm"))))
6615    (clobber (reg:CC FLAGS_REG))]
6616   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6617   "sbb{b}\t{%2, %0|%0, %2}"
6618   [(set_attr "type" "alu")
6619    (set_attr "pent_pair" "pu")
6620    (set_attr "mode" "QI")])
6621
6622 (define_insn "subhi3_carry"
6623   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6624           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6625             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6626                (match_operand:HI 2 "general_operand" "ri,rm"))))
6627    (clobber (reg:CC FLAGS_REG))]
6628   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6629   "sbb{w}\t{%2, %0|%0, %2}"
6630   [(set_attr "type" "alu")
6631    (set_attr "pent_pair" "pu")
6632    (set_attr "mode" "HI")])
6633
6634 (define_insn "subsi3_carry"
6635   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6636           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6637             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6638                (match_operand:SI 2 "general_operand" "ri,rm"))))
6639    (clobber (reg:CC FLAGS_REG))]
6640   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6641   "sbb{l}\t{%2, %0|%0, %2}"
6642   [(set_attr "type" "alu")
6643    (set_attr "pent_pair" "pu")
6644    (set_attr "mode" "SI")])
6645
6646 (define_insn "subsi3_carry_zext"
6647   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6648           (zero_extend:DI
6649             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6650               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6651                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6652    (clobber (reg:CC FLAGS_REG))]
6653   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6654   "sbb{l}\t{%2, %k0|%k0, %2}"
6655   [(set_attr "type" "alu")
6656    (set_attr "pent_pair" "pu")
6657    (set_attr "mode" "SI")])
6658
6659 (define_expand "subsi3"
6660   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6661                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6662                              (match_operand:SI 2 "general_operand" "")))
6663               (clobber (reg:CC FLAGS_REG))])]
6664   ""
6665   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6666
6667 (define_insn "*subsi_1"
6668   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6669         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6670                   (match_operand:SI 2 "general_operand" "ri,rm")))
6671    (clobber (reg:CC FLAGS_REG))]
6672   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6673   "sub{l}\t{%2, %0|%0, %2}"
6674   [(set_attr "type" "alu")
6675    (set_attr "mode" "SI")])
6676
6677 (define_insn "*subsi_1_zext"
6678   [(set (match_operand:DI 0 "register_operand" "=r")
6679         (zero_extend:DI
6680           (minus:SI (match_operand:SI 1 "register_operand" "0")
6681                     (match_operand:SI 2 "general_operand" "rim"))))
6682    (clobber (reg:CC FLAGS_REG))]
6683   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6684   "sub{l}\t{%2, %k0|%k0, %2}"
6685   [(set_attr "type" "alu")
6686    (set_attr "mode" "SI")])
6687
6688 (define_insn "*subsi_2"
6689   [(set (reg FLAGS_REG)
6690         (compare
6691           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6692                     (match_operand:SI 2 "general_operand" "ri,rm"))
6693           (const_int 0)))
6694    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6695         (minus:SI (match_dup 1) (match_dup 2)))]
6696   "ix86_match_ccmode (insn, CCGOCmode)
6697    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6698   "sub{l}\t{%2, %0|%0, %2}"
6699   [(set_attr "type" "alu")
6700    (set_attr "mode" "SI")])
6701
6702 (define_insn "*subsi_2_zext"
6703   [(set (reg FLAGS_REG)
6704         (compare
6705           (minus:SI (match_operand:SI 1 "register_operand" "0")
6706                     (match_operand:SI 2 "general_operand" "rim"))
6707           (const_int 0)))
6708    (set (match_operand:DI 0 "register_operand" "=r")
6709         (zero_extend:DI
6710           (minus:SI (match_dup 1)
6711                     (match_dup 2))))]
6712   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6713    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6714   "sub{l}\t{%2, %k0|%k0, %2}"
6715   [(set_attr "type" "alu")
6716    (set_attr "mode" "SI")])
6717
6718 (define_insn "*subsi_3"
6719   [(set (reg FLAGS_REG)
6720         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6721                  (match_operand:SI 2 "general_operand" "ri,rm")))
6722    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6723         (minus:SI (match_dup 1) (match_dup 2)))]
6724   "ix86_match_ccmode (insn, CCmode)
6725    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6726   "sub{l}\t{%2, %0|%0, %2}"
6727   [(set_attr "type" "alu")
6728    (set_attr "mode" "SI")])
6729
6730 (define_insn "*subsi_3_zext"
6731   [(set (reg FLAGS_REG)
6732         (compare (match_operand:SI 1 "register_operand" "0")
6733                  (match_operand:SI 2 "general_operand" "rim")))
6734    (set (match_operand:DI 0 "register_operand" "=r")
6735         (zero_extend:DI
6736           (minus:SI (match_dup 1)
6737                     (match_dup 2))))]
6738   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6739    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6740   "sub{l}\t{%2, %1|%1, %2}"
6741   [(set_attr "type" "alu")
6742    (set_attr "mode" "DI")])
6743
6744 (define_expand "subhi3"
6745   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6746                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6747                              (match_operand:HI 2 "general_operand" "")))
6748               (clobber (reg:CC FLAGS_REG))])]
6749   "TARGET_HIMODE_MATH"
6750   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6751
6752 (define_insn "*subhi_1"
6753   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6754         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6755                   (match_operand:HI 2 "general_operand" "ri,rm")))
6756    (clobber (reg:CC FLAGS_REG))]
6757   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6758   "sub{w}\t{%2, %0|%0, %2}"
6759   [(set_attr "type" "alu")
6760    (set_attr "mode" "HI")])
6761
6762 (define_insn "*subhi_2"
6763   [(set (reg FLAGS_REG)
6764         (compare
6765           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6766                     (match_operand:HI 2 "general_operand" "ri,rm"))
6767           (const_int 0)))
6768    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6769         (minus:HI (match_dup 1) (match_dup 2)))]
6770   "ix86_match_ccmode (insn, CCGOCmode)
6771    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6772   "sub{w}\t{%2, %0|%0, %2}"
6773   [(set_attr "type" "alu")
6774    (set_attr "mode" "HI")])
6775
6776 (define_insn "*subhi_3"
6777   [(set (reg FLAGS_REG)
6778         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6779                  (match_operand:HI 2 "general_operand" "ri,rm")))
6780    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6781         (minus:HI (match_dup 1) (match_dup 2)))]
6782   "ix86_match_ccmode (insn, CCmode)
6783    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6784   "sub{w}\t{%2, %0|%0, %2}"
6785   [(set_attr "type" "alu")
6786    (set_attr "mode" "HI")])
6787
6788 (define_expand "subqi3"
6789   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6790                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6791                              (match_operand:QI 2 "general_operand" "")))
6792               (clobber (reg:CC FLAGS_REG))])]
6793   "TARGET_QIMODE_MATH"
6794   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6795
6796 (define_insn "*subqi_1"
6797   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6798         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6799                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6800    (clobber (reg:CC FLAGS_REG))]
6801   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6802   "sub{b}\t{%2, %0|%0, %2}"
6803   [(set_attr "type" "alu")
6804    (set_attr "mode" "QI")])
6805
6806 (define_insn "*subqi_1_slp"
6807   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6808         (minus:QI (match_dup 0)
6809                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6810    (clobber (reg:CC FLAGS_REG))]
6811   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6812    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6813   "sub{b}\t{%1, %0|%0, %1}"
6814   [(set_attr "type" "alu1")
6815    (set_attr "mode" "QI")])
6816
6817 (define_insn "*subqi_2"
6818   [(set (reg FLAGS_REG)
6819         (compare
6820           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6821                     (match_operand:QI 2 "general_operand" "qi,qm"))
6822           (const_int 0)))
6823    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6824         (minus:HI (match_dup 1) (match_dup 2)))]
6825   "ix86_match_ccmode (insn, CCGOCmode)
6826    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6827   "sub{b}\t{%2, %0|%0, %2}"
6828   [(set_attr "type" "alu")
6829    (set_attr "mode" "QI")])
6830
6831 (define_insn "*subqi_3"
6832   [(set (reg FLAGS_REG)
6833         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6834                  (match_operand:QI 2 "general_operand" "qi,qm")))
6835    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6836         (minus:HI (match_dup 1) (match_dup 2)))]
6837   "ix86_match_ccmode (insn, CCmode)
6838    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6839   "sub{b}\t{%2, %0|%0, %2}"
6840   [(set_attr "type" "alu")
6841    (set_attr "mode" "QI")])
6842
6843 ;; The patterns that match these are at the end of this file.
6844
6845 (define_expand "subxf3"
6846   [(set (match_operand:XF 0 "register_operand" "")
6847         (minus:XF (match_operand:XF 1 "register_operand" "")
6848                   (match_operand:XF 2 "register_operand" "")))]
6849   "TARGET_80387"
6850   "")
6851
6852 (define_expand "subdf3"
6853   [(set (match_operand:DF 0 "register_operand" "")
6854         (minus:DF (match_operand:DF 1 "register_operand" "")
6855                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6856   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6857   "")
6858
6859 (define_expand "subsf3"
6860   [(set (match_operand:SF 0 "register_operand" "")
6861         (minus:SF (match_operand:SF 1 "register_operand" "")
6862                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6863   "TARGET_80387 || TARGET_SSE_MATH"
6864   "")
6865 \f
6866 ;; Multiply instructions
6867
6868 (define_expand "muldi3"
6869   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6870                    (mult:DI (match_operand:DI 1 "register_operand" "")
6871                             (match_operand:DI 2 "x86_64_general_operand" "")))
6872               (clobber (reg:CC FLAGS_REG))])]
6873   "TARGET_64BIT"
6874   "")
6875
6876 ;; On AMDFAM10 
6877 ;; IMUL reg64, reg64, imm8      Direct
6878 ;; IMUL reg64, mem64, imm8      VectorPath
6879 ;; IMUL reg64, reg64, imm32     Direct
6880 ;; IMUL reg64, mem64, imm32     VectorPath 
6881 ;; IMUL reg64, reg64            Direct
6882 ;; IMUL reg64, mem64            Direct
6883
6884 (define_insn "*muldi3_1_rex64"
6885   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6886         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6887                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6888    (clobber (reg:CC FLAGS_REG))]
6889   "TARGET_64BIT
6890    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6891   "@
6892    imul{q}\t{%2, %1, %0|%0, %1, %2}
6893    imul{q}\t{%2, %1, %0|%0, %1, %2}
6894    imul{q}\t{%2, %0|%0, %2}"
6895   [(set_attr "type" "imul")
6896    (set_attr "prefix_0f" "0,0,1")
6897    (set (attr "athlon_decode")
6898         (cond [(eq_attr "cpu" "athlon")
6899                   (const_string "vector")
6900                (eq_attr "alternative" "1")
6901                   (const_string "vector")
6902                (and (eq_attr "alternative" "2")
6903                     (match_operand 1 "memory_operand" ""))
6904                   (const_string "vector")]
6905               (const_string "direct")))
6906    (set (attr "amdfam10_decode")
6907         (cond [(and (eq_attr "alternative" "0,1")
6908                     (match_operand 1 "memory_operand" ""))
6909                   (const_string "vector")]
6910               (const_string "direct")))       
6911    (set_attr "mode" "DI")])
6912
6913 (define_expand "mulsi3"
6914   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6915                    (mult:SI (match_operand:SI 1 "register_operand" "")
6916                             (match_operand:SI 2 "general_operand" "")))
6917               (clobber (reg:CC FLAGS_REG))])]
6918   ""
6919   "")
6920
6921 ;; On AMDFAM10 
6922 ;; IMUL reg32, reg32, imm8      Direct
6923 ;; IMUL reg32, mem32, imm8      VectorPath
6924 ;; IMUL reg32, reg32, imm32     Direct
6925 ;; IMUL reg32, mem32, imm32     VectorPath
6926 ;; IMUL reg32, reg32            Direct
6927 ;; IMUL reg32, mem32            Direct
6928
6929 (define_insn "*mulsi3_1"
6930   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6931         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6932                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6933    (clobber (reg:CC FLAGS_REG))]
6934   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6935   "@
6936    imul{l}\t{%2, %1, %0|%0, %1, %2}
6937    imul{l}\t{%2, %1, %0|%0, %1, %2}
6938    imul{l}\t{%2, %0|%0, %2}"
6939   [(set_attr "type" "imul")
6940    (set_attr "prefix_0f" "0,0,1")
6941    (set (attr "athlon_decode")
6942         (cond [(eq_attr "cpu" "athlon")
6943                   (const_string "vector")
6944                (eq_attr "alternative" "1")
6945                   (const_string "vector")
6946                (and (eq_attr "alternative" "2")
6947                     (match_operand 1 "memory_operand" ""))
6948                   (const_string "vector")]
6949               (const_string "direct")))
6950    (set (attr "amdfam10_decode")
6951         (cond [(and (eq_attr "alternative" "0,1")
6952                     (match_operand 1 "memory_operand" ""))
6953                   (const_string "vector")]
6954               (const_string "direct")))       
6955    (set_attr "mode" "SI")])
6956
6957 (define_insn "*mulsi3_1_zext"
6958   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6959         (zero_extend:DI
6960           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6961                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6962    (clobber (reg:CC FLAGS_REG))]
6963   "TARGET_64BIT
6964    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6965   "@
6966    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6967    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6968    imul{l}\t{%2, %k0|%k0, %2}"
6969   [(set_attr "type" "imul")
6970    (set_attr "prefix_0f" "0,0,1")
6971    (set (attr "athlon_decode")
6972         (cond [(eq_attr "cpu" "athlon")
6973                   (const_string "vector")
6974                (eq_attr "alternative" "1")
6975                   (const_string "vector")
6976                (and (eq_attr "alternative" "2")
6977                     (match_operand 1 "memory_operand" ""))
6978                   (const_string "vector")]
6979               (const_string "direct")))
6980    (set (attr "amdfam10_decode")
6981         (cond [(and (eq_attr "alternative" "0,1")
6982                     (match_operand 1 "memory_operand" ""))
6983                   (const_string "vector")]
6984               (const_string "direct")))       
6985    (set_attr "mode" "SI")])
6986
6987 (define_expand "mulhi3"
6988   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6989                    (mult:HI (match_operand:HI 1 "register_operand" "")
6990                             (match_operand:HI 2 "general_operand" "")))
6991               (clobber (reg:CC FLAGS_REG))])]
6992   "TARGET_HIMODE_MATH"
6993   "")
6994
6995 ;; On AMDFAM10
6996 ;; IMUL reg16, reg16, imm8      VectorPath
6997 ;; IMUL reg16, mem16, imm8      VectorPath
6998 ;; IMUL reg16, reg16, imm16     VectorPath
6999 ;; IMUL reg16, mem16, imm16     VectorPath
7000 ;; IMUL reg16, reg16            Direct
7001 ;; IMUL reg16, mem16            Direct
7002 (define_insn "*mulhi3_1"
7003   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7004         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7005                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7006    (clobber (reg:CC FLAGS_REG))]
7007   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7008   "@
7009    imul{w}\t{%2, %1, %0|%0, %1, %2}
7010    imul{w}\t{%2, %1, %0|%0, %1, %2}
7011    imul{w}\t{%2, %0|%0, %2}"
7012   [(set_attr "type" "imul")
7013    (set_attr "prefix_0f" "0,0,1")
7014    (set (attr "athlon_decode")
7015         (cond [(eq_attr "cpu" "athlon")
7016                   (const_string "vector")
7017                (eq_attr "alternative" "1,2")
7018                   (const_string "vector")]
7019               (const_string "direct")))
7020    (set (attr "amdfam10_decode")
7021         (cond [(eq_attr "alternative" "0,1")
7022                   (const_string "vector")]
7023               (const_string "direct")))
7024    (set_attr "mode" "HI")])
7025
7026 (define_expand "mulqi3"
7027   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7028                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7029                             (match_operand:QI 2 "register_operand" "")))
7030               (clobber (reg:CC FLAGS_REG))])]
7031   "TARGET_QIMODE_MATH"
7032   "")
7033
7034 ;;On AMDFAM10
7035 ;; MUL reg8     Direct
7036 ;; MUL mem8     Direct
7037
7038 (define_insn "*mulqi3_1"
7039   [(set (match_operand:QI 0 "register_operand" "=a")
7040         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7041                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7042    (clobber (reg:CC FLAGS_REG))]
7043   "TARGET_QIMODE_MATH
7044    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7045   "mul{b}\t%2"
7046   [(set_attr "type" "imul")
7047    (set_attr "length_immediate" "0")
7048    (set (attr "athlon_decode")
7049      (if_then_else (eq_attr "cpu" "athlon")
7050         (const_string "vector")
7051         (const_string "direct")))
7052    (set_attr "amdfam10_decode" "direct")        
7053    (set_attr "mode" "QI")])
7054
7055 (define_expand "umulqihi3"
7056   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7057                    (mult:HI (zero_extend:HI
7058                               (match_operand:QI 1 "nonimmediate_operand" ""))
7059                             (zero_extend:HI
7060                               (match_operand:QI 2 "register_operand" ""))))
7061               (clobber (reg:CC FLAGS_REG))])]
7062   "TARGET_QIMODE_MATH"
7063   "")
7064
7065 (define_insn "*umulqihi3_1"
7066   [(set (match_operand:HI 0 "register_operand" "=a")
7067         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7068                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7069    (clobber (reg:CC FLAGS_REG))]
7070   "TARGET_QIMODE_MATH
7071    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7072   "mul{b}\t%2"
7073   [(set_attr "type" "imul")
7074    (set_attr "length_immediate" "0")
7075    (set (attr "athlon_decode")
7076      (if_then_else (eq_attr "cpu" "athlon")
7077         (const_string "vector")
7078         (const_string "direct")))
7079    (set_attr "amdfam10_decode" "direct")        
7080    (set_attr "mode" "QI")])
7081
7082 (define_expand "mulqihi3"
7083   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7084                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7085                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7086               (clobber (reg:CC FLAGS_REG))])]
7087   "TARGET_QIMODE_MATH"
7088   "")
7089
7090 (define_insn "*mulqihi3_insn"
7091   [(set (match_operand:HI 0 "register_operand" "=a")
7092         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7093                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7094    (clobber (reg:CC FLAGS_REG))]
7095   "TARGET_QIMODE_MATH
7096    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7097   "imul{b}\t%2"
7098   [(set_attr "type" "imul")
7099    (set_attr "length_immediate" "0")
7100    (set (attr "athlon_decode")
7101      (if_then_else (eq_attr "cpu" "athlon")
7102         (const_string "vector")
7103         (const_string "direct")))
7104    (set_attr "amdfam10_decode" "direct")        
7105    (set_attr "mode" "QI")])
7106
7107 (define_expand "umulditi3"
7108   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7109                    (mult:TI (zero_extend:TI
7110                               (match_operand:DI 1 "nonimmediate_operand" ""))
7111                             (zero_extend:TI
7112                               (match_operand:DI 2 "register_operand" ""))))
7113               (clobber (reg:CC FLAGS_REG))])]
7114   "TARGET_64BIT"
7115   "")
7116
7117 (define_insn "*umulditi3_insn"
7118   [(set (match_operand:TI 0 "register_operand" "=A")
7119         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7120                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7121    (clobber (reg:CC FLAGS_REG))]
7122   "TARGET_64BIT
7123    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7124   "mul{q}\t%2"
7125   [(set_attr "type" "imul")
7126    (set_attr "length_immediate" "0")
7127    (set (attr "athlon_decode")
7128      (if_then_else (eq_attr "cpu" "athlon")
7129         (const_string "vector")
7130         (const_string "double")))
7131    (set_attr "amdfam10_decode" "double")        
7132    (set_attr "mode" "DI")])
7133
7134 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7135 (define_expand "umulsidi3"
7136   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7137                    (mult:DI (zero_extend:DI
7138                               (match_operand:SI 1 "nonimmediate_operand" ""))
7139                             (zero_extend:DI
7140                               (match_operand:SI 2 "register_operand" ""))))
7141               (clobber (reg:CC FLAGS_REG))])]
7142   "!TARGET_64BIT"
7143   "")
7144
7145 (define_insn "*umulsidi3_insn"
7146   [(set (match_operand:DI 0 "register_operand" "=A")
7147         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7148                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7149    (clobber (reg:CC FLAGS_REG))]
7150   "!TARGET_64BIT
7151    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7152   "mul{l}\t%2"
7153   [(set_attr "type" "imul")
7154    (set_attr "length_immediate" "0")
7155    (set (attr "athlon_decode")
7156      (if_then_else (eq_attr "cpu" "athlon")
7157         (const_string "vector")
7158         (const_string "double")))
7159    (set_attr "amdfam10_decode" "double")        
7160    (set_attr "mode" "SI")])
7161
7162 (define_expand "mulditi3"
7163   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7164                    (mult:TI (sign_extend:TI
7165                               (match_operand:DI 1 "nonimmediate_operand" ""))
7166                             (sign_extend:TI
7167                               (match_operand:DI 2 "register_operand" ""))))
7168               (clobber (reg:CC FLAGS_REG))])]
7169   "TARGET_64BIT"
7170   "")
7171
7172 (define_insn "*mulditi3_insn"
7173   [(set (match_operand:TI 0 "register_operand" "=A")
7174         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7175                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7176    (clobber (reg:CC FLAGS_REG))]
7177   "TARGET_64BIT
7178    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7179   "imul{q}\t%2"
7180   [(set_attr "type" "imul")
7181    (set_attr "length_immediate" "0")
7182    (set (attr "athlon_decode")
7183      (if_then_else (eq_attr "cpu" "athlon")
7184         (const_string "vector")
7185         (const_string "double")))
7186    (set_attr "amdfam10_decode" "double")
7187    (set_attr "mode" "DI")])
7188
7189 (define_expand "mulsidi3"
7190   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7191                    (mult:DI (sign_extend:DI
7192                               (match_operand:SI 1 "nonimmediate_operand" ""))
7193                             (sign_extend:DI
7194                               (match_operand:SI 2 "register_operand" ""))))
7195               (clobber (reg:CC FLAGS_REG))])]
7196   "!TARGET_64BIT"
7197   "")
7198
7199 (define_insn "*mulsidi3_insn"
7200   [(set (match_operand:DI 0 "register_operand" "=A")
7201         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7202                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7203    (clobber (reg:CC FLAGS_REG))]
7204   "!TARGET_64BIT
7205    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7206   "imul{l}\t%2"
7207   [(set_attr "type" "imul")
7208    (set_attr "length_immediate" "0")
7209    (set (attr "athlon_decode")
7210      (if_then_else (eq_attr "cpu" "athlon")
7211         (const_string "vector")
7212         (const_string "double")))
7213    (set_attr "amdfam10_decode" "double")        
7214    (set_attr "mode" "SI")])
7215
7216 (define_expand "umuldi3_highpart"
7217   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7218                    (truncate:DI
7219                      (lshiftrt:TI
7220                        (mult:TI (zero_extend:TI
7221                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7222                                 (zero_extend:TI
7223                                   (match_operand:DI 2 "register_operand" "")))
7224                        (const_int 64))))
7225               (clobber (match_scratch:DI 3 ""))
7226               (clobber (reg:CC FLAGS_REG))])]
7227   "TARGET_64BIT"
7228   "")
7229
7230 (define_insn "*umuldi3_highpart_rex64"
7231   [(set (match_operand:DI 0 "register_operand" "=d")
7232         (truncate:DI
7233           (lshiftrt:TI
7234             (mult:TI (zero_extend:TI
7235                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7236                      (zero_extend:TI
7237                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7238             (const_int 64))))
7239    (clobber (match_scratch:DI 3 "=1"))
7240    (clobber (reg:CC FLAGS_REG))]
7241   "TARGET_64BIT
7242    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7243   "mul{q}\t%2"
7244   [(set_attr "type" "imul")
7245    (set_attr "length_immediate" "0")
7246    (set (attr "athlon_decode")
7247      (if_then_else (eq_attr "cpu" "athlon")
7248         (const_string "vector")
7249         (const_string "double")))
7250    (set_attr "amdfam10_decode" "double")        
7251    (set_attr "mode" "DI")])
7252
7253 (define_expand "umulsi3_highpart"
7254   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7255                    (truncate:SI
7256                      (lshiftrt:DI
7257                        (mult:DI (zero_extend:DI
7258                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7259                                 (zero_extend:DI
7260                                   (match_operand:SI 2 "register_operand" "")))
7261                        (const_int 32))))
7262               (clobber (match_scratch:SI 3 ""))
7263               (clobber (reg:CC FLAGS_REG))])]
7264   ""
7265   "")
7266
7267 (define_insn "*umulsi3_highpart_insn"
7268   [(set (match_operand:SI 0 "register_operand" "=d")
7269         (truncate:SI
7270           (lshiftrt:DI
7271             (mult:DI (zero_extend:DI
7272                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7273                      (zero_extend:DI
7274                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7275             (const_int 32))))
7276    (clobber (match_scratch:SI 3 "=1"))
7277    (clobber (reg:CC FLAGS_REG))]
7278   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7279   "mul{l}\t%2"
7280   [(set_attr "type" "imul")
7281    (set_attr "length_immediate" "0")
7282    (set (attr "athlon_decode")
7283      (if_then_else (eq_attr "cpu" "athlon")
7284         (const_string "vector")
7285         (const_string "double")))
7286    (set_attr "amdfam10_decode" "double")
7287    (set_attr "mode" "SI")])
7288
7289 (define_insn "*umulsi3_highpart_zext"
7290   [(set (match_operand:DI 0 "register_operand" "=d")
7291         (zero_extend:DI (truncate:SI
7292           (lshiftrt:DI
7293             (mult:DI (zero_extend:DI
7294                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7295                      (zero_extend:DI
7296                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7297             (const_int 32)))))
7298    (clobber (match_scratch:SI 3 "=1"))
7299    (clobber (reg:CC FLAGS_REG))]
7300   "TARGET_64BIT
7301    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7302   "mul{l}\t%2"
7303   [(set_attr "type" "imul")
7304    (set_attr "length_immediate" "0")
7305    (set (attr "athlon_decode")
7306      (if_then_else (eq_attr "cpu" "athlon")
7307         (const_string "vector")
7308         (const_string "double")))
7309    (set_attr "amdfam10_decode" "double")
7310    (set_attr "mode" "SI")])
7311
7312 (define_expand "smuldi3_highpart"
7313   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7314                    (truncate:DI
7315                      (lshiftrt:TI
7316                        (mult:TI (sign_extend:TI
7317                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7318                                 (sign_extend:TI
7319                                   (match_operand:DI 2 "register_operand" "")))
7320                        (const_int 64))))
7321               (clobber (match_scratch:DI 3 ""))
7322               (clobber (reg:CC FLAGS_REG))])]
7323   "TARGET_64BIT"
7324   "")
7325
7326 (define_insn "*smuldi3_highpart_rex64"
7327   [(set (match_operand:DI 0 "register_operand" "=d")
7328         (truncate:DI
7329           (lshiftrt:TI
7330             (mult:TI (sign_extend:TI
7331                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7332                      (sign_extend:TI
7333                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7334             (const_int 64))))
7335    (clobber (match_scratch:DI 3 "=1"))
7336    (clobber (reg:CC FLAGS_REG))]
7337   "TARGET_64BIT
7338    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7339   "imul{q}\t%2"
7340   [(set_attr "type" "imul")
7341    (set (attr "athlon_decode")
7342      (if_then_else (eq_attr "cpu" "athlon")
7343         (const_string "vector")
7344         (const_string "double")))
7345    (set_attr "amdfam10_decode" "double")
7346    (set_attr "mode" "DI")])
7347
7348 (define_expand "smulsi3_highpart"
7349   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7350                    (truncate:SI
7351                      (lshiftrt:DI
7352                        (mult:DI (sign_extend:DI
7353                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7354                                 (sign_extend:DI
7355                                   (match_operand:SI 2 "register_operand" "")))
7356                        (const_int 32))))
7357               (clobber (match_scratch:SI 3 ""))
7358               (clobber (reg:CC FLAGS_REG))])]
7359   ""
7360   "")
7361
7362 (define_insn "*smulsi3_highpart_insn"
7363   [(set (match_operand:SI 0 "register_operand" "=d")
7364         (truncate:SI
7365           (lshiftrt:DI
7366             (mult:DI (sign_extend:DI
7367                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7368                      (sign_extend:DI
7369                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7370             (const_int 32))))
7371    (clobber (match_scratch:SI 3 "=1"))
7372    (clobber (reg:CC FLAGS_REG))]
7373   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7374   "imul{l}\t%2"
7375   [(set_attr "type" "imul")
7376    (set (attr "athlon_decode")
7377      (if_then_else (eq_attr "cpu" "athlon")
7378         (const_string "vector")
7379         (const_string "double")))
7380    (set_attr "amdfam10_decode" "double")
7381    (set_attr "mode" "SI")])
7382
7383 (define_insn "*smulsi3_highpart_zext"
7384   [(set (match_operand:DI 0 "register_operand" "=d")
7385         (zero_extend:DI (truncate:SI
7386           (lshiftrt:DI
7387             (mult:DI (sign_extend:DI
7388                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7389                      (sign_extend:DI
7390                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7391             (const_int 32)))))
7392    (clobber (match_scratch:SI 3 "=1"))
7393    (clobber (reg:CC FLAGS_REG))]
7394   "TARGET_64BIT
7395    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7396   "imul{l}\t%2"
7397   [(set_attr "type" "imul")
7398    (set (attr "athlon_decode")
7399      (if_then_else (eq_attr "cpu" "athlon")
7400         (const_string "vector")
7401         (const_string "double")))
7402    (set_attr "amdfam10_decode" "double")
7403    (set_attr "mode" "SI")])
7404
7405 ;; The patterns that match these are at the end of this file.
7406
7407 (define_expand "mulxf3"
7408   [(set (match_operand:XF 0 "register_operand" "")
7409         (mult:XF (match_operand:XF 1 "register_operand" "")
7410                  (match_operand:XF 2 "register_operand" "")))]
7411   "TARGET_80387"
7412   "")
7413
7414 (define_expand "muldf3"
7415   [(set (match_operand:DF 0 "register_operand" "")
7416         (mult:DF (match_operand:DF 1 "register_operand" "")
7417                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7418   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7419   "")
7420
7421 (define_expand "mulsf3"
7422   [(set (match_operand:SF 0 "register_operand" "")
7423         (mult:SF (match_operand:SF 1 "register_operand" "")
7424                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7425   "TARGET_80387 || TARGET_SSE_MATH"
7426   "")
7427 \f
7428 ;; Divide instructions
7429
7430 (define_insn "divqi3"
7431   [(set (match_operand:QI 0 "register_operand" "=a")
7432         (div:QI (match_operand:HI 1 "register_operand" "0")
7433                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7434    (clobber (reg:CC FLAGS_REG))]
7435   "TARGET_QIMODE_MATH"
7436   "idiv{b}\t%2"
7437   [(set_attr "type" "idiv")
7438    (set_attr "mode" "QI")])
7439
7440 (define_insn "udivqi3"
7441   [(set (match_operand:QI 0 "register_operand" "=a")
7442         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7443                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7444    (clobber (reg:CC FLAGS_REG))]
7445   "TARGET_QIMODE_MATH"
7446   "div{b}\t%2"
7447   [(set_attr "type" "idiv")
7448    (set_attr "mode" "QI")])
7449
7450 ;; The patterns that match these are at the end of this file.
7451
7452 (define_expand "divxf3"
7453   [(set (match_operand:XF 0 "register_operand" "")
7454         (div:XF (match_operand:XF 1 "register_operand" "")
7455                 (match_operand:XF 2 "register_operand" "")))]
7456   "TARGET_80387"
7457   "")
7458
7459 (define_expand "divdf3"
7460   [(set (match_operand:DF 0 "register_operand" "")
7461         (div:DF (match_operand:DF 1 "register_operand" "")
7462                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7463    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7464    "")
7465
7466 (define_expand "divsf3"
7467   [(set (match_operand:SF 0 "register_operand" "")
7468         (div:SF (match_operand:SF 1 "register_operand" "")
7469                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7470   "TARGET_80387 || TARGET_SSE_MATH"
7471   "")
7472 \f
7473 ;; Remainder instructions.
7474
7475 (define_expand "divmoddi4"
7476   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7477                    (div:DI (match_operand:DI 1 "register_operand" "")
7478                            (match_operand:DI 2 "nonimmediate_operand" "")))
7479               (set (match_operand:DI 3 "register_operand" "")
7480                    (mod:DI (match_dup 1) (match_dup 2)))
7481               (clobber (reg:CC FLAGS_REG))])]
7482   "TARGET_64BIT"
7483   "")
7484
7485 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7486 ;; Penalize eax case slightly because it results in worse scheduling
7487 ;; of code.
7488 (define_insn "*divmoddi4_nocltd_rex64"
7489   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7490         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7491                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7492    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7493         (mod:DI (match_dup 2) (match_dup 3)))
7494    (clobber (reg:CC FLAGS_REG))]
7495   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7496   "#"
7497   [(set_attr "type" "multi")])
7498
7499 (define_insn "*divmoddi4_cltd_rex64"
7500   [(set (match_operand:DI 0 "register_operand" "=a")
7501         (div:DI (match_operand:DI 2 "register_operand" "a")
7502                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7503    (set (match_operand:DI 1 "register_operand" "=&d")
7504         (mod:DI (match_dup 2) (match_dup 3)))
7505    (clobber (reg:CC FLAGS_REG))]
7506   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7507   "#"
7508   [(set_attr "type" "multi")])
7509
7510 (define_insn "*divmoddi_noext_rex64"
7511   [(set (match_operand:DI 0 "register_operand" "=a")
7512         (div:DI (match_operand:DI 1 "register_operand" "0")
7513                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7514    (set (match_operand:DI 3 "register_operand" "=d")
7515         (mod:DI (match_dup 1) (match_dup 2)))
7516    (use (match_operand:DI 4 "register_operand" "3"))
7517    (clobber (reg:CC FLAGS_REG))]
7518   "TARGET_64BIT"
7519   "idiv{q}\t%2"
7520   [(set_attr "type" "idiv")
7521    (set_attr "mode" "DI")])
7522
7523 (define_split
7524   [(set (match_operand:DI 0 "register_operand" "")
7525         (div:DI (match_operand:DI 1 "register_operand" "")
7526                 (match_operand:DI 2 "nonimmediate_operand" "")))
7527    (set (match_operand:DI 3 "register_operand" "")
7528         (mod:DI (match_dup 1) (match_dup 2)))
7529    (clobber (reg:CC FLAGS_REG))]
7530   "TARGET_64BIT && reload_completed"
7531   [(parallel [(set (match_dup 3)
7532                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7533               (clobber (reg:CC FLAGS_REG))])
7534    (parallel [(set (match_dup 0)
7535                    (div:DI (reg:DI 0) (match_dup 2)))
7536               (set (match_dup 3)
7537                    (mod:DI (reg:DI 0) (match_dup 2)))
7538               (use (match_dup 3))
7539               (clobber (reg:CC FLAGS_REG))])]
7540 {
7541   /* Avoid use of cltd in favor of a mov+shift.  */
7542   if (!TARGET_USE_CLTD && !optimize_size)
7543     {
7544       if (true_regnum (operands[1]))
7545         emit_move_insn (operands[0], operands[1]);
7546       else
7547         emit_move_insn (operands[3], operands[1]);
7548       operands[4] = operands[3];
7549     }
7550   else
7551     {
7552       gcc_assert (!true_regnum (operands[1]));
7553       operands[4] = operands[1];
7554     }
7555 })
7556
7557
7558 (define_expand "divmodsi4"
7559   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7560                    (div:SI (match_operand:SI 1 "register_operand" "")
7561                            (match_operand:SI 2 "nonimmediate_operand" "")))
7562               (set (match_operand:SI 3 "register_operand" "")
7563                    (mod:SI (match_dup 1) (match_dup 2)))
7564               (clobber (reg:CC FLAGS_REG))])]
7565   ""
7566   "")
7567
7568 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7569 ;; Penalize eax case slightly because it results in worse scheduling
7570 ;; of code.
7571 (define_insn "*divmodsi4_nocltd"
7572   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7573         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7574                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7575    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7576         (mod:SI (match_dup 2) (match_dup 3)))
7577    (clobber (reg:CC FLAGS_REG))]
7578   "!optimize_size && !TARGET_USE_CLTD"
7579   "#"
7580   [(set_attr "type" "multi")])
7581
7582 (define_insn "*divmodsi4_cltd"
7583   [(set (match_operand:SI 0 "register_operand" "=a")
7584         (div:SI (match_operand:SI 2 "register_operand" "a")
7585                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7586    (set (match_operand:SI 1 "register_operand" "=&d")
7587         (mod:SI (match_dup 2) (match_dup 3)))
7588    (clobber (reg:CC FLAGS_REG))]
7589   "optimize_size || TARGET_USE_CLTD"
7590   "#"
7591   [(set_attr "type" "multi")])
7592
7593 (define_insn "*divmodsi_noext"
7594   [(set (match_operand:SI 0 "register_operand" "=a")
7595         (div:SI (match_operand:SI 1 "register_operand" "0")
7596                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7597    (set (match_operand:SI 3 "register_operand" "=d")
7598         (mod:SI (match_dup 1) (match_dup 2)))
7599    (use (match_operand:SI 4 "register_operand" "3"))
7600    (clobber (reg:CC FLAGS_REG))]
7601   ""
7602   "idiv{l}\t%2"
7603   [(set_attr "type" "idiv")
7604    (set_attr "mode" "SI")])
7605
7606 (define_split
7607   [(set (match_operand:SI 0 "register_operand" "")
7608         (div:SI (match_operand:SI 1 "register_operand" "")
7609                 (match_operand:SI 2 "nonimmediate_operand" "")))
7610    (set (match_operand:SI 3 "register_operand" "")
7611         (mod:SI (match_dup 1) (match_dup 2)))
7612    (clobber (reg:CC FLAGS_REG))]
7613   "reload_completed"
7614   [(parallel [(set (match_dup 3)
7615                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7616               (clobber (reg:CC FLAGS_REG))])
7617    (parallel [(set (match_dup 0)
7618                    (div:SI (reg:SI 0) (match_dup 2)))
7619               (set (match_dup 3)
7620                    (mod:SI (reg:SI 0) (match_dup 2)))
7621               (use (match_dup 3))
7622               (clobber (reg:CC FLAGS_REG))])]
7623 {
7624   /* Avoid use of cltd in favor of a mov+shift.  */
7625   if (!TARGET_USE_CLTD && !optimize_size)
7626     {
7627       if (true_regnum (operands[1]))
7628         emit_move_insn (operands[0], operands[1]);
7629       else
7630         emit_move_insn (operands[3], operands[1]);
7631       operands[4] = operands[3];
7632     }
7633   else
7634     {
7635       gcc_assert (!true_regnum (operands[1]));
7636       operands[4] = operands[1];
7637     }
7638 })
7639 ;; %%% Split me.
7640 (define_insn "divmodhi4"
7641   [(set (match_operand:HI 0 "register_operand" "=a")
7642         (div:HI (match_operand:HI 1 "register_operand" "0")
7643                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7644    (set (match_operand:HI 3 "register_operand" "=&d")
7645         (mod:HI (match_dup 1) (match_dup 2)))
7646    (clobber (reg:CC FLAGS_REG))]
7647   "TARGET_HIMODE_MATH"
7648   "cwtd\;idiv{w}\t%2"
7649   [(set_attr "type" "multi")
7650    (set_attr "length_immediate" "0")
7651    (set_attr "mode" "SI")])
7652
7653 (define_insn "udivmoddi4"
7654   [(set (match_operand:DI 0 "register_operand" "=a")
7655         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7656                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7657    (set (match_operand:DI 3 "register_operand" "=&d")
7658         (umod:DI (match_dup 1) (match_dup 2)))
7659    (clobber (reg:CC FLAGS_REG))]
7660   "TARGET_64BIT"
7661   "xor{q}\t%3, %3\;div{q}\t%2"
7662   [(set_attr "type" "multi")
7663    (set_attr "length_immediate" "0")
7664    (set_attr "mode" "DI")])
7665
7666 (define_insn "*udivmoddi4_noext"
7667   [(set (match_operand:DI 0 "register_operand" "=a")
7668         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7669                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7670    (set (match_operand:DI 3 "register_operand" "=d")
7671         (umod:DI (match_dup 1) (match_dup 2)))
7672    (use (match_dup 3))
7673    (clobber (reg:CC FLAGS_REG))]
7674   "TARGET_64BIT"
7675   "div{q}\t%2"
7676   [(set_attr "type" "idiv")
7677    (set_attr "mode" "DI")])
7678
7679 (define_split
7680   [(set (match_operand:DI 0 "register_operand" "")
7681         (udiv:DI (match_operand:DI 1 "register_operand" "")
7682                  (match_operand:DI 2 "nonimmediate_operand" "")))
7683    (set (match_operand:DI 3 "register_operand" "")
7684         (umod:DI (match_dup 1) (match_dup 2)))
7685    (clobber (reg:CC FLAGS_REG))]
7686   "TARGET_64BIT && reload_completed"
7687   [(set (match_dup 3) (const_int 0))
7688    (parallel [(set (match_dup 0)
7689                    (udiv:DI (match_dup 1) (match_dup 2)))
7690               (set (match_dup 3)
7691                    (umod:DI (match_dup 1) (match_dup 2)))
7692               (use (match_dup 3))
7693               (clobber (reg:CC FLAGS_REG))])]
7694   "")
7695
7696 (define_insn "udivmodsi4"
7697   [(set (match_operand:SI 0 "register_operand" "=a")
7698         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7699                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7700    (set (match_operand:SI 3 "register_operand" "=&d")
7701         (umod:SI (match_dup 1) (match_dup 2)))
7702    (clobber (reg:CC FLAGS_REG))]
7703   ""
7704   "xor{l}\t%3, %3\;div{l}\t%2"
7705   [(set_attr "type" "multi")
7706    (set_attr "length_immediate" "0")
7707    (set_attr "mode" "SI")])
7708
7709 (define_insn "*udivmodsi4_noext"
7710   [(set (match_operand:SI 0 "register_operand" "=a")
7711         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7712                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7713    (set (match_operand:SI 3 "register_operand" "=d")
7714         (umod:SI (match_dup 1) (match_dup 2)))
7715    (use (match_dup 3))
7716    (clobber (reg:CC FLAGS_REG))]
7717   ""
7718   "div{l}\t%2"
7719   [(set_attr "type" "idiv")
7720    (set_attr "mode" "SI")])
7721
7722 (define_split
7723   [(set (match_operand:SI 0 "register_operand" "")
7724         (udiv:SI (match_operand:SI 1 "register_operand" "")
7725                  (match_operand:SI 2 "nonimmediate_operand" "")))
7726    (set (match_operand:SI 3 "register_operand" "")
7727         (umod:SI (match_dup 1) (match_dup 2)))
7728    (clobber (reg:CC FLAGS_REG))]
7729   "reload_completed"
7730   [(set (match_dup 3) (const_int 0))
7731    (parallel [(set (match_dup 0)
7732                    (udiv:SI (match_dup 1) (match_dup 2)))
7733               (set (match_dup 3)
7734                    (umod:SI (match_dup 1) (match_dup 2)))
7735               (use (match_dup 3))
7736               (clobber (reg:CC FLAGS_REG))])]
7737   "")
7738
7739 (define_expand "udivmodhi4"
7740   [(set (match_dup 4) (const_int 0))
7741    (parallel [(set (match_operand:HI 0 "register_operand" "")
7742                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7743                             (match_operand:HI 2 "nonimmediate_operand" "")))
7744               (set (match_operand:HI 3 "register_operand" "")
7745                    (umod:HI (match_dup 1) (match_dup 2)))
7746               (use (match_dup 4))
7747               (clobber (reg:CC FLAGS_REG))])]
7748   "TARGET_HIMODE_MATH"
7749   "operands[4] = gen_reg_rtx (HImode);")
7750
7751 (define_insn "*udivmodhi_noext"
7752   [(set (match_operand:HI 0 "register_operand" "=a")
7753         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7754                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7755    (set (match_operand:HI 3 "register_operand" "=d")
7756         (umod:HI (match_dup 1) (match_dup 2)))
7757    (use (match_operand:HI 4 "register_operand" "3"))
7758    (clobber (reg:CC FLAGS_REG))]
7759   ""
7760   "div{w}\t%2"
7761   [(set_attr "type" "idiv")
7762    (set_attr "mode" "HI")])
7763
7764 ;; We cannot use div/idiv for double division, because it causes
7765 ;; "division by zero" on the overflow and that's not what we expect
7766 ;; from truncate.  Because true (non truncating) double division is
7767 ;; never generated, we can't create this insn anyway.
7768 ;
7769 ;(define_insn ""
7770 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7771 ;       (truncate:SI
7772 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7773 ;                  (zero_extend:DI
7774 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7775 ;   (set (match_operand:SI 3 "register_operand" "=d")
7776 ;       (truncate:SI
7777 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7778 ;   (clobber (reg:CC FLAGS_REG))]
7779 ;  ""
7780 ;  "div{l}\t{%2, %0|%0, %2}"
7781 ;  [(set_attr "type" "idiv")])
7782 \f
7783 ;;- Logical AND instructions
7784
7785 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7786 ;; Note that this excludes ah.
7787
7788 (define_insn "*testdi_1_rex64"
7789   [(set (reg FLAGS_REG)
7790         (compare
7791           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7792                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7793           (const_int 0)))]
7794   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7795    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7796   "@
7797    test{l}\t{%k1, %k0|%k0, %k1}
7798    test{l}\t{%k1, %k0|%k0, %k1}
7799    test{q}\t{%1, %0|%0, %1}
7800    test{q}\t{%1, %0|%0, %1}
7801    test{q}\t{%1, %0|%0, %1}"
7802   [(set_attr "type" "test")
7803    (set_attr "modrm" "0,1,0,1,1")
7804    (set_attr "mode" "SI,SI,DI,DI,DI")
7805    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7806
7807 (define_insn "testsi_1"
7808   [(set (reg FLAGS_REG)
7809         (compare
7810           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7811                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7812           (const_int 0)))]
7813   "ix86_match_ccmode (insn, CCNOmode)
7814    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7815   "test{l}\t{%1, %0|%0, %1}"
7816   [(set_attr "type" "test")
7817    (set_attr "modrm" "0,1,1")
7818    (set_attr "mode" "SI")
7819    (set_attr "pent_pair" "uv,np,uv")])
7820
7821 (define_expand "testsi_ccno_1"
7822   [(set (reg:CCNO FLAGS_REG)
7823         (compare:CCNO
7824           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7825                   (match_operand:SI 1 "nonmemory_operand" ""))
7826           (const_int 0)))]
7827   ""
7828   "")
7829
7830 (define_insn "*testhi_1"
7831   [(set (reg FLAGS_REG)
7832         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7833                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7834                  (const_int 0)))]
7835   "ix86_match_ccmode (insn, CCNOmode)
7836    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7837   "test{w}\t{%1, %0|%0, %1}"
7838   [(set_attr "type" "test")
7839    (set_attr "modrm" "0,1,1")
7840    (set_attr "mode" "HI")
7841    (set_attr "pent_pair" "uv,np,uv")])
7842
7843 (define_expand "testqi_ccz_1"
7844   [(set (reg:CCZ FLAGS_REG)
7845         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7846                              (match_operand:QI 1 "nonmemory_operand" ""))
7847                  (const_int 0)))]
7848   ""
7849   "")
7850
7851 (define_insn "*testqi_1_maybe_si"
7852   [(set (reg FLAGS_REG)
7853         (compare
7854           (and:QI
7855             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7856             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7857           (const_int 0)))]
7858    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7859     && ix86_match_ccmode (insn,
7860                          CONST_INT_P (operands[1])
7861                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7862 {
7863   if (which_alternative == 3)
7864     {
7865       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7866         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7867       return "test{l}\t{%1, %k0|%k0, %1}";
7868     }
7869   return "test{b}\t{%1, %0|%0, %1}";
7870 }
7871   [(set_attr "type" "test")
7872    (set_attr "modrm" "0,1,1,1")
7873    (set_attr "mode" "QI,QI,QI,SI")
7874    (set_attr "pent_pair" "uv,np,uv,np")])
7875
7876 (define_insn "*testqi_1"
7877   [(set (reg FLAGS_REG)
7878         (compare
7879           (and:QI
7880             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7881             (match_operand:QI 1 "general_operand" "n,n,qn"))
7882           (const_int 0)))]
7883   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7884    && ix86_match_ccmode (insn, CCNOmode)"
7885   "test{b}\t{%1, %0|%0, %1}"
7886   [(set_attr "type" "test")
7887    (set_attr "modrm" "0,1,1")
7888    (set_attr "mode" "QI")
7889    (set_attr "pent_pair" "uv,np,uv")])
7890
7891 (define_expand "testqi_ext_ccno_0"
7892   [(set (reg:CCNO FLAGS_REG)
7893         (compare:CCNO
7894           (and:SI
7895             (zero_extract:SI
7896               (match_operand 0 "ext_register_operand" "")
7897               (const_int 8)
7898               (const_int 8))
7899             (match_operand 1 "const_int_operand" ""))
7900           (const_int 0)))]
7901   ""
7902   "")
7903
7904 (define_insn "*testqi_ext_0"
7905   [(set (reg FLAGS_REG)
7906         (compare
7907           (and:SI
7908             (zero_extract:SI
7909               (match_operand 0 "ext_register_operand" "Q")
7910               (const_int 8)
7911               (const_int 8))
7912             (match_operand 1 "const_int_operand" "n"))
7913           (const_int 0)))]
7914   "ix86_match_ccmode (insn, CCNOmode)"
7915   "test{b}\t{%1, %h0|%h0, %1}"
7916   [(set_attr "type" "test")
7917    (set_attr "mode" "QI")
7918    (set_attr "length_immediate" "1")
7919    (set_attr "pent_pair" "np")])
7920
7921 (define_insn "*testqi_ext_1"
7922   [(set (reg FLAGS_REG)
7923         (compare
7924           (and:SI
7925             (zero_extract:SI
7926               (match_operand 0 "ext_register_operand" "Q")
7927               (const_int 8)
7928               (const_int 8))
7929             (zero_extend:SI
7930               (match_operand:QI 1 "general_operand" "Qm")))
7931           (const_int 0)))]
7932   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7933    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7934   "test{b}\t{%1, %h0|%h0, %1}"
7935   [(set_attr "type" "test")
7936    (set_attr "mode" "QI")])
7937
7938 (define_insn "*testqi_ext_1_rex64"
7939   [(set (reg FLAGS_REG)
7940         (compare
7941           (and:SI
7942             (zero_extract:SI
7943               (match_operand 0 "ext_register_operand" "Q")
7944               (const_int 8)
7945               (const_int 8))
7946             (zero_extend:SI
7947               (match_operand:QI 1 "register_operand" "Q")))
7948           (const_int 0)))]
7949   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7950   "test{b}\t{%1, %h0|%h0, %1}"
7951   [(set_attr "type" "test")
7952    (set_attr "mode" "QI")])
7953
7954 (define_insn "*testqi_ext_2"
7955   [(set (reg FLAGS_REG)
7956         (compare
7957           (and:SI
7958             (zero_extract:SI
7959               (match_operand 0 "ext_register_operand" "Q")
7960               (const_int 8)
7961               (const_int 8))
7962             (zero_extract:SI
7963               (match_operand 1 "ext_register_operand" "Q")
7964               (const_int 8)
7965               (const_int 8)))
7966           (const_int 0)))]
7967   "ix86_match_ccmode (insn, CCNOmode)"
7968   "test{b}\t{%h1, %h0|%h0, %h1}"
7969   [(set_attr "type" "test")
7970    (set_attr "mode" "QI")])
7971
7972 ;; Combine likes to form bit extractions for some tests.  Humor it.
7973 (define_insn "*testqi_ext_3"
7974   [(set (reg FLAGS_REG)
7975         (compare (zero_extract:SI
7976                    (match_operand 0 "nonimmediate_operand" "rm")
7977                    (match_operand:SI 1 "const_int_operand" "")
7978                    (match_operand:SI 2 "const_int_operand" ""))
7979                  (const_int 0)))]
7980   "ix86_match_ccmode (insn, CCNOmode)
7981    && INTVAL (operands[1]) > 0
7982    && INTVAL (operands[2]) >= 0
7983    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7984    && (GET_MODE (operands[0]) == SImode
7985        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7986        || GET_MODE (operands[0]) == HImode
7987        || GET_MODE (operands[0]) == QImode)"
7988   "#")
7989
7990 (define_insn "*testqi_ext_3_rex64"
7991   [(set (reg FLAGS_REG)
7992         (compare (zero_extract:DI
7993                    (match_operand 0 "nonimmediate_operand" "rm")
7994                    (match_operand:DI 1 "const_int_operand" "")
7995                    (match_operand:DI 2 "const_int_operand" ""))
7996                  (const_int 0)))]
7997   "TARGET_64BIT
7998    && ix86_match_ccmode (insn, CCNOmode)
7999    && INTVAL (operands[1]) > 0
8000    && INTVAL (operands[2]) >= 0
8001    /* Ensure that resulting mask is zero or sign extended operand.  */
8002    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8003        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8004            && INTVAL (operands[1]) > 32))
8005    && (GET_MODE (operands[0]) == SImode
8006        || GET_MODE (operands[0]) == DImode
8007        || GET_MODE (operands[0]) == HImode
8008        || GET_MODE (operands[0]) == QImode)"
8009   "#")
8010
8011 (define_split
8012   [(set (match_operand 0 "flags_reg_operand" "")
8013         (match_operator 1 "compare_operator"
8014           [(zero_extract
8015              (match_operand 2 "nonimmediate_operand" "")
8016              (match_operand 3 "const_int_operand" "")
8017              (match_operand 4 "const_int_operand" ""))
8018            (const_int 0)]))]
8019   "ix86_match_ccmode (insn, CCNOmode)"
8020   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8021 {
8022   rtx val = operands[2];
8023   HOST_WIDE_INT len = INTVAL (operands[3]);
8024   HOST_WIDE_INT pos = INTVAL (operands[4]);
8025   HOST_WIDE_INT mask;
8026   enum machine_mode mode, submode;
8027
8028   mode = GET_MODE (val);
8029   if (MEM_P (val))
8030     {
8031       /* ??? Combine likes to put non-volatile mem extractions in QImode
8032          no matter the size of the test.  So find a mode that works.  */
8033       if (! MEM_VOLATILE_P (val))
8034         {
8035           mode = smallest_mode_for_size (pos + len, MODE_INT);
8036           val = adjust_address (val, mode, 0);
8037         }
8038     }
8039   else if (GET_CODE (val) == SUBREG
8040            && (submode = GET_MODE (SUBREG_REG (val)),
8041                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8042            && pos + len <= GET_MODE_BITSIZE (submode))
8043     {
8044       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8045       mode = submode;
8046       val = SUBREG_REG (val);
8047     }
8048   else if (mode == HImode && pos + len <= 8)
8049     {
8050       /* Small HImode tests can be converted to QImode.  */
8051       mode = QImode;
8052       val = gen_lowpart (QImode, val);
8053     }
8054
8055   if (len == HOST_BITS_PER_WIDE_INT)
8056     mask = -1;
8057   else
8058     mask = ((HOST_WIDE_INT)1 << len) - 1;
8059   mask <<= pos;
8060
8061   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8062 })
8063
8064 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8065 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8066 ;; this is relatively important trick.
8067 ;; Do the conversion only post-reload to avoid limiting of the register class
8068 ;; to QI regs.
8069 (define_split
8070   [(set (match_operand 0 "flags_reg_operand" "")
8071         (match_operator 1 "compare_operator"
8072           [(and (match_operand 2 "register_operand" "")
8073                 (match_operand 3 "const_int_operand" ""))
8074            (const_int 0)]))]
8075    "reload_completed
8076     && QI_REG_P (operands[2])
8077     && GET_MODE (operands[2]) != QImode
8078     && ((ix86_match_ccmode (insn, CCZmode)
8079          && !(INTVAL (operands[3]) & ~(255 << 8)))
8080         || (ix86_match_ccmode (insn, CCNOmode)
8081             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8082   [(set (match_dup 0)
8083         (match_op_dup 1
8084           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8085                    (match_dup 3))
8086            (const_int 0)]))]
8087   "operands[2] = gen_lowpart (SImode, operands[2]);
8088    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8089
8090 (define_split
8091   [(set (match_operand 0 "flags_reg_operand" "")
8092         (match_operator 1 "compare_operator"
8093           [(and (match_operand 2 "nonimmediate_operand" "")
8094                 (match_operand 3 "const_int_operand" ""))
8095            (const_int 0)]))]
8096    "reload_completed
8097     && GET_MODE (operands[2]) != QImode
8098     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8099     && ((ix86_match_ccmode (insn, CCZmode)
8100          && !(INTVAL (operands[3]) & ~255))
8101         || (ix86_match_ccmode (insn, CCNOmode)
8102             && !(INTVAL (operands[3]) & ~127)))"
8103   [(set (match_dup 0)
8104         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8105                          (const_int 0)]))]
8106   "operands[2] = gen_lowpart (QImode, operands[2]);
8107    operands[3] = gen_lowpart (QImode, operands[3]);")
8108
8109
8110 ;; %%% This used to optimize known byte-wide and operations to memory,
8111 ;; and sometimes to QImode registers.  If this is considered useful,
8112 ;; it should be done with splitters.
8113
8114 (define_expand "anddi3"
8115   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8116         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8117                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8118    (clobber (reg:CC FLAGS_REG))]
8119   "TARGET_64BIT"
8120   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8121
8122 (define_insn "*anddi_1_rex64"
8123   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8124         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8125                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8126    (clobber (reg:CC FLAGS_REG))]
8127   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8128 {
8129   switch (get_attr_type (insn))
8130     {
8131     case TYPE_IMOVX:
8132       {
8133         enum machine_mode mode;
8134
8135         gcc_assert (CONST_INT_P (operands[2]));
8136         if (INTVAL (operands[2]) == 0xff)
8137           mode = QImode;
8138         else
8139           {
8140             gcc_assert (INTVAL (operands[2]) == 0xffff);
8141             mode = HImode;
8142           }
8143
8144         operands[1] = gen_lowpart (mode, operands[1]);
8145         if (mode == QImode)
8146           return "movz{bq|x}\t{%1,%0|%0, %1}";
8147         else
8148           return "movz{wq|x}\t{%1,%0|%0, %1}";
8149       }
8150
8151     default:
8152       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8153       if (get_attr_mode (insn) == MODE_SI)
8154         return "and{l}\t{%k2, %k0|%k0, %k2}";
8155       else
8156         return "and{q}\t{%2, %0|%0, %2}";
8157     }
8158 }
8159   [(set_attr "type" "alu,alu,alu,imovx")
8160    (set_attr "length_immediate" "*,*,*,0")
8161    (set_attr "mode" "SI,DI,DI,DI")])
8162
8163 (define_insn "*anddi_2"
8164   [(set (reg FLAGS_REG)
8165         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8166                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8167                  (const_int 0)))
8168    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8169         (and:DI (match_dup 1) (match_dup 2)))]
8170   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8171    && ix86_binary_operator_ok (AND, DImode, operands)"
8172   "@
8173    and{l}\t{%k2, %k0|%k0, %k2}
8174    and{q}\t{%2, %0|%0, %2}
8175    and{q}\t{%2, %0|%0, %2}"
8176   [(set_attr "type" "alu")
8177    (set_attr "mode" "SI,DI,DI")])
8178
8179 (define_expand "andsi3"
8180   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8181         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8182                 (match_operand:SI 2 "general_operand" "")))
8183    (clobber (reg:CC FLAGS_REG))]
8184   ""
8185   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8186
8187 (define_insn "*andsi_1"
8188   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8189         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8190                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8191    (clobber (reg:CC FLAGS_REG))]
8192   "ix86_binary_operator_ok (AND, SImode, operands)"
8193 {
8194   switch (get_attr_type (insn))
8195     {
8196     case TYPE_IMOVX:
8197       {
8198         enum machine_mode mode;
8199
8200         gcc_assert (CONST_INT_P (operands[2]));
8201         if (INTVAL (operands[2]) == 0xff)
8202           mode = QImode;
8203         else
8204           {
8205             gcc_assert (INTVAL (operands[2]) == 0xffff);
8206             mode = HImode;
8207           }
8208
8209         operands[1] = gen_lowpart (mode, operands[1]);
8210         if (mode == QImode)
8211           return "movz{bl|x}\t{%1,%0|%0, %1}";
8212         else
8213           return "movz{wl|x}\t{%1,%0|%0, %1}";
8214       }
8215
8216     default:
8217       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8218       return "and{l}\t{%2, %0|%0, %2}";
8219     }
8220 }
8221   [(set_attr "type" "alu,alu,imovx")
8222    (set_attr "length_immediate" "*,*,0")
8223    (set_attr "mode" "SI")])
8224
8225 (define_split
8226   [(set (match_operand 0 "register_operand" "")
8227         (and (match_dup 0)
8228              (const_int -65536)))
8229    (clobber (reg:CC FLAGS_REG))]
8230   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8231   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8232   "operands[1] = gen_lowpart (HImode, operands[0]);")
8233
8234 (define_split
8235   [(set (match_operand 0 "ext_register_operand" "")
8236         (and (match_dup 0)
8237              (const_int -256)))
8238    (clobber (reg:CC FLAGS_REG))]
8239   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8240   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8241   "operands[1] = gen_lowpart (QImode, operands[0]);")
8242
8243 (define_split
8244   [(set (match_operand 0 "ext_register_operand" "")
8245         (and (match_dup 0)
8246              (const_int -65281)))
8247    (clobber (reg:CC FLAGS_REG))]
8248   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8249   [(parallel [(set (zero_extract:SI (match_dup 0)
8250                                     (const_int 8)
8251                                     (const_int 8))
8252                    (xor:SI
8253                      (zero_extract:SI (match_dup 0)
8254                                       (const_int 8)
8255                                       (const_int 8))
8256                      (zero_extract:SI (match_dup 0)
8257                                       (const_int 8)
8258                                       (const_int 8))))
8259               (clobber (reg:CC FLAGS_REG))])]
8260   "operands[0] = gen_lowpart (SImode, operands[0]);")
8261
8262 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8263 (define_insn "*andsi_1_zext"
8264   [(set (match_operand:DI 0 "register_operand" "=r")
8265         (zero_extend:DI
8266           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8267                   (match_operand:SI 2 "general_operand" "rim"))))
8268    (clobber (reg:CC FLAGS_REG))]
8269   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8270   "and{l}\t{%2, %k0|%k0, %2}"
8271   [(set_attr "type" "alu")
8272    (set_attr "mode" "SI")])
8273
8274 (define_insn "*andsi_2"
8275   [(set (reg FLAGS_REG)
8276         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8277                          (match_operand:SI 2 "general_operand" "rim,ri"))
8278                  (const_int 0)))
8279    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8280         (and:SI (match_dup 1) (match_dup 2)))]
8281   "ix86_match_ccmode (insn, CCNOmode)
8282    && ix86_binary_operator_ok (AND, SImode, operands)"
8283   "and{l}\t{%2, %0|%0, %2}"
8284   [(set_attr "type" "alu")
8285    (set_attr "mode" "SI")])
8286
8287 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8288 (define_insn "*andsi_2_zext"
8289   [(set (reg FLAGS_REG)
8290         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8291                          (match_operand:SI 2 "general_operand" "rim"))
8292                  (const_int 0)))
8293    (set (match_operand:DI 0 "register_operand" "=r")
8294         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8295   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8296    && ix86_binary_operator_ok (AND, SImode, operands)"
8297   "and{l}\t{%2, %k0|%k0, %2}"
8298   [(set_attr "type" "alu")
8299    (set_attr "mode" "SI")])
8300
8301 (define_expand "andhi3"
8302   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8303         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8304                 (match_operand:HI 2 "general_operand" "")))
8305    (clobber (reg:CC FLAGS_REG))]
8306   "TARGET_HIMODE_MATH"
8307   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8308
8309 (define_insn "*andhi_1"
8310   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8311         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8312                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8313    (clobber (reg:CC FLAGS_REG))]
8314   "ix86_binary_operator_ok (AND, HImode, operands)"
8315 {
8316   switch (get_attr_type (insn))
8317     {
8318     case TYPE_IMOVX:
8319       gcc_assert (CONST_INT_P (operands[2]));
8320       gcc_assert (INTVAL (operands[2]) == 0xff);
8321       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8322
8323     default:
8324       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8325
8326       return "and{w}\t{%2, %0|%0, %2}";
8327     }
8328 }
8329   [(set_attr "type" "alu,alu,imovx")
8330    (set_attr "length_immediate" "*,*,0")
8331    (set_attr "mode" "HI,HI,SI")])
8332
8333 (define_insn "*andhi_2"
8334   [(set (reg FLAGS_REG)
8335         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8336                          (match_operand:HI 2 "general_operand" "rim,ri"))
8337                  (const_int 0)))
8338    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8339         (and:HI (match_dup 1) (match_dup 2)))]
8340   "ix86_match_ccmode (insn, CCNOmode)
8341    && ix86_binary_operator_ok (AND, HImode, operands)"
8342   "and{w}\t{%2, %0|%0, %2}"
8343   [(set_attr "type" "alu")
8344    (set_attr "mode" "HI")])
8345
8346 (define_expand "andqi3"
8347   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8348         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8349                 (match_operand:QI 2 "general_operand" "")))
8350    (clobber (reg:CC FLAGS_REG))]
8351   "TARGET_QIMODE_MATH"
8352   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8353
8354 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8355 (define_insn "*andqi_1"
8356   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8357         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8358                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8359    (clobber (reg:CC FLAGS_REG))]
8360   "ix86_binary_operator_ok (AND, QImode, operands)"
8361   "@
8362    and{b}\t{%2, %0|%0, %2}
8363    and{b}\t{%2, %0|%0, %2}
8364    and{l}\t{%k2, %k0|%k0, %k2}"
8365   [(set_attr "type" "alu")
8366    (set_attr "mode" "QI,QI,SI")])
8367
8368 (define_insn "*andqi_1_slp"
8369   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8370         (and:QI (match_dup 0)
8371                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8372    (clobber (reg:CC FLAGS_REG))]
8373   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8374    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8375   "and{b}\t{%1, %0|%0, %1}"
8376   [(set_attr "type" "alu1")
8377    (set_attr "mode" "QI")])
8378
8379 (define_insn "*andqi_2_maybe_si"
8380   [(set (reg FLAGS_REG)
8381         (compare (and:QI
8382                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8383                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8384                  (const_int 0)))
8385    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8386         (and:QI (match_dup 1) (match_dup 2)))]
8387   "ix86_binary_operator_ok (AND, QImode, operands)
8388    && ix86_match_ccmode (insn,
8389                          CONST_INT_P (operands[2])
8390                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8391 {
8392   if (which_alternative == 2)
8393     {
8394       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8395         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8396       return "and{l}\t{%2, %k0|%k0, %2}";
8397     }
8398   return "and{b}\t{%2, %0|%0, %2}";
8399 }
8400   [(set_attr "type" "alu")
8401    (set_attr "mode" "QI,QI,SI")])
8402
8403 (define_insn "*andqi_2"
8404   [(set (reg FLAGS_REG)
8405         (compare (and:QI
8406                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8407                    (match_operand:QI 2 "general_operand" "qim,qi"))
8408                  (const_int 0)))
8409    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8410         (and:QI (match_dup 1) (match_dup 2)))]
8411   "ix86_match_ccmode (insn, CCNOmode)
8412    && ix86_binary_operator_ok (AND, QImode, operands)"
8413   "and{b}\t{%2, %0|%0, %2}"
8414   [(set_attr "type" "alu")
8415    (set_attr "mode" "QI")])
8416
8417 (define_insn "*andqi_2_slp"
8418   [(set (reg FLAGS_REG)
8419         (compare (and:QI
8420                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8421                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8422                  (const_int 0)))
8423    (set (strict_low_part (match_dup 0))
8424         (and:QI (match_dup 0) (match_dup 1)))]
8425   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8426    && ix86_match_ccmode (insn, CCNOmode)
8427    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8428   "and{b}\t{%1, %0|%0, %1}"
8429   [(set_attr "type" "alu1")
8430    (set_attr "mode" "QI")])
8431
8432 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8433 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8434 ;; for a QImode operand, which of course failed.
8435
8436 (define_insn "andqi_ext_0"
8437   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8438                          (const_int 8)
8439                          (const_int 8))
8440         (and:SI
8441           (zero_extract:SI
8442             (match_operand 1 "ext_register_operand" "0")
8443             (const_int 8)
8444             (const_int 8))
8445           (match_operand 2 "const_int_operand" "n")))
8446    (clobber (reg:CC FLAGS_REG))]
8447   ""
8448   "and{b}\t{%2, %h0|%h0, %2}"
8449   [(set_attr "type" "alu")
8450    (set_attr "length_immediate" "1")
8451    (set_attr "mode" "QI")])
8452
8453 ;; Generated by peephole translating test to and.  This shows up
8454 ;; often in fp comparisons.
8455
8456 (define_insn "*andqi_ext_0_cc"
8457   [(set (reg FLAGS_REG)
8458         (compare
8459           (and:SI
8460             (zero_extract:SI
8461               (match_operand 1 "ext_register_operand" "0")
8462               (const_int 8)
8463               (const_int 8))
8464             (match_operand 2 "const_int_operand" "n"))
8465           (const_int 0)))
8466    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8467                          (const_int 8)
8468                          (const_int 8))
8469         (and:SI
8470           (zero_extract:SI
8471             (match_dup 1)
8472             (const_int 8)
8473             (const_int 8))
8474           (match_dup 2)))]
8475   "ix86_match_ccmode (insn, CCNOmode)"
8476   "and{b}\t{%2, %h0|%h0, %2}"
8477   [(set_attr "type" "alu")
8478    (set_attr "length_immediate" "1")
8479    (set_attr "mode" "QI")])
8480
8481 (define_insn "*andqi_ext_1"
8482   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8483                          (const_int 8)
8484                          (const_int 8))
8485         (and:SI
8486           (zero_extract:SI
8487             (match_operand 1 "ext_register_operand" "0")
8488             (const_int 8)
8489             (const_int 8))
8490           (zero_extend:SI
8491             (match_operand:QI 2 "general_operand" "Qm"))))
8492    (clobber (reg:CC FLAGS_REG))]
8493   "!TARGET_64BIT"
8494   "and{b}\t{%2, %h0|%h0, %2}"
8495   [(set_attr "type" "alu")
8496    (set_attr "length_immediate" "0")
8497    (set_attr "mode" "QI")])
8498
8499 (define_insn "*andqi_ext_1_rex64"
8500   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8501                          (const_int 8)
8502                          (const_int 8))
8503         (and:SI
8504           (zero_extract:SI
8505             (match_operand 1 "ext_register_operand" "0")
8506             (const_int 8)
8507             (const_int 8))
8508           (zero_extend:SI
8509             (match_operand 2 "ext_register_operand" "Q"))))
8510    (clobber (reg:CC FLAGS_REG))]
8511   "TARGET_64BIT"
8512   "and{b}\t{%2, %h0|%h0, %2}"
8513   [(set_attr "type" "alu")
8514    (set_attr "length_immediate" "0")
8515    (set_attr "mode" "QI")])
8516
8517 (define_insn "*andqi_ext_2"
8518   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8519                          (const_int 8)
8520                          (const_int 8))
8521         (and:SI
8522           (zero_extract:SI
8523             (match_operand 1 "ext_register_operand" "%0")
8524             (const_int 8)
8525             (const_int 8))
8526           (zero_extract:SI
8527             (match_operand 2 "ext_register_operand" "Q")
8528             (const_int 8)
8529             (const_int 8))))
8530    (clobber (reg:CC FLAGS_REG))]
8531   ""
8532   "and{b}\t{%h2, %h0|%h0, %h2}"
8533   [(set_attr "type" "alu")
8534    (set_attr "length_immediate" "0")
8535    (set_attr "mode" "QI")])
8536
8537 ;; Convert wide AND instructions with immediate operand to shorter QImode
8538 ;; equivalents when possible.
8539 ;; Don't do the splitting with memory operands, since it introduces risk
8540 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8541 ;; for size, but that can (should?) be handled by generic code instead.
8542 (define_split
8543   [(set (match_operand 0 "register_operand" "")
8544         (and (match_operand 1 "register_operand" "")
8545              (match_operand 2 "const_int_operand" "")))
8546    (clobber (reg:CC FLAGS_REG))]
8547    "reload_completed
8548     && QI_REG_P (operands[0])
8549     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8550     && !(~INTVAL (operands[2]) & ~(255 << 8))
8551     && GET_MODE (operands[0]) != QImode"
8552   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8553                    (and:SI (zero_extract:SI (match_dup 1)
8554                                             (const_int 8) (const_int 8))
8555                            (match_dup 2)))
8556               (clobber (reg:CC FLAGS_REG))])]
8557   "operands[0] = gen_lowpart (SImode, operands[0]);
8558    operands[1] = gen_lowpart (SImode, operands[1]);
8559    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8560
8561 ;; Since AND can be encoded with sign extended immediate, this is only
8562 ;; profitable when 7th bit is not set.
8563 (define_split
8564   [(set (match_operand 0 "register_operand" "")
8565         (and (match_operand 1 "general_operand" "")
8566              (match_operand 2 "const_int_operand" "")))
8567    (clobber (reg:CC FLAGS_REG))]
8568    "reload_completed
8569     && ANY_QI_REG_P (operands[0])
8570     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8571     && !(~INTVAL (operands[2]) & ~255)
8572     && !(INTVAL (operands[2]) & 128)
8573     && GET_MODE (operands[0]) != QImode"
8574   [(parallel [(set (strict_low_part (match_dup 0))
8575                    (and:QI (match_dup 1)
8576                            (match_dup 2)))
8577               (clobber (reg:CC FLAGS_REG))])]
8578   "operands[0] = gen_lowpart (QImode, operands[0]);
8579    operands[1] = gen_lowpart (QImode, operands[1]);
8580    operands[2] = gen_lowpart (QImode, operands[2]);")
8581 \f
8582 ;; Logical inclusive OR instructions
8583
8584 ;; %%% This used to optimize known byte-wide and operations to memory.
8585 ;; If this is considered useful, it should be done with splitters.
8586
8587 (define_expand "iordi3"
8588   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8589         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8590                 (match_operand:DI 2 "x86_64_general_operand" "")))
8591    (clobber (reg:CC FLAGS_REG))]
8592   "TARGET_64BIT"
8593   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8594
8595 (define_insn "*iordi_1_rex64"
8596   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8597         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8598                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8599    (clobber (reg:CC FLAGS_REG))]
8600   "TARGET_64BIT
8601    && ix86_binary_operator_ok (IOR, DImode, operands)"
8602   "or{q}\t{%2, %0|%0, %2}"
8603   [(set_attr "type" "alu")
8604    (set_attr "mode" "DI")])
8605
8606 (define_insn "*iordi_2_rex64"
8607   [(set (reg FLAGS_REG)
8608         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8609                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8610                  (const_int 0)))
8611    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8612         (ior:DI (match_dup 1) (match_dup 2)))]
8613   "TARGET_64BIT
8614    && ix86_match_ccmode (insn, CCNOmode)
8615    && ix86_binary_operator_ok (IOR, DImode, operands)"
8616   "or{q}\t{%2, %0|%0, %2}"
8617   [(set_attr "type" "alu")
8618    (set_attr "mode" "DI")])
8619
8620 (define_insn "*iordi_3_rex64"
8621   [(set (reg FLAGS_REG)
8622         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8623                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8624                  (const_int 0)))
8625    (clobber (match_scratch:DI 0 "=r"))]
8626   "TARGET_64BIT
8627    && ix86_match_ccmode (insn, CCNOmode)
8628    && ix86_binary_operator_ok (IOR, DImode, operands)"
8629   "or{q}\t{%2, %0|%0, %2}"
8630   [(set_attr "type" "alu")
8631    (set_attr "mode" "DI")])
8632
8633
8634 (define_expand "iorsi3"
8635   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8636         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8637                 (match_operand:SI 2 "general_operand" "")))
8638    (clobber (reg:CC FLAGS_REG))]
8639   ""
8640   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8641
8642 (define_insn "*iorsi_1"
8643   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8644         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8645                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8646    (clobber (reg:CC FLAGS_REG))]
8647   "ix86_binary_operator_ok (IOR, SImode, operands)"
8648   "or{l}\t{%2, %0|%0, %2}"
8649   [(set_attr "type" "alu")
8650    (set_attr "mode" "SI")])
8651
8652 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8653 (define_insn "*iorsi_1_zext"
8654   [(set (match_operand:DI 0 "register_operand" "=rm")
8655         (zero_extend:DI
8656           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8657                   (match_operand:SI 2 "general_operand" "rim"))))
8658    (clobber (reg:CC FLAGS_REG))]
8659   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8660   "or{l}\t{%2, %k0|%k0, %2}"
8661   [(set_attr "type" "alu")
8662    (set_attr "mode" "SI")])
8663
8664 (define_insn "*iorsi_1_zext_imm"
8665   [(set (match_operand:DI 0 "register_operand" "=rm")
8666         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8667                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8668    (clobber (reg:CC FLAGS_REG))]
8669   "TARGET_64BIT"
8670   "or{l}\t{%2, %k0|%k0, %2}"
8671   [(set_attr "type" "alu")
8672    (set_attr "mode" "SI")])
8673
8674 (define_insn "*iorsi_2"
8675   [(set (reg FLAGS_REG)
8676         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8677                          (match_operand:SI 2 "general_operand" "rim,ri"))
8678                  (const_int 0)))
8679    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8680         (ior:SI (match_dup 1) (match_dup 2)))]
8681   "ix86_match_ccmode (insn, CCNOmode)
8682    && ix86_binary_operator_ok (IOR, SImode, operands)"
8683   "or{l}\t{%2, %0|%0, %2}"
8684   [(set_attr "type" "alu")
8685    (set_attr "mode" "SI")])
8686
8687 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8688 ;; ??? Special case for immediate operand is missing - it is tricky.
8689 (define_insn "*iorsi_2_zext"
8690   [(set (reg FLAGS_REG)
8691         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8692                          (match_operand:SI 2 "general_operand" "rim"))
8693                  (const_int 0)))
8694    (set (match_operand:DI 0 "register_operand" "=r")
8695         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8696   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8697    && ix86_binary_operator_ok (IOR, SImode, operands)"
8698   "or{l}\t{%2, %k0|%k0, %2}"
8699   [(set_attr "type" "alu")
8700    (set_attr "mode" "SI")])
8701
8702 (define_insn "*iorsi_2_zext_imm"
8703   [(set (reg FLAGS_REG)
8704         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8705                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8706                  (const_int 0)))
8707    (set (match_operand:DI 0 "register_operand" "=r")
8708         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8709   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8710    && ix86_binary_operator_ok (IOR, SImode, operands)"
8711   "or{l}\t{%2, %k0|%k0, %2}"
8712   [(set_attr "type" "alu")
8713    (set_attr "mode" "SI")])
8714
8715 (define_insn "*iorsi_3"
8716   [(set (reg FLAGS_REG)
8717         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8718                          (match_operand:SI 2 "general_operand" "rim"))
8719                  (const_int 0)))
8720    (clobber (match_scratch:SI 0 "=r"))]
8721   "ix86_match_ccmode (insn, CCNOmode)
8722    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8723   "or{l}\t{%2, %0|%0, %2}"
8724   [(set_attr "type" "alu")
8725    (set_attr "mode" "SI")])
8726
8727 (define_expand "iorhi3"
8728   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8729         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8730                 (match_operand:HI 2 "general_operand" "")))
8731    (clobber (reg:CC FLAGS_REG))]
8732   "TARGET_HIMODE_MATH"
8733   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8734
8735 (define_insn "*iorhi_1"
8736   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8737         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8738                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8739    (clobber (reg:CC FLAGS_REG))]
8740   "ix86_binary_operator_ok (IOR, HImode, operands)"
8741   "or{w}\t{%2, %0|%0, %2}"
8742   [(set_attr "type" "alu")
8743    (set_attr "mode" "HI")])
8744
8745 (define_insn "*iorhi_2"
8746   [(set (reg FLAGS_REG)
8747         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8748                          (match_operand:HI 2 "general_operand" "rim,ri"))
8749                  (const_int 0)))
8750    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8751         (ior:HI (match_dup 1) (match_dup 2)))]
8752   "ix86_match_ccmode (insn, CCNOmode)
8753    && ix86_binary_operator_ok (IOR, HImode, operands)"
8754   "or{w}\t{%2, %0|%0, %2}"
8755   [(set_attr "type" "alu")
8756    (set_attr "mode" "HI")])
8757
8758 (define_insn "*iorhi_3"
8759   [(set (reg FLAGS_REG)
8760         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8761                          (match_operand:HI 2 "general_operand" "rim"))
8762                  (const_int 0)))
8763    (clobber (match_scratch:HI 0 "=r"))]
8764   "ix86_match_ccmode (insn, CCNOmode)
8765    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8766   "or{w}\t{%2, %0|%0, %2}"
8767   [(set_attr "type" "alu")
8768    (set_attr "mode" "HI")])
8769
8770 (define_expand "iorqi3"
8771   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8772         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8773                 (match_operand:QI 2 "general_operand" "")))
8774    (clobber (reg:CC FLAGS_REG))]
8775   "TARGET_QIMODE_MATH"
8776   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8777
8778 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8779 (define_insn "*iorqi_1"
8780   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8781         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8782                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8783    (clobber (reg:CC FLAGS_REG))]
8784   "ix86_binary_operator_ok (IOR, QImode, operands)"
8785   "@
8786    or{b}\t{%2, %0|%0, %2}
8787    or{b}\t{%2, %0|%0, %2}
8788    or{l}\t{%k2, %k0|%k0, %k2}"
8789   [(set_attr "type" "alu")
8790    (set_attr "mode" "QI,QI,SI")])
8791
8792 (define_insn "*iorqi_1_slp"
8793   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8794         (ior:QI (match_dup 0)
8795                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8796    (clobber (reg:CC FLAGS_REG))]
8797   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8798    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8799   "or{b}\t{%1, %0|%0, %1}"
8800   [(set_attr "type" "alu1")
8801    (set_attr "mode" "QI")])
8802
8803 (define_insn "*iorqi_2"
8804   [(set (reg FLAGS_REG)
8805         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8806                          (match_operand:QI 2 "general_operand" "qim,qi"))
8807                  (const_int 0)))
8808    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8809         (ior:QI (match_dup 1) (match_dup 2)))]
8810   "ix86_match_ccmode (insn, CCNOmode)
8811    && ix86_binary_operator_ok (IOR, QImode, operands)"
8812   "or{b}\t{%2, %0|%0, %2}"
8813   [(set_attr "type" "alu")
8814    (set_attr "mode" "QI")])
8815
8816 (define_insn "*iorqi_2_slp"
8817   [(set (reg FLAGS_REG)
8818         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8819                          (match_operand:QI 1 "general_operand" "qim,qi"))
8820                  (const_int 0)))
8821    (set (strict_low_part (match_dup 0))
8822         (ior:QI (match_dup 0) (match_dup 1)))]
8823   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8824    && ix86_match_ccmode (insn, CCNOmode)
8825    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8826   "or{b}\t{%1, %0|%0, %1}"
8827   [(set_attr "type" "alu1")
8828    (set_attr "mode" "QI")])
8829
8830 (define_insn "*iorqi_3"
8831   [(set (reg FLAGS_REG)
8832         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8833                          (match_operand:QI 2 "general_operand" "qim"))
8834                  (const_int 0)))
8835    (clobber (match_scratch:QI 0 "=q"))]
8836   "ix86_match_ccmode (insn, CCNOmode)
8837    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8838   "or{b}\t{%2, %0|%0, %2}"
8839   [(set_attr "type" "alu")
8840    (set_attr "mode" "QI")])
8841
8842 (define_insn "iorqi_ext_0"
8843   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8844                          (const_int 8)
8845                          (const_int 8))
8846         (ior:SI
8847           (zero_extract:SI
8848             (match_operand 1 "ext_register_operand" "0")
8849             (const_int 8)
8850             (const_int 8))
8851           (match_operand 2 "const_int_operand" "n")))
8852    (clobber (reg:CC FLAGS_REG))]
8853   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8854   "or{b}\t{%2, %h0|%h0, %2}"
8855   [(set_attr "type" "alu")
8856    (set_attr "length_immediate" "1")
8857    (set_attr "mode" "QI")])
8858
8859 (define_insn "*iorqi_ext_1"
8860   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8861                          (const_int 8)
8862                          (const_int 8))
8863         (ior:SI
8864           (zero_extract:SI
8865             (match_operand 1 "ext_register_operand" "0")
8866             (const_int 8)
8867             (const_int 8))
8868           (zero_extend:SI
8869             (match_operand:QI 2 "general_operand" "Qm"))))
8870    (clobber (reg:CC FLAGS_REG))]
8871   "!TARGET_64BIT
8872    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8873   "or{b}\t{%2, %h0|%h0, %2}"
8874   [(set_attr "type" "alu")
8875    (set_attr "length_immediate" "0")
8876    (set_attr "mode" "QI")])
8877
8878 (define_insn "*iorqi_ext_1_rex64"
8879   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8880                          (const_int 8)
8881                          (const_int 8))
8882         (ior:SI
8883           (zero_extract:SI
8884             (match_operand 1 "ext_register_operand" "0")
8885             (const_int 8)
8886             (const_int 8))
8887           (zero_extend:SI
8888             (match_operand 2 "ext_register_operand" "Q"))))
8889    (clobber (reg:CC FLAGS_REG))]
8890   "TARGET_64BIT
8891    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8892   "or{b}\t{%2, %h0|%h0, %2}"
8893   [(set_attr "type" "alu")
8894    (set_attr "length_immediate" "0")
8895    (set_attr "mode" "QI")])
8896
8897 (define_insn "*iorqi_ext_2"
8898   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8899                          (const_int 8)
8900                          (const_int 8))
8901         (ior:SI
8902           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8903                            (const_int 8)
8904                            (const_int 8))
8905           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8906                            (const_int 8)
8907                            (const_int 8))))
8908    (clobber (reg:CC FLAGS_REG))]
8909   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8910   "ior{b}\t{%h2, %h0|%h0, %h2}"
8911   [(set_attr "type" "alu")
8912    (set_attr "length_immediate" "0")
8913    (set_attr "mode" "QI")])
8914
8915 (define_split
8916   [(set (match_operand 0 "register_operand" "")
8917         (ior (match_operand 1 "register_operand" "")
8918              (match_operand 2 "const_int_operand" "")))
8919    (clobber (reg:CC FLAGS_REG))]
8920    "reload_completed
8921     && QI_REG_P (operands[0])
8922     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8923     && !(INTVAL (operands[2]) & ~(255 << 8))
8924     && GET_MODE (operands[0]) != QImode"
8925   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8926                    (ior:SI (zero_extract:SI (match_dup 1)
8927                                             (const_int 8) (const_int 8))
8928                            (match_dup 2)))
8929               (clobber (reg:CC FLAGS_REG))])]
8930   "operands[0] = gen_lowpart (SImode, operands[0]);
8931    operands[1] = gen_lowpart (SImode, operands[1]);
8932    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8933
8934 ;; Since OR can be encoded with sign extended immediate, this is only
8935 ;; profitable when 7th bit is set.
8936 (define_split
8937   [(set (match_operand 0 "register_operand" "")
8938         (ior (match_operand 1 "general_operand" "")
8939              (match_operand 2 "const_int_operand" "")))
8940    (clobber (reg:CC FLAGS_REG))]
8941    "reload_completed
8942     && ANY_QI_REG_P (operands[0])
8943     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8944     && !(INTVAL (operands[2]) & ~255)
8945     && (INTVAL (operands[2]) & 128)
8946     && GET_MODE (operands[0]) != QImode"
8947   [(parallel [(set (strict_low_part (match_dup 0))
8948                    (ior:QI (match_dup 1)
8949                            (match_dup 2)))
8950               (clobber (reg:CC FLAGS_REG))])]
8951   "operands[0] = gen_lowpart (QImode, operands[0]);
8952    operands[1] = gen_lowpart (QImode, operands[1]);
8953    operands[2] = gen_lowpart (QImode, operands[2]);")
8954 \f
8955 ;; Logical XOR instructions
8956
8957 ;; %%% This used to optimize known byte-wide and operations to memory.
8958 ;; If this is considered useful, it should be done with splitters.
8959
8960 (define_expand "xordi3"
8961   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8962         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8963                 (match_operand:DI 2 "x86_64_general_operand" "")))
8964    (clobber (reg:CC FLAGS_REG))]
8965   "TARGET_64BIT"
8966   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8967
8968 (define_insn "*xordi_1_rex64"
8969   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8970         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8971                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8972    (clobber (reg:CC FLAGS_REG))]
8973   "TARGET_64BIT
8974    && ix86_binary_operator_ok (XOR, DImode, operands)"
8975   "@
8976    xor{q}\t{%2, %0|%0, %2}
8977    xor{q}\t{%2, %0|%0, %2}"
8978   [(set_attr "type" "alu")
8979    (set_attr "mode" "DI,DI")])
8980
8981 (define_insn "*xordi_2_rex64"
8982   [(set (reg FLAGS_REG)
8983         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8984                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8985                  (const_int 0)))
8986    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8987         (xor:DI (match_dup 1) (match_dup 2)))]
8988   "TARGET_64BIT
8989    && ix86_match_ccmode (insn, CCNOmode)
8990    && ix86_binary_operator_ok (XOR, DImode, operands)"
8991   "@
8992    xor{q}\t{%2, %0|%0, %2}
8993    xor{q}\t{%2, %0|%0, %2}"
8994   [(set_attr "type" "alu")
8995    (set_attr "mode" "DI,DI")])
8996
8997 (define_insn "*xordi_3_rex64"
8998   [(set (reg FLAGS_REG)
8999         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9000                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9001                  (const_int 0)))
9002    (clobber (match_scratch:DI 0 "=r"))]
9003   "TARGET_64BIT
9004    && ix86_match_ccmode (insn, CCNOmode)
9005    && ix86_binary_operator_ok (XOR, DImode, operands)"
9006   "xor{q}\t{%2, %0|%0, %2}"
9007   [(set_attr "type" "alu")
9008    (set_attr "mode" "DI")])
9009
9010 (define_expand "xorsi3"
9011   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9012         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9013                 (match_operand:SI 2 "general_operand" "")))
9014    (clobber (reg:CC FLAGS_REG))]
9015   ""
9016   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9017
9018 (define_insn "*xorsi_1"
9019   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9020         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9021                 (match_operand:SI 2 "general_operand" "ri,rm")))
9022    (clobber (reg:CC FLAGS_REG))]
9023   "ix86_binary_operator_ok (XOR, SImode, operands)"
9024   "xor{l}\t{%2, %0|%0, %2}"
9025   [(set_attr "type" "alu")
9026    (set_attr "mode" "SI")])
9027
9028 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9029 ;; Add speccase for immediates
9030 (define_insn "*xorsi_1_zext"
9031   [(set (match_operand:DI 0 "register_operand" "=r")
9032         (zero_extend:DI
9033           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9034                   (match_operand:SI 2 "general_operand" "rim"))))
9035    (clobber (reg:CC FLAGS_REG))]
9036   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9037   "xor{l}\t{%2, %k0|%k0, %2}"
9038   [(set_attr "type" "alu")
9039    (set_attr "mode" "SI")])
9040
9041 (define_insn "*xorsi_1_zext_imm"
9042   [(set (match_operand:DI 0 "register_operand" "=r")
9043         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9044                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9045    (clobber (reg:CC FLAGS_REG))]
9046   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9047   "xor{l}\t{%2, %k0|%k0, %2}"
9048   [(set_attr "type" "alu")
9049    (set_attr "mode" "SI")])
9050
9051 (define_insn "*xorsi_2"
9052   [(set (reg FLAGS_REG)
9053         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9054                          (match_operand:SI 2 "general_operand" "rim,ri"))
9055                  (const_int 0)))
9056    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9057         (xor:SI (match_dup 1) (match_dup 2)))]
9058   "ix86_match_ccmode (insn, CCNOmode)
9059    && ix86_binary_operator_ok (XOR, SImode, operands)"
9060   "xor{l}\t{%2, %0|%0, %2}"
9061   [(set_attr "type" "alu")
9062    (set_attr "mode" "SI")])
9063
9064 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9065 ;; ??? Special case for immediate operand is missing - it is tricky.
9066 (define_insn "*xorsi_2_zext"
9067   [(set (reg FLAGS_REG)
9068         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9069                          (match_operand:SI 2 "general_operand" "rim"))
9070                  (const_int 0)))
9071    (set (match_operand:DI 0 "register_operand" "=r")
9072         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9073   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9074    && ix86_binary_operator_ok (XOR, SImode, operands)"
9075   "xor{l}\t{%2, %k0|%k0, %2}"
9076   [(set_attr "type" "alu")
9077    (set_attr "mode" "SI")])
9078
9079 (define_insn "*xorsi_2_zext_imm"
9080   [(set (reg FLAGS_REG)
9081         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9082                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9083                  (const_int 0)))
9084    (set (match_operand:DI 0 "register_operand" "=r")
9085         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9086   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9087    && ix86_binary_operator_ok (XOR, SImode, operands)"
9088   "xor{l}\t{%2, %k0|%k0, %2}"
9089   [(set_attr "type" "alu")
9090    (set_attr "mode" "SI")])
9091
9092 (define_insn "*xorsi_3"
9093   [(set (reg FLAGS_REG)
9094         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9095                          (match_operand:SI 2 "general_operand" "rim"))
9096                  (const_int 0)))
9097    (clobber (match_scratch:SI 0 "=r"))]
9098   "ix86_match_ccmode (insn, CCNOmode)
9099    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9100   "xor{l}\t{%2, %0|%0, %2}"
9101   [(set_attr "type" "alu")
9102    (set_attr "mode" "SI")])
9103
9104 (define_expand "xorhi3"
9105   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9106         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9107                 (match_operand:HI 2 "general_operand" "")))
9108    (clobber (reg:CC FLAGS_REG))]
9109   "TARGET_HIMODE_MATH"
9110   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9111
9112 (define_insn "*xorhi_1"
9113   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9114         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9115                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9116    (clobber (reg:CC FLAGS_REG))]
9117   "ix86_binary_operator_ok (XOR, HImode, operands)"
9118   "xor{w}\t{%2, %0|%0, %2}"
9119   [(set_attr "type" "alu")
9120    (set_attr "mode" "HI")])
9121
9122 (define_insn "*xorhi_2"
9123   [(set (reg FLAGS_REG)
9124         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9125                          (match_operand:HI 2 "general_operand" "rim,ri"))
9126                  (const_int 0)))
9127    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9128         (xor:HI (match_dup 1) (match_dup 2)))]
9129   "ix86_match_ccmode (insn, CCNOmode)
9130    && ix86_binary_operator_ok (XOR, HImode, operands)"
9131   "xor{w}\t{%2, %0|%0, %2}"
9132   [(set_attr "type" "alu")
9133    (set_attr "mode" "HI")])
9134
9135 (define_insn "*xorhi_3"
9136   [(set (reg FLAGS_REG)
9137         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9138                          (match_operand:HI 2 "general_operand" "rim"))
9139                  (const_int 0)))
9140    (clobber (match_scratch:HI 0 "=r"))]
9141   "ix86_match_ccmode (insn, CCNOmode)
9142    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9143   "xor{w}\t{%2, %0|%0, %2}"
9144   [(set_attr "type" "alu")
9145    (set_attr "mode" "HI")])
9146
9147 (define_expand "xorqi3"
9148   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9149         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9150                 (match_operand:QI 2 "general_operand" "")))
9151    (clobber (reg:CC FLAGS_REG))]
9152   "TARGET_QIMODE_MATH"
9153   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9154
9155 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9156 (define_insn "*xorqi_1"
9157   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9158         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9159                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9160    (clobber (reg:CC FLAGS_REG))]
9161   "ix86_binary_operator_ok (XOR, QImode, operands)"
9162   "@
9163    xor{b}\t{%2, %0|%0, %2}
9164    xor{b}\t{%2, %0|%0, %2}
9165    xor{l}\t{%k2, %k0|%k0, %k2}"
9166   [(set_attr "type" "alu")
9167    (set_attr "mode" "QI,QI,SI")])
9168
9169 (define_insn "*xorqi_1_slp"
9170   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9171         (xor:QI (match_dup 0)
9172                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9173    (clobber (reg:CC FLAGS_REG))]
9174   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9175    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9176   "xor{b}\t{%1, %0|%0, %1}"
9177   [(set_attr "type" "alu1")
9178    (set_attr "mode" "QI")])
9179
9180 (define_insn "xorqi_ext_0"
9181   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9182                          (const_int 8)
9183                          (const_int 8))
9184         (xor:SI
9185           (zero_extract:SI
9186             (match_operand 1 "ext_register_operand" "0")
9187             (const_int 8)
9188             (const_int 8))
9189           (match_operand 2 "const_int_operand" "n")))
9190    (clobber (reg:CC FLAGS_REG))]
9191   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9192   "xor{b}\t{%2, %h0|%h0, %2}"
9193   [(set_attr "type" "alu")
9194    (set_attr "length_immediate" "1")
9195    (set_attr "mode" "QI")])
9196
9197 (define_insn "*xorqi_ext_1"
9198   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9199                          (const_int 8)
9200                          (const_int 8))
9201         (xor:SI
9202           (zero_extract:SI
9203             (match_operand 1 "ext_register_operand" "0")
9204             (const_int 8)
9205             (const_int 8))
9206           (zero_extend:SI
9207             (match_operand:QI 2 "general_operand" "Qm"))))
9208    (clobber (reg:CC FLAGS_REG))]
9209   "!TARGET_64BIT
9210    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9211   "xor{b}\t{%2, %h0|%h0, %2}"
9212   [(set_attr "type" "alu")
9213    (set_attr "length_immediate" "0")
9214    (set_attr "mode" "QI")])
9215
9216 (define_insn "*xorqi_ext_1_rex64"
9217   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9218                          (const_int 8)
9219                          (const_int 8))
9220         (xor:SI
9221           (zero_extract:SI
9222             (match_operand 1 "ext_register_operand" "0")
9223             (const_int 8)
9224             (const_int 8))
9225           (zero_extend:SI
9226             (match_operand 2 "ext_register_operand" "Q"))))
9227    (clobber (reg:CC FLAGS_REG))]
9228   "TARGET_64BIT
9229    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9230   "xor{b}\t{%2, %h0|%h0, %2}"
9231   [(set_attr "type" "alu")
9232    (set_attr "length_immediate" "0")
9233    (set_attr "mode" "QI")])
9234
9235 (define_insn "*xorqi_ext_2"
9236   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9237                          (const_int 8)
9238                          (const_int 8))
9239         (xor:SI
9240           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9241                            (const_int 8)
9242                            (const_int 8))
9243           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9244                            (const_int 8)
9245                            (const_int 8))))
9246    (clobber (reg:CC FLAGS_REG))]
9247   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9248   "xor{b}\t{%h2, %h0|%h0, %h2}"
9249   [(set_attr "type" "alu")
9250    (set_attr "length_immediate" "0")
9251    (set_attr "mode" "QI")])
9252
9253 (define_insn "*xorqi_cc_1"
9254   [(set (reg FLAGS_REG)
9255         (compare
9256           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9257                   (match_operand:QI 2 "general_operand" "qim,qi"))
9258           (const_int 0)))
9259    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9260         (xor:QI (match_dup 1) (match_dup 2)))]
9261   "ix86_match_ccmode (insn, CCNOmode)
9262    && ix86_binary_operator_ok (XOR, QImode, operands)"
9263   "xor{b}\t{%2, %0|%0, %2}"
9264   [(set_attr "type" "alu")
9265    (set_attr "mode" "QI")])
9266
9267 (define_insn "*xorqi_2_slp"
9268   [(set (reg FLAGS_REG)
9269         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9270                          (match_operand:QI 1 "general_operand" "qim,qi"))
9271                  (const_int 0)))
9272    (set (strict_low_part (match_dup 0))
9273         (xor:QI (match_dup 0) (match_dup 1)))]
9274   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9275    && ix86_match_ccmode (insn, CCNOmode)
9276    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9277   "xor{b}\t{%1, %0|%0, %1}"
9278   [(set_attr "type" "alu1")
9279    (set_attr "mode" "QI")])
9280
9281 (define_insn "*xorqi_cc_2"
9282   [(set (reg FLAGS_REG)
9283         (compare
9284           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9285                   (match_operand:QI 2 "general_operand" "qim"))
9286           (const_int 0)))
9287    (clobber (match_scratch:QI 0 "=q"))]
9288   "ix86_match_ccmode (insn, CCNOmode)
9289    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9290   "xor{b}\t{%2, %0|%0, %2}"
9291   [(set_attr "type" "alu")
9292    (set_attr "mode" "QI")])
9293
9294 (define_insn "*xorqi_cc_ext_1"
9295   [(set (reg FLAGS_REG)
9296         (compare
9297           (xor:SI
9298             (zero_extract:SI
9299               (match_operand 1 "ext_register_operand" "0")
9300               (const_int 8)
9301               (const_int 8))
9302             (match_operand:QI 2 "general_operand" "qmn"))
9303           (const_int 0)))
9304    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9305                          (const_int 8)
9306                          (const_int 8))
9307         (xor:SI
9308           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9309           (match_dup 2)))]
9310   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9311   "xor{b}\t{%2, %h0|%h0, %2}"
9312   [(set_attr "type" "alu")
9313    (set_attr "mode" "QI")])
9314
9315 (define_insn "*xorqi_cc_ext_1_rex64"
9316   [(set (reg FLAGS_REG)
9317         (compare
9318           (xor:SI
9319             (zero_extract:SI
9320               (match_operand 1 "ext_register_operand" "0")
9321               (const_int 8)
9322               (const_int 8))
9323             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9324           (const_int 0)))
9325    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9326                          (const_int 8)
9327                          (const_int 8))
9328         (xor:SI
9329           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9330           (match_dup 2)))]
9331   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9332   "xor{b}\t{%2, %h0|%h0, %2}"
9333   [(set_attr "type" "alu")
9334    (set_attr "mode" "QI")])
9335
9336 (define_expand "xorqi_cc_ext_1"
9337   [(parallel [
9338      (set (reg:CCNO FLAGS_REG)
9339           (compare:CCNO
9340             (xor:SI
9341               (zero_extract:SI
9342                 (match_operand 1 "ext_register_operand" "")
9343                 (const_int 8)
9344                 (const_int 8))
9345               (match_operand:QI 2 "general_operand" ""))
9346             (const_int 0)))
9347      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9348                            (const_int 8)
9349                            (const_int 8))
9350           (xor:SI
9351             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9352             (match_dup 2)))])]
9353   ""
9354   "")
9355
9356 (define_split
9357   [(set (match_operand 0 "register_operand" "")
9358         (xor (match_operand 1 "register_operand" "")
9359              (match_operand 2 "const_int_operand" "")))
9360    (clobber (reg:CC FLAGS_REG))]
9361    "reload_completed
9362     && QI_REG_P (operands[0])
9363     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9364     && !(INTVAL (operands[2]) & ~(255 << 8))
9365     && GET_MODE (operands[0]) != QImode"
9366   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9367                    (xor:SI (zero_extract:SI (match_dup 1)
9368                                             (const_int 8) (const_int 8))
9369                            (match_dup 2)))
9370               (clobber (reg:CC FLAGS_REG))])]
9371   "operands[0] = gen_lowpart (SImode, operands[0]);
9372    operands[1] = gen_lowpart (SImode, operands[1]);
9373    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9374
9375 ;; Since XOR can be encoded with sign extended immediate, this is only
9376 ;; profitable when 7th bit is set.
9377 (define_split
9378   [(set (match_operand 0 "register_operand" "")
9379         (xor (match_operand 1 "general_operand" "")
9380              (match_operand 2 "const_int_operand" "")))
9381    (clobber (reg:CC FLAGS_REG))]
9382    "reload_completed
9383     && ANY_QI_REG_P (operands[0])
9384     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9385     && !(INTVAL (operands[2]) & ~255)
9386     && (INTVAL (operands[2]) & 128)
9387     && GET_MODE (operands[0]) != QImode"
9388   [(parallel [(set (strict_low_part (match_dup 0))
9389                    (xor:QI (match_dup 1)
9390                            (match_dup 2)))
9391               (clobber (reg:CC FLAGS_REG))])]
9392   "operands[0] = gen_lowpart (QImode, operands[0]);
9393    operands[1] = gen_lowpart (QImode, operands[1]);
9394    operands[2] = gen_lowpart (QImode, operands[2]);")
9395 \f
9396 ;; Negation instructions
9397
9398 (define_expand "negti2"
9399   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9400                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9401               (clobber (reg:CC FLAGS_REG))])]
9402   "TARGET_64BIT"
9403   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9404
9405 (define_insn "*negti2_1"
9406   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9407         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9408    (clobber (reg:CC FLAGS_REG))]
9409   "TARGET_64BIT
9410    && ix86_unary_operator_ok (NEG, TImode, operands)"
9411   "#")
9412
9413 (define_split
9414   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9415         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9416    (clobber (reg:CC FLAGS_REG))]
9417   "TARGET_64BIT && reload_completed"
9418   [(parallel
9419     [(set (reg:CCZ FLAGS_REG)
9420           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9421      (set (match_dup 0) (neg:DI (match_dup 2)))])
9422    (parallel
9423     [(set (match_dup 1)
9424           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9425                             (match_dup 3))
9426                    (const_int 0)))
9427      (clobber (reg:CC FLAGS_REG))])
9428    (parallel
9429     [(set (match_dup 1)
9430           (neg:DI (match_dup 1)))
9431      (clobber (reg:CC FLAGS_REG))])]
9432   "split_ti (operands+1, 1, operands+2, operands+3);
9433    split_ti (operands+0, 1, operands+0, operands+1);")
9434
9435 (define_expand "negdi2"
9436   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9437                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9438               (clobber (reg:CC FLAGS_REG))])]
9439   ""
9440   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9441
9442 (define_insn "*negdi2_1"
9443   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9444         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9445    (clobber (reg:CC FLAGS_REG))]
9446   "!TARGET_64BIT
9447    && ix86_unary_operator_ok (NEG, DImode, operands)"
9448   "#")
9449
9450 (define_split
9451   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9452         (neg:DI (match_operand:DI 1 "general_operand" "")))
9453    (clobber (reg:CC FLAGS_REG))]
9454   "!TARGET_64BIT && reload_completed"
9455   [(parallel
9456     [(set (reg:CCZ FLAGS_REG)
9457           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9458      (set (match_dup 0) (neg:SI (match_dup 2)))])
9459    (parallel
9460     [(set (match_dup 1)
9461           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9462                             (match_dup 3))
9463                    (const_int 0)))
9464      (clobber (reg:CC FLAGS_REG))])
9465    (parallel
9466     [(set (match_dup 1)
9467           (neg:SI (match_dup 1)))
9468      (clobber (reg:CC FLAGS_REG))])]
9469   "split_di (operands+1, 1, operands+2, operands+3);
9470    split_di (operands+0, 1, operands+0, operands+1);")
9471
9472 (define_insn "*negdi2_1_rex64"
9473   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9474         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9475    (clobber (reg:CC FLAGS_REG))]
9476   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9477   "neg{q}\t%0"
9478   [(set_attr "type" "negnot")
9479    (set_attr "mode" "DI")])
9480
9481 ;; The problem with neg is that it does not perform (compare x 0),
9482 ;; it really performs (compare 0 x), which leaves us with the zero
9483 ;; flag being the only useful item.
9484
9485 (define_insn "*negdi2_cmpz_rex64"
9486   [(set (reg:CCZ FLAGS_REG)
9487         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9488                      (const_int 0)))
9489    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9490         (neg:DI (match_dup 1)))]
9491   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9492   "neg{q}\t%0"
9493   [(set_attr "type" "negnot")
9494    (set_attr "mode" "DI")])
9495
9496
9497 (define_expand "negsi2"
9498   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9499                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9500               (clobber (reg:CC FLAGS_REG))])]
9501   ""
9502   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9503
9504 (define_insn "*negsi2_1"
9505   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9506         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9507    (clobber (reg:CC FLAGS_REG))]
9508   "ix86_unary_operator_ok (NEG, SImode, operands)"
9509   "neg{l}\t%0"
9510   [(set_attr "type" "negnot")
9511    (set_attr "mode" "SI")])
9512
9513 ;; Combine is quite creative about this pattern.
9514 (define_insn "*negsi2_1_zext"
9515   [(set (match_operand:DI 0 "register_operand" "=r")
9516         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9517                                         (const_int 32)))
9518                      (const_int 32)))
9519    (clobber (reg:CC FLAGS_REG))]
9520   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9521   "neg{l}\t%k0"
9522   [(set_attr "type" "negnot")
9523    (set_attr "mode" "SI")])
9524
9525 ;; The problem with neg is that it does not perform (compare x 0),
9526 ;; it really performs (compare 0 x), which leaves us with the zero
9527 ;; flag being the only useful item.
9528
9529 (define_insn "*negsi2_cmpz"
9530   [(set (reg:CCZ FLAGS_REG)
9531         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9532                      (const_int 0)))
9533    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9534         (neg:SI (match_dup 1)))]
9535   "ix86_unary_operator_ok (NEG, SImode, operands)"
9536   "neg{l}\t%0"
9537   [(set_attr "type" "negnot")
9538    (set_attr "mode" "SI")])
9539
9540 (define_insn "*negsi2_cmpz_zext"
9541   [(set (reg:CCZ FLAGS_REG)
9542         (compare:CCZ (lshiftrt:DI
9543                        (neg:DI (ashift:DI
9544                                  (match_operand:DI 1 "register_operand" "0")
9545                                  (const_int 32)))
9546                        (const_int 32))
9547                      (const_int 0)))
9548    (set (match_operand:DI 0 "register_operand" "=r")
9549         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9550                                         (const_int 32)))
9551                      (const_int 32)))]
9552   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9553   "neg{l}\t%k0"
9554   [(set_attr "type" "negnot")
9555    (set_attr "mode" "SI")])
9556
9557 (define_expand "neghi2"
9558   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9559                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9560               (clobber (reg:CC FLAGS_REG))])]
9561   "TARGET_HIMODE_MATH"
9562   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9563
9564 (define_insn "*neghi2_1"
9565   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9566         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9567    (clobber (reg:CC FLAGS_REG))]
9568   "ix86_unary_operator_ok (NEG, HImode, operands)"
9569   "neg{w}\t%0"
9570   [(set_attr "type" "negnot")
9571    (set_attr "mode" "HI")])
9572
9573 (define_insn "*neghi2_cmpz"
9574   [(set (reg:CCZ FLAGS_REG)
9575         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9576                      (const_int 0)))
9577    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9578         (neg:HI (match_dup 1)))]
9579   "ix86_unary_operator_ok (NEG, HImode, operands)"
9580   "neg{w}\t%0"
9581   [(set_attr "type" "negnot")
9582    (set_attr "mode" "HI")])
9583
9584 (define_expand "negqi2"
9585   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9586                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9587               (clobber (reg:CC FLAGS_REG))])]
9588   "TARGET_QIMODE_MATH"
9589   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9590
9591 (define_insn "*negqi2_1"
9592   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9593         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9594    (clobber (reg:CC FLAGS_REG))]
9595   "ix86_unary_operator_ok (NEG, QImode, operands)"
9596   "neg{b}\t%0"
9597   [(set_attr "type" "negnot")
9598    (set_attr "mode" "QI")])
9599
9600 (define_insn "*negqi2_cmpz"
9601   [(set (reg:CCZ FLAGS_REG)
9602         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9603                      (const_int 0)))
9604    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9605         (neg:QI (match_dup 1)))]
9606   "ix86_unary_operator_ok (NEG, QImode, operands)"
9607   "neg{b}\t%0"
9608   [(set_attr "type" "negnot")
9609    (set_attr "mode" "QI")])
9610
9611 ;; Changing of sign for FP values is doable using integer unit too.
9612
9613 (define_expand "negsf2"
9614   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9615         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9616   "TARGET_80387 || TARGET_SSE_MATH"
9617   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9618
9619 (define_expand "abssf2"
9620   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9621         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9622   "TARGET_80387 || TARGET_SSE_MATH"
9623   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9624
9625 (define_insn "*absnegsf2_mixed"
9626   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9627         (match_operator:SF 3 "absneg_operator"
9628           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9629    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9630    (clobber (reg:CC FLAGS_REG))]
9631   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9632    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9633   "#")
9634
9635 (define_insn "*absnegsf2_sse"
9636   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9637         (match_operator:SF 3 "absneg_operator"
9638           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9639    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9640    (clobber (reg:CC FLAGS_REG))]
9641   "TARGET_SSE_MATH
9642    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9643   "#")
9644
9645 (define_insn "*absnegsf2_i387"
9646   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9647         (match_operator:SF 3 "absneg_operator"
9648           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9649    (use (match_operand 2 "" ""))
9650    (clobber (reg:CC FLAGS_REG))]
9651   "TARGET_80387 && !TARGET_SSE_MATH
9652    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9653   "#")
9654
9655 (define_expand "negdf2"
9656   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9657         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9658   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9659   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9660
9661 (define_expand "absdf2"
9662   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9663         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9664   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9665   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9666
9667 (define_insn "*absnegdf2_mixed"
9668   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
9669         (match_operator:DF 3 "absneg_operator"
9670           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9671    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
9672    (clobber (reg:CC FLAGS_REG))]
9673   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9674    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9675   "#")
9676
9677 (define_insn "*absnegdf2_sse"
9678   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
9679         (match_operator:DF 3 "absneg_operator"
9680           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
9681    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
9682    (clobber (reg:CC FLAGS_REG))]
9683   "TARGET_SSE2 && TARGET_SSE_MATH
9684    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9685   "#")
9686
9687 (define_insn "*absnegdf2_i387"
9688   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9689         (match_operator:DF 3 "absneg_operator"
9690           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9691    (use (match_operand 2 "" ""))
9692    (clobber (reg:CC FLAGS_REG))]
9693   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9694    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9695   "#")
9696
9697 (define_expand "negxf2"
9698   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9699         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9700   "TARGET_80387"
9701   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9702
9703 (define_expand "absxf2"
9704   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9705         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9706   "TARGET_80387"
9707   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9708
9709 (define_insn "*absnegxf2_i387"
9710   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9711         (match_operator:XF 3 "absneg_operator"
9712           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9713    (use (match_operand 2 "" ""))
9714    (clobber (reg:CC FLAGS_REG))]
9715   "TARGET_80387
9716    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9717   "#")
9718
9719 (define_expand "negtf2"
9720   [(set (match_operand:TF 0 "nonimmediate_operand" "")
9721         (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
9722   "TARGET_64BIT"
9723   "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
9724
9725 (define_expand "abstf2"
9726   [(set (match_operand:TF 0 "nonimmediate_operand" "")
9727         (abs:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
9728   "TARGET_64BIT"
9729   "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
9730
9731 (define_insn "*absnegtf2_sse"
9732   [(set (match_operand:TF 0 "nonimmediate_operand"    "=x,x,m")
9733         (match_operator:TF 3 "absneg_operator"
9734           [(match_operand:TF 1 "nonimmediate_operand" "0, x,0")]))
9735    (use (match_operand:TF 2 "nonimmediate_operand"    "xm,0,X"))
9736    (clobber (reg:CC FLAGS_REG))]
9737   "TARGET_64BIT
9738    && ix86_unary_operator_ok (GET_CODE (operands[3]), TFmode, operands)"
9739   "#")
9740
9741 ;; Splitters for fp abs and neg.
9742
9743 (define_split
9744   [(set (match_operand 0 "fp_register_operand" "")
9745         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9746    (use (match_operand 2 "" ""))
9747    (clobber (reg:CC FLAGS_REG))]
9748   "reload_completed"
9749   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9750
9751 (define_split
9752   [(set (match_operand 0 "register_operand" "")
9753         (match_operator 3 "absneg_operator"
9754           [(match_operand 1 "register_operand" "")]))
9755    (use (match_operand 2 "nonimmediate_operand" ""))
9756    (clobber (reg:CC FLAGS_REG))]
9757   "reload_completed && SSE_REG_P (operands[0])"
9758   [(set (match_dup 0) (match_dup 3))]
9759 {
9760   enum machine_mode mode = GET_MODE (operands[0]);
9761   enum machine_mode vmode = GET_MODE (operands[2]);
9762   rtx tmp;
9763
9764   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9765   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9766   if (operands_match_p (operands[0], operands[2]))
9767     {
9768       tmp = operands[1];
9769       operands[1] = operands[2];
9770       operands[2] = tmp;
9771     }
9772   if (GET_CODE (operands[3]) == ABS)
9773     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9774   else
9775     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9776   operands[3] = tmp;
9777 })
9778
9779 (define_split
9780   [(set (match_operand:SF 0 "register_operand" "")
9781         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9782    (use (match_operand:V4SF 2 "" ""))
9783    (clobber (reg:CC FLAGS_REG))]
9784   "reload_completed"
9785   [(parallel [(set (match_dup 0) (match_dup 1))
9786               (clobber (reg:CC FLAGS_REG))])]
9787 {
9788   rtx tmp;
9789   operands[0] = gen_lowpart (SImode, operands[0]);
9790   if (GET_CODE (operands[1]) == ABS)
9791     {
9792       tmp = gen_int_mode (0x7fffffff, SImode);
9793       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9794     }
9795   else
9796     {
9797       tmp = gen_int_mode (0x80000000, SImode);
9798       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9799     }
9800   operands[1] = tmp;
9801 })
9802
9803 (define_split
9804   [(set (match_operand:DF 0 "register_operand" "")
9805         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9806    (use (match_operand 2 "" ""))
9807    (clobber (reg:CC FLAGS_REG))]
9808   "reload_completed"
9809   [(parallel [(set (match_dup 0) (match_dup 1))
9810               (clobber (reg:CC FLAGS_REG))])]
9811 {
9812   rtx tmp;
9813   if (TARGET_64BIT)
9814     {
9815       tmp = gen_lowpart (DImode, operands[0]);
9816       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9817       operands[0] = tmp;
9818
9819       if (GET_CODE (operands[1]) == ABS)
9820         tmp = const0_rtx;
9821       else
9822         tmp = gen_rtx_NOT (DImode, tmp);
9823     }
9824   else
9825     {
9826       operands[0] = gen_highpart (SImode, operands[0]);
9827       if (GET_CODE (operands[1]) == ABS)
9828         {
9829           tmp = gen_int_mode (0x7fffffff, SImode);
9830           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9831         }
9832       else
9833         {
9834           tmp = gen_int_mode (0x80000000, SImode);
9835           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9836         }
9837     }
9838   operands[1] = tmp;
9839 })
9840
9841 (define_split
9842   [(set (match_operand:XF 0 "register_operand" "")
9843         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9844    (use (match_operand 2 "" ""))
9845    (clobber (reg:CC FLAGS_REG))]
9846   "reload_completed"
9847   [(parallel [(set (match_dup 0) (match_dup 1))
9848               (clobber (reg:CC FLAGS_REG))])]
9849 {
9850   rtx tmp;
9851   operands[0] = gen_rtx_REG (SImode,
9852                              true_regnum (operands[0])
9853                              + (TARGET_64BIT ? 1 : 2));
9854   if (GET_CODE (operands[1]) == ABS)
9855     {
9856       tmp = GEN_INT (0x7fff);
9857       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9858     }
9859   else
9860     {
9861       tmp = GEN_INT (0x8000);
9862       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9863     }
9864   operands[1] = tmp;
9865 })
9866
9867 (define_split
9868   [(set (match_operand 0 "memory_operand" "")
9869         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9870    (use (match_operand 2 "" ""))
9871    (clobber (reg:CC FLAGS_REG))]
9872   "reload_completed"
9873   [(parallel [(set (match_dup 0) (match_dup 1))
9874               (clobber (reg:CC FLAGS_REG))])]
9875 {
9876   enum machine_mode mode = GET_MODE (operands[0]);
9877   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9878   rtx tmp;
9879
9880   operands[0] = adjust_address (operands[0], QImode, size - 1);
9881   if (GET_CODE (operands[1]) == ABS)
9882     {
9883       tmp = gen_int_mode (0x7f, QImode);
9884       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9885     }
9886   else
9887     {
9888       tmp = gen_int_mode (0x80, QImode);
9889       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9890     }
9891   operands[1] = tmp;
9892 })
9893
9894 ;; Conditionalize these after reload. If they match before reload, we
9895 ;; lose the clobber and ability to use integer instructions.
9896
9897 (define_insn "*negsf2_1"
9898   [(set (match_operand:SF 0 "register_operand" "=f")
9899         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9900   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9901   "fchs"
9902   [(set_attr "type" "fsgn")
9903    (set_attr "mode" "SF")])
9904
9905 (define_insn "*negdf2_1"
9906   [(set (match_operand:DF 0 "register_operand" "=f")
9907         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9908   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9909   "fchs"
9910   [(set_attr "type" "fsgn")
9911    (set_attr "mode" "DF")])
9912
9913 (define_insn "*negxf2_1"
9914   [(set (match_operand:XF 0 "register_operand" "=f")
9915         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9916   "TARGET_80387"
9917   "fchs"
9918   [(set_attr "type" "fsgn")
9919    (set_attr "mode" "XF")])
9920
9921 (define_insn "*abssf2_1"
9922   [(set (match_operand:SF 0 "register_operand" "=f")
9923         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9924   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9925   "fabs"
9926   [(set_attr "type" "fsgn")
9927    (set_attr "mode" "SF")])
9928
9929 (define_insn "*absdf2_1"
9930   [(set (match_operand:DF 0 "register_operand" "=f")
9931         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9932   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9933   "fabs"
9934   [(set_attr "type" "fsgn")
9935    (set_attr "mode" "DF")])
9936
9937 (define_insn "*absxf2_1"
9938   [(set (match_operand:XF 0 "register_operand" "=f")
9939         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9940   "TARGET_80387"
9941   "fabs"
9942   [(set_attr "type" "fsgn")
9943    (set_attr "mode" "DF")])
9944
9945 (define_insn "*negextendsfdf2"
9946   [(set (match_operand:DF 0 "register_operand" "=f")
9947         (neg:DF (float_extend:DF
9948                   (match_operand:SF 1 "register_operand" "0"))))]
9949   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9950   "fchs"
9951   [(set_attr "type" "fsgn")
9952    (set_attr "mode" "DF")])
9953
9954 (define_insn "*negextenddfxf2"
9955   [(set (match_operand:XF 0 "register_operand" "=f")
9956         (neg:XF (float_extend:XF
9957                   (match_operand:DF 1 "register_operand" "0"))))]
9958   "TARGET_80387"
9959   "fchs"
9960   [(set_attr "type" "fsgn")
9961    (set_attr "mode" "XF")])
9962
9963 (define_insn "*negextendsfxf2"
9964   [(set (match_operand:XF 0 "register_operand" "=f")
9965         (neg:XF (float_extend:XF
9966                   (match_operand:SF 1 "register_operand" "0"))))]
9967   "TARGET_80387"
9968   "fchs"
9969   [(set_attr "type" "fsgn")
9970    (set_attr "mode" "XF")])
9971
9972 (define_insn "*absextendsfdf2"
9973   [(set (match_operand:DF 0 "register_operand" "=f")
9974         (abs:DF (float_extend:DF
9975                   (match_operand:SF 1 "register_operand" "0"))))]
9976   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9977   "fabs"
9978   [(set_attr "type" "fsgn")
9979    (set_attr "mode" "DF")])
9980
9981 (define_insn "*absextenddfxf2"
9982   [(set (match_operand:XF 0 "register_operand" "=f")
9983         (abs:XF (float_extend:XF
9984           (match_operand:DF 1 "register_operand" "0"))))]
9985   "TARGET_80387"
9986   "fabs"
9987   [(set_attr "type" "fsgn")
9988    (set_attr "mode" "XF")])
9989
9990 (define_insn "*absextendsfxf2"
9991   [(set (match_operand:XF 0 "register_operand" "=f")
9992         (abs:XF (float_extend:XF
9993           (match_operand:SF 1 "register_operand" "0"))))]
9994   "TARGET_80387"
9995   "fabs"
9996   [(set_attr "type" "fsgn")
9997    (set_attr "mode" "XF")])
9998
9999 ;; Copysign instructions
10000
10001 (define_mode_macro CSGNMODE [SF DF TF])
10002 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10003
10004 (define_expand "copysign<mode>3"
10005   [(match_operand:CSGNMODE 0 "register_operand" "")
10006    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10007    (match_operand:CSGNMODE 2 "register_operand" "")]
10008   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10009    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10010 {
10011   ix86_expand_copysign (operands);
10012   DONE;
10013 })
10014
10015 (define_insn_and_split "copysign<mode>3_const"
10016   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10017         (unspec:CSGNMODE
10018           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10019            (match_operand:CSGNMODE 2 "register_operand" "0")
10020            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10021           UNSPEC_COPYSIGN))]
10022   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10023    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10024   "#"
10025   "&& reload_completed"
10026   [(const_int 0)]
10027 {
10028   ix86_split_copysign_const (operands);
10029   DONE;
10030 })
10031
10032 (define_insn "copysign<mode>3_var"
10033   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10034         (unspec:CSGNMODE
10035           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10036            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10037            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10038            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10039           UNSPEC_COPYSIGN))
10040    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10041   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10042    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10043   "#")
10044
10045 (define_split
10046   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10047         (unspec:CSGNMODE
10048           [(match_operand:CSGNMODE 2 "register_operand" "")
10049            (match_operand:CSGNMODE 3 "register_operand" "")
10050            (match_operand:<CSGNVMODE> 4 "" "")
10051            (match_operand:<CSGNVMODE> 5 "" "")]
10052           UNSPEC_COPYSIGN))
10053    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10054   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10055     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10056    && reload_completed"
10057   [(const_int 0)]
10058 {
10059   ix86_split_copysign_var (operands);
10060   DONE;
10061 })
10062 \f
10063 ;; One complement instructions
10064
10065 (define_expand "one_cmpldi2"
10066   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10067         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10068   "TARGET_64BIT"
10069   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10070
10071 (define_insn "*one_cmpldi2_1_rex64"
10072   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10073         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10074   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10075   "not{q}\t%0"
10076   [(set_attr "type" "negnot")
10077    (set_attr "mode" "DI")])
10078
10079 (define_insn "*one_cmpldi2_2_rex64"
10080   [(set (reg FLAGS_REG)
10081         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10082                  (const_int 0)))
10083    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10084         (not:DI (match_dup 1)))]
10085   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10086    && ix86_unary_operator_ok (NOT, DImode, operands)"
10087   "#"
10088   [(set_attr "type" "alu1")
10089    (set_attr "mode" "DI")])
10090
10091 (define_split
10092   [(set (match_operand 0 "flags_reg_operand" "")
10093         (match_operator 2 "compare_operator"
10094           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10095            (const_int 0)]))
10096    (set (match_operand:DI 1 "nonimmediate_operand" "")
10097         (not:DI (match_dup 3)))]
10098   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10099   [(parallel [(set (match_dup 0)
10100                    (match_op_dup 2
10101                      [(xor:DI (match_dup 3) (const_int -1))
10102                       (const_int 0)]))
10103               (set (match_dup 1)
10104                    (xor:DI (match_dup 3) (const_int -1)))])]
10105   "")
10106
10107 (define_expand "one_cmplsi2"
10108   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10109         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10110   ""
10111   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10112
10113 (define_insn "*one_cmplsi2_1"
10114   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10115         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10116   "ix86_unary_operator_ok (NOT, SImode, operands)"
10117   "not{l}\t%0"
10118   [(set_attr "type" "negnot")
10119    (set_attr "mode" "SI")])
10120
10121 ;; ??? Currently never generated - xor is used instead.
10122 (define_insn "*one_cmplsi2_1_zext"
10123   [(set (match_operand:DI 0 "register_operand" "=r")
10124         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10125   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10126   "not{l}\t%k0"
10127   [(set_attr "type" "negnot")
10128    (set_attr "mode" "SI")])
10129
10130 (define_insn "*one_cmplsi2_2"
10131   [(set (reg FLAGS_REG)
10132         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10133                  (const_int 0)))
10134    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10135         (not:SI (match_dup 1)))]
10136   "ix86_match_ccmode (insn, CCNOmode)
10137    && ix86_unary_operator_ok (NOT, SImode, operands)"
10138   "#"
10139   [(set_attr "type" "alu1")
10140    (set_attr "mode" "SI")])
10141
10142 (define_split
10143   [(set (match_operand 0 "flags_reg_operand" "")
10144         (match_operator 2 "compare_operator"
10145           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10146            (const_int 0)]))
10147    (set (match_operand:SI 1 "nonimmediate_operand" "")
10148         (not:SI (match_dup 3)))]
10149   "ix86_match_ccmode (insn, CCNOmode)"
10150   [(parallel [(set (match_dup 0)
10151                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10152                                     (const_int 0)]))
10153               (set (match_dup 1)
10154                    (xor:SI (match_dup 3) (const_int -1)))])]
10155   "")
10156
10157 ;; ??? Currently never generated - xor is used instead.
10158 (define_insn "*one_cmplsi2_2_zext"
10159   [(set (reg FLAGS_REG)
10160         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10161                  (const_int 0)))
10162    (set (match_operand:DI 0 "register_operand" "=r")
10163         (zero_extend:DI (not:SI (match_dup 1))))]
10164   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10165    && ix86_unary_operator_ok (NOT, SImode, operands)"
10166   "#"
10167   [(set_attr "type" "alu1")
10168    (set_attr "mode" "SI")])
10169
10170 (define_split
10171   [(set (match_operand 0 "flags_reg_operand" "")
10172         (match_operator 2 "compare_operator"
10173           [(not:SI (match_operand:SI 3 "register_operand" ""))
10174            (const_int 0)]))
10175    (set (match_operand:DI 1 "register_operand" "")
10176         (zero_extend:DI (not:SI (match_dup 3))))]
10177   "ix86_match_ccmode (insn, CCNOmode)"
10178   [(parallel [(set (match_dup 0)
10179                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10180                                     (const_int 0)]))
10181               (set (match_dup 1)
10182                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10183   "")
10184
10185 (define_expand "one_cmplhi2"
10186   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10187         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10188   "TARGET_HIMODE_MATH"
10189   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10190
10191 (define_insn "*one_cmplhi2_1"
10192   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10193         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10194   "ix86_unary_operator_ok (NOT, HImode, operands)"
10195   "not{w}\t%0"
10196   [(set_attr "type" "negnot")
10197    (set_attr "mode" "HI")])
10198
10199 (define_insn "*one_cmplhi2_2"
10200   [(set (reg FLAGS_REG)
10201         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10202                  (const_int 0)))
10203    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10204         (not:HI (match_dup 1)))]
10205   "ix86_match_ccmode (insn, CCNOmode)
10206    && ix86_unary_operator_ok (NEG, HImode, operands)"
10207   "#"
10208   [(set_attr "type" "alu1")
10209    (set_attr "mode" "HI")])
10210
10211 (define_split
10212   [(set (match_operand 0 "flags_reg_operand" "")
10213         (match_operator 2 "compare_operator"
10214           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10215            (const_int 0)]))
10216    (set (match_operand:HI 1 "nonimmediate_operand" "")
10217         (not:HI (match_dup 3)))]
10218   "ix86_match_ccmode (insn, CCNOmode)"
10219   [(parallel [(set (match_dup 0)
10220                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10221                                     (const_int 0)]))
10222               (set (match_dup 1)
10223                    (xor:HI (match_dup 3) (const_int -1)))])]
10224   "")
10225
10226 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10227 (define_expand "one_cmplqi2"
10228   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10229         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10230   "TARGET_QIMODE_MATH"
10231   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10232
10233 (define_insn "*one_cmplqi2_1"
10234   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10235         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10236   "ix86_unary_operator_ok (NOT, QImode, operands)"
10237   "@
10238    not{b}\t%0
10239    not{l}\t%k0"
10240   [(set_attr "type" "negnot")
10241    (set_attr "mode" "QI,SI")])
10242
10243 (define_insn "*one_cmplqi2_2"
10244   [(set (reg FLAGS_REG)
10245         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10246                  (const_int 0)))
10247    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10248         (not:QI (match_dup 1)))]
10249   "ix86_match_ccmode (insn, CCNOmode)
10250    && ix86_unary_operator_ok (NOT, QImode, operands)"
10251   "#"
10252   [(set_attr "type" "alu1")
10253    (set_attr "mode" "QI")])
10254
10255 (define_split
10256   [(set (match_operand 0 "flags_reg_operand" "")
10257         (match_operator 2 "compare_operator"
10258           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10259            (const_int 0)]))
10260    (set (match_operand:QI 1 "nonimmediate_operand" "")
10261         (not:QI (match_dup 3)))]
10262   "ix86_match_ccmode (insn, CCNOmode)"
10263   [(parallel [(set (match_dup 0)
10264                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10265                                     (const_int 0)]))
10266               (set (match_dup 1)
10267                    (xor:QI (match_dup 3) (const_int -1)))])]
10268   "")
10269 \f
10270 ;; Arithmetic shift instructions
10271
10272 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10273 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10274 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10275 ;; from the assembler input.
10276 ;;
10277 ;; This instruction shifts the target reg/mem as usual, but instead of
10278 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10279 ;; is a left shift double, bits are taken from the high order bits of
10280 ;; reg, else if the insn is a shift right double, bits are taken from the
10281 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10282 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10283 ;;
10284 ;; Since sh[lr]d does not change the `reg' operand, that is done
10285 ;; separately, making all shifts emit pairs of shift double and normal
10286 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10287 ;; support a 63 bit shift, each shift where the count is in a reg expands
10288 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10289 ;;
10290 ;; If the shift count is a constant, we need never emit more than one
10291 ;; shift pair, instead using moves and sign extension for counts greater
10292 ;; than 31.
10293
10294 (define_expand "ashlti3"
10295   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10296                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10297                               (match_operand:QI 2 "nonmemory_operand" "")))
10298               (clobber (reg:CC FLAGS_REG))])]
10299   "TARGET_64BIT"
10300 {
10301   if (! immediate_operand (operands[2], QImode))
10302     {
10303       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10304       DONE;
10305     }
10306   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10307   DONE;
10308 })
10309
10310 (define_insn "ashlti3_1"
10311   [(set (match_operand:TI 0 "register_operand" "=r")
10312         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10313                    (match_operand:QI 2 "register_operand" "c")))
10314    (clobber (match_scratch:DI 3 "=&r"))
10315    (clobber (reg:CC FLAGS_REG))]
10316   "TARGET_64BIT"
10317   "#"
10318   [(set_attr "type" "multi")])
10319
10320 (define_insn "*ashlti3_2"
10321   [(set (match_operand:TI 0 "register_operand" "=r")
10322         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10323                    (match_operand:QI 2 "immediate_operand" "O")))
10324    (clobber (reg:CC FLAGS_REG))]
10325   "TARGET_64BIT"
10326   "#"
10327   [(set_attr "type" "multi")])
10328
10329 (define_split
10330   [(set (match_operand:TI 0 "register_operand" "")
10331         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10332                    (match_operand:QI 2 "register_operand" "")))
10333    (clobber (match_scratch:DI 3 ""))
10334    (clobber (reg:CC FLAGS_REG))]
10335   "TARGET_64BIT && reload_completed"
10336   [(const_int 0)]
10337   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10338
10339 (define_split
10340   [(set (match_operand:TI 0 "register_operand" "")
10341         (ashift:TI (match_operand:TI 1 "register_operand" "")
10342                    (match_operand:QI 2 "immediate_operand" "")))
10343    (clobber (reg:CC FLAGS_REG))]
10344   "TARGET_64BIT && reload_completed"
10345   [(const_int 0)]
10346   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10347
10348 (define_insn "x86_64_shld"
10349   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10350         (ior:DI (ashift:DI (match_dup 0)
10351                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10352                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10353                   (minus:QI (const_int 64) (match_dup 2)))))
10354    (clobber (reg:CC FLAGS_REG))]
10355   "TARGET_64BIT"
10356   "@
10357    shld{q}\t{%2, %1, %0|%0, %1, %2}
10358    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10359   [(set_attr "type" "ishift")
10360    (set_attr "prefix_0f" "1")
10361    (set_attr "mode" "DI")
10362    (set_attr "athlon_decode" "vector")
10363    (set_attr "amdfam10_decode" "vector")])   
10364
10365 (define_expand "x86_64_shift_adj"
10366   [(set (reg:CCZ FLAGS_REG)
10367         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10368                              (const_int 64))
10369                      (const_int 0)))
10370    (set (match_operand:DI 0 "register_operand" "")
10371         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10372                          (match_operand:DI 1 "register_operand" "")
10373                          (match_dup 0)))
10374    (set (match_dup 1)
10375         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10376                          (match_operand:DI 3 "register_operand" "r")
10377                          (match_dup 1)))]
10378   "TARGET_64BIT"
10379   "")
10380
10381 (define_expand "ashldi3"
10382   [(set (match_operand:DI 0 "shiftdi_operand" "")
10383         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10384                    (match_operand:QI 2 "nonmemory_operand" "")))]
10385   ""
10386   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10387
10388 (define_insn "*ashldi3_1_rex64"
10389   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10390         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10391                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10392    (clobber (reg:CC FLAGS_REG))]
10393   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10394 {
10395   switch (get_attr_type (insn))
10396     {
10397     case TYPE_ALU:
10398       gcc_assert (operands[2] == const1_rtx);
10399       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10400       return "add{q}\t%0, %0";
10401
10402     case TYPE_LEA:
10403       gcc_assert (CONST_INT_P (operands[2]));
10404       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10405       operands[1] = gen_rtx_MULT (DImode, operands[1],
10406                                   GEN_INT (1 << INTVAL (operands[2])));
10407       return "lea{q}\t{%a1, %0|%0, %a1}";
10408
10409     default:
10410       if (REG_P (operands[2]))
10411         return "sal{q}\t{%b2, %0|%0, %b2}";
10412       else if (operands[2] == const1_rtx
10413                && (TARGET_SHIFT1 || optimize_size))
10414         return "sal{q}\t%0";
10415       else
10416         return "sal{q}\t{%2, %0|%0, %2}";
10417     }
10418 }
10419   [(set (attr "type")
10420      (cond [(eq_attr "alternative" "1")
10421               (const_string "lea")
10422             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10423                           (const_int 0))
10424                       (match_operand 0 "register_operand" ""))
10425                  (match_operand 2 "const1_operand" ""))
10426               (const_string "alu")
10427            ]
10428            (const_string "ishift")))
10429    (set_attr "mode" "DI")])
10430
10431 ;; Convert lea to the lea pattern to avoid flags dependency.
10432 (define_split
10433   [(set (match_operand:DI 0 "register_operand" "")
10434         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10435                    (match_operand:QI 2 "immediate_operand" "")))
10436    (clobber (reg:CC FLAGS_REG))]
10437   "TARGET_64BIT && reload_completed
10438    && true_regnum (operands[0]) != true_regnum (operands[1])"
10439   [(set (match_dup 0)
10440         (mult:DI (match_dup 1)
10441                  (match_dup 2)))]
10442   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10443
10444 ;; This pattern can't accept a variable shift count, since shifts by
10445 ;; zero don't affect the flags.  We assume that shifts by constant
10446 ;; zero are optimized away.
10447 (define_insn "*ashldi3_cmp_rex64"
10448   [(set (reg FLAGS_REG)
10449         (compare
10450           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10451                      (match_operand:QI 2 "immediate_operand" "e"))
10452           (const_int 0)))
10453    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10454         (ashift:DI (match_dup 1) (match_dup 2)))]
10455   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10456    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10457    && (optimize_size
10458        || !TARGET_PARTIAL_FLAG_REG_STALL
10459        || (operands[2] == const1_rtx
10460            && (TARGET_SHIFT1
10461                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10462 {
10463   switch (get_attr_type (insn))
10464     {
10465     case TYPE_ALU:
10466       gcc_assert (operands[2] == const1_rtx);
10467       return "add{q}\t%0, %0";
10468
10469     default:
10470       if (REG_P (operands[2]))
10471         return "sal{q}\t{%b2, %0|%0, %b2}";
10472       else if (operands[2] == const1_rtx
10473                && (TARGET_SHIFT1 || optimize_size))
10474         return "sal{q}\t%0";
10475       else
10476         return "sal{q}\t{%2, %0|%0, %2}";
10477     }
10478 }
10479   [(set (attr "type")
10480      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10481                           (const_int 0))
10482                       (match_operand 0 "register_operand" ""))
10483                  (match_operand 2 "const1_operand" ""))
10484               (const_string "alu")
10485            ]
10486            (const_string "ishift")))
10487    (set_attr "mode" "DI")])
10488
10489 (define_insn "*ashldi3_cconly_rex64"
10490   [(set (reg FLAGS_REG)
10491         (compare
10492           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10493                      (match_operand:QI 2 "immediate_operand" "e"))
10494           (const_int 0)))
10495    (clobber (match_scratch:DI 0 "=r"))]
10496   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10497    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10498    && (optimize_size
10499        || !TARGET_PARTIAL_FLAG_REG_STALL
10500        || (operands[2] == const1_rtx
10501            && (TARGET_SHIFT1
10502                || TARGET_DOUBLE_WITH_ADD)))"
10503 {
10504   switch (get_attr_type (insn))
10505     {
10506     case TYPE_ALU:
10507       gcc_assert (operands[2] == const1_rtx);
10508       return "add{q}\t%0, %0";
10509
10510     default:
10511       if (REG_P (operands[2]))
10512         return "sal{q}\t{%b2, %0|%0, %b2}";
10513       else if (operands[2] == const1_rtx
10514                && (TARGET_SHIFT1 || optimize_size))
10515         return "sal{q}\t%0";
10516       else
10517         return "sal{q}\t{%2, %0|%0, %2}";
10518     }
10519 }
10520   [(set (attr "type")
10521      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10522                           (const_int 0))
10523                       (match_operand 0 "register_operand" ""))
10524                  (match_operand 2 "const1_operand" ""))
10525               (const_string "alu")
10526            ]
10527            (const_string "ishift")))
10528    (set_attr "mode" "DI")])
10529
10530 (define_insn "*ashldi3_1"
10531   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10532         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10533                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10534    (clobber (reg:CC FLAGS_REG))]
10535   "!TARGET_64BIT"
10536   "#"
10537   [(set_attr "type" "multi")])
10538
10539 ;; By default we don't ask for a scratch register, because when DImode
10540 ;; values are manipulated, registers are already at a premium.  But if
10541 ;; we have one handy, we won't turn it away.
10542 (define_peephole2
10543   [(match_scratch:SI 3 "r")
10544    (parallel [(set (match_operand:DI 0 "register_operand" "")
10545                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10546                               (match_operand:QI 2 "nonmemory_operand" "")))
10547               (clobber (reg:CC FLAGS_REG))])
10548    (match_dup 3)]
10549   "!TARGET_64BIT && TARGET_CMOVE"
10550   [(const_int 0)]
10551   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10552
10553 (define_split
10554   [(set (match_operand:DI 0 "register_operand" "")
10555         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10556                    (match_operand:QI 2 "nonmemory_operand" "")))
10557    (clobber (reg:CC FLAGS_REG))]
10558   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10559                      ? flow2_completed : reload_completed)"
10560   [(const_int 0)]
10561   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10562
10563 (define_insn "x86_shld_1"
10564   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10565         (ior:SI (ashift:SI (match_dup 0)
10566                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10567                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10568                   (minus:QI (const_int 32) (match_dup 2)))))
10569    (clobber (reg:CC FLAGS_REG))]
10570   ""
10571   "@
10572    shld{l}\t{%2, %1, %0|%0, %1, %2}
10573    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10574   [(set_attr "type" "ishift")
10575    (set_attr "prefix_0f" "1")
10576    (set_attr "mode" "SI")
10577    (set_attr "pent_pair" "np")
10578    (set_attr "athlon_decode" "vector")
10579    (set_attr "amdfam10_decode" "vector")])   
10580
10581 (define_expand "x86_shift_adj_1"
10582   [(set (reg:CCZ FLAGS_REG)
10583         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10584                              (const_int 32))
10585                      (const_int 0)))
10586    (set (match_operand:SI 0 "register_operand" "")
10587         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10588                          (match_operand:SI 1 "register_operand" "")
10589                          (match_dup 0)))
10590    (set (match_dup 1)
10591         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10592                          (match_operand:SI 3 "register_operand" "r")
10593                          (match_dup 1)))]
10594   "TARGET_CMOVE"
10595   "")
10596
10597 (define_expand "x86_shift_adj_2"
10598   [(use (match_operand:SI 0 "register_operand" ""))
10599    (use (match_operand:SI 1 "register_operand" ""))
10600    (use (match_operand:QI 2 "register_operand" ""))]
10601   ""
10602 {
10603   rtx label = gen_label_rtx ();
10604   rtx tmp;
10605
10606   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10607
10608   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10609   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10610   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10611                               gen_rtx_LABEL_REF (VOIDmode, label),
10612                               pc_rtx);
10613   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10614   JUMP_LABEL (tmp) = label;
10615
10616   emit_move_insn (operands[0], operands[1]);
10617   ix86_expand_clear (operands[1]);
10618
10619   emit_label (label);
10620   LABEL_NUSES (label) = 1;
10621
10622   DONE;
10623 })
10624
10625 (define_expand "ashlsi3"
10626   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10627         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10628                    (match_operand:QI 2 "nonmemory_operand" "")))
10629    (clobber (reg:CC FLAGS_REG))]
10630   ""
10631   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10632
10633 (define_insn "*ashlsi3_1"
10634   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10635         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10636                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10637    (clobber (reg:CC FLAGS_REG))]
10638   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10639 {
10640   switch (get_attr_type (insn))
10641     {
10642     case TYPE_ALU:
10643       gcc_assert (operands[2] == const1_rtx);
10644       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10645       return "add{l}\t%0, %0";
10646
10647     case TYPE_LEA:
10648       return "#";
10649
10650     default:
10651       if (REG_P (operands[2]))
10652         return "sal{l}\t{%b2, %0|%0, %b2}";
10653       else if (operands[2] == const1_rtx
10654                && (TARGET_SHIFT1 || optimize_size))
10655         return "sal{l}\t%0";
10656       else
10657         return "sal{l}\t{%2, %0|%0, %2}";
10658     }
10659 }
10660   [(set (attr "type")
10661      (cond [(eq_attr "alternative" "1")
10662               (const_string "lea")
10663             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10664                           (const_int 0))
10665                       (match_operand 0 "register_operand" ""))
10666                  (match_operand 2 "const1_operand" ""))
10667               (const_string "alu")
10668            ]
10669            (const_string "ishift")))
10670    (set_attr "mode" "SI")])
10671
10672 ;; Convert lea to the lea pattern to avoid flags dependency.
10673 (define_split
10674   [(set (match_operand 0 "register_operand" "")
10675         (ashift (match_operand 1 "index_register_operand" "")
10676                 (match_operand:QI 2 "const_int_operand" "")))
10677    (clobber (reg:CC FLAGS_REG))]
10678   "reload_completed
10679    && true_regnum (operands[0]) != true_regnum (operands[1])
10680    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10681   [(const_int 0)]
10682 {
10683   rtx pat;
10684   enum machine_mode mode = GET_MODE (operands[0]);
10685
10686   if (GET_MODE_SIZE (mode) < 4)
10687     operands[0] = gen_lowpart (SImode, operands[0]);
10688   if (mode != Pmode)
10689     operands[1] = gen_lowpart (Pmode, operands[1]);
10690   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10691
10692   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10693   if (Pmode != SImode)
10694     pat = gen_rtx_SUBREG (SImode, pat, 0);
10695   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10696   DONE;
10697 })
10698
10699 ;; Rare case of shifting RSP is handled by generating move and shift
10700 (define_split
10701   [(set (match_operand 0 "register_operand" "")
10702         (ashift (match_operand 1 "register_operand" "")
10703                 (match_operand:QI 2 "const_int_operand" "")))
10704    (clobber (reg:CC FLAGS_REG))]
10705   "reload_completed
10706    && true_regnum (operands[0]) != true_regnum (operands[1])"
10707   [(const_int 0)]
10708 {
10709   rtx pat, clob;
10710   emit_move_insn (operands[0], operands[1]);
10711   pat = gen_rtx_SET (VOIDmode, operands[0],
10712                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10713                                      operands[0], operands[2]));
10714   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10715   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10716   DONE;
10717 })
10718
10719 (define_insn "*ashlsi3_1_zext"
10720   [(set (match_operand:DI 0 "register_operand" "=r,r")
10721         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10722                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10723    (clobber (reg:CC FLAGS_REG))]
10724   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10725 {
10726   switch (get_attr_type (insn))
10727     {
10728     case TYPE_ALU:
10729       gcc_assert (operands[2] == const1_rtx);
10730       return "add{l}\t%k0, %k0";
10731
10732     case TYPE_LEA:
10733       return "#";
10734
10735     default:
10736       if (REG_P (operands[2]))
10737         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10738       else if (operands[2] == const1_rtx
10739                && (TARGET_SHIFT1 || optimize_size))
10740         return "sal{l}\t%k0";
10741       else
10742         return "sal{l}\t{%2, %k0|%k0, %2}";
10743     }
10744 }
10745   [(set (attr "type")
10746      (cond [(eq_attr "alternative" "1")
10747               (const_string "lea")
10748             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10749                      (const_int 0))
10750                  (match_operand 2 "const1_operand" ""))
10751               (const_string "alu")
10752            ]
10753            (const_string "ishift")))
10754    (set_attr "mode" "SI")])
10755
10756 ;; Convert lea to the lea pattern to avoid flags dependency.
10757 (define_split
10758   [(set (match_operand:DI 0 "register_operand" "")
10759         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10760                                 (match_operand:QI 2 "const_int_operand" ""))))
10761    (clobber (reg:CC FLAGS_REG))]
10762   "TARGET_64BIT && reload_completed
10763    && true_regnum (operands[0]) != true_regnum (operands[1])"
10764   [(set (match_dup 0) (zero_extend:DI
10765                         (subreg:SI (mult:SI (match_dup 1)
10766                                             (match_dup 2)) 0)))]
10767 {
10768   operands[1] = gen_lowpart (Pmode, operands[1]);
10769   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10770 })
10771
10772 ;; This pattern can't accept a variable shift count, since shifts by
10773 ;; zero don't affect the flags.  We assume that shifts by constant
10774 ;; zero are optimized away.
10775 (define_insn "*ashlsi3_cmp"
10776   [(set (reg FLAGS_REG)
10777         (compare
10778           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10779                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10780           (const_int 0)))
10781    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10782         (ashift:SI (match_dup 1) (match_dup 2)))]
10783   "ix86_match_ccmode (insn, CCGOCmode)
10784    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10785    && (optimize_size
10786        || !TARGET_PARTIAL_FLAG_REG_STALL
10787        || (operands[2] == const1_rtx
10788            && (TARGET_SHIFT1
10789                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10790 {
10791   switch (get_attr_type (insn))
10792     {
10793     case TYPE_ALU:
10794       gcc_assert (operands[2] == const1_rtx);
10795       return "add{l}\t%0, %0";
10796
10797     default:
10798       if (REG_P (operands[2]))
10799         return "sal{l}\t{%b2, %0|%0, %b2}";
10800       else if (operands[2] == const1_rtx
10801                && (TARGET_SHIFT1 || optimize_size))
10802         return "sal{l}\t%0";
10803       else
10804         return "sal{l}\t{%2, %0|%0, %2}";
10805     }
10806 }
10807   [(set (attr "type")
10808      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10809                           (const_int 0))
10810                       (match_operand 0 "register_operand" ""))
10811                  (match_operand 2 "const1_operand" ""))
10812               (const_string "alu")
10813            ]
10814            (const_string "ishift")))
10815    (set_attr "mode" "SI")])
10816
10817 (define_insn "*ashlsi3_cconly"
10818   [(set (reg FLAGS_REG)
10819         (compare
10820           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10821                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10822           (const_int 0)))
10823    (clobber (match_scratch:SI 0 "=r"))]
10824   "ix86_match_ccmode (insn, CCGOCmode)
10825    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10826    && (optimize_size
10827        || !TARGET_PARTIAL_FLAG_REG_STALL
10828        || (operands[2] == const1_rtx
10829            && (TARGET_SHIFT1
10830                || TARGET_DOUBLE_WITH_ADD)))"
10831 {
10832   switch (get_attr_type (insn))
10833     {
10834     case TYPE_ALU:
10835       gcc_assert (operands[2] == const1_rtx);
10836       return "add{l}\t%0, %0";
10837
10838     default:
10839       if (REG_P (operands[2]))
10840         return "sal{l}\t{%b2, %0|%0, %b2}";
10841       else if (operands[2] == const1_rtx
10842                && (TARGET_SHIFT1 || optimize_size))
10843         return "sal{l}\t%0";
10844       else
10845         return "sal{l}\t{%2, %0|%0, %2}";
10846     }
10847 }
10848   [(set (attr "type")
10849      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10850                           (const_int 0))
10851                       (match_operand 0 "register_operand" ""))
10852                  (match_operand 2 "const1_operand" ""))
10853               (const_string "alu")
10854            ]
10855            (const_string "ishift")))
10856    (set_attr "mode" "SI")])
10857
10858 (define_insn "*ashlsi3_cmp_zext"
10859   [(set (reg FLAGS_REG)
10860         (compare
10861           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10862                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10863           (const_int 0)))
10864    (set (match_operand:DI 0 "register_operand" "=r")
10865         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10866   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10867    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10868    && (optimize_size
10869        || !TARGET_PARTIAL_FLAG_REG_STALL
10870        || (operands[2] == const1_rtx
10871            && (TARGET_SHIFT1
10872                || TARGET_DOUBLE_WITH_ADD)))"
10873 {
10874   switch (get_attr_type (insn))
10875     {
10876     case TYPE_ALU:
10877       gcc_assert (operands[2] == const1_rtx);
10878       return "add{l}\t%k0, %k0";
10879
10880     default:
10881       if (REG_P (operands[2]))
10882         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10883       else if (operands[2] == const1_rtx
10884                && (TARGET_SHIFT1 || optimize_size))
10885         return "sal{l}\t%k0";
10886       else
10887         return "sal{l}\t{%2, %k0|%k0, %2}";
10888     }
10889 }
10890   [(set (attr "type")
10891      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10892                      (const_int 0))
10893                  (match_operand 2 "const1_operand" ""))
10894               (const_string "alu")
10895            ]
10896            (const_string "ishift")))
10897    (set_attr "mode" "SI")])
10898
10899 (define_expand "ashlhi3"
10900   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10901         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10902                    (match_operand:QI 2 "nonmemory_operand" "")))
10903    (clobber (reg:CC FLAGS_REG))]
10904   "TARGET_HIMODE_MATH"
10905   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10906
10907 (define_insn "*ashlhi3_1_lea"
10908   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10909         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10910                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10911    (clobber (reg:CC FLAGS_REG))]
10912   "!TARGET_PARTIAL_REG_STALL
10913    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10914 {
10915   switch (get_attr_type (insn))
10916     {
10917     case TYPE_LEA:
10918       return "#";
10919     case TYPE_ALU:
10920       gcc_assert (operands[2] == const1_rtx);
10921       return "add{w}\t%0, %0";
10922
10923     default:
10924       if (REG_P (operands[2]))
10925         return "sal{w}\t{%b2, %0|%0, %b2}";
10926       else if (operands[2] == const1_rtx
10927                && (TARGET_SHIFT1 || optimize_size))
10928         return "sal{w}\t%0";
10929       else
10930         return "sal{w}\t{%2, %0|%0, %2}";
10931     }
10932 }
10933   [(set (attr "type")
10934      (cond [(eq_attr "alternative" "1")
10935               (const_string "lea")
10936             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10937                           (const_int 0))
10938                       (match_operand 0 "register_operand" ""))
10939                  (match_operand 2 "const1_operand" ""))
10940               (const_string "alu")
10941            ]
10942            (const_string "ishift")))
10943    (set_attr "mode" "HI,SI")])
10944
10945 (define_insn "*ashlhi3_1"
10946   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10947         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10948                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10949    (clobber (reg:CC FLAGS_REG))]
10950   "TARGET_PARTIAL_REG_STALL
10951    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10952 {
10953   switch (get_attr_type (insn))
10954     {
10955     case TYPE_ALU:
10956       gcc_assert (operands[2] == const1_rtx);
10957       return "add{w}\t%0, %0";
10958
10959     default:
10960       if (REG_P (operands[2]))
10961         return "sal{w}\t{%b2, %0|%0, %b2}";
10962       else if (operands[2] == const1_rtx
10963                && (TARGET_SHIFT1 || optimize_size))
10964         return "sal{w}\t%0";
10965       else
10966         return "sal{w}\t{%2, %0|%0, %2}";
10967     }
10968 }
10969   [(set (attr "type")
10970      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10971                           (const_int 0))
10972                       (match_operand 0 "register_operand" ""))
10973                  (match_operand 2 "const1_operand" ""))
10974               (const_string "alu")
10975            ]
10976            (const_string "ishift")))
10977    (set_attr "mode" "HI")])
10978
10979 ;; This pattern can't accept a variable shift count, since shifts by
10980 ;; zero don't affect the flags.  We assume that shifts by constant
10981 ;; zero are optimized away.
10982 (define_insn "*ashlhi3_cmp"
10983   [(set (reg FLAGS_REG)
10984         (compare
10985           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10986                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10987           (const_int 0)))
10988    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10989         (ashift:HI (match_dup 1) (match_dup 2)))]
10990   "ix86_match_ccmode (insn, CCGOCmode)
10991    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10992    && (optimize_size
10993        || !TARGET_PARTIAL_FLAG_REG_STALL
10994        || (operands[2] == const1_rtx
10995            && (TARGET_SHIFT1
10996                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10997 {
10998   switch (get_attr_type (insn))
10999     {
11000     case TYPE_ALU:
11001       gcc_assert (operands[2] == const1_rtx);
11002       return "add{w}\t%0, %0";
11003
11004     default:
11005       if (REG_P (operands[2]))
11006         return "sal{w}\t{%b2, %0|%0, %b2}";
11007       else if (operands[2] == const1_rtx
11008                && (TARGET_SHIFT1 || optimize_size))
11009         return "sal{w}\t%0";
11010       else
11011         return "sal{w}\t{%2, %0|%0, %2}";
11012     }
11013 }
11014   [(set (attr "type")
11015      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11016                           (const_int 0))
11017                       (match_operand 0 "register_operand" ""))
11018                  (match_operand 2 "const1_operand" ""))
11019               (const_string "alu")
11020            ]
11021            (const_string "ishift")))
11022    (set_attr "mode" "HI")])
11023
11024 (define_insn "*ashlhi3_cconly"
11025   [(set (reg FLAGS_REG)
11026         (compare
11027           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11028                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11029           (const_int 0)))
11030    (clobber (match_scratch:HI 0 "=r"))]
11031   "ix86_match_ccmode (insn, CCGOCmode)
11032    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11033    && (optimize_size
11034        || !TARGET_PARTIAL_FLAG_REG_STALL
11035        || (operands[2] == const1_rtx
11036            && (TARGET_SHIFT1
11037                || TARGET_DOUBLE_WITH_ADD)))"
11038 {
11039   switch (get_attr_type (insn))
11040     {
11041     case TYPE_ALU:
11042       gcc_assert (operands[2] == const1_rtx);
11043       return "add{w}\t%0, %0";
11044
11045     default:
11046       if (REG_P (operands[2]))
11047         return "sal{w}\t{%b2, %0|%0, %b2}";
11048       else if (operands[2] == const1_rtx
11049                && (TARGET_SHIFT1 || optimize_size))
11050         return "sal{w}\t%0";
11051       else
11052         return "sal{w}\t{%2, %0|%0, %2}";
11053     }
11054 }
11055   [(set (attr "type")
11056      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11057                           (const_int 0))
11058                       (match_operand 0 "register_operand" ""))
11059                  (match_operand 2 "const1_operand" ""))
11060               (const_string "alu")
11061            ]
11062            (const_string "ishift")))
11063    (set_attr "mode" "HI")])
11064
11065 (define_expand "ashlqi3"
11066   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11067         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11068                    (match_operand:QI 2 "nonmemory_operand" "")))
11069    (clobber (reg:CC FLAGS_REG))]
11070   "TARGET_QIMODE_MATH"
11071   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11072
11073 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11074
11075 (define_insn "*ashlqi3_1_lea"
11076   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11077         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11078                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11079    (clobber (reg:CC FLAGS_REG))]
11080   "!TARGET_PARTIAL_REG_STALL
11081    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11082 {
11083   switch (get_attr_type (insn))
11084     {
11085     case TYPE_LEA:
11086       return "#";
11087     case TYPE_ALU:
11088       gcc_assert (operands[2] == const1_rtx);
11089       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11090         return "add{l}\t%k0, %k0";
11091       else
11092         return "add{b}\t%0, %0";
11093
11094     default:
11095       if (REG_P (operands[2]))
11096         {
11097           if (get_attr_mode (insn) == MODE_SI)
11098             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11099           else
11100             return "sal{b}\t{%b2, %0|%0, %b2}";
11101         }
11102       else if (operands[2] == const1_rtx
11103                && (TARGET_SHIFT1 || optimize_size))
11104         {
11105           if (get_attr_mode (insn) == MODE_SI)
11106             return "sal{l}\t%0";
11107           else
11108             return "sal{b}\t%0";
11109         }
11110       else
11111         {
11112           if (get_attr_mode (insn) == MODE_SI)
11113             return "sal{l}\t{%2, %k0|%k0, %2}";
11114           else
11115             return "sal{b}\t{%2, %0|%0, %2}";
11116         }
11117     }
11118 }
11119   [(set (attr "type")
11120      (cond [(eq_attr "alternative" "2")
11121               (const_string "lea")
11122             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11123                           (const_int 0))
11124                       (match_operand 0 "register_operand" ""))
11125                  (match_operand 2 "const1_operand" ""))
11126               (const_string "alu")
11127            ]
11128            (const_string "ishift")))
11129    (set_attr "mode" "QI,SI,SI")])
11130
11131 (define_insn "*ashlqi3_1"
11132   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11133         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11134                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11135    (clobber (reg:CC FLAGS_REG))]
11136   "TARGET_PARTIAL_REG_STALL
11137    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11138 {
11139   switch (get_attr_type (insn))
11140     {
11141     case TYPE_ALU:
11142       gcc_assert (operands[2] == const1_rtx);
11143       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11144         return "add{l}\t%k0, %k0";
11145       else
11146         return "add{b}\t%0, %0";
11147
11148     default:
11149       if (REG_P (operands[2]))
11150         {
11151           if (get_attr_mode (insn) == MODE_SI)
11152             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11153           else
11154             return "sal{b}\t{%b2, %0|%0, %b2}";
11155         }
11156       else if (operands[2] == const1_rtx
11157                && (TARGET_SHIFT1 || optimize_size))
11158         {
11159           if (get_attr_mode (insn) == MODE_SI)
11160             return "sal{l}\t%0";
11161           else
11162             return "sal{b}\t%0";
11163         }
11164       else
11165         {
11166           if (get_attr_mode (insn) == MODE_SI)
11167             return "sal{l}\t{%2, %k0|%k0, %2}";
11168           else
11169             return "sal{b}\t{%2, %0|%0, %2}";
11170         }
11171     }
11172 }
11173   [(set (attr "type")
11174      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11175                           (const_int 0))
11176                       (match_operand 0 "register_operand" ""))
11177                  (match_operand 2 "const1_operand" ""))
11178               (const_string "alu")
11179            ]
11180            (const_string "ishift")))
11181    (set_attr "mode" "QI,SI")])
11182
11183 ;; This pattern can't accept a variable shift count, since shifts by
11184 ;; zero don't affect the flags.  We assume that shifts by constant
11185 ;; zero are optimized away.
11186 (define_insn "*ashlqi3_cmp"
11187   [(set (reg FLAGS_REG)
11188         (compare
11189           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11190                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11191           (const_int 0)))
11192    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11193         (ashift:QI (match_dup 1) (match_dup 2)))]
11194   "ix86_match_ccmode (insn, CCGOCmode)
11195    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11196    && (optimize_size
11197        || !TARGET_PARTIAL_FLAG_REG_STALL
11198        || (operands[2] == const1_rtx
11199            && (TARGET_SHIFT1
11200                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11201 {
11202   switch (get_attr_type (insn))
11203     {
11204     case TYPE_ALU:
11205       gcc_assert (operands[2] == const1_rtx);
11206       return "add{b}\t%0, %0";
11207
11208     default:
11209       if (REG_P (operands[2]))
11210         return "sal{b}\t{%b2, %0|%0, %b2}";
11211       else if (operands[2] == const1_rtx
11212                && (TARGET_SHIFT1 || optimize_size))
11213         return "sal{b}\t%0";
11214       else
11215         return "sal{b}\t{%2, %0|%0, %2}";
11216     }
11217 }
11218   [(set (attr "type")
11219      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11220                           (const_int 0))
11221                       (match_operand 0 "register_operand" ""))
11222                  (match_operand 2 "const1_operand" ""))
11223               (const_string "alu")
11224            ]
11225            (const_string "ishift")))
11226    (set_attr "mode" "QI")])
11227
11228 (define_insn "*ashlqi3_cconly"
11229   [(set (reg FLAGS_REG)
11230         (compare
11231           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11232                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11233           (const_int 0)))
11234    (clobber (match_scratch:QI 0 "=q"))]
11235   "ix86_match_ccmode (insn, CCGOCmode)
11236    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11237    && (optimize_size
11238        || !TARGET_PARTIAL_FLAG_REG_STALL
11239        || (operands[2] == const1_rtx
11240            && (TARGET_SHIFT1
11241                || TARGET_DOUBLE_WITH_ADD)))"
11242 {
11243   switch (get_attr_type (insn))
11244     {
11245     case TYPE_ALU:
11246       gcc_assert (operands[2] == const1_rtx);
11247       return "add{b}\t%0, %0";
11248
11249     default:
11250       if (REG_P (operands[2]))
11251         return "sal{b}\t{%b2, %0|%0, %b2}";
11252       else if (operands[2] == const1_rtx
11253                && (TARGET_SHIFT1 || optimize_size))
11254         return "sal{b}\t%0";
11255       else
11256         return "sal{b}\t{%2, %0|%0, %2}";
11257     }
11258 }
11259   [(set (attr "type")
11260      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11261                           (const_int 0))
11262                       (match_operand 0 "register_operand" ""))
11263                  (match_operand 2 "const1_operand" ""))
11264               (const_string "alu")
11265            ]
11266            (const_string "ishift")))
11267    (set_attr "mode" "QI")])
11268
11269 ;; See comment above `ashldi3' about how this works.
11270
11271 (define_expand "ashrti3"
11272   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11273                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11274                                 (match_operand:QI 2 "nonmemory_operand" "")))
11275               (clobber (reg:CC FLAGS_REG))])]
11276   "TARGET_64BIT"
11277 {
11278   if (! immediate_operand (operands[2], QImode))
11279     {
11280       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11281       DONE;
11282     }
11283   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11284   DONE;
11285 })
11286
11287 (define_insn "ashrti3_1"
11288   [(set (match_operand:TI 0 "register_operand" "=r")
11289         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11290                      (match_operand:QI 2 "register_operand" "c")))
11291    (clobber (match_scratch:DI 3 "=&r"))
11292    (clobber (reg:CC FLAGS_REG))]
11293   "TARGET_64BIT"
11294   "#"
11295   [(set_attr "type" "multi")])
11296
11297 (define_insn "*ashrti3_2"
11298   [(set (match_operand:TI 0 "register_operand" "=r")
11299         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11300                      (match_operand:QI 2 "immediate_operand" "O")))
11301    (clobber (reg:CC FLAGS_REG))]
11302   "TARGET_64BIT"
11303   "#"
11304   [(set_attr "type" "multi")])
11305
11306 (define_split
11307   [(set (match_operand:TI 0 "register_operand" "")
11308         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11309                      (match_operand:QI 2 "register_operand" "")))
11310    (clobber (match_scratch:DI 3 ""))
11311    (clobber (reg:CC FLAGS_REG))]
11312   "TARGET_64BIT && reload_completed"
11313   [(const_int 0)]
11314   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11315
11316 (define_split
11317   [(set (match_operand:TI 0 "register_operand" "")
11318         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11319                      (match_operand:QI 2 "immediate_operand" "")))
11320    (clobber (reg:CC FLAGS_REG))]
11321   "TARGET_64BIT && reload_completed"
11322   [(const_int 0)]
11323   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11324
11325 (define_insn "x86_64_shrd"
11326   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11327         (ior:DI (ashiftrt:DI (match_dup 0)
11328                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11329                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11330                   (minus:QI (const_int 64) (match_dup 2)))))
11331    (clobber (reg:CC FLAGS_REG))]
11332   "TARGET_64BIT"
11333   "@
11334    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11335    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11336   [(set_attr "type" "ishift")
11337    (set_attr "prefix_0f" "1")
11338    (set_attr "mode" "DI")
11339    (set_attr "athlon_decode" "vector")
11340    (set_attr "amdfam10_decode" "vector")])   
11341
11342 (define_expand "ashrdi3"
11343   [(set (match_operand:DI 0 "shiftdi_operand" "")
11344         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11345                      (match_operand:QI 2 "nonmemory_operand" "")))]
11346   ""
11347   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11348
11349 (define_insn "*ashrdi3_63_rex64"
11350   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11351         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11352                      (match_operand:DI 2 "const_int_operand" "i,i")))
11353    (clobber (reg:CC FLAGS_REG))]
11354   "TARGET_64BIT && INTVAL (operands[2]) == 63
11355    && (TARGET_USE_CLTD || optimize_size)
11356    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11357   "@
11358    {cqto|cqo}
11359    sar{q}\t{%2, %0|%0, %2}"
11360   [(set_attr "type" "imovx,ishift")
11361    (set_attr "prefix_0f" "0,*")
11362    (set_attr "length_immediate" "0,*")
11363    (set_attr "modrm" "0,1")
11364    (set_attr "mode" "DI")])
11365
11366 (define_insn "*ashrdi3_1_one_bit_rex64"
11367   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11368         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11369                      (match_operand:QI 2 "const1_operand" "")))
11370    (clobber (reg:CC FLAGS_REG))]
11371   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11372    && (TARGET_SHIFT1 || optimize_size)"
11373   "sar{q}\t%0"
11374   [(set_attr "type" "ishift")
11375    (set (attr "length")
11376      (if_then_else (match_operand:DI 0 "register_operand" "")
11377         (const_string "2")
11378         (const_string "*")))])
11379
11380 (define_insn "*ashrdi3_1_rex64"
11381   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11382         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11383                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11384    (clobber (reg:CC FLAGS_REG))]
11385   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11386   "@
11387    sar{q}\t{%2, %0|%0, %2}
11388    sar{q}\t{%b2, %0|%0, %b2}"
11389   [(set_attr "type" "ishift")
11390    (set_attr "mode" "DI")])
11391
11392 ;; This pattern can't accept a variable shift count, since shifts by
11393 ;; zero don't affect the flags.  We assume that shifts by constant
11394 ;; zero are optimized away.
11395 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11396   [(set (reg FLAGS_REG)
11397         (compare
11398           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11399                        (match_operand:QI 2 "const1_operand" ""))
11400           (const_int 0)))
11401    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11402         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11403   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11404    && (TARGET_SHIFT1 || optimize_size)
11405    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11406   "sar{q}\t%0"
11407   [(set_attr "type" "ishift")
11408    (set (attr "length")
11409      (if_then_else (match_operand:DI 0 "register_operand" "")
11410         (const_string "2")
11411         (const_string "*")))])
11412
11413 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11414   [(set (reg FLAGS_REG)
11415         (compare
11416           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11417                        (match_operand:QI 2 "const1_operand" ""))
11418           (const_int 0)))
11419    (clobber (match_scratch:DI 0 "=r"))]
11420   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11421    && (TARGET_SHIFT1 || optimize_size)
11422    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11423   "sar{q}\t%0"
11424   [(set_attr "type" "ishift")
11425    (set_attr "length" "2")])
11426
11427 ;; This pattern can't accept a variable shift count, since shifts by
11428 ;; zero don't affect the flags.  We assume that shifts by constant
11429 ;; zero are optimized away.
11430 (define_insn "*ashrdi3_cmp_rex64"
11431   [(set (reg FLAGS_REG)
11432         (compare
11433           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11434                        (match_operand:QI 2 "const_int_operand" "n"))
11435           (const_int 0)))
11436    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11437         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11438   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11439    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11440    && (optimize_size
11441        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11442   "sar{q}\t{%2, %0|%0, %2}"
11443   [(set_attr "type" "ishift")
11444    (set_attr "mode" "DI")])
11445
11446 (define_insn "*ashrdi3_cconly_rex64"
11447   [(set (reg FLAGS_REG)
11448         (compare
11449           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11450                        (match_operand:QI 2 "const_int_operand" "n"))
11451           (const_int 0)))
11452    (clobber (match_scratch:DI 0 "=r"))]
11453   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11454    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11455    && (optimize_size
11456        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11457   "sar{q}\t{%2, %0|%0, %2}"
11458   [(set_attr "type" "ishift")
11459    (set_attr "mode" "DI")])
11460
11461 (define_insn "*ashrdi3_1"
11462   [(set (match_operand:DI 0 "register_operand" "=r")
11463         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11464                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11465    (clobber (reg:CC FLAGS_REG))]
11466   "!TARGET_64BIT"
11467   "#"
11468   [(set_attr "type" "multi")])
11469
11470 ;; By default we don't ask for a scratch register, because when DImode
11471 ;; values are manipulated, registers are already at a premium.  But if
11472 ;; we have one handy, we won't turn it away.
11473 (define_peephole2
11474   [(match_scratch:SI 3 "r")
11475    (parallel [(set (match_operand:DI 0 "register_operand" "")
11476                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11477                                 (match_operand:QI 2 "nonmemory_operand" "")))
11478               (clobber (reg:CC FLAGS_REG))])
11479    (match_dup 3)]
11480   "!TARGET_64BIT && TARGET_CMOVE"
11481   [(const_int 0)]
11482   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11483
11484 (define_split
11485   [(set (match_operand:DI 0 "register_operand" "")
11486         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11487                      (match_operand:QI 2 "nonmemory_operand" "")))
11488    (clobber (reg:CC FLAGS_REG))]
11489   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11490                      ? flow2_completed : reload_completed)"
11491   [(const_int 0)]
11492   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11493
11494 (define_insn "x86_shrd_1"
11495   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11496         (ior:SI (ashiftrt:SI (match_dup 0)
11497                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11498                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11499                   (minus:QI (const_int 32) (match_dup 2)))))
11500    (clobber (reg:CC FLAGS_REG))]
11501   ""
11502   "@
11503    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11504    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11505   [(set_attr "type" "ishift")
11506    (set_attr "prefix_0f" "1")
11507    (set_attr "pent_pair" "np")
11508    (set_attr "mode" "SI")])
11509
11510 (define_expand "x86_shift_adj_3"
11511   [(use (match_operand:SI 0 "register_operand" ""))
11512    (use (match_operand:SI 1 "register_operand" ""))
11513    (use (match_operand:QI 2 "register_operand" ""))]
11514   ""
11515 {
11516   rtx label = gen_label_rtx ();
11517   rtx tmp;
11518
11519   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11520
11521   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11522   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11523   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11524                               gen_rtx_LABEL_REF (VOIDmode, label),
11525                               pc_rtx);
11526   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11527   JUMP_LABEL (tmp) = label;
11528
11529   emit_move_insn (operands[0], operands[1]);
11530   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11531
11532   emit_label (label);
11533   LABEL_NUSES (label) = 1;
11534
11535   DONE;
11536 })
11537
11538 (define_insn "ashrsi3_31"
11539   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11540         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11541                      (match_operand:SI 2 "const_int_operand" "i,i")))
11542    (clobber (reg:CC FLAGS_REG))]
11543   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11544    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11545   "@
11546    {cltd|cdq}
11547    sar{l}\t{%2, %0|%0, %2}"
11548   [(set_attr "type" "imovx,ishift")
11549    (set_attr "prefix_0f" "0,*")
11550    (set_attr "length_immediate" "0,*")
11551    (set_attr "modrm" "0,1")
11552    (set_attr "mode" "SI")])
11553
11554 (define_insn "*ashrsi3_31_zext"
11555   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11556         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11557                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11558    (clobber (reg:CC FLAGS_REG))]
11559   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11560    && INTVAL (operands[2]) == 31
11561    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11562   "@
11563    {cltd|cdq}
11564    sar{l}\t{%2, %k0|%k0, %2}"
11565   [(set_attr "type" "imovx,ishift")
11566    (set_attr "prefix_0f" "0,*")
11567    (set_attr "length_immediate" "0,*")
11568    (set_attr "modrm" "0,1")
11569    (set_attr "mode" "SI")])
11570
11571 (define_expand "ashrsi3"
11572   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11573         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11574                      (match_operand:QI 2 "nonmemory_operand" "")))
11575    (clobber (reg:CC FLAGS_REG))]
11576   ""
11577   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11578
11579 (define_insn "*ashrsi3_1_one_bit"
11580   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11581         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11582                      (match_operand:QI 2 "const1_operand" "")))
11583    (clobber (reg:CC FLAGS_REG))]
11584   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11585    && (TARGET_SHIFT1 || optimize_size)"
11586   "sar{l}\t%0"
11587   [(set_attr "type" "ishift")
11588    (set (attr "length")
11589      (if_then_else (match_operand:SI 0 "register_operand" "")
11590         (const_string "2")
11591         (const_string "*")))])
11592
11593 (define_insn "*ashrsi3_1_one_bit_zext"
11594   [(set (match_operand:DI 0 "register_operand" "=r")
11595         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11596                                      (match_operand:QI 2 "const1_operand" ""))))
11597    (clobber (reg:CC FLAGS_REG))]
11598   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11599    && (TARGET_SHIFT1 || optimize_size)"
11600   "sar{l}\t%k0"
11601   [(set_attr "type" "ishift")
11602    (set_attr "length" "2")])
11603
11604 (define_insn "*ashrsi3_1"
11605   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11606         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11607                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11608    (clobber (reg:CC FLAGS_REG))]
11609   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11610   "@
11611    sar{l}\t{%2, %0|%0, %2}
11612    sar{l}\t{%b2, %0|%0, %b2}"
11613   [(set_attr "type" "ishift")
11614    (set_attr "mode" "SI")])
11615
11616 (define_insn "*ashrsi3_1_zext"
11617   [(set (match_operand:DI 0 "register_operand" "=r,r")
11618         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11619                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11620    (clobber (reg:CC FLAGS_REG))]
11621   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11622   "@
11623    sar{l}\t{%2, %k0|%k0, %2}
11624    sar{l}\t{%b2, %k0|%k0, %b2}"
11625   [(set_attr "type" "ishift")
11626    (set_attr "mode" "SI")])
11627
11628 ;; This pattern can't accept a variable shift count, since shifts by
11629 ;; zero don't affect the flags.  We assume that shifts by constant
11630 ;; zero are optimized away.
11631 (define_insn "*ashrsi3_one_bit_cmp"
11632   [(set (reg FLAGS_REG)
11633         (compare
11634           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11635                        (match_operand:QI 2 "const1_operand" ""))
11636           (const_int 0)))
11637    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11638         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11639   "ix86_match_ccmode (insn, CCGOCmode)
11640    && (TARGET_SHIFT1 || optimize_size)
11641    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11642   "sar{l}\t%0"
11643   [(set_attr "type" "ishift")
11644    (set (attr "length")
11645      (if_then_else (match_operand:SI 0 "register_operand" "")
11646         (const_string "2")
11647         (const_string "*")))])
11648
11649 (define_insn "*ashrsi3_one_bit_cconly"
11650   [(set (reg FLAGS_REG)
11651         (compare
11652           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11653                        (match_operand:QI 2 "const1_operand" ""))
11654           (const_int 0)))
11655    (clobber (match_scratch:SI 0 "=r"))]
11656   "ix86_match_ccmode (insn, CCGOCmode)
11657    && (TARGET_SHIFT1 || optimize_size)
11658    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11659   "sar{l}\t%0"
11660   [(set_attr "type" "ishift")
11661    (set_attr "length" "2")])
11662
11663 (define_insn "*ashrsi3_one_bit_cmp_zext"
11664   [(set (reg FLAGS_REG)
11665         (compare
11666           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11667                        (match_operand:QI 2 "const1_operand" ""))
11668           (const_int 0)))
11669    (set (match_operand:DI 0 "register_operand" "=r")
11670         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11671   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11672    && (TARGET_SHIFT1 || optimize_size)
11673    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11674   "sar{l}\t%k0"
11675   [(set_attr "type" "ishift")
11676    (set_attr "length" "2")])
11677
11678 ;; This pattern can't accept a variable shift count, since shifts by
11679 ;; zero don't affect the flags.  We assume that shifts by constant
11680 ;; zero are optimized away.
11681 (define_insn "*ashrsi3_cmp"
11682   [(set (reg FLAGS_REG)
11683         (compare
11684           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11685                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11686           (const_int 0)))
11687    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11688         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11689   "ix86_match_ccmode (insn, CCGOCmode)
11690    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11691    && (optimize_size
11692        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11693   "sar{l}\t{%2, %0|%0, %2}"
11694   [(set_attr "type" "ishift")
11695    (set_attr "mode" "SI")])
11696
11697 (define_insn "*ashrsi3_cconly"
11698   [(set (reg FLAGS_REG)
11699         (compare
11700           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11701                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11702           (const_int 0)))
11703    (clobber (match_scratch:SI 0 "=r"))]
11704   "ix86_match_ccmode (insn, CCGOCmode)
11705    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11706    && (optimize_size
11707        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11708   "sar{l}\t{%2, %0|%0, %2}"
11709   [(set_attr "type" "ishift")
11710    (set_attr "mode" "SI")])
11711
11712 (define_insn "*ashrsi3_cmp_zext"
11713   [(set (reg FLAGS_REG)
11714         (compare
11715           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11716                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11717           (const_int 0)))
11718    (set (match_operand:DI 0 "register_operand" "=r")
11719         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11720   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11721    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11722    && (optimize_size
11723        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11724   "sar{l}\t{%2, %k0|%k0, %2}"
11725   [(set_attr "type" "ishift")
11726    (set_attr "mode" "SI")])
11727
11728 (define_expand "ashrhi3"
11729   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11730         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11731                      (match_operand:QI 2 "nonmemory_operand" "")))
11732    (clobber (reg:CC FLAGS_REG))]
11733   "TARGET_HIMODE_MATH"
11734   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11735
11736 (define_insn "*ashrhi3_1_one_bit"
11737   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11738         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11739                      (match_operand:QI 2 "const1_operand" "")))
11740    (clobber (reg:CC FLAGS_REG))]
11741   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11742    && (TARGET_SHIFT1 || optimize_size)"
11743   "sar{w}\t%0"
11744   [(set_attr "type" "ishift")
11745    (set (attr "length")
11746      (if_then_else (match_operand 0 "register_operand" "")
11747         (const_string "2")
11748         (const_string "*")))])
11749
11750 (define_insn "*ashrhi3_1"
11751   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11752         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11753                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11754    (clobber (reg:CC FLAGS_REG))]
11755   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11756   "@
11757    sar{w}\t{%2, %0|%0, %2}
11758    sar{w}\t{%b2, %0|%0, %b2}"
11759   [(set_attr "type" "ishift")
11760    (set_attr "mode" "HI")])
11761
11762 ;; This pattern can't accept a variable shift count, since shifts by
11763 ;; zero don't affect the flags.  We assume that shifts by constant
11764 ;; zero are optimized away.
11765 (define_insn "*ashrhi3_one_bit_cmp"
11766   [(set (reg FLAGS_REG)
11767         (compare
11768           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11769                        (match_operand:QI 2 "const1_operand" ""))
11770           (const_int 0)))
11771    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11772         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11773   "ix86_match_ccmode (insn, CCGOCmode)
11774    && (TARGET_SHIFT1 || optimize_size)
11775    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11776   "sar{w}\t%0"
11777   [(set_attr "type" "ishift")
11778    (set (attr "length")
11779      (if_then_else (match_operand 0 "register_operand" "")
11780         (const_string "2")
11781         (const_string "*")))])
11782
11783 (define_insn "*ashrhi3_one_bit_cconly"
11784   [(set (reg FLAGS_REG)
11785         (compare
11786           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11787                        (match_operand:QI 2 "const1_operand" ""))
11788           (const_int 0)))
11789    (clobber (match_scratch:HI 0 "=r"))]
11790   "ix86_match_ccmode (insn, CCGOCmode)
11791    && (TARGET_SHIFT1 || optimize_size)
11792    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11793   "sar{w}\t%0"
11794   [(set_attr "type" "ishift")
11795    (set_attr "length" "2")])
11796
11797 ;; This pattern can't accept a variable shift count, since shifts by
11798 ;; zero don't affect the flags.  We assume that shifts by constant
11799 ;; zero are optimized away.
11800 (define_insn "*ashrhi3_cmp"
11801   [(set (reg FLAGS_REG)
11802         (compare
11803           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11804                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11805           (const_int 0)))
11806    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11807         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11808   "ix86_match_ccmode (insn, CCGOCmode)
11809    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11810    && (optimize_size
11811        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11812   "sar{w}\t{%2, %0|%0, %2}"
11813   [(set_attr "type" "ishift")
11814    (set_attr "mode" "HI")])
11815
11816 (define_insn "*ashrhi3_cconly"
11817   [(set (reg FLAGS_REG)
11818         (compare
11819           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11820                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11821           (const_int 0)))
11822    (clobber (match_scratch:HI 0 "=r"))]
11823   "ix86_match_ccmode (insn, CCGOCmode)
11824    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11825    && (optimize_size
11826        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11827   "sar{w}\t{%2, %0|%0, %2}"
11828   [(set_attr "type" "ishift")
11829    (set_attr "mode" "HI")])
11830
11831 (define_expand "ashrqi3"
11832   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11833         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11834                      (match_operand:QI 2 "nonmemory_operand" "")))
11835    (clobber (reg:CC FLAGS_REG))]
11836   "TARGET_QIMODE_MATH"
11837   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11838
11839 (define_insn "*ashrqi3_1_one_bit"
11840   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11841         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11842                      (match_operand:QI 2 "const1_operand" "")))
11843    (clobber (reg:CC FLAGS_REG))]
11844   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11845    && (TARGET_SHIFT1 || optimize_size)"
11846   "sar{b}\t%0"
11847   [(set_attr "type" "ishift")
11848    (set (attr "length")
11849      (if_then_else (match_operand 0 "register_operand" "")
11850         (const_string "2")
11851         (const_string "*")))])
11852
11853 (define_insn "*ashrqi3_1_one_bit_slp"
11854   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11855         (ashiftrt:QI (match_dup 0)
11856                      (match_operand:QI 1 "const1_operand" "")))
11857    (clobber (reg:CC FLAGS_REG))]
11858   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11859    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11860    && (TARGET_SHIFT1 || optimize_size)"
11861   "sar{b}\t%0"
11862   [(set_attr "type" "ishift1")
11863    (set (attr "length")
11864      (if_then_else (match_operand 0 "register_operand" "")
11865         (const_string "2")
11866         (const_string "*")))])
11867
11868 (define_insn "*ashrqi3_1"
11869   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11870         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11871                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11872    (clobber (reg:CC FLAGS_REG))]
11873   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11874   "@
11875    sar{b}\t{%2, %0|%0, %2}
11876    sar{b}\t{%b2, %0|%0, %b2}"
11877   [(set_attr "type" "ishift")
11878    (set_attr "mode" "QI")])
11879
11880 (define_insn "*ashrqi3_1_slp"
11881   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11882         (ashiftrt:QI (match_dup 0)
11883                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11884    (clobber (reg:CC FLAGS_REG))]
11885   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11886    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11887   "@
11888    sar{b}\t{%1, %0|%0, %1}
11889    sar{b}\t{%b1, %0|%0, %b1}"
11890   [(set_attr "type" "ishift1")
11891    (set_attr "mode" "QI")])
11892
11893 ;; This pattern can't accept a variable shift count, since shifts by
11894 ;; zero don't affect the flags.  We assume that shifts by constant
11895 ;; zero are optimized away.
11896 (define_insn "*ashrqi3_one_bit_cmp"
11897   [(set (reg FLAGS_REG)
11898         (compare
11899           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11900                        (match_operand:QI 2 "const1_operand" "I"))
11901           (const_int 0)))
11902    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11903         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11904   "ix86_match_ccmode (insn, CCGOCmode)
11905    && (TARGET_SHIFT1 || optimize_size)
11906    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11907   "sar{b}\t%0"
11908   [(set_attr "type" "ishift")
11909    (set (attr "length")
11910      (if_then_else (match_operand 0 "register_operand" "")
11911         (const_string "2")
11912         (const_string "*")))])
11913
11914 (define_insn "*ashrqi3_one_bit_cconly"
11915   [(set (reg FLAGS_REG)
11916         (compare
11917           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11918                        (match_operand:QI 2 "const1_operand" "I"))
11919           (const_int 0)))
11920    (clobber (match_scratch:QI 0 "=q"))]
11921   "ix86_match_ccmode (insn, CCGOCmode)
11922    && (TARGET_SHIFT1 || optimize_size)
11923    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11924   "sar{b}\t%0"
11925   [(set_attr "type" "ishift")
11926    (set_attr "length" "2")])
11927
11928 ;; This pattern can't accept a variable shift count, since shifts by
11929 ;; zero don't affect the flags.  We assume that shifts by constant
11930 ;; zero are optimized away.
11931 (define_insn "*ashrqi3_cmp"
11932   [(set (reg FLAGS_REG)
11933         (compare
11934           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11935                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11936           (const_int 0)))
11937    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11938         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11939   "ix86_match_ccmode (insn, CCGOCmode)
11940    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11941    && (optimize_size
11942        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11943   "sar{b}\t{%2, %0|%0, %2}"
11944   [(set_attr "type" "ishift")
11945    (set_attr "mode" "QI")])
11946
11947 (define_insn "*ashrqi3_cconly"
11948   [(set (reg FLAGS_REG)
11949         (compare
11950           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11951                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11952           (const_int 0)))
11953    (clobber (match_scratch:QI 0 "=q"))]
11954   "ix86_match_ccmode (insn, CCGOCmode)
11955    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11956    && (optimize_size
11957        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11958   "sar{b}\t{%2, %0|%0, %2}"
11959   [(set_attr "type" "ishift")
11960    (set_attr "mode" "QI")])
11961
11962 \f
11963 ;; Logical shift instructions
11964
11965 ;; See comment above `ashldi3' about how this works.
11966
11967 (define_expand "lshrti3"
11968   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11969                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11970                                 (match_operand:QI 2 "nonmemory_operand" "")))
11971               (clobber (reg:CC FLAGS_REG))])]
11972   "TARGET_64BIT"
11973 {
11974   if (! immediate_operand (operands[2], QImode))
11975     {
11976       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11977       DONE;
11978     }
11979   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11980   DONE;
11981 })
11982
11983 (define_insn "lshrti3_1"
11984   [(set (match_operand:TI 0 "register_operand" "=r")
11985         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11986                      (match_operand:QI 2 "register_operand" "c")))
11987    (clobber (match_scratch:DI 3 "=&r"))
11988    (clobber (reg:CC FLAGS_REG))]
11989   "TARGET_64BIT"
11990   "#"
11991   [(set_attr "type" "multi")])
11992
11993 (define_insn "*lshrti3_2"
11994   [(set (match_operand:TI 0 "register_operand" "=r")
11995         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11996                      (match_operand:QI 2 "immediate_operand" "O")))
11997    (clobber (reg:CC FLAGS_REG))]
11998   "TARGET_64BIT"
11999   "#"
12000   [(set_attr "type" "multi")])
12001
12002 (define_split
12003   [(set (match_operand:TI 0 "register_operand" "")
12004         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12005                      (match_operand:QI 2 "register_operand" "")))
12006    (clobber (match_scratch:DI 3 ""))
12007    (clobber (reg:CC FLAGS_REG))]
12008   "TARGET_64BIT && reload_completed"
12009   [(const_int 0)]
12010   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12011
12012 (define_split
12013   [(set (match_operand:TI 0 "register_operand" "")
12014         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12015                      (match_operand:QI 2 "immediate_operand" "")))
12016    (clobber (reg:CC FLAGS_REG))]
12017   "TARGET_64BIT && reload_completed"
12018   [(const_int 0)]
12019   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12020
12021 (define_expand "lshrdi3"
12022   [(set (match_operand:DI 0 "shiftdi_operand" "")
12023         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12024                      (match_operand:QI 2 "nonmemory_operand" "")))]
12025   ""
12026   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12027
12028 (define_insn "*lshrdi3_1_one_bit_rex64"
12029   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12030         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12031                      (match_operand:QI 2 "const1_operand" "")))
12032    (clobber (reg:CC FLAGS_REG))]
12033   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12034    && (TARGET_SHIFT1 || optimize_size)"
12035   "shr{q}\t%0"
12036   [(set_attr "type" "ishift")
12037    (set (attr "length")
12038      (if_then_else (match_operand:DI 0 "register_operand" "")
12039         (const_string "2")
12040         (const_string "*")))])
12041
12042 (define_insn "*lshrdi3_1_rex64"
12043   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12044         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12045                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12046    (clobber (reg:CC FLAGS_REG))]
12047   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12048   "@
12049    shr{q}\t{%2, %0|%0, %2}
12050    shr{q}\t{%b2, %0|%0, %b2}"
12051   [(set_attr "type" "ishift")
12052    (set_attr "mode" "DI")])
12053
12054 ;; This pattern can't accept a variable shift count, since shifts by
12055 ;; zero don't affect the flags.  We assume that shifts by constant
12056 ;; zero are optimized away.
12057 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12058   [(set (reg FLAGS_REG)
12059         (compare
12060           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12061                        (match_operand:QI 2 "const1_operand" ""))
12062           (const_int 0)))
12063    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12064         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12065   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12066    && (TARGET_SHIFT1 || optimize_size)
12067    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12068   "shr{q}\t%0"
12069   [(set_attr "type" "ishift")
12070    (set (attr "length")
12071      (if_then_else (match_operand:DI 0 "register_operand" "")
12072         (const_string "2")
12073         (const_string "*")))])
12074
12075 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12076   [(set (reg FLAGS_REG)
12077         (compare
12078           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12079                        (match_operand:QI 2 "const1_operand" ""))
12080           (const_int 0)))
12081    (clobber (match_scratch:DI 0 "=r"))]
12082   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12083    && (TARGET_SHIFT1 || optimize_size)
12084    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12085   "shr{q}\t%0"
12086   [(set_attr "type" "ishift")
12087    (set_attr "length" "2")])
12088
12089 ;; This pattern can't accept a variable shift count, since shifts by
12090 ;; zero don't affect the flags.  We assume that shifts by constant
12091 ;; zero are optimized away.
12092 (define_insn "*lshrdi3_cmp_rex64"
12093   [(set (reg FLAGS_REG)
12094         (compare
12095           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12096                        (match_operand:QI 2 "const_int_operand" "e"))
12097           (const_int 0)))
12098    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12099         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12100   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12101    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12102    && (optimize_size
12103        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12104   "shr{q}\t{%2, %0|%0, %2}"
12105   [(set_attr "type" "ishift")
12106    (set_attr "mode" "DI")])
12107
12108 (define_insn "*lshrdi3_cconly_rex64"
12109   [(set (reg FLAGS_REG)
12110         (compare
12111           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12112                        (match_operand:QI 2 "const_int_operand" "e"))
12113           (const_int 0)))
12114    (clobber (match_scratch:DI 0 "=r"))]
12115   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12116    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12117    && (optimize_size
12118        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12119   "shr{q}\t{%2, %0|%0, %2}"
12120   [(set_attr "type" "ishift")
12121    (set_attr "mode" "DI")])
12122
12123 (define_insn "*lshrdi3_1"
12124   [(set (match_operand:DI 0 "register_operand" "=r")
12125         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12126                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12127    (clobber (reg:CC FLAGS_REG))]
12128   "!TARGET_64BIT"
12129   "#"
12130   [(set_attr "type" "multi")])
12131
12132 ;; By default we don't ask for a scratch register, because when DImode
12133 ;; values are manipulated, registers are already at a premium.  But if
12134 ;; we have one handy, we won't turn it away.
12135 (define_peephole2
12136   [(match_scratch:SI 3 "r")
12137    (parallel [(set (match_operand:DI 0 "register_operand" "")
12138                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12139                                 (match_operand:QI 2 "nonmemory_operand" "")))
12140               (clobber (reg:CC FLAGS_REG))])
12141    (match_dup 3)]
12142   "!TARGET_64BIT && TARGET_CMOVE"
12143   [(const_int 0)]
12144   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12145
12146 (define_split
12147   [(set (match_operand:DI 0 "register_operand" "")
12148         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12149                      (match_operand:QI 2 "nonmemory_operand" "")))
12150    (clobber (reg:CC FLAGS_REG))]
12151   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12152                      ? flow2_completed : reload_completed)"
12153   [(const_int 0)]
12154   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12155
12156 (define_expand "lshrsi3"
12157   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12158         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12159                      (match_operand:QI 2 "nonmemory_operand" "")))
12160    (clobber (reg:CC FLAGS_REG))]
12161   ""
12162   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12163
12164 (define_insn "*lshrsi3_1_one_bit"
12165   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12166         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12167                      (match_operand:QI 2 "const1_operand" "")))
12168    (clobber (reg:CC FLAGS_REG))]
12169   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12170    && (TARGET_SHIFT1 || optimize_size)"
12171   "shr{l}\t%0"
12172   [(set_attr "type" "ishift")
12173    (set (attr "length")
12174      (if_then_else (match_operand:SI 0 "register_operand" "")
12175         (const_string "2")
12176         (const_string "*")))])
12177
12178 (define_insn "*lshrsi3_1_one_bit_zext"
12179   [(set (match_operand:DI 0 "register_operand" "=r")
12180         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12181                      (match_operand:QI 2 "const1_operand" "")))
12182    (clobber (reg:CC FLAGS_REG))]
12183   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12184    && (TARGET_SHIFT1 || optimize_size)"
12185   "shr{l}\t%k0"
12186   [(set_attr "type" "ishift")
12187    (set_attr "length" "2")])
12188
12189 (define_insn "*lshrsi3_1"
12190   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12191         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12192                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12193    (clobber (reg:CC FLAGS_REG))]
12194   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12195   "@
12196    shr{l}\t{%2, %0|%0, %2}
12197    shr{l}\t{%b2, %0|%0, %b2}"
12198   [(set_attr "type" "ishift")
12199    (set_attr "mode" "SI")])
12200
12201 (define_insn "*lshrsi3_1_zext"
12202   [(set (match_operand:DI 0 "register_operand" "=r,r")
12203         (zero_extend:DI
12204           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12205                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12206    (clobber (reg:CC FLAGS_REG))]
12207   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12208   "@
12209    shr{l}\t{%2, %k0|%k0, %2}
12210    shr{l}\t{%b2, %k0|%k0, %b2}"
12211   [(set_attr "type" "ishift")
12212    (set_attr "mode" "SI")])
12213
12214 ;; This pattern can't accept a variable shift count, since shifts by
12215 ;; zero don't affect the flags.  We assume that shifts by constant
12216 ;; zero are optimized away.
12217 (define_insn "*lshrsi3_one_bit_cmp"
12218   [(set (reg FLAGS_REG)
12219         (compare
12220           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12221                        (match_operand:QI 2 "const1_operand" ""))
12222           (const_int 0)))
12223    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12224         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12225   "ix86_match_ccmode (insn, CCGOCmode)
12226    && (TARGET_SHIFT1 || optimize_size)
12227    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12228   "shr{l}\t%0"
12229   [(set_attr "type" "ishift")
12230    (set (attr "length")
12231      (if_then_else (match_operand:SI 0 "register_operand" "")
12232         (const_string "2")
12233         (const_string "*")))])
12234
12235 (define_insn "*lshrsi3_one_bit_cconly"
12236   [(set (reg FLAGS_REG)
12237         (compare
12238           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12239                        (match_operand:QI 2 "const1_operand" ""))
12240           (const_int 0)))
12241    (clobber (match_scratch:SI 0 "=r"))]
12242   "ix86_match_ccmode (insn, CCGOCmode)
12243    && (TARGET_SHIFT1 || optimize_size)
12244    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12245   "shr{l}\t%0"
12246   [(set_attr "type" "ishift")
12247    (set_attr "length" "2")])
12248
12249 (define_insn "*lshrsi3_cmp_one_bit_zext"
12250   [(set (reg FLAGS_REG)
12251         (compare
12252           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12253                        (match_operand:QI 2 "const1_operand" ""))
12254           (const_int 0)))
12255    (set (match_operand:DI 0 "register_operand" "=r")
12256         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12257   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12258    && (TARGET_SHIFT1 || optimize_size)
12259    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12260   "shr{l}\t%k0"
12261   [(set_attr "type" "ishift")
12262    (set_attr "length" "2")])
12263
12264 ;; This pattern can't accept a variable shift count, since shifts by
12265 ;; zero don't affect the flags.  We assume that shifts by constant
12266 ;; zero are optimized away.
12267 (define_insn "*lshrsi3_cmp"
12268   [(set (reg FLAGS_REG)
12269         (compare
12270           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12271                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12272           (const_int 0)))
12273    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12274         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12275   "ix86_match_ccmode (insn, CCGOCmode)
12276    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12277    && (optimize_size
12278        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12279   "shr{l}\t{%2, %0|%0, %2}"
12280   [(set_attr "type" "ishift")
12281    (set_attr "mode" "SI")])
12282
12283 (define_insn "*lshrsi3_cconly"
12284   [(set (reg FLAGS_REG)
12285       (compare
12286         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12287                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12288         (const_int 0)))
12289    (clobber (match_scratch:SI 0 "=r"))]
12290   "ix86_match_ccmode (insn, CCGOCmode)
12291    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12292    && (optimize_size
12293        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12294   "shr{l}\t{%2, %0|%0, %2}"
12295   [(set_attr "type" "ishift")
12296    (set_attr "mode" "SI")])
12297
12298 (define_insn "*lshrsi3_cmp_zext"
12299   [(set (reg FLAGS_REG)
12300         (compare
12301           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12302                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12303           (const_int 0)))
12304    (set (match_operand:DI 0 "register_operand" "=r")
12305         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12306   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12307    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12308    && (optimize_size
12309        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12310   "shr{l}\t{%2, %k0|%k0, %2}"
12311   [(set_attr "type" "ishift")
12312    (set_attr "mode" "SI")])
12313
12314 (define_expand "lshrhi3"
12315   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12316         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12317                      (match_operand:QI 2 "nonmemory_operand" "")))
12318    (clobber (reg:CC FLAGS_REG))]
12319   "TARGET_HIMODE_MATH"
12320   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12321
12322 (define_insn "*lshrhi3_1_one_bit"
12323   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12324         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12325                      (match_operand:QI 2 "const1_operand" "")))
12326    (clobber (reg:CC FLAGS_REG))]
12327   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12328    && (TARGET_SHIFT1 || optimize_size)"
12329   "shr{w}\t%0"
12330   [(set_attr "type" "ishift")
12331    (set (attr "length")
12332      (if_then_else (match_operand 0 "register_operand" "")
12333         (const_string "2")
12334         (const_string "*")))])
12335
12336 (define_insn "*lshrhi3_1"
12337   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12338         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12339                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12340    (clobber (reg:CC FLAGS_REG))]
12341   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12342   "@
12343    shr{w}\t{%2, %0|%0, %2}
12344    shr{w}\t{%b2, %0|%0, %b2}"
12345   [(set_attr "type" "ishift")
12346    (set_attr "mode" "HI")])
12347
12348 ;; This pattern can't accept a variable shift count, since shifts by
12349 ;; zero don't affect the flags.  We assume that shifts by constant
12350 ;; zero are optimized away.
12351 (define_insn "*lshrhi3_one_bit_cmp"
12352   [(set (reg FLAGS_REG)
12353         (compare
12354           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12355                        (match_operand:QI 2 "const1_operand" ""))
12356           (const_int 0)))
12357    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12358         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12359   "ix86_match_ccmode (insn, CCGOCmode)
12360    && (TARGET_SHIFT1 || optimize_size)
12361    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12362   "shr{w}\t%0"
12363   [(set_attr "type" "ishift")
12364    (set (attr "length")
12365      (if_then_else (match_operand:SI 0 "register_operand" "")
12366         (const_string "2")
12367         (const_string "*")))])
12368
12369 (define_insn "*lshrhi3_one_bit_cconly"
12370   [(set (reg FLAGS_REG)
12371         (compare
12372           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12373                        (match_operand:QI 2 "const1_operand" ""))
12374           (const_int 0)))
12375    (clobber (match_scratch:HI 0 "=r"))]
12376   "ix86_match_ccmode (insn, CCGOCmode)
12377    && (TARGET_SHIFT1 || optimize_size)
12378    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12379   "shr{w}\t%0"
12380   [(set_attr "type" "ishift")
12381    (set_attr "length" "2")])
12382
12383 ;; This pattern can't accept a variable shift count, since shifts by
12384 ;; zero don't affect the flags.  We assume that shifts by constant
12385 ;; zero are optimized away.
12386 (define_insn "*lshrhi3_cmp"
12387   [(set (reg FLAGS_REG)
12388         (compare
12389           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12390                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12391           (const_int 0)))
12392    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12393         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12394   "ix86_match_ccmode (insn, CCGOCmode)
12395    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12396    && (optimize_size
12397        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12398   "shr{w}\t{%2, %0|%0, %2}"
12399   [(set_attr "type" "ishift")
12400    (set_attr "mode" "HI")])
12401
12402 (define_insn "*lshrhi3_cconly"
12403   [(set (reg FLAGS_REG)
12404         (compare
12405           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12406                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12407           (const_int 0)))
12408    (clobber (match_scratch:HI 0 "=r"))]
12409   "ix86_match_ccmode (insn, CCGOCmode)
12410    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12411    && (optimize_size
12412        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12413   "shr{w}\t{%2, %0|%0, %2}"
12414   [(set_attr "type" "ishift")
12415    (set_attr "mode" "HI")])
12416
12417 (define_expand "lshrqi3"
12418   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12419         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12420                      (match_operand:QI 2 "nonmemory_operand" "")))
12421    (clobber (reg:CC FLAGS_REG))]
12422   "TARGET_QIMODE_MATH"
12423   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12424
12425 (define_insn "*lshrqi3_1_one_bit"
12426   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12427         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12428                      (match_operand:QI 2 "const1_operand" "")))
12429    (clobber (reg:CC FLAGS_REG))]
12430   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12431    && (TARGET_SHIFT1 || optimize_size)"
12432   "shr{b}\t%0"
12433   [(set_attr "type" "ishift")
12434    (set (attr "length")
12435      (if_then_else (match_operand 0 "register_operand" "")
12436         (const_string "2")
12437         (const_string "*")))])
12438
12439 (define_insn "*lshrqi3_1_one_bit_slp"
12440   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12441         (lshiftrt:QI (match_dup 0)
12442                      (match_operand:QI 1 "const1_operand" "")))
12443    (clobber (reg:CC FLAGS_REG))]
12444   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12445    && (TARGET_SHIFT1 || optimize_size)"
12446   "shr{b}\t%0"
12447   [(set_attr "type" "ishift1")
12448    (set (attr "length")
12449      (if_then_else (match_operand 0 "register_operand" "")
12450         (const_string "2")
12451         (const_string "*")))])
12452
12453 (define_insn "*lshrqi3_1"
12454   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12455         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12456                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12457    (clobber (reg:CC FLAGS_REG))]
12458   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12459   "@
12460    shr{b}\t{%2, %0|%0, %2}
12461    shr{b}\t{%b2, %0|%0, %b2}"
12462   [(set_attr "type" "ishift")
12463    (set_attr "mode" "QI")])
12464
12465 (define_insn "*lshrqi3_1_slp"
12466   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12467         (lshiftrt:QI (match_dup 0)
12468                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12469    (clobber (reg:CC FLAGS_REG))]
12470   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12471    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12472   "@
12473    shr{b}\t{%1, %0|%0, %1}
12474    shr{b}\t{%b1, %0|%0, %b1}"
12475   [(set_attr "type" "ishift1")
12476    (set_attr "mode" "QI")])
12477
12478 ;; This pattern can't accept a variable shift count, since shifts by
12479 ;; zero don't affect the flags.  We assume that shifts by constant
12480 ;; zero are optimized away.
12481 (define_insn "*lshrqi2_one_bit_cmp"
12482   [(set (reg FLAGS_REG)
12483         (compare
12484           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12485                        (match_operand:QI 2 "const1_operand" ""))
12486           (const_int 0)))
12487    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12488         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12489   "ix86_match_ccmode (insn, CCGOCmode)
12490    && (TARGET_SHIFT1 || optimize_size)
12491    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12492   "shr{b}\t%0"
12493   [(set_attr "type" "ishift")
12494    (set (attr "length")
12495      (if_then_else (match_operand:SI 0 "register_operand" "")
12496         (const_string "2")
12497         (const_string "*")))])
12498
12499 (define_insn "*lshrqi2_one_bit_cconly"
12500   [(set (reg FLAGS_REG)
12501         (compare
12502           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12503                        (match_operand:QI 2 "const1_operand" ""))
12504           (const_int 0)))
12505    (clobber (match_scratch:QI 0 "=q"))]
12506   "ix86_match_ccmode (insn, CCGOCmode)
12507    && (TARGET_SHIFT1 || optimize_size)
12508    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12509   "shr{b}\t%0"
12510   [(set_attr "type" "ishift")
12511    (set_attr "length" "2")])
12512
12513 ;; This pattern can't accept a variable shift count, since shifts by
12514 ;; zero don't affect the flags.  We assume that shifts by constant
12515 ;; zero are optimized away.
12516 (define_insn "*lshrqi2_cmp"
12517   [(set (reg FLAGS_REG)
12518         (compare
12519           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12520                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12521           (const_int 0)))
12522    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12523         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12524   "ix86_match_ccmode (insn, CCGOCmode)
12525    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12526    && (optimize_size
12527        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12528   "shr{b}\t{%2, %0|%0, %2}"
12529   [(set_attr "type" "ishift")
12530    (set_attr "mode" "QI")])
12531
12532 (define_insn "*lshrqi2_cconly"
12533   [(set (reg FLAGS_REG)
12534         (compare
12535           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12536                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12537           (const_int 0)))
12538    (clobber (match_scratch:QI 0 "=q"))]
12539   "ix86_match_ccmode (insn, CCGOCmode)
12540    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12541    && (optimize_size
12542        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12543   "shr{b}\t{%2, %0|%0, %2}"
12544   [(set_attr "type" "ishift")
12545    (set_attr "mode" "QI")])
12546 \f
12547 ;; Rotate instructions
12548
12549 (define_expand "rotldi3"
12550   [(set (match_operand:DI 0 "shiftdi_operand" "")
12551         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12552                    (match_operand:QI 2 "nonmemory_operand" "")))
12553    (clobber (reg:CC FLAGS_REG))]
12554  ""
12555 {
12556   if (TARGET_64BIT)
12557     {
12558       ix86_expand_binary_operator (ROTATE, DImode, operands);
12559       DONE;
12560     }
12561   if (!const_1_to_31_operand (operands[2], VOIDmode))
12562     FAIL;
12563   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12564   DONE;
12565 })
12566
12567 ;; Implement rotation using two double-precision shift instructions
12568 ;; and a scratch register.
12569 (define_insn_and_split "ix86_rotldi3"
12570  [(set (match_operand:DI 0 "register_operand" "=r")
12571        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12572                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12573   (clobber (reg:CC FLAGS_REG))
12574   (clobber (match_scratch:SI 3 "=&r"))]
12575  "!TARGET_64BIT"
12576  ""
12577  "&& reload_completed"
12578  [(set (match_dup 3) (match_dup 4))
12579   (parallel
12580    [(set (match_dup 4)
12581          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12582                  (lshiftrt:SI (match_dup 5)
12583                               (minus:QI (const_int 32) (match_dup 2)))))
12584     (clobber (reg:CC FLAGS_REG))])
12585   (parallel
12586    [(set (match_dup 5)
12587          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12588                  (lshiftrt:SI (match_dup 3)
12589                               (minus:QI (const_int 32) (match_dup 2)))))
12590     (clobber (reg:CC FLAGS_REG))])]
12591  "split_di (operands, 1, operands + 4, operands + 5);")
12592
12593 (define_insn "*rotlsi3_1_one_bit_rex64"
12594   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12595         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12596                    (match_operand:QI 2 "const1_operand" "")))
12597    (clobber (reg:CC FLAGS_REG))]
12598   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12599    && (TARGET_SHIFT1 || optimize_size)"
12600   "rol{q}\t%0"
12601   [(set_attr "type" "rotate")
12602    (set (attr "length")
12603      (if_then_else (match_operand:DI 0 "register_operand" "")
12604         (const_string "2")
12605         (const_string "*")))])
12606
12607 (define_insn "*rotldi3_1_rex64"
12608   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12609         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12610                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12611    (clobber (reg:CC FLAGS_REG))]
12612   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12613   "@
12614    rol{q}\t{%2, %0|%0, %2}
12615    rol{q}\t{%b2, %0|%0, %b2}"
12616   [(set_attr "type" "rotate")
12617    (set_attr "mode" "DI")])
12618
12619 (define_expand "rotlsi3"
12620   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12621         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12622                    (match_operand:QI 2 "nonmemory_operand" "")))
12623    (clobber (reg:CC FLAGS_REG))]
12624   ""
12625   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12626
12627 (define_insn "*rotlsi3_1_one_bit"
12628   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12629         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12630                    (match_operand:QI 2 "const1_operand" "")))
12631    (clobber (reg:CC FLAGS_REG))]
12632   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12633    && (TARGET_SHIFT1 || optimize_size)"
12634   "rol{l}\t%0"
12635   [(set_attr "type" "rotate")
12636    (set (attr "length")
12637      (if_then_else (match_operand:SI 0 "register_operand" "")
12638         (const_string "2")
12639         (const_string "*")))])
12640
12641 (define_insn "*rotlsi3_1_one_bit_zext"
12642   [(set (match_operand:DI 0 "register_operand" "=r")
12643         (zero_extend:DI
12644           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12645                      (match_operand:QI 2 "const1_operand" ""))))
12646    (clobber (reg:CC FLAGS_REG))]
12647   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12648    && (TARGET_SHIFT1 || optimize_size)"
12649   "rol{l}\t%k0"
12650   [(set_attr "type" "rotate")
12651    (set_attr "length" "2")])
12652
12653 (define_insn "*rotlsi3_1"
12654   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12655         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12656                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12657    (clobber (reg:CC FLAGS_REG))]
12658   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12659   "@
12660    rol{l}\t{%2, %0|%0, %2}
12661    rol{l}\t{%b2, %0|%0, %b2}"
12662   [(set_attr "type" "rotate")
12663    (set_attr "mode" "SI")])
12664
12665 (define_insn "*rotlsi3_1_zext"
12666   [(set (match_operand:DI 0 "register_operand" "=r,r")
12667         (zero_extend:DI
12668           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12669                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12670    (clobber (reg:CC FLAGS_REG))]
12671   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12672   "@
12673    rol{l}\t{%2, %k0|%k0, %2}
12674    rol{l}\t{%b2, %k0|%k0, %b2}"
12675   [(set_attr "type" "rotate")
12676    (set_attr "mode" "SI")])
12677
12678 (define_expand "rotlhi3"
12679   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12680         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12681                    (match_operand:QI 2 "nonmemory_operand" "")))
12682    (clobber (reg:CC FLAGS_REG))]
12683   "TARGET_HIMODE_MATH"
12684   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12685
12686 (define_insn "*rotlhi3_1_one_bit"
12687   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12688         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12689                    (match_operand:QI 2 "const1_operand" "")))
12690    (clobber (reg:CC FLAGS_REG))]
12691   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12692    && (TARGET_SHIFT1 || optimize_size)"
12693   "rol{w}\t%0"
12694   [(set_attr "type" "rotate")
12695    (set (attr "length")
12696      (if_then_else (match_operand 0 "register_operand" "")
12697         (const_string "2")
12698         (const_string "*")))])
12699
12700 (define_insn "*rotlhi3_1"
12701   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12702         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12703                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12704    (clobber (reg:CC FLAGS_REG))]
12705   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12706   "@
12707    rol{w}\t{%2, %0|%0, %2}
12708    rol{w}\t{%b2, %0|%0, %b2}"
12709   [(set_attr "type" "rotate")
12710    (set_attr "mode" "HI")])
12711
12712 (define_split
12713  [(set (match_operand:HI 0 "register_operand" "")
12714        (rotate:HI (match_dup 0) (const_int 8)))
12715   (clobber (reg:CC FLAGS_REG))]
12716  "reload_completed"
12717  [(parallel [(set (strict_low_part (match_dup 0))
12718                   (bswap:HI (match_dup 0)))
12719              (clobber (reg:CC FLAGS_REG))])]
12720  "")
12721
12722 (define_expand "rotlqi3"
12723   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12724         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12725                    (match_operand:QI 2 "nonmemory_operand" "")))
12726    (clobber (reg:CC FLAGS_REG))]
12727   "TARGET_QIMODE_MATH"
12728   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12729
12730 (define_insn "*rotlqi3_1_one_bit_slp"
12731   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12732         (rotate:QI (match_dup 0)
12733                    (match_operand:QI 1 "const1_operand" "")))
12734    (clobber (reg:CC FLAGS_REG))]
12735   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12736    && (TARGET_SHIFT1 || optimize_size)"
12737   "rol{b}\t%0"
12738   [(set_attr "type" "rotate1")
12739    (set (attr "length")
12740      (if_then_else (match_operand 0 "register_operand" "")
12741         (const_string "2")
12742         (const_string "*")))])
12743
12744 (define_insn "*rotlqi3_1_one_bit"
12745   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12746         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12747                    (match_operand:QI 2 "const1_operand" "")))
12748    (clobber (reg:CC FLAGS_REG))]
12749   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12750    && (TARGET_SHIFT1 || optimize_size)"
12751   "rol{b}\t%0"
12752   [(set_attr "type" "rotate")
12753    (set (attr "length")
12754      (if_then_else (match_operand 0 "register_operand" "")
12755         (const_string "2")
12756         (const_string "*")))])
12757
12758 (define_insn "*rotlqi3_1_slp"
12759   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12760         (rotate:QI (match_dup 0)
12761                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12762    (clobber (reg:CC FLAGS_REG))]
12763   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12764    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12765   "@
12766    rol{b}\t{%1, %0|%0, %1}
12767    rol{b}\t{%b1, %0|%0, %b1}"
12768   [(set_attr "type" "rotate1")
12769    (set_attr "mode" "QI")])
12770
12771 (define_insn "*rotlqi3_1"
12772   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12773         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12774                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12775    (clobber (reg:CC FLAGS_REG))]
12776   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12777   "@
12778    rol{b}\t{%2, %0|%0, %2}
12779    rol{b}\t{%b2, %0|%0, %b2}"
12780   [(set_attr "type" "rotate")
12781    (set_attr "mode" "QI")])
12782
12783 (define_expand "rotrdi3"
12784   [(set (match_operand:DI 0 "shiftdi_operand" "")
12785         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12786                    (match_operand:QI 2 "nonmemory_operand" "")))
12787    (clobber (reg:CC FLAGS_REG))]
12788  ""
12789 {
12790   if (TARGET_64BIT)
12791     {
12792       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12793       DONE;
12794     }
12795   if (!const_1_to_31_operand (operands[2], VOIDmode))
12796     FAIL;
12797   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12798   DONE;
12799 })
12800
12801 ;; Implement rotation using two double-precision shift instructions
12802 ;; and a scratch register.
12803 (define_insn_and_split "ix86_rotrdi3"
12804  [(set (match_operand:DI 0 "register_operand" "=r")
12805        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12806                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12807   (clobber (reg:CC FLAGS_REG))
12808   (clobber (match_scratch:SI 3 "=&r"))]
12809  "!TARGET_64BIT"
12810  ""
12811  "&& reload_completed"
12812  [(set (match_dup 3) (match_dup 4))
12813   (parallel
12814    [(set (match_dup 4)
12815          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12816                  (ashift:SI (match_dup 5)
12817                             (minus:QI (const_int 32) (match_dup 2)))))
12818     (clobber (reg:CC FLAGS_REG))])
12819   (parallel
12820    [(set (match_dup 5)
12821          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12822                  (ashift:SI (match_dup 3)
12823                             (minus:QI (const_int 32) (match_dup 2)))))
12824     (clobber (reg:CC FLAGS_REG))])]
12825  "split_di (operands, 1, operands + 4, operands + 5);")
12826
12827 (define_insn "*rotrdi3_1_one_bit_rex64"
12828   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12829         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12830                      (match_operand:QI 2 "const1_operand" "")))
12831    (clobber (reg:CC FLAGS_REG))]
12832   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12833    && (TARGET_SHIFT1 || optimize_size)"
12834   "ror{q}\t%0"
12835   [(set_attr "type" "rotate")
12836    (set (attr "length")
12837      (if_then_else (match_operand:DI 0 "register_operand" "")
12838         (const_string "2")
12839         (const_string "*")))])
12840
12841 (define_insn "*rotrdi3_1_rex64"
12842   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12843         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12844                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12845    (clobber (reg:CC FLAGS_REG))]
12846   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12847   "@
12848    ror{q}\t{%2, %0|%0, %2}
12849    ror{q}\t{%b2, %0|%0, %b2}"
12850   [(set_attr "type" "rotate")
12851    (set_attr "mode" "DI")])
12852
12853 (define_expand "rotrsi3"
12854   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12855         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12856                      (match_operand:QI 2 "nonmemory_operand" "")))
12857    (clobber (reg:CC FLAGS_REG))]
12858   ""
12859   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12860
12861 (define_insn "*rotrsi3_1_one_bit"
12862   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12863         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12864                      (match_operand:QI 2 "const1_operand" "")))
12865    (clobber (reg:CC FLAGS_REG))]
12866   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12867    && (TARGET_SHIFT1 || optimize_size)"
12868   "ror{l}\t%0"
12869   [(set_attr "type" "rotate")
12870    (set (attr "length")
12871      (if_then_else (match_operand:SI 0 "register_operand" "")
12872         (const_string "2")
12873         (const_string "*")))])
12874
12875 (define_insn "*rotrsi3_1_one_bit_zext"
12876   [(set (match_operand:DI 0 "register_operand" "=r")
12877         (zero_extend:DI
12878           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12879                        (match_operand:QI 2 "const1_operand" ""))))
12880    (clobber (reg:CC FLAGS_REG))]
12881   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12882    && (TARGET_SHIFT1 || optimize_size)"
12883   "ror{l}\t%k0"
12884   [(set_attr "type" "rotate")
12885    (set (attr "length")
12886      (if_then_else (match_operand:SI 0 "register_operand" "")
12887         (const_string "2")
12888         (const_string "*")))])
12889
12890 (define_insn "*rotrsi3_1"
12891   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12892         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12893                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12894    (clobber (reg:CC FLAGS_REG))]
12895   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12896   "@
12897    ror{l}\t{%2, %0|%0, %2}
12898    ror{l}\t{%b2, %0|%0, %b2}"
12899   [(set_attr "type" "rotate")
12900    (set_attr "mode" "SI")])
12901
12902 (define_insn "*rotrsi3_1_zext"
12903   [(set (match_operand:DI 0 "register_operand" "=r,r")
12904         (zero_extend:DI
12905           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12906                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12907    (clobber (reg:CC FLAGS_REG))]
12908   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12909   "@
12910    ror{l}\t{%2, %k0|%k0, %2}
12911    ror{l}\t{%b2, %k0|%k0, %b2}"
12912   [(set_attr "type" "rotate")
12913    (set_attr "mode" "SI")])
12914
12915 (define_expand "rotrhi3"
12916   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12917         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12918                      (match_operand:QI 2 "nonmemory_operand" "")))
12919    (clobber (reg:CC FLAGS_REG))]
12920   "TARGET_HIMODE_MATH"
12921   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12922
12923 (define_insn "*rotrhi3_one_bit"
12924   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12925         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12926                      (match_operand:QI 2 "const1_operand" "")))
12927    (clobber (reg:CC FLAGS_REG))]
12928   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12929    && (TARGET_SHIFT1 || optimize_size)"
12930   "ror{w}\t%0"
12931   [(set_attr "type" "rotate")
12932    (set (attr "length")
12933      (if_then_else (match_operand 0 "register_operand" "")
12934         (const_string "2")
12935         (const_string "*")))])
12936
12937 (define_insn "*rotrhi3_1"
12938   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12939         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12940                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12941    (clobber (reg:CC FLAGS_REG))]
12942   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12943   "@
12944    ror{w}\t{%2, %0|%0, %2}
12945    ror{w}\t{%b2, %0|%0, %b2}"
12946   [(set_attr "type" "rotate")
12947    (set_attr "mode" "HI")])
12948
12949 (define_split
12950  [(set (match_operand:HI 0 "register_operand" "")
12951        (rotatert:HI (match_dup 0) (const_int 8)))
12952   (clobber (reg:CC FLAGS_REG))]
12953  "reload_completed"
12954  [(parallel [(set (strict_low_part (match_dup 0))
12955                   (bswap:HI (match_dup 0)))
12956              (clobber (reg:CC FLAGS_REG))])]
12957  "")
12958
12959 (define_expand "rotrqi3"
12960   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12961         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12962                      (match_operand:QI 2 "nonmemory_operand" "")))
12963    (clobber (reg:CC FLAGS_REG))]
12964   "TARGET_QIMODE_MATH"
12965   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12966
12967 (define_insn "*rotrqi3_1_one_bit"
12968   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12969         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12970                      (match_operand:QI 2 "const1_operand" "")))
12971    (clobber (reg:CC FLAGS_REG))]
12972   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12973    && (TARGET_SHIFT1 || optimize_size)"
12974   "ror{b}\t%0"
12975   [(set_attr "type" "rotate")
12976    (set (attr "length")
12977      (if_then_else (match_operand 0 "register_operand" "")
12978         (const_string "2")
12979         (const_string "*")))])
12980
12981 (define_insn "*rotrqi3_1_one_bit_slp"
12982   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12983         (rotatert:QI (match_dup 0)
12984                      (match_operand:QI 1 "const1_operand" "")))
12985    (clobber (reg:CC FLAGS_REG))]
12986   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12987    && (TARGET_SHIFT1 || optimize_size)"
12988   "ror{b}\t%0"
12989   [(set_attr "type" "rotate1")
12990    (set (attr "length")
12991      (if_then_else (match_operand 0 "register_operand" "")
12992         (const_string "2")
12993         (const_string "*")))])
12994
12995 (define_insn "*rotrqi3_1"
12996   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12997         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12998                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12999    (clobber (reg:CC FLAGS_REG))]
13000   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13001   "@
13002    ror{b}\t{%2, %0|%0, %2}
13003    ror{b}\t{%b2, %0|%0, %b2}"
13004   [(set_attr "type" "rotate")
13005    (set_attr "mode" "QI")])
13006
13007 (define_insn "*rotrqi3_1_slp"
13008   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13009         (rotatert:QI (match_dup 0)
13010                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13011    (clobber (reg:CC FLAGS_REG))]
13012   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13013    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13014   "@
13015    ror{b}\t{%1, %0|%0, %1}
13016    ror{b}\t{%b1, %0|%0, %b1}"
13017   [(set_attr "type" "rotate1")
13018    (set_attr "mode" "QI")])
13019 \f
13020 ;; Bit set / bit test instructions
13021
13022 (define_expand "extv"
13023   [(set (match_operand:SI 0 "register_operand" "")
13024         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13025                          (match_operand:SI 2 "const8_operand" "")
13026                          (match_operand:SI 3 "const8_operand" "")))]
13027   ""
13028 {
13029   /* Handle extractions from %ah et al.  */
13030   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13031     FAIL;
13032
13033   /* From mips.md: extract_bit_field doesn't verify that our source
13034      matches the predicate, so check it again here.  */
13035   if (! ext_register_operand (operands[1], VOIDmode))
13036     FAIL;
13037 })
13038
13039 (define_expand "extzv"
13040   [(set (match_operand:SI 0 "register_operand" "")
13041         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13042                          (match_operand:SI 2 "const8_operand" "")
13043                          (match_operand:SI 3 "const8_operand" "")))]
13044   ""
13045 {
13046   /* Handle extractions from %ah et al.  */
13047   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13048     FAIL;
13049
13050   /* From mips.md: extract_bit_field doesn't verify that our source
13051      matches the predicate, so check it again here.  */
13052   if (! ext_register_operand (operands[1], VOIDmode))
13053     FAIL;
13054 })
13055
13056 (define_expand "insv"
13057   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13058                       (match_operand 1 "const8_operand" "")
13059                       (match_operand 2 "const8_operand" ""))
13060         (match_operand 3 "register_operand" ""))]
13061   ""
13062 {
13063   /* Handle insertions to %ah et al.  */
13064   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13065     FAIL;
13066
13067   /* From mips.md: insert_bit_field doesn't verify that our source
13068      matches the predicate, so check it again here.  */
13069   if (! ext_register_operand (operands[0], VOIDmode))
13070     FAIL;
13071
13072   if (TARGET_64BIT)
13073     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13074   else
13075     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13076
13077   DONE;
13078 })
13079
13080 ;; %%% bts, btr, btc, bt.
13081 ;; In general these instructions are *slow* when applied to memory,
13082 ;; since they enforce atomic operation.  When applied to registers,
13083 ;; it depends on the cpu implementation.  They're never faster than
13084 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13085 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13086 ;; within the instruction itself, so operating on bits in the high
13087 ;; 32-bits of a register becomes easier.
13088 ;;
13089 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13090 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13091 ;; negdf respectively, so they can never be disabled entirely.
13092
13093 (define_insn "*btsq"
13094   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13095                          (const_int 1)
13096                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13097         (const_int 1))
13098    (clobber (reg:CC FLAGS_REG))]
13099   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13100   "bts{q} %1,%0"
13101   [(set_attr "type" "alu1")])
13102
13103 (define_insn "*btrq"
13104   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13105                          (const_int 1)
13106                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13107         (const_int 0))
13108    (clobber (reg:CC FLAGS_REG))]
13109   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13110   "btr{q} %1,%0"
13111   [(set_attr "type" "alu1")])
13112
13113 (define_insn "*btcq"
13114   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13115                          (const_int 1)
13116                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13117         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13118    (clobber (reg:CC FLAGS_REG))]
13119   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13120   "btc{q} %1,%0"
13121   [(set_attr "type" "alu1")])
13122
13123 ;; Allow Nocona to avoid these instructions if a register is available.
13124
13125 (define_peephole2
13126   [(match_scratch:DI 2 "r")
13127    (parallel [(set (zero_extract:DI
13128                      (match_operand:DI 0 "register_operand" "")
13129                      (const_int 1)
13130                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13131                    (const_int 1))
13132               (clobber (reg:CC FLAGS_REG))])]
13133   "TARGET_64BIT && !TARGET_USE_BT"
13134   [(const_int 0)]
13135 {
13136   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13137   rtx op1;
13138
13139   if (HOST_BITS_PER_WIDE_INT >= 64)
13140     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13141   else if (i < HOST_BITS_PER_WIDE_INT)
13142     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13143   else
13144     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13145
13146   op1 = immed_double_const (lo, hi, DImode);
13147   if (i >= 31)
13148     {
13149       emit_move_insn (operands[2], op1);
13150       op1 = operands[2];
13151     }
13152
13153   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13154   DONE;
13155 })
13156
13157 (define_peephole2
13158   [(match_scratch:DI 2 "r")
13159    (parallel [(set (zero_extract:DI
13160                      (match_operand:DI 0 "register_operand" "")
13161                      (const_int 1)
13162                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13163                    (const_int 0))
13164               (clobber (reg:CC FLAGS_REG))])]
13165   "TARGET_64BIT && !TARGET_USE_BT"
13166   [(const_int 0)]
13167 {
13168   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13169   rtx op1;
13170
13171   if (HOST_BITS_PER_WIDE_INT >= 64)
13172     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13173   else if (i < HOST_BITS_PER_WIDE_INT)
13174     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13175   else
13176     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13177
13178   op1 = immed_double_const (~lo, ~hi, DImode);
13179   if (i >= 32)
13180     {
13181       emit_move_insn (operands[2], op1);
13182       op1 = operands[2];
13183     }
13184
13185   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13186   DONE;
13187 })
13188
13189 (define_peephole2
13190   [(match_scratch:DI 2 "r")
13191    (parallel [(set (zero_extract:DI
13192                      (match_operand:DI 0 "register_operand" "")
13193                      (const_int 1)
13194                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13195               (not:DI (zero_extract:DI
13196                         (match_dup 0) (const_int 1) (match_dup 1))))
13197               (clobber (reg:CC FLAGS_REG))])]
13198   "TARGET_64BIT && !TARGET_USE_BT"
13199   [(const_int 0)]
13200 {
13201   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13202   rtx op1;
13203
13204   if (HOST_BITS_PER_WIDE_INT >= 64)
13205     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13206   else if (i < HOST_BITS_PER_WIDE_INT)
13207     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13208   else
13209     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13210
13211   op1 = immed_double_const (lo, hi, DImode);
13212   if (i >= 31)
13213     {
13214       emit_move_insn (operands[2], op1);
13215       op1 = operands[2];
13216     }
13217
13218   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13219   DONE;
13220 })
13221 \f
13222 ;; Store-flag instructions.
13223
13224 ;; For all sCOND expanders, also expand the compare or test insn that
13225 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13226
13227 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13228 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13229 ;; way, which can later delete the movzx if only QImode is needed.
13230
13231 (define_expand "seq"
13232   [(set (match_operand:QI 0 "register_operand" "")
13233         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13234   ""
13235   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13236
13237 (define_expand "sne"
13238   [(set (match_operand:QI 0 "register_operand" "")
13239         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13240   ""
13241   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13242
13243 (define_expand "sgt"
13244   [(set (match_operand:QI 0 "register_operand" "")
13245         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13246   ""
13247   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13248
13249 (define_expand "sgtu"
13250   [(set (match_operand:QI 0 "register_operand" "")
13251         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13252   ""
13253   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13254
13255 (define_expand "slt"
13256   [(set (match_operand:QI 0 "register_operand" "")
13257         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13258   ""
13259   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13260
13261 (define_expand "sltu"
13262   [(set (match_operand:QI 0 "register_operand" "")
13263         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13264   ""
13265   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13266
13267 (define_expand "sge"
13268   [(set (match_operand:QI 0 "register_operand" "")
13269         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13270   ""
13271   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13272
13273 (define_expand "sgeu"
13274   [(set (match_operand:QI 0 "register_operand" "")
13275         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13276   ""
13277   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13278
13279 (define_expand "sle"
13280   [(set (match_operand:QI 0 "register_operand" "")
13281         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13282   ""
13283   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13284
13285 (define_expand "sleu"
13286   [(set (match_operand:QI 0 "register_operand" "")
13287         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13288   ""
13289   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13290
13291 (define_expand "sunordered"
13292   [(set (match_operand:QI 0 "register_operand" "")
13293         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13294   "TARGET_80387 || TARGET_SSE"
13295   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13296
13297 (define_expand "sordered"
13298   [(set (match_operand:QI 0 "register_operand" "")
13299         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13300   "TARGET_80387"
13301   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13302
13303 (define_expand "suneq"
13304   [(set (match_operand:QI 0 "register_operand" "")
13305         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13306   "TARGET_80387 || TARGET_SSE"
13307   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13308
13309 (define_expand "sunge"
13310   [(set (match_operand:QI 0 "register_operand" "")
13311         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13312   "TARGET_80387 || TARGET_SSE"
13313   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13314
13315 (define_expand "sungt"
13316   [(set (match_operand:QI 0 "register_operand" "")
13317         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13318   "TARGET_80387 || TARGET_SSE"
13319   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13320
13321 (define_expand "sunle"
13322   [(set (match_operand:QI 0 "register_operand" "")
13323         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13324   "TARGET_80387 || TARGET_SSE"
13325   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13326
13327 (define_expand "sunlt"
13328   [(set (match_operand:QI 0 "register_operand" "")
13329         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13330   "TARGET_80387 || TARGET_SSE"
13331   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13332
13333 (define_expand "sltgt"
13334   [(set (match_operand:QI 0 "register_operand" "")
13335         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13336   "TARGET_80387 || TARGET_SSE"
13337   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13338
13339 (define_insn "*setcc_1"
13340   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13341         (match_operator:QI 1 "ix86_comparison_operator"
13342           [(reg FLAGS_REG) (const_int 0)]))]
13343   ""
13344   "set%C1\t%0"
13345   [(set_attr "type" "setcc")
13346    (set_attr "mode" "QI")])
13347
13348 (define_insn "*setcc_2"
13349   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13350         (match_operator:QI 1 "ix86_comparison_operator"
13351           [(reg FLAGS_REG) (const_int 0)]))]
13352   ""
13353   "set%C1\t%0"
13354   [(set_attr "type" "setcc")
13355    (set_attr "mode" "QI")])
13356
13357 ;; In general it is not safe to assume too much about CCmode registers,
13358 ;; so simplify-rtx stops when it sees a second one.  Under certain
13359 ;; conditions this is safe on x86, so help combine not create
13360 ;;
13361 ;;      seta    %al
13362 ;;      testb   %al, %al
13363 ;;      sete    %al
13364
13365 (define_split
13366   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13367         (ne:QI (match_operator 1 "ix86_comparison_operator"
13368                  [(reg FLAGS_REG) (const_int 0)])
13369             (const_int 0)))]
13370   ""
13371   [(set (match_dup 0) (match_dup 1))]
13372 {
13373   PUT_MODE (operands[1], QImode);
13374 })
13375
13376 (define_split
13377   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13378         (ne:QI (match_operator 1 "ix86_comparison_operator"
13379                  [(reg FLAGS_REG) (const_int 0)])
13380             (const_int 0)))]
13381   ""
13382   [(set (match_dup 0) (match_dup 1))]
13383 {
13384   PUT_MODE (operands[1], QImode);
13385 })
13386
13387 (define_split
13388   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13389         (eq:QI (match_operator 1 "ix86_comparison_operator"
13390                  [(reg FLAGS_REG) (const_int 0)])
13391             (const_int 0)))]
13392   ""
13393   [(set (match_dup 0) (match_dup 1))]
13394 {
13395   rtx new_op1 = copy_rtx (operands[1]);
13396   operands[1] = new_op1;
13397   PUT_MODE (new_op1, QImode);
13398   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13399                                              GET_MODE (XEXP (new_op1, 0))));
13400
13401   /* Make sure that (a) the CCmode we have for the flags is strong
13402      enough for the reversed compare or (b) we have a valid FP compare.  */
13403   if (! ix86_comparison_operator (new_op1, VOIDmode))
13404     FAIL;
13405 })
13406
13407 (define_split
13408   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13409         (eq:QI (match_operator 1 "ix86_comparison_operator"
13410                  [(reg FLAGS_REG) (const_int 0)])
13411             (const_int 0)))]
13412   ""
13413   [(set (match_dup 0) (match_dup 1))]
13414 {
13415   rtx new_op1 = copy_rtx (operands[1]);
13416   operands[1] = new_op1;
13417   PUT_MODE (new_op1, QImode);
13418   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13419                                              GET_MODE (XEXP (new_op1, 0))));
13420
13421   /* Make sure that (a) the CCmode we have for the flags is strong
13422      enough for the reversed compare or (b) we have a valid FP compare.  */
13423   if (! ix86_comparison_operator (new_op1, VOIDmode))
13424     FAIL;
13425 })
13426
13427 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13428 ;; subsequent logical operations are used to imitate conditional moves.
13429 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13430 ;; it directly.
13431
13432 (define_insn "*sse_setccsf"
13433   [(set (match_operand:SF 0 "register_operand" "=x")
13434         (match_operator:SF 1 "sse_comparison_operator"
13435           [(match_operand:SF 2 "register_operand" "0")
13436            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13437   "TARGET_SSE"
13438   "cmp%D1ss\t{%3, %0|%0, %3}"
13439   [(set_attr "type" "ssecmp")
13440    (set_attr "mode" "SF")])
13441
13442 (define_insn "*sse_setccdf"
13443   [(set (match_operand:DF 0 "register_operand" "=x")
13444         (match_operator:DF 1 "sse_comparison_operator"
13445           [(match_operand:DF 2 "register_operand" "0")
13446            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13447   "TARGET_SSE2"
13448   "cmp%D1sd\t{%3, %0|%0, %3}"
13449   [(set_attr "type" "ssecmp")
13450    (set_attr "mode" "DF")])
13451 \f
13452 ;; Basic conditional jump instructions.
13453 ;; We ignore the overflow flag for signed branch instructions.
13454
13455 ;; For all bCOND expanders, also expand the compare or test insn that
13456 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13457
13458 (define_expand "beq"
13459   [(set (pc)
13460         (if_then_else (match_dup 1)
13461                       (label_ref (match_operand 0 "" ""))
13462                       (pc)))]
13463   ""
13464   "ix86_expand_branch (EQ, operands[0]); DONE;")
13465
13466 (define_expand "bne"
13467   [(set (pc)
13468         (if_then_else (match_dup 1)
13469                       (label_ref (match_operand 0 "" ""))
13470                       (pc)))]
13471   ""
13472   "ix86_expand_branch (NE, operands[0]); DONE;")
13473
13474 (define_expand "bgt"
13475   [(set (pc)
13476         (if_then_else (match_dup 1)
13477                       (label_ref (match_operand 0 "" ""))
13478                       (pc)))]
13479   ""
13480   "ix86_expand_branch (GT, operands[0]); DONE;")
13481
13482 (define_expand "bgtu"
13483   [(set (pc)
13484         (if_then_else (match_dup 1)
13485                       (label_ref (match_operand 0 "" ""))
13486                       (pc)))]
13487   ""
13488   "ix86_expand_branch (GTU, operands[0]); DONE;")
13489
13490 (define_expand "blt"
13491   [(set (pc)
13492         (if_then_else (match_dup 1)
13493                       (label_ref (match_operand 0 "" ""))
13494                       (pc)))]
13495   ""
13496   "ix86_expand_branch (LT, operands[0]); DONE;")
13497
13498 (define_expand "bltu"
13499   [(set (pc)
13500         (if_then_else (match_dup 1)
13501                       (label_ref (match_operand 0 "" ""))
13502                       (pc)))]
13503   ""
13504   "ix86_expand_branch (LTU, operands[0]); DONE;")
13505
13506 (define_expand "bge"
13507   [(set (pc)
13508         (if_then_else (match_dup 1)
13509                       (label_ref (match_operand 0 "" ""))
13510                       (pc)))]
13511   ""
13512   "ix86_expand_branch (GE, operands[0]); DONE;")
13513
13514 (define_expand "bgeu"
13515   [(set (pc)
13516         (if_then_else (match_dup 1)
13517                       (label_ref (match_operand 0 "" ""))
13518                       (pc)))]
13519   ""
13520   "ix86_expand_branch (GEU, operands[0]); DONE;")
13521
13522 (define_expand "ble"
13523   [(set (pc)
13524         (if_then_else (match_dup 1)
13525                       (label_ref (match_operand 0 "" ""))
13526                       (pc)))]
13527   ""
13528   "ix86_expand_branch (LE, operands[0]); DONE;")
13529
13530 (define_expand "bleu"
13531   [(set (pc)
13532         (if_then_else (match_dup 1)
13533                       (label_ref (match_operand 0 "" ""))
13534                       (pc)))]
13535   ""
13536   "ix86_expand_branch (LEU, operands[0]); DONE;")
13537
13538 (define_expand "bunordered"
13539   [(set (pc)
13540         (if_then_else (match_dup 1)
13541                       (label_ref (match_operand 0 "" ""))
13542                       (pc)))]
13543   "TARGET_80387 || TARGET_SSE_MATH"
13544   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13545
13546 (define_expand "bordered"
13547   [(set (pc)
13548         (if_then_else (match_dup 1)
13549                       (label_ref (match_operand 0 "" ""))
13550                       (pc)))]
13551   "TARGET_80387 || TARGET_SSE_MATH"
13552   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13553
13554 (define_expand "buneq"
13555   [(set (pc)
13556         (if_then_else (match_dup 1)
13557                       (label_ref (match_operand 0 "" ""))
13558                       (pc)))]
13559   "TARGET_80387 || TARGET_SSE_MATH"
13560   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13561
13562 (define_expand "bunge"
13563   [(set (pc)
13564         (if_then_else (match_dup 1)
13565                       (label_ref (match_operand 0 "" ""))
13566                       (pc)))]
13567   "TARGET_80387 || TARGET_SSE_MATH"
13568   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13569
13570 (define_expand "bungt"
13571   [(set (pc)
13572         (if_then_else (match_dup 1)
13573                       (label_ref (match_operand 0 "" ""))
13574                       (pc)))]
13575   "TARGET_80387 || TARGET_SSE_MATH"
13576   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13577
13578 (define_expand "bunle"
13579   [(set (pc)
13580         (if_then_else (match_dup 1)
13581                       (label_ref (match_operand 0 "" ""))
13582                       (pc)))]
13583   "TARGET_80387 || TARGET_SSE_MATH"
13584   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13585
13586 (define_expand "bunlt"
13587   [(set (pc)
13588         (if_then_else (match_dup 1)
13589                       (label_ref (match_operand 0 "" ""))
13590                       (pc)))]
13591   "TARGET_80387 || TARGET_SSE_MATH"
13592   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13593
13594 (define_expand "bltgt"
13595   [(set (pc)
13596         (if_then_else (match_dup 1)
13597                       (label_ref (match_operand 0 "" ""))
13598                       (pc)))]
13599   "TARGET_80387 || TARGET_SSE_MATH"
13600   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13601
13602 (define_insn "*jcc_1"
13603   [(set (pc)
13604         (if_then_else (match_operator 1 "ix86_comparison_operator"
13605                                       [(reg FLAGS_REG) (const_int 0)])
13606                       (label_ref (match_operand 0 "" ""))
13607                       (pc)))]
13608   ""
13609   "%+j%C1\t%l0"
13610   [(set_attr "type" "ibr")
13611    (set_attr "modrm" "0")
13612    (set (attr "length")
13613            (if_then_else (and (ge (minus (match_dup 0) (pc))
13614                                   (const_int -126))
13615                               (lt (minus (match_dup 0) (pc))
13616                                   (const_int 128)))
13617              (const_int 2)
13618              (const_int 6)))])
13619
13620 (define_insn "*jcc_2"
13621   [(set (pc)
13622         (if_then_else (match_operator 1 "ix86_comparison_operator"
13623                                       [(reg FLAGS_REG) (const_int 0)])
13624                       (pc)
13625                       (label_ref (match_operand 0 "" ""))))]
13626   ""
13627   "%+j%c1\t%l0"
13628   [(set_attr "type" "ibr")
13629    (set_attr "modrm" "0")
13630    (set (attr "length")
13631            (if_then_else (and (ge (minus (match_dup 0) (pc))
13632                                   (const_int -126))
13633                               (lt (minus (match_dup 0) (pc))
13634                                   (const_int 128)))
13635              (const_int 2)
13636              (const_int 6)))])
13637
13638 ;; In general it is not safe to assume too much about CCmode registers,
13639 ;; so simplify-rtx stops when it sees a second one.  Under certain
13640 ;; conditions this is safe on x86, so help combine not create
13641 ;;
13642 ;;      seta    %al
13643 ;;      testb   %al, %al
13644 ;;      je      Lfoo
13645
13646 (define_split
13647   [(set (pc)
13648         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13649                                       [(reg FLAGS_REG) (const_int 0)])
13650                           (const_int 0))
13651                       (label_ref (match_operand 1 "" ""))
13652                       (pc)))]
13653   ""
13654   [(set (pc)
13655         (if_then_else (match_dup 0)
13656                       (label_ref (match_dup 1))
13657                       (pc)))]
13658 {
13659   PUT_MODE (operands[0], VOIDmode);
13660 })
13661
13662 (define_split
13663   [(set (pc)
13664         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13665                                       [(reg FLAGS_REG) (const_int 0)])
13666                           (const_int 0))
13667                       (label_ref (match_operand 1 "" ""))
13668                       (pc)))]
13669   ""
13670   [(set (pc)
13671         (if_then_else (match_dup 0)
13672                       (label_ref (match_dup 1))
13673                       (pc)))]
13674 {
13675   rtx new_op0 = copy_rtx (operands[0]);
13676   operands[0] = new_op0;
13677   PUT_MODE (new_op0, VOIDmode);
13678   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13679                                              GET_MODE (XEXP (new_op0, 0))));
13680
13681   /* Make sure that (a) the CCmode we have for the flags is strong
13682      enough for the reversed compare or (b) we have a valid FP compare.  */
13683   if (! ix86_comparison_operator (new_op0, VOIDmode))
13684     FAIL;
13685 })
13686
13687 ;; Define combination compare-and-branch fp compare instructions to use
13688 ;; during early optimization.  Splitting the operation apart early makes
13689 ;; for bad code when we want to reverse the operation.
13690
13691 (define_insn "*fp_jcc_1_mixed"
13692   [(set (pc)
13693         (if_then_else (match_operator 0 "comparison_operator"
13694                         [(match_operand 1 "register_operand" "f,x")
13695                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13696           (label_ref (match_operand 3 "" ""))
13697           (pc)))
13698    (clobber (reg:CCFP FPSR_REG))
13699    (clobber (reg:CCFP FLAGS_REG))]
13700   "TARGET_MIX_SSE_I387
13701    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13702    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13703    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13704   "#")
13705
13706 (define_insn "*fp_jcc_1_sse"
13707   [(set (pc)
13708         (if_then_else (match_operator 0 "comparison_operator"
13709                         [(match_operand 1 "register_operand" "x")
13710                          (match_operand 2 "nonimmediate_operand" "xm")])
13711           (label_ref (match_operand 3 "" ""))
13712           (pc)))
13713    (clobber (reg:CCFP FPSR_REG))
13714    (clobber (reg:CCFP FLAGS_REG))]
13715   "TARGET_SSE_MATH
13716    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13717    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13718    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13719   "#")
13720
13721 (define_insn "*fp_jcc_1_387"
13722   [(set (pc)
13723         (if_then_else (match_operator 0 "comparison_operator"
13724                         [(match_operand 1 "register_operand" "f")
13725                          (match_operand 2 "register_operand" "f")])
13726           (label_ref (match_operand 3 "" ""))
13727           (pc)))
13728    (clobber (reg:CCFP FPSR_REG))
13729    (clobber (reg:CCFP FLAGS_REG))]
13730   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13731    && TARGET_CMOVE
13732    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13733    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13734   "#")
13735
13736 (define_insn "*fp_jcc_2_mixed"
13737   [(set (pc)
13738         (if_then_else (match_operator 0 "comparison_operator"
13739                         [(match_operand 1 "register_operand" "f,x")
13740                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13741           (pc)
13742           (label_ref (match_operand 3 "" ""))))
13743    (clobber (reg:CCFP FPSR_REG))
13744    (clobber (reg:CCFP FLAGS_REG))]
13745   "TARGET_MIX_SSE_I387
13746    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13747    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13748    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13749   "#")
13750
13751 (define_insn "*fp_jcc_2_sse"
13752   [(set (pc)
13753         (if_then_else (match_operator 0 "comparison_operator"
13754                         [(match_operand 1 "register_operand" "x")
13755                          (match_operand 2 "nonimmediate_operand" "xm")])
13756           (pc)
13757           (label_ref (match_operand 3 "" ""))))
13758    (clobber (reg:CCFP FPSR_REG))
13759    (clobber (reg:CCFP FLAGS_REG))]
13760   "TARGET_SSE_MATH
13761    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13762    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13763    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13764   "#")
13765
13766 (define_insn "*fp_jcc_2_387"
13767   [(set (pc)
13768         (if_then_else (match_operator 0 "comparison_operator"
13769                         [(match_operand 1 "register_operand" "f")
13770                          (match_operand 2 "register_operand" "f")])
13771           (pc)
13772           (label_ref (match_operand 3 "" ""))))
13773    (clobber (reg:CCFP FPSR_REG))
13774    (clobber (reg:CCFP FLAGS_REG))]
13775   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13776    && TARGET_CMOVE
13777    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13778    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13779   "#")
13780
13781 (define_insn "*fp_jcc_3_387"
13782   [(set (pc)
13783         (if_then_else (match_operator 0 "comparison_operator"
13784                         [(match_operand 1 "register_operand" "f")
13785                          (match_operand 2 "nonimmediate_operand" "fm")])
13786           (label_ref (match_operand 3 "" ""))
13787           (pc)))
13788    (clobber (reg:CCFP FPSR_REG))
13789    (clobber (reg:CCFP FLAGS_REG))
13790    (clobber (match_scratch:HI 4 "=a"))]
13791   "TARGET_80387
13792    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13793    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13794    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13795    && SELECT_CC_MODE (GET_CODE (operands[0]),
13796                       operands[1], operands[2]) == CCFPmode
13797    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13798   "#")
13799
13800 (define_insn "*fp_jcc_4_387"
13801   [(set (pc)
13802         (if_then_else (match_operator 0 "comparison_operator"
13803                         [(match_operand 1 "register_operand" "f")
13804                          (match_operand 2 "nonimmediate_operand" "fm")])
13805           (pc)
13806           (label_ref (match_operand 3 "" ""))))
13807    (clobber (reg:CCFP FPSR_REG))
13808    (clobber (reg:CCFP FLAGS_REG))
13809    (clobber (match_scratch:HI 4 "=a"))]
13810   "TARGET_80387
13811    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13812    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13813    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13814    && SELECT_CC_MODE (GET_CODE (operands[0]),
13815                       operands[1], operands[2]) == CCFPmode
13816    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13817   "#")
13818
13819 (define_insn "*fp_jcc_5_387"
13820   [(set (pc)
13821         (if_then_else (match_operator 0 "comparison_operator"
13822                         [(match_operand 1 "register_operand" "f")
13823                          (match_operand 2 "register_operand" "f")])
13824           (label_ref (match_operand 3 "" ""))
13825           (pc)))
13826    (clobber (reg:CCFP FPSR_REG))
13827    (clobber (reg:CCFP FLAGS_REG))
13828    (clobber (match_scratch:HI 4 "=a"))]
13829   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13830    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13831    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13832   "#")
13833
13834 (define_insn "*fp_jcc_6_387"
13835   [(set (pc)
13836         (if_then_else (match_operator 0 "comparison_operator"
13837                         [(match_operand 1 "register_operand" "f")
13838                          (match_operand 2 "register_operand" "f")])
13839           (pc)
13840           (label_ref (match_operand 3 "" ""))))
13841    (clobber (reg:CCFP FPSR_REG))
13842    (clobber (reg:CCFP FLAGS_REG))
13843    (clobber (match_scratch:HI 4 "=a"))]
13844   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13845    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13846    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13847   "#")
13848
13849 (define_insn "*fp_jcc_7_387"
13850   [(set (pc)
13851         (if_then_else (match_operator 0 "comparison_operator"
13852                         [(match_operand 1 "register_operand" "f")
13853                          (match_operand 2 "const0_operand" "X")])
13854           (label_ref (match_operand 3 "" ""))
13855           (pc)))
13856    (clobber (reg:CCFP FPSR_REG))
13857    (clobber (reg:CCFP FLAGS_REG))
13858    (clobber (match_scratch:HI 4 "=a"))]
13859   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13860    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13861    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13862    && SELECT_CC_MODE (GET_CODE (operands[0]),
13863                       operands[1], operands[2]) == CCFPmode
13864    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13865   "#")
13866
13867 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13868 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13869 ;; with a precedence over other operators and is always put in the first
13870 ;; place. Swap condition and operands to match ficom instruction.
13871
13872 (define_insn "*fp_jcc_8<mode>_387"
13873   [(set (pc)
13874         (if_then_else (match_operator 0 "comparison_operator"
13875                         [(match_operator 1 "float_operator"
13876                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13877                            (match_operand 3 "register_operand" "f,f")])
13878           (label_ref (match_operand 4 "" ""))
13879           (pc)))
13880    (clobber (reg:CCFP FPSR_REG))
13881    (clobber (reg:CCFP FLAGS_REG))
13882    (clobber (match_scratch:HI 5 "=a,a"))]
13883   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13884    && TARGET_USE_<MODE>MODE_FIOP
13885    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13886    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13887    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13888    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13889   "#")
13890
13891 (define_split
13892   [(set (pc)
13893         (if_then_else (match_operator 0 "comparison_operator"
13894                         [(match_operand 1 "register_operand" "")
13895                          (match_operand 2 "nonimmediate_operand" "")])
13896           (match_operand 3 "" "")
13897           (match_operand 4 "" "")))
13898    (clobber (reg:CCFP FPSR_REG))
13899    (clobber (reg:CCFP FLAGS_REG))]
13900   "reload_completed"
13901   [(const_int 0)]
13902 {
13903   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13904                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13905   DONE;
13906 })
13907
13908 (define_split
13909   [(set (pc)
13910         (if_then_else (match_operator 0 "comparison_operator"
13911                         [(match_operand 1 "register_operand" "")
13912                          (match_operand 2 "general_operand" "")])
13913           (match_operand 3 "" "")
13914           (match_operand 4 "" "")))
13915    (clobber (reg:CCFP FPSR_REG))
13916    (clobber (reg:CCFP FLAGS_REG))
13917    (clobber (match_scratch:HI 5 "=a"))]
13918   "reload_completed"
13919   [(const_int 0)]
13920 {
13921   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13922                         operands[3], operands[4], operands[5], NULL_RTX);
13923   DONE;
13924 })
13925
13926 (define_split
13927   [(set (pc)
13928         (if_then_else (match_operator 0 "comparison_operator"
13929                         [(match_operator 1 "float_operator"
13930                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13931                            (match_operand 3 "register_operand" "")])
13932           (match_operand 4 "" "")
13933           (match_operand 5 "" "")))
13934    (clobber (reg:CCFP FPSR_REG))
13935    (clobber (reg:CCFP FLAGS_REG))
13936    (clobber (match_scratch:HI 6 "=a"))]
13937   "reload_completed"
13938   [(const_int 0)]
13939 {
13940   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13941   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13942                         operands[3], operands[7],
13943                         operands[4], operands[5], operands[6], NULL_RTX);
13944   DONE;
13945 })
13946
13947 ;; %%% Kill this when reload knows how to do it.
13948 (define_split
13949   [(set (pc)
13950         (if_then_else (match_operator 0 "comparison_operator"
13951                         [(match_operator 1 "float_operator"
13952                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13953                            (match_operand 3 "register_operand" "")])
13954           (match_operand 4 "" "")
13955           (match_operand 5 "" "")))
13956    (clobber (reg:CCFP FPSR_REG))
13957    (clobber (reg:CCFP FLAGS_REG))
13958    (clobber (match_scratch:HI 6 "=a"))]
13959   "reload_completed"
13960   [(const_int 0)]
13961 {
13962   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13963   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13964   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13965                         operands[3], operands[7],
13966                         operands[4], operands[5], operands[6], operands[2]);
13967   DONE;
13968 })
13969 \f
13970 ;; Unconditional and other jump instructions
13971
13972 (define_insn "jump"
13973   [(set (pc)
13974         (label_ref (match_operand 0 "" "")))]
13975   ""
13976   "jmp\t%l0"
13977   [(set_attr "type" "ibr")
13978    (set (attr "length")
13979            (if_then_else (and (ge (minus (match_dup 0) (pc))
13980                                   (const_int -126))
13981                               (lt (minus (match_dup 0) (pc))
13982                                   (const_int 128)))
13983              (const_int 2)
13984              (const_int 5)))
13985    (set_attr "modrm" "0")])
13986
13987 (define_expand "indirect_jump"
13988   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13989   ""
13990   "")
13991
13992 (define_insn "*indirect_jump"
13993   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13994   "!TARGET_64BIT"
13995   "jmp\t%A0"
13996   [(set_attr "type" "ibr")
13997    (set_attr "length_immediate" "0")])
13998
13999 (define_insn "*indirect_jump_rtx64"
14000   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14001   "TARGET_64BIT"
14002   "jmp\t%A0"
14003   [(set_attr "type" "ibr")
14004    (set_attr "length_immediate" "0")])
14005
14006 (define_expand "tablejump"
14007   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14008               (use (label_ref (match_operand 1 "" "")))])]
14009   ""
14010 {
14011   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14012      relative.  Convert the relative address to an absolute address.  */
14013   if (flag_pic)
14014     {
14015       rtx op0, op1;
14016       enum rtx_code code;
14017
14018       /* We can't use @GOTOFF for text labels on VxWorks;
14019          see gotoff_operand.  */
14020       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14021         {
14022           code = PLUS;
14023           op0 = operands[0];
14024           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14025         }
14026       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14027         {
14028           code = PLUS;
14029           op0 = operands[0];
14030           op1 = pic_offset_table_rtx;
14031         }
14032       else
14033         {
14034           code = MINUS;
14035           op0 = pic_offset_table_rtx;
14036           op1 = operands[0];
14037         }
14038
14039       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14040                                          OPTAB_DIRECT);
14041     }
14042 })
14043
14044 (define_insn "*tablejump_1"
14045   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14046    (use (label_ref (match_operand 1 "" "")))]
14047   "!TARGET_64BIT"
14048   "jmp\t%A0"
14049   [(set_attr "type" "ibr")
14050    (set_attr "length_immediate" "0")])
14051
14052 (define_insn "*tablejump_1_rtx64"
14053   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14054    (use (label_ref (match_operand 1 "" "")))]
14055   "TARGET_64BIT"
14056   "jmp\t%A0"
14057   [(set_attr "type" "ibr")
14058    (set_attr "length_immediate" "0")])
14059 \f
14060 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14061
14062 (define_peephole2
14063   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14064    (set (match_operand:QI 1 "register_operand" "")
14065         (match_operator:QI 2 "ix86_comparison_operator"
14066           [(reg FLAGS_REG) (const_int 0)]))
14067    (set (match_operand 3 "q_regs_operand" "")
14068         (zero_extend (match_dup 1)))]
14069   "(peep2_reg_dead_p (3, operands[1])
14070     || operands_match_p (operands[1], operands[3]))
14071    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14072   [(set (match_dup 4) (match_dup 0))
14073    (set (strict_low_part (match_dup 5))
14074         (match_dup 2))]
14075 {
14076   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14077   operands[5] = gen_lowpart (QImode, operands[3]);
14078   ix86_expand_clear (operands[3]);
14079 })
14080
14081 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14082
14083 (define_peephole2
14084   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14085    (set (match_operand:QI 1 "register_operand" "")
14086         (match_operator:QI 2 "ix86_comparison_operator"
14087           [(reg FLAGS_REG) (const_int 0)]))
14088    (parallel [(set (match_operand 3 "q_regs_operand" "")
14089                    (zero_extend (match_dup 1)))
14090               (clobber (reg:CC FLAGS_REG))])]
14091   "(peep2_reg_dead_p (3, operands[1])
14092     || operands_match_p (operands[1], operands[3]))
14093    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14094   [(set (match_dup 4) (match_dup 0))
14095    (set (strict_low_part (match_dup 5))
14096         (match_dup 2))]
14097 {
14098   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14099   operands[5] = gen_lowpart (QImode, operands[3]);
14100   ix86_expand_clear (operands[3]);
14101 })
14102 \f
14103 ;; Call instructions.
14104
14105 ;; The predicates normally associated with named expanders are not properly
14106 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14107 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14108
14109 ;; Call subroutine returning no value.
14110
14111 (define_expand "call_pop"
14112   [(parallel [(call (match_operand:QI 0 "" "")
14113                     (match_operand:SI 1 "" ""))
14114               (set (reg:SI SP_REG)
14115                    (plus:SI (reg:SI SP_REG)
14116                             (match_operand:SI 3 "" "")))])]
14117   "!TARGET_64BIT"
14118 {
14119   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14120   DONE;
14121 })
14122
14123 (define_insn "*call_pop_0"
14124   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14125          (match_operand:SI 1 "" ""))
14126    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14127                             (match_operand:SI 2 "immediate_operand" "")))]
14128   "!TARGET_64BIT"
14129 {
14130   if (SIBLING_CALL_P (insn))
14131     return "jmp\t%P0";
14132   else
14133     return "call\t%P0";
14134 }
14135   [(set_attr "type" "call")])
14136
14137 (define_insn "*call_pop_1"
14138   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14139          (match_operand:SI 1 "" ""))
14140    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14141                             (match_operand:SI 2 "immediate_operand" "i")))]
14142   "!TARGET_64BIT"
14143 {
14144   if (constant_call_address_operand (operands[0], Pmode))
14145     {
14146       if (SIBLING_CALL_P (insn))
14147         return "jmp\t%P0";
14148       else
14149         return "call\t%P0";
14150     }
14151   if (SIBLING_CALL_P (insn))
14152     return "jmp\t%A0";
14153   else
14154     return "call\t%A0";
14155 }
14156   [(set_attr "type" "call")])
14157
14158 (define_expand "call"
14159   [(call (match_operand:QI 0 "" "")
14160          (match_operand 1 "" ""))
14161    (use (match_operand 2 "" ""))]
14162   ""
14163 {
14164   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14165   DONE;
14166 })
14167
14168 (define_expand "sibcall"
14169   [(call (match_operand:QI 0 "" "")
14170          (match_operand 1 "" ""))
14171    (use (match_operand 2 "" ""))]
14172   ""
14173 {
14174   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14175   DONE;
14176 })
14177
14178 (define_insn "*call_0"
14179   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14180          (match_operand 1 "" ""))]
14181   ""
14182 {
14183   if (SIBLING_CALL_P (insn))
14184     return "jmp\t%P0";
14185   else
14186     return "call\t%P0";
14187 }
14188   [(set_attr "type" "call")])
14189
14190 (define_insn "*call_1"
14191   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14192          (match_operand 1 "" ""))]
14193   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14194 {
14195   if (constant_call_address_operand (operands[0], Pmode))
14196     return "call\t%P0";
14197   return "call\t%A0";
14198 }
14199   [(set_attr "type" "call")])
14200
14201 (define_insn "*sibcall_1"
14202   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14203          (match_operand 1 "" ""))]
14204   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14205 {
14206   if (constant_call_address_operand (operands[0], Pmode))
14207     return "jmp\t%P0";
14208   return "jmp\t%A0";
14209 }
14210   [(set_attr "type" "call")])
14211
14212 (define_insn "*call_1_rex64"
14213   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14214          (match_operand 1 "" ""))]
14215   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14216    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14217 {
14218   if (constant_call_address_operand (operands[0], Pmode))
14219     return "call\t%P0";
14220   return "call\t%A0";
14221 }
14222   [(set_attr "type" "call")])
14223
14224 (define_insn "*call_1_rex64_large"
14225   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14226          (match_operand 1 "" ""))]
14227   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14228   "call\t%A0"
14229   [(set_attr "type" "call")])
14230
14231 (define_insn "*sibcall_1_rex64"
14232   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14233          (match_operand 1 "" ""))]
14234   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14235   "jmp\t%P0"
14236   [(set_attr "type" "call")])
14237
14238 (define_insn "*sibcall_1_rex64_v"
14239   [(call (mem:QI (reg:DI R11_REG))
14240          (match_operand 0 "" ""))]
14241   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14242   "jmp\t*%%r11"
14243   [(set_attr "type" "call")])
14244
14245
14246 ;; Call subroutine, returning value in operand 0
14247
14248 (define_expand "call_value_pop"
14249   [(parallel [(set (match_operand 0 "" "")
14250                    (call (match_operand:QI 1 "" "")
14251                          (match_operand:SI 2 "" "")))
14252               (set (reg:SI SP_REG)
14253                    (plus:SI (reg:SI SP_REG)
14254                             (match_operand:SI 4 "" "")))])]
14255   "!TARGET_64BIT"
14256 {
14257   ix86_expand_call (operands[0], operands[1], operands[2],
14258                     operands[3], operands[4], 0);
14259   DONE;
14260 })
14261
14262 (define_expand "call_value"
14263   [(set (match_operand 0 "" "")
14264         (call (match_operand:QI 1 "" "")
14265               (match_operand:SI 2 "" "")))
14266    (use (match_operand:SI 3 "" ""))]
14267   ;; Operand 2 not used on the i386.
14268   ""
14269 {
14270   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14271   DONE;
14272 })
14273
14274 (define_expand "sibcall_value"
14275   [(set (match_operand 0 "" "")
14276         (call (match_operand:QI 1 "" "")
14277               (match_operand:SI 2 "" "")))
14278    (use (match_operand:SI 3 "" ""))]
14279   ;; Operand 2 not used on the i386.
14280   ""
14281 {
14282   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14283   DONE;
14284 })
14285
14286 ;; Call subroutine returning any type.
14287
14288 (define_expand "untyped_call"
14289   [(parallel [(call (match_operand 0 "" "")
14290                     (const_int 0))
14291               (match_operand 1 "" "")
14292               (match_operand 2 "" "")])]
14293   ""
14294 {
14295   int i;
14296
14297   /* In order to give reg-stack an easier job in validating two
14298      coprocessor registers as containing a possible return value,
14299      simply pretend the untyped call returns a complex long double
14300      value.  */
14301
14302   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14303                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14304                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14305                     NULL, 0);
14306
14307   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14308     {
14309       rtx set = XVECEXP (operands[2], 0, i);
14310       emit_move_insn (SET_DEST (set), SET_SRC (set));
14311     }
14312
14313   /* The optimizer does not know that the call sets the function value
14314      registers we stored in the result block.  We avoid problems by
14315      claiming that all hard registers are used and clobbered at this
14316      point.  */
14317   emit_insn (gen_blockage (const0_rtx));
14318
14319   DONE;
14320 })
14321 \f
14322 ;; Prologue and epilogue instructions
14323
14324 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14325 ;; all of memory.  This blocks insns from being moved across this point.
14326
14327 (define_insn "blockage"
14328   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14329   ""
14330   ""
14331   [(set_attr "length" "0")])
14332
14333 ;; Insn emitted into the body of a function to return from a function.
14334 ;; This is only done if the function's epilogue is known to be simple.
14335 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14336
14337 (define_expand "return"
14338   [(return)]
14339   "ix86_can_use_return_insn_p ()"
14340 {
14341   if (current_function_pops_args)
14342     {
14343       rtx popc = GEN_INT (current_function_pops_args);
14344       emit_jump_insn (gen_return_pop_internal (popc));
14345       DONE;
14346     }
14347 })
14348
14349 (define_insn "return_internal"
14350   [(return)]
14351   "reload_completed"
14352   "ret"
14353   [(set_attr "length" "1")
14354    (set_attr "length_immediate" "0")
14355    (set_attr "modrm" "0")])
14356
14357 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14358 ;; instruction Athlon and K8 have.
14359
14360 (define_insn "return_internal_long"
14361   [(return)
14362    (unspec [(const_int 0)] UNSPEC_REP)]
14363   "reload_completed"
14364   "rep {;} ret"
14365   [(set_attr "length" "1")
14366    (set_attr "length_immediate" "0")
14367    (set_attr "prefix_rep" "1")
14368    (set_attr "modrm" "0")])
14369
14370 (define_insn "return_pop_internal"
14371   [(return)
14372    (use (match_operand:SI 0 "const_int_operand" ""))]
14373   "reload_completed"
14374   "ret\t%0"
14375   [(set_attr "length" "3")
14376    (set_attr "length_immediate" "2")
14377    (set_attr "modrm" "0")])
14378
14379 (define_insn "return_indirect_internal"
14380   [(return)
14381    (use (match_operand:SI 0 "register_operand" "r"))]
14382   "reload_completed"
14383   "jmp\t%A0"
14384   [(set_attr "type" "ibr")
14385    (set_attr "length_immediate" "0")])
14386
14387 (define_insn "nop"
14388   [(const_int 0)]
14389   ""
14390   "nop"
14391   [(set_attr "length" "1")
14392    (set_attr "length_immediate" "0")
14393    (set_attr "modrm" "0")])
14394
14395 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14396 ;; branch prediction penalty for the third jump in a 16-byte
14397 ;; block on K8.
14398
14399 (define_insn "align"
14400   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14401   ""
14402 {
14403 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14404   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14405 #else
14406   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14407      The align insn is used to avoid 3 jump instructions in the row to improve
14408      branch prediction and the benefits hardly outweigh the cost of extra 8
14409      nops on the average inserted by full alignment pseudo operation.  */
14410 #endif
14411   return "";
14412 }
14413   [(set_attr "length" "16")])
14414
14415 (define_expand "prologue"
14416   [(const_int 1)]
14417   ""
14418   "ix86_expand_prologue (); DONE;")
14419
14420 (define_insn "set_got"
14421   [(set (match_operand:SI 0 "register_operand" "=r")
14422         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14423    (clobber (reg:CC FLAGS_REG))]
14424   "!TARGET_64BIT"
14425   { return output_set_got (operands[0], NULL_RTX); }
14426   [(set_attr "type" "multi")
14427    (set_attr "length" "12")])
14428
14429 (define_insn "set_got_labelled"
14430   [(set (match_operand:SI 0 "register_operand" "=r")
14431         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14432          UNSPEC_SET_GOT))
14433    (clobber (reg:CC FLAGS_REG))]
14434   "!TARGET_64BIT"
14435   { return output_set_got (operands[0], operands[1]); }
14436   [(set_attr "type" "multi")
14437    (set_attr "length" "12")])
14438
14439 (define_insn "set_got_rex64"
14440   [(set (match_operand:DI 0 "register_operand" "=r")
14441         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14442   "TARGET_64BIT"
14443   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14444   [(set_attr "type" "lea")
14445    (set_attr "length" "6")])
14446
14447 (define_insn "set_rip_rex64"
14448   [(set (match_operand:DI 0 "register_operand" "=r")
14449         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14450   "TARGET_64BIT"
14451   "lea{q}\t%l1(%%rip), %0"
14452   [(set_attr "type" "lea")
14453    (set_attr "length" "6")])
14454
14455 (define_insn "set_got_offset_rex64"
14456   [(set (match_operand:DI 0 "register_operand" "=r")
14457         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14458   "TARGET_64BIT"
14459   "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
14460   [(set_attr "type" "imov")
14461    (set_attr "length" "11")])
14462
14463 (define_expand "epilogue"
14464   [(const_int 1)]
14465   ""
14466   "ix86_expand_epilogue (1); DONE;")
14467
14468 (define_expand "sibcall_epilogue"
14469   [(const_int 1)]
14470   ""
14471   "ix86_expand_epilogue (0); DONE;")
14472
14473 (define_expand "eh_return"
14474   [(use (match_operand 0 "register_operand" ""))]
14475   ""
14476 {
14477   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14478
14479   /* Tricky bit: we write the address of the handler to which we will
14480      be returning into someone else's stack frame, one word below the
14481      stack address we wish to restore.  */
14482   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14483   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14484   tmp = gen_rtx_MEM (Pmode, tmp);
14485   emit_move_insn (tmp, ra);
14486
14487   if (Pmode == SImode)
14488     emit_jump_insn (gen_eh_return_si (sa));
14489   else
14490     emit_jump_insn (gen_eh_return_di (sa));
14491   emit_barrier ();
14492   DONE;
14493 })
14494
14495 (define_insn_and_split "eh_return_si"
14496   [(set (pc)
14497         (unspec [(match_operand:SI 0 "register_operand" "c")]
14498                  UNSPEC_EH_RETURN))]
14499   "!TARGET_64BIT"
14500   "#"
14501   "reload_completed"
14502   [(const_int 1)]
14503   "ix86_expand_epilogue (2); DONE;")
14504
14505 (define_insn_and_split "eh_return_di"
14506   [(set (pc)
14507         (unspec [(match_operand:DI 0 "register_operand" "c")]
14508                  UNSPEC_EH_RETURN))]
14509   "TARGET_64BIT"
14510   "#"
14511   "reload_completed"
14512   [(const_int 1)]
14513   "ix86_expand_epilogue (2); DONE;")
14514
14515 (define_insn "leave"
14516   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14517    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14518    (clobber (mem:BLK (scratch)))]
14519   "!TARGET_64BIT"
14520   "leave"
14521   [(set_attr "type" "leave")])
14522
14523 (define_insn "leave_rex64"
14524   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14525    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14526    (clobber (mem:BLK (scratch)))]
14527   "TARGET_64BIT"
14528   "leave"
14529   [(set_attr "type" "leave")])
14530 \f
14531 (define_expand "ffssi2"
14532   [(parallel
14533      [(set (match_operand:SI 0 "register_operand" "")
14534            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14535       (clobber (match_scratch:SI 2 ""))
14536       (clobber (reg:CC FLAGS_REG))])]
14537   ""
14538   "")
14539
14540 (define_insn_and_split "*ffs_cmove"
14541   [(set (match_operand:SI 0 "register_operand" "=r")
14542         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14543    (clobber (match_scratch:SI 2 "=&r"))
14544    (clobber (reg:CC FLAGS_REG))]
14545   "TARGET_CMOVE"
14546   "#"
14547   "&& reload_completed"
14548   [(set (match_dup 2) (const_int -1))
14549    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14550               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14551    (set (match_dup 0) (if_then_else:SI
14552                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14553                         (match_dup 2)
14554                         (match_dup 0)))
14555    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14556               (clobber (reg:CC FLAGS_REG))])]
14557   "")
14558
14559 (define_insn_and_split "*ffs_no_cmove"
14560   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14561         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14562    (clobber (match_scratch:SI 2 "=&q"))
14563    (clobber (reg:CC FLAGS_REG))]
14564   ""
14565   "#"
14566   "reload_completed"
14567   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14568               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14569    (set (strict_low_part (match_dup 3))
14570         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14571    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14572               (clobber (reg:CC FLAGS_REG))])
14573    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14574               (clobber (reg:CC FLAGS_REG))])
14575    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14576               (clobber (reg:CC FLAGS_REG))])]
14577 {
14578   operands[3] = gen_lowpart (QImode, operands[2]);
14579   ix86_expand_clear (operands[2]);
14580 })
14581
14582 (define_insn "*ffssi_1"
14583   [(set (reg:CCZ FLAGS_REG)
14584         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14585                      (const_int 0)))
14586    (set (match_operand:SI 0 "register_operand" "=r")
14587         (ctz:SI (match_dup 1)))]
14588   ""
14589   "bsf{l}\t{%1, %0|%0, %1}"
14590   [(set_attr "prefix_0f" "1")])
14591
14592 (define_expand "ffsdi2"
14593   [(parallel
14594      [(set (match_operand:DI 0 "register_operand" "")
14595            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14596       (clobber (match_scratch:DI 2 ""))
14597       (clobber (reg:CC FLAGS_REG))])]
14598   "TARGET_64BIT && TARGET_CMOVE"
14599   "")
14600
14601 (define_insn_and_split "*ffs_rex64"
14602   [(set (match_operand:DI 0 "register_operand" "=r")
14603         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14604    (clobber (match_scratch:DI 2 "=&r"))
14605    (clobber (reg:CC FLAGS_REG))]
14606   "TARGET_64BIT && TARGET_CMOVE"
14607   "#"
14608   "&& reload_completed"
14609   [(set (match_dup 2) (const_int -1))
14610    (parallel [(set (reg:CCZ FLAGS_REG)
14611                    (compare:CCZ (match_dup 1) (const_int 0)))
14612               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14613    (set (match_dup 0) (if_then_else:DI
14614                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14615                         (match_dup 2)
14616                         (match_dup 0)))
14617    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14618               (clobber (reg:CC FLAGS_REG))])]
14619   "")
14620
14621 (define_insn "*ffsdi_1"
14622   [(set (reg:CCZ FLAGS_REG)
14623         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14624                      (const_int 0)))
14625    (set (match_operand:DI 0 "register_operand" "=r")
14626         (ctz:DI (match_dup 1)))]
14627   "TARGET_64BIT"
14628   "bsf{q}\t{%1, %0|%0, %1}"
14629   [(set_attr "prefix_0f" "1")])
14630
14631 (define_insn "ctzsi2"
14632   [(set (match_operand:SI 0 "register_operand" "=r")
14633         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14634    (clobber (reg:CC FLAGS_REG))]
14635   ""
14636   "bsf{l}\t{%1, %0|%0, %1}"
14637   [(set_attr "prefix_0f" "1")])
14638
14639 (define_insn "ctzdi2"
14640   [(set (match_operand:DI 0 "register_operand" "=r")
14641         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14642    (clobber (reg:CC FLAGS_REG))]
14643   "TARGET_64BIT"
14644   "bsf{q}\t{%1, %0|%0, %1}"
14645   [(set_attr "prefix_0f" "1")])
14646
14647 (define_expand "clzsi2"
14648   [(parallel
14649      [(set (match_operand:SI 0 "register_operand" "")
14650            (minus:SI (const_int 31)
14651                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14652       (clobber (reg:CC FLAGS_REG))])
14653    (parallel
14654      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14655       (clobber (reg:CC FLAGS_REG))])]
14656   ""
14657 {
14658   if (TARGET_ABM)
14659     {
14660       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14661       DONE;
14662     }
14663 })
14664
14665 (define_insn "clzsi2_abm"
14666   [(set (match_operand:SI 0 "register_operand" "=r")
14667         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14668    (clobber (reg:CC FLAGS_REG))]
14669   "TARGET_ABM"
14670   "lzcnt{l}\t{%1, %0|%0, %1}"
14671   [(set_attr "prefix_rep" "1")
14672    (set_attr "type" "bitmanip")
14673    (set_attr "mode" "SI")])
14674
14675 (define_insn "*bsr"
14676   [(set (match_operand:SI 0 "register_operand" "=r")
14677         (minus:SI (const_int 31)
14678                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14679    (clobber (reg:CC FLAGS_REG))]
14680   ""
14681   "bsr{l}\t{%1, %0|%0, %1}"
14682   [(set_attr "prefix_0f" "1")
14683    (set_attr "mode" "SI")])
14684
14685 (define_insn "popcountsi2"
14686   [(set (match_operand:SI 0 "register_operand" "=r")
14687         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14688    (clobber (reg:CC FLAGS_REG))]
14689   "TARGET_POPCNT"
14690   "popcnt{l}\t{%1, %0|%0, %1}"
14691   [(set_attr "prefix_rep" "1")
14692    (set_attr "type" "bitmanip")
14693    (set_attr "mode" "SI")])
14694
14695 (define_insn "*popcountsi2_cmp"
14696   [(set (reg FLAGS_REG)
14697         (compare
14698           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14699           (const_int 0)))
14700    (set (match_operand:SI 0 "register_operand" "=r")
14701         (popcount:SI (match_dup 1)))]
14702   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14703   "popcnt{l}\t{%1, %0|%0, %1}"
14704   [(set_attr "prefix_rep" "1")
14705    (set_attr "type" "bitmanip")
14706    (set_attr "mode" "SI")])
14707
14708 (define_insn "*popcountsi2_cmp_zext"
14709   [(set (reg FLAGS_REG)
14710         (compare
14711           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14712           (const_int 0)))
14713    (set (match_operand:DI 0 "register_operand" "=r")
14714         (zero_extend:DI(popcount:SI (match_dup 1))))]
14715   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14716   "popcnt{l}\t{%1, %0|%0, %1}"
14717   [(set_attr "prefix_rep" "1")
14718    (set_attr "type" "bitmanip")
14719    (set_attr "mode" "SI")])
14720
14721 (define_expand "bswapsi2"
14722   [(set (match_operand:SI 0 "register_operand" "")
14723         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14724   ""
14725 {
14726   if (!TARGET_BSWAP)
14727     {
14728       rtx x = operands[0];
14729
14730       emit_move_insn (x, operands[1]);
14731       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14732       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14733       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14734       DONE;
14735     }
14736 })
14737
14738 (define_insn "*bswapsi_1"
14739   [(set (match_operand:SI 0 "register_operand" "=r")
14740         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14741   "TARGET_BSWAP"
14742   "bswap\t%0"
14743   [(set_attr "prefix_0f" "1")
14744    (set_attr "length" "2")])
14745
14746 (define_insn "*bswaphi_lowpart_1"
14747   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14748         (bswap:HI (match_dup 0)))
14749    (clobber (reg:CC FLAGS_REG))]
14750   "TARGET_USE_XCHGB || optimize_size"
14751   "@
14752     xchg{b}\t{%h0, %b0|%b0, %h0}
14753     rol{w}\t{$8, %0|%0, 8}"
14754   [(set_attr "length" "2,4")
14755    (set_attr "mode" "QI,HI")])
14756
14757 (define_insn "bswaphi_lowpart"
14758   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14759         (bswap:HI (match_dup 0)))
14760    (clobber (reg:CC FLAGS_REG))]
14761   ""
14762   "rol{w}\t{$8, %0|%0, 8}"
14763   [(set_attr "length" "4")
14764    (set_attr "mode" "HI")])
14765
14766 (define_insn "bswapdi2"
14767   [(set (match_operand:DI 0 "register_operand" "=r")
14768         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14769   "TARGET_64BIT"
14770   "bswap\t%0"
14771   [(set_attr "prefix_0f" "1")
14772    (set_attr "length" "3")])
14773
14774 (define_expand "clzdi2"
14775   [(parallel
14776      [(set (match_operand:DI 0 "register_operand" "")
14777            (minus:DI (const_int 63)
14778                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14779       (clobber (reg:CC FLAGS_REG))])
14780    (parallel
14781      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14782       (clobber (reg:CC FLAGS_REG))])]
14783   "TARGET_64BIT"
14784 {
14785   if (TARGET_ABM)
14786     {
14787       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14788       DONE;
14789     }
14790 })
14791
14792 (define_insn "clzdi2_abm"
14793   [(set (match_operand:DI 0 "register_operand" "=r")
14794         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14795    (clobber (reg:CC FLAGS_REG))]
14796   "TARGET_64BIT && TARGET_ABM"
14797   "lzcnt{q}\t{%1, %0|%0, %1}"
14798   [(set_attr "prefix_rep" "1")
14799    (set_attr "type" "bitmanip")
14800    (set_attr "mode" "DI")])
14801
14802 (define_insn "*bsr_rex64"
14803   [(set (match_operand:DI 0 "register_operand" "=r")
14804         (minus:DI (const_int 63)
14805                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14806    (clobber (reg:CC FLAGS_REG))]
14807   "TARGET_64BIT"
14808   "bsr{q}\t{%1, %0|%0, %1}"
14809   [(set_attr "prefix_0f" "1")
14810    (set_attr "mode" "DI")])
14811
14812 (define_insn "popcountdi2"
14813   [(set (match_operand:DI 0 "register_operand" "=r")
14814         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14815    (clobber (reg:CC FLAGS_REG))]
14816   "TARGET_64BIT && TARGET_POPCNT"
14817   "popcnt{q}\t{%1, %0|%0, %1}"
14818   [(set_attr "prefix_rep" "1")
14819    (set_attr "type" "bitmanip")
14820    (set_attr "mode" "DI")])
14821
14822 (define_insn "*popcountdi2_cmp"
14823   [(set (reg FLAGS_REG)
14824         (compare
14825           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14826           (const_int 0)))
14827    (set (match_operand:DI 0 "register_operand" "=r")
14828         (popcount:DI (match_dup 1)))]
14829   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14830   "popcnt{q}\t{%1, %0|%0, %1}"
14831   [(set_attr "prefix_rep" "1")
14832    (set_attr "type" "bitmanip")
14833    (set_attr "mode" "DI")])
14834
14835 (define_expand "clzhi2"
14836   [(parallel
14837      [(set (match_operand:HI 0 "register_operand" "")
14838            (minus:HI (const_int 15)
14839                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14840       (clobber (reg:CC FLAGS_REG))])
14841    (parallel
14842      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14843       (clobber (reg:CC FLAGS_REG))])]
14844   ""
14845 {
14846   if (TARGET_ABM)
14847     {
14848       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14849       DONE;
14850     }
14851 })
14852
14853 (define_insn "clzhi2_abm"
14854   [(set (match_operand:HI 0 "register_operand" "=r")
14855         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14856    (clobber (reg:CC FLAGS_REG))]
14857   "TARGET_ABM"
14858   "lzcnt{w}\t{%1, %0|%0, %1}"
14859   [(set_attr "prefix_rep" "1")
14860    (set_attr "type" "bitmanip")
14861    (set_attr "mode" "HI")])
14862
14863 (define_insn "*bsrhi"
14864   [(set (match_operand:HI 0 "register_operand" "=r")
14865         (minus:HI (const_int 15)
14866                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14867    (clobber (reg:CC FLAGS_REG))]
14868   ""
14869   "bsr{w}\t{%1, %0|%0, %1}"
14870   [(set_attr "prefix_0f" "1")
14871    (set_attr "mode" "HI")])
14872
14873 (define_insn "popcounthi2"
14874   [(set (match_operand:HI 0 "register_operand" "=r")
14875         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14876    (clobber (reg:CC FLAGS_REG))]
14877   "TARGET_POPCNT"
14878   "popcnt{w}\t{%1, %0|%0, %1}"
14879   [(set_attr "prefix_rep" "1")
14880    (set_attr "type" "bitmanip")
14881    (set_attr "mode" "HI")])
14882
14883 (define_insn "*popcounthi2_cmp"
14884   [(set (reg FLAGS_REG)
14885         (compare
14886           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14887           (const_int 0)))
14888    (set (match_operand:HI 0 "register_operand" "=r")
14889         (popcount:HI (match_dup 1)))]
14890   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14891   "popcnt{w}\t{%1, %0|%0, %1}"
14892   [(set_attr "prefix_rep" "1")
14893    (set_attr "type" "bitmanip")
14894    (set_attr "mode" "HI")])
14895
14896 (define_expand "paritydi2"
14897   [(set (match_operand:DI 0 "register_operand" "")
14898         (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
14899   "! TARGET_POPCNT"
14900 {
14901   rtx scratch = gen_reg_rtx (QImode);
14902   rtx cond;
14903
14904   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14905                                 NULL_RTX, operands[1]));
14906
14907   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14908                          gen_rtx_REG (CCmode, FLAGS_REG),
14909                          const0_rtx);
14910   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14911
14912   if (TARGET_64BIT)
14913     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14914   else
14915     {
14916       rtx tmp = gen_reg_rtx (SImode);
14917
14918       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14919       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14920     }
14921   DONE;
14922 })
14923
14924 (define_insn_and_split "paritydi2_cmp"
14925   [(set (reg:CC FLAGS_REG)
14926         (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
14927    (clobber (match_scratch:DI 0 "=r,X"))
14928    (clobber (match_scratch:SI 1 "=r,r"))
14929    (clobber (match_scratch:HI 2 "=Q,Q"))]
14930   "! TARGET_POPCNT"
14931   "#"
14932   "&& reload_completed"
14933   [(parallel
14934      [(set (match_dup 1)
14935            (xor:SI (match_dup 1) (match_dup 4)))
14936       (clobber (reg:CC FLAGS_REG))])
14937    (parallel
14938      [(set (reg:CC FLAGS_REG)
14939            (parity:CC (match_dup 1)))
14940       (clobber (match_dup 1))
14941       (clobber (match_dup 2))])]
14942 {
14943   operands[4] = gen_lowpart (SImode, operands[3]);
14944
14945   if (MEM_P (operands[3]))
14946     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
14947   else if (! TARGET_64BIT)
14948     operands[1] = gen_highpart (SImode, operands[3]);
14949   else
14950     {
14951       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14952       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14953     }
14954 })
14955
14956 (define_expand "paritysi2"
14957   [(set (match_operand:SI 0 "register_operand" "")
14958         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
14959   "! TARGET_POPCNT"
14960 {
14961   rtx scratch = gen_reg_rtx (QImode);
14962   rtx cond;
14963
14964   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14965
14966   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14967                          gen_rtx_REG (CCmode, FLAGS_REG),
14968                          const0_rtx);
14969   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14970
14971   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14972   DONE;
14973 })
14974
14975 (define_insn_and_split "paritysi2_cmp"
14976   [(set (reg:CC FLAGS_REG)
14977         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
14978    (clobber (match_scratch:SI 0 "=r,X"))
14979    (clobber (match_scratch:HI 1 "=Q,Q"))]
14980   "! TARGET_POPCNT"
14981   "#"
14982   "&& reload_completed"
14983   [(parallel
14984      [(set (match_dup 1)
14985            (xor:HI (match_dup 1) (match_dup 3)))
14986       (clobber (reg:CC FLAGS_REG))])
14987    (parallel
14988      [(set (reg:CC FLAGS_REG)
14989            (parity:CC (match_dup 1)))
14990       (clobber (match_dup 1))])]
14991 {
14992   operands[3] = gen_lowpart (HImode, operands[2]);
14993
14994   if (MEM_P (operands[2]))
14995     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
14996   else
14997     {
14998       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14999       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15000     }
15001 })
15002
15003 (define_insn "*parityhi2_cmp"
15004   [(set (reg:CC FLAGS_REG)
15005         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15006    (clobber (match_scratch:HI 0 "=Q"))]
15007   "! TARGET_POPCNT"
15008   "xor{b}\t{%h0, %b0|%b0, %h0}"
15009   [(set_attr "length" "2")
15010    (set_attr "mode" "HI")])
15011
15012 (define_insn "*parityqi2_cmp"
15013   [(set (reg:CC FLAGS_REG)
15014         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15015   "! TARGET_POPCNT"
15016   "test{b}\t%0, %0"
15017   [(set_attr "length" "2")
15018    (set_attr "mode" "QI")])
15019 \f
15020 ;; Thread-local storage patterns for ELF.
15021 ;;
15022 ;; Note that these code sequences must appear exactly as shown
15023 ;; in order to allow linker relaxation.
15024
15025 (define_insn "*tls_global_dynamic_32_gnu"
15026   [(set (match_operand:SI 0 "register_operand" "=a")
15027         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15028                     (match_operand:SI 2 "tls_symbolic_operand" "")
15029                     (match_operand:SI 3 "call_insn_operand" "")]
15030                     UNSPEC_TLS_GD))
15031    (clobber (match_scratch:SI 4 "=d"))
15032    (clobber (match_scratch:SI 5 "=c"))
15033    (clobber (reg:CC FLAGS_REG))]
15034   "!TARGET_64BIT && TARGET_GNU_TLS"
15035   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15036   [(set_attr "type" "multi")
15037    (set_attr "length" "12")])
15038
15039 (define_insn "*tls_global_dynamic_32_sun"
15040   [(set (match_operand:SI 0 "register_operand" "=a")
15041         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15042                     (match_operand:SI 2 "tls_symbolic_operand" "")
15043                     (match_operand:SI 3 "call_insn_operand" "")]
15044                     UNSPEC_TLS_GD))
15045    (clobber (match_scratch:SI 4 "=d"))
15046    (clobber (match_scratch:SI 5 "=c"))
15047    (clobber (reg:CC FLAGS_REG))]
15048   "!TARGET_64BIT && TARGET_SUN_TLS"
15049   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15050         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15051   [(set_attr "type" "multi")
15052    (set_attr "length" "14")])
15053
15054 (define_expand "tls_global_dynamic_32"
15055   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15056                    (unspec:SI
15057                     [(match_dup 2)
15058                      (match_operand:SI 1 "tls_symbolic_operand" "")
15059                      (match_dup 3)]
15060                     UNSPEC_TLS_GD))
15061               (clobber (match_scratch:SI 4 ""))
15062               (clobber (match_scratch:SI 5 ""))
15063               (clobber (reg:CC FLAGS_REG))])]
15064   ""
15065 {
15066   if (flag_pic)
15067     operands[2] = pic_offset_table_rtx;
15068   else
15069     {
15070       operands[2] = gen_reg_rtx (Pmode);
15071       emit_insn (gen_set_got (operands[2]));
15072     }
15073   if (TARGET_GNU2_TLS)
15074     {
15075        emit_insn (gen_tls_dynamic_gnu2_32
15076                   (operands[0], operands[1], operands[2]));
15077        DONE;
15078     }
15079   operands[3] = ix86_tls_get_addr ();
15080 })
15081
15082 (define_insn "*tls_global_dynamic_64"
15083   [(set (match_operand:DI 0 "register_operand" "=a")
15084         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15085                  (match_operand:DI 3 "" "")))
15086    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15087               UNSPEC_TLS_GD)]
15088   "TARGET_64BIT"
15089   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15090   [(set_attr "type" "multi")
15091    (set_attr "length" "16")])
15092
15093 (define_expand "tls_global_dynamic_64"
15094   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15095                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15096               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15097                          UNSPEC_TLS_GD)])]
15098   ""
15099 {
15100   if (TARGET_GNU2_TLS)
15101     {
15102        emit_insn (gen_tls_dynamic_gnu2_64
15103                   (operands[0], operands[1]));
15104        DONE;
15105     }
15106   operands[2] = ix86_tls_get_addr ();
15107 })
15108
15109 (define_insn "*tls_local_dynamic_base_32_gnu"
15110   [(set (match_operand:SI 0 "register_operand" "=a")
15111         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15112                     (match_operand:SI 2 "call_insn_operand" "")]
15113                    UNSPEC_TLS_LD_BASE))
15114    (clobber (match_scratch:SI 3 "=d"))
15115    (clobber (match_scratch:SI 4 "=c"))
15116    (clobber (reg:CC FLAGS_REG))]
15117   "!TARGET_64BIT && TARGET_GNU_TLS"
15118   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15119   [(set_attr "type" "multi")
15120    (set_attr "length" "11")])
15121
15122 (define_insn "*tls_local_dynamic_base_32_sun"
15123   [(set (match_operand:SI 0 "register_operand" "=a")
15124         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15125                     (match_operand:SI 2 "call_insn_operand" "")]
15126                    UNSPEC_TLS_LD_BASE))
15127    (clobber (match_scratch:SI 3 "=d"))
15128    (clobber (match_scratch:SI 4 "=c"))
15129    (clobber (reg:CC FLAGS_REG))]
15130   "!TARGET_64BIT && TARGET_SUN_TLS"
15131   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15132         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15133   [(set_attr "type" "multi")
15134    (set_attr "length" "13")])
15135
15136 (define_expand "tls_local_dynamic_base_32"
15137   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15138                    (unspec:SI [(match_dup 1) (match_dup 2)]
15139                               UNSPEC_TLS_LD_BASE))
15140               (clobber (match_scratch:SI 3 ""))
15141               (clobber (match_scratch:SI 4 ""))
15142               (clobber (reg:CC FLAGS_REG))])]
15143   ""
15144 {
15145   if (flag_pic)
15146     operands[1] = pic_offset_table_rtx;
15147   else
15148     {
15149       operands[1] = gen_reg_rtx (Pmode);
15150       emit_insn (gen_set_got (operands[1]));
15151     }
15152   if (TARGET_GNU2_TLS)
15153     {
15154        emit_insn (gen_tls_dynamic_gnu2_32
15155                   (operands[0], ix86_tls_module_base (), operands[1]));
15156        DONE;
15157     }
15158   operands[2] = ix86_tls_get_addr ();
15159 })
15160
15161 (define_insn "*tls_local_dynamic_base_64"
15162   [(set (match_operand:DI 0 "register_operand" "=a")
15163         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15164                  (match_operand:DI 2 "" "")))
15165    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15166   "TARGET_64BIT"
15167   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15168   [(set_attr "type" "multi")
15169    (set_attr "length" "12")])
15170
15171 (define_expand "tls_local_dynamic_base_64"
15172   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15173                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15174               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15175   ""
15176 {
15177   if (TARGET_GNU2_TLS)
15178     {
15179        emit_insn (gen_tls_dynamic_gnu2_64
15180                   (operands[0], ix86_tls_module_base ()));
15181        DONE;
15182     }
15183   operands[1] = ix86_tls_get_addr ();
15184 })
15185
15186 ;; Local dynamic of a single variable is a lose.  Show combine how
15187 ;; to convert that back to global dynamic.
15188
15189 (define_insn_and_split "*tls_local_dynamic_32_once"
15190   [(set (match_operand:SI 0 "register_operand" "=a")
15191         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15192                              (match_operand:SI 2 "call_insn_operand" "")]
15193                             UNSPEC_TLS_LD_BASE)
15194                  (const:SI (unspec:SI
15195                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15196                             UNSPEC_DTPOFF))))
15197    (clobber (match_scratch:SI 4 "=d"))
15198    (clobber (match_scratch:SI 5 "=c"))
15199    (clobber (reg:CC FLAGS_REG))]
15200   ""
15201   "#"
15202   ""
15203   [(parallel [(set (match_dup 0)
15204                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15205                               UNSPEC_TLS_GD))
15206               (clobber (match_dup 4))
15207               (clobber (match_dup 5))
15208               (clobber (reg:CC FLAGS_REG))])]
15209   "")
15210
15211 ;; Load and add the thread base pointer from %gs:0.
15212
15213 (define_insn "*load_tp_si"
15214   [(set (match_operand:SI 0 "register_operand" "=r")
15215         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15216   "!TARGET_64BIT"
15217   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15218   [(set_attr "type" "imov")
15219    (set_attr "modrm" "0")
15220    (set_attr "length" "7")
15221    (set_attr "memory" "load")
15222    (set_attr "imm_disp" "false")])
15223
15224 (define_insn "*add_tp_si"
15225   [(set (match_operand:SI 0 "register_operand" "=r")
15226         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15227                  (match_operand:SI 1 "register_operand" "0")))
15228    (clobber (reg:CC FLAGS_REG))]
15229   "!TARGET_64BIT"
15230   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15231   [(set_attr "type" "alu")
15232    (set_attr "modrm" "0")
15233    (set_attr "length" "7")
15234    (set_attr "memory" "load")
15235    (set_attr "imm_disp" "false")])
15236
15237 (define_insn "*load_tp_di"
15238   [(set (match_operand:DI 0 "register_operand" "=r")
15239         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15240   "TARGET_64BIT"
15241   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15242   [(set_attr "type" "imov")
15243    (set_attr "modrm" "0")
15244    (set_attr "length" "7")
15245    (set_attr "memory" "load")
15246    (set_attr "imm_disp" "false")])
15247
15248 (define_insn "*add_tp_di"
15249   [(set (match_operand:DI 0 "register_operand" "=r")
15250         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15251                  (match_operand:DI 1 "register_operand" "0")))
15252    (clobber (reg:CC FLAGS_REG))]
15253   "TARGET_64BIT"
15254   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15255   [(set_attr "type" "alu")
15256    (set_attr "modrm" "0")
15257    (set_attr "length" "7")
15258    (set_attr "memory" "load")
15259    (set_attr "imm_disp" "false")])
15260
15261 ;; GNU2 TLS patterns can be split.
15262
15263 (define_expand "tls_dynamic_gnu2_32"
15264   [(set (match_dup 3)
15265         (plus:SI (match_operand:SI 2 "register_operand" "")
15266                  (const:SI
15267                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15268                              UNSPEC_TLSDESC))))
15269    (parallel
15270     [(set (match_operand:SI 0 "register_operand" "")
15271           (unspec:SI [(match_dup 1) (match_dup 3)
15272                       (match_dup 2) (reg:SI SP_REG)]
15273                       UNSPEC_TLSDESC))
15274      (clobber (reg:CC FLAGS_REG))])]
15275   "!TARGET_64BIT && TARGET_GNU2_TLS"
15276 {
15277   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15278   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15279 })
15280
15281 (define_insn "*tls_dynamic_lea_32"
15282   [(set (match_operand:SI 0 "register_operand" "=r")
15283         (plus:SI (match_operand:SI 1 "register_operand" "b")
15284                  (const:SI
15285                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15286                               UNSPEC_TLSDESC))))]
15287   "!TARGET_64BIT && TARGET_GNU2_TLS"
15288   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15289   [(set_attr "type" "lea")
15290    (set_attr "mode" "SI")
15291    (set_attr "length" "6")
15292    (set_attr "length_address" "4")])
15293
15294 (define_insn "*tls_dynamic_call_32"
15295   [(set (match_operand:SI 0 "register_operand" "=a")
15296         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15297                     (match_operand:SI 2 "register_operand" "0")
15298                     ;; we have to make sure %ebx still points to the GOT
15299                     (match_operand:SI 3 "register_operand" "b")
15300                     (reg:SI SP_REG)]
15301                    UNSPEC_TLSDESC))
15302    (clobber (reg:CC FLAGS_REG))]
15303   "!TARGET_64BIT && TARGET_GNU2_TLS"
15304   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15305   [(set_attr "type" "call")
15306    (set_attr "length" "2")
15307    (set_attr "length_address" "0")])
15308
15309 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15310   [(set (match_operand:SI 0 "register_operand" "=&a")
15311         (plus:SI
15312          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15313                      (match_operand:SI 4 "" "")
15314                      (match_operand:SI 2 "register_operand" "b")
15315                      (reg:SI SP_REG)]
15316                     UNSPEC_TLSDESC)
15317          (const:SI (unspec:SI
15318                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15319                     UNSPEC_DTPOFF))))
15320    (clobber (reg:CC FLAGS_REG))]
15321   "!TARGET_64BIT && TARGET_GNU2_TLS"
15322   "#"
15323   ""
15324   [(set (match_dup 0) (match_dup 5))]
15325 {
15326   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15327   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15328 })
15329
15330 (define_expand "tls_dynamic_gnu2_64"
15331   [(set (match_dup 2)
15332         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15333                    UNSPEC_TLSDESC))
15334    (parallel
15335     [(set (match_operand:DI 0 "register_operand" "")
15336           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15337                      UNSPEC_TLSDESC))
15338      (clobber (reg:CC FLAGS_REG))])]
15339   "TARGET_64BIT && TARGET_GNU2_TLS"
15340 {
15341   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15342   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15343 })
15344
15345 (define_insn "*tls_dynamic_lea_64"
15346   [(set (match_operand:DI 0 "register_operand" "=r")
15347         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15348                    UNSPEC_TLSDESC))]
15349   "TARGET_64BIT && TARGET_GNU2_TLS"
15350   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15351   [(set_attr "type" "lea")
15352    (set_attr "mode" "DI")
15353    (set_attr "length" "7")
15354    (set_attr "length_address" "4")])
15355
15356 (define_insn "*tls_dynamic_call_64"
15357   [(set (match_operand:DI 0 "register_operand" "=a")
15358         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15359                     (match_operand:DI 2 "register_operand" "0")
15360                     (reg:DI SP_REG)]
15361                    UNSPEC_TLSDESC))
15362    (clobber (reg:CC FLAGS_REG))]
15363   "TARGET_64BIT && TARGET_GNU2_TLS"
15364   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15365   [(set_attr "type" "call")
15366    (set_attr "length" "2")
15367    (set_attr "length_address" "0")])
15368
15369 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15370   [(set (match_operand:DI 0 "register_operand" "=&a")
15371         (plus:DI
15372          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15373                      (match_operand:DI 3 "" "")
15374                      (reg:DI SP_REG)]
15375                     UNSPEC_TLSDESC)
15376          (const:DI (unspec:DI
15377                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15378                     UNSPEC_DTPOFF))))
15379    (clobber (reg:CC FLAGS_REG))]
15380   "TARGET_64BIT && TARGET_GNU2_TLS"
15381   "#"
15382   ""
15383   [(set (match_dup 0) (match_dup 4))]
15384 {
15385   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15386   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15387 })
15388
15389 ;;
15390 \f
15391 ;; These patterns match the binary 387 instructions for addM3, subM3,
15392 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15393 ;; SFmode.  The first is the normal insn, the second the same insn but
15394 ;; with one operand a conversion, and the third the same insn but with
15395 ;; the other operand a conversion.  The conversion may be SFmode or
15396 ;; SImode if the target mode DFmode, but only SImode if the target mode
15397 ;; is SFmode.
15398
15399 ;; Gcc is slightly more smart about handling normal two address instructions
15400 ;; so use special patterns for add and mull.
15401
15402 (define_insn "*fop_sf_comm_mixed"
15403   [(set (match_operand:SF 0 "register_operand" "=f,x")
15404         (match_operator:SF 3 "binary_fp_operator"
15405                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15406                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15407   "TARGET_MIX_SSE_I387
15408    && COMMUTATIVE_ARITH_P (operands[3])
15409    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15410   "* return output_387_binary_op (insn, operands);"
15411   [(set (attr "type")
15412         (if_then_else (eq_attr "alternative" "1")
15413            (if_then_else (match_operand:SF 3 "mult_operator" "")
15414               (const_string "ssemul")
15415               (const_string "sseadd"))
15416            (if_then_else (match_operand:SF 3 "mult_operator" "")
15417               (const_string "fmul")
15418               (const_string "fop"))))
15419    (set_attr "mode" "SF")])
15420
15421 (define_insn "*fop_sf_comm_sse"
15422   [(set (match_operand:SF 0 "register_operand" "=x")
15423         (match_operator:SF 3 "binary_fp_operator"
15424                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15425                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15426   "TARGET_SSE_MATH
15427    && COMMUTATIVE_ARITH_P (operands[3])
15428    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15429   "* return output_387_binary_op (insn, operands);"
15430   [(set (attr "type")
15431         (if_then_else (match_operand:SF 3 "mult_operator" "")
15432            (const_string "ssemul")
15433            (const_string "sseadd")))
15434    (set_attr "mode" "SF")])
15435
15436 (define_insn "*fop_sf_comm_i387"
15437   [(set (match_operand:SF 0 "register_operand" "=f")
15438         (match_operator:SF 3 "binary_fp_operator"
15439                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15440                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15441   "TARGET_80387
15442    && COMMUTATIVE_ARITH_P (operands[3])
15443    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15444   "* return output_387_binary_op (insn, operands);"
15445   [(set (attr "type")
15446         (if_then_else (match_operand:SF 3 "mult_operator" "")
15447            (const_string "fmul")
15448            (const_string "fop")))
15449    (set_attr "mode" "SF")])
15450
15451 (define_insn "*fop_sf_1_mixed"
15452   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15453         (match_operator:SF 3 "binary_fp_operator"
15454                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15455                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15456   "TARGET_MIX_SSE_I387
15457    && !COMMUTATIVE_ARITH_P (operands[3])
15458    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15459   "* return output_387_binary_op (insn, operands);"
15460   [(set (attr "type")
15461         (cond [(and (eq_attr "alternative" "2")
15462                     (match_operand:SF 3 "mult_operator" ""))
15463                  (const_string "ssemul")
15464                (and (eq_attr "alternative" "2")
15465                     (match_operand:SF 3 "div_operator" ""))
15466                  (const_string "ssediv")
15467                (eq_attr "alternative" "2")
15468                  (const_string "sseadd")
15469                (match_operand:SF 3 "mult_operator" "")
15470                  (const_string "fmul")
15471                (match_operand:SF 3 "div_operator" "")
15472                  (const_string "fdiv")
15473               ]
15474               (const_string "fop")))
15475    (set_attr "mode" "SF")])
15476
15477 (define_insn "*fop_sf_1_sse"
15478   [(set (match_operand:SF 0 "register_operand" "=x")
15479         (match_operator:SF 3 "binary_fp_operator"
15480                         [(match_operand:SF 1 "register_operand" "0")
15481                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15482   "TARGET_SSE_MATH
15483    && !COMMUTATIVE_ARITH_P (operands[3])"
15484   "* return output_387_binary_op (insn, operands);"
15485   [(set (attr "type")
15486         (cond [(match_operand:SF 3 "mult_operator" "")
15487                  (const_string "ssemul")
15488                (match_operand:SF 3 "div_operator" "")
15489                  (const_string "ssediv")
15490               ]
15491               (const_string "sseadd")))
15492    (set_attr "mode" "SF")])
15493
15494 ;; This pattern is not fully shadowed by the pattern above.
15495 (define_insn "*fop_sf_1_i387"
15496   [(set (match_operand:SF 0 "register_operand" "=f,f")
15497         (match_operator:SF 3 "binary_fp_operator"
15498                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15499                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15500   "TARGET_80387 && !TARGET_SSE_MATH
15501    && !COMMUTATIVE_ARITH_P (operands[3])
15502    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15503   "* return output_387_binary_op (insn, operands);"
15504   [(set (attr "type")
15505         (cond [(match_operand:SF 3 "mult_operator" "")
15506                  (const_string "fmul")
15507                (match_operand:SF 3 "div_operator" "")
15508                  (const_string "fdiv")
15509               ]
15510               (const_string "fop")))
15511    (set_attr "mode" "SF")])
15512
15513 ;; ??? Add SSE splitters for these!
15514 (define_insn "*fop_sf_2<mode>_i387"
15515   [(set (match_operand:SF 0 "register_operand" "=f,f")
15516         (match_operator:SF 3 "binary_fp_operator"
15517           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15518            (match_operand:SF 2 "register_operand" "0,0")]))]
15519   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15520   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15521   [(set (attr "type")
15522         (cond [(match_operand:SF 3 "mult_operator" "")
15523                  (const_string "fmul")
15524                (match_operand:SF 3 "div_operator" "")
15525                  (const_string "fdiv")
15526               ]
15527               (const_string "fop")))
15528    (set_attr "fp_int_src" "true")
15529    (set_attr "mode" "<MODE>")])
15530
15531 (define_insn "*fop_sf_3<mode>_i387"
15532   [(set (match_operand:SF 0 "register_operand" "=f,f")
15533         (match_operator:SF 3 "binary_fp_operator"
15534           [(match_operand:SF 1 "register_operand" "0,0")
15535            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15536   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15537   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15538   [(set (attr "type")
15539         (cond [(match_operand:SF 3 "mult_operator" "")
15540                  (const_string "fmul")
15541                (match_operand:SF 3 "div_operator" "")
15542                  (const_string "fdiv")
15543               ]
15544               (const_string "fop")))
15545    (set_attr "fp_int_src" "true")
15546    (set_attr "mode" "<MODE>")])
15547
15548 (define_insn "*fop_df_comm_mixed"
15549   [(set (match_operand:DF 0 "register_operand" "=f,x")
15550         (match_operator:DF 3 "binary_fp_operator"
15551           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15552            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15553   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15554    && COMMUTATIVE_ARITH_P (operands[3])
15555    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15556   "* return output_387_binary_op (insn, operands);"
15557   [(set (attr "type")
15558         (if_then_else (eq_attr "alternative" "1")
15559            (if_then_else (match_operand:DF 3 "mult_operator" "")
15560               (const_string "ssemul")
15561               (const_string "sseadd"))
15562            (if_then_else (match_operand:DF 3 "mult_operator" "")
15563               (const_string "fmul")
15564               (const_string "fop"))))
15565    (set_attr "mode" "DF")])
15566
15567 (define_insn "*fop_df_comm_sse"
15568   [(set (match_operand:DF 0 "register_operand" "=x")
15569         (match_operator:DF 3 "binary_fp_operator"
15570           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15571            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15572   "TARGET_SSE2 && TARGET_SSE_MATH
15573    && COMMUTATIVE_ARITH_P (operands[3])
15574    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15575   "* return output_387_binary_op (insn, operands);"
15576   [(set (attr "type")
15577         (if_then_else (match_operand:DF 3 "mult_operator" "")
15578            (const_string "ssemul")
15579            (const_string "sseadd")))
15580    (set_attr "mode" "DF")])
15581
15582 (define_insn "*fop_df_comm_i387"
15583   [(set (match_operand:DF 0 "register_operand" "=f")
15584         (match_operator:DF 3 "binary_fp_operator"
15585                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15586                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15587   "TARGET_80387
15588    && COMMUTATIVE_ARITH_P (operands[3])
15589    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15590   "* return output_387_binary_op (insn, operands);"
15591   [(set (attr "type")
15592         (if_then_else (match_operand:DF 3 "mult_operator" "")
15593            (const_string "fmul")
15594            (const_string "fop")))
15595    (set_attr "mode" "DF")])
15596
15597 (define_insn "*fop_df_1_mixed"
15598   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15599         (match_operator:DF 3 "binary_fp_operator"
15600           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15601            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15602   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15603    && !COMMUTATIVE_ARITH_P (operands[3])
15604    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15605   "* return output_387_binary_op (insn, operands);"
15606   [(set (attr "type")
15607         (cond [(and (eq_attr "alternative" "2")
15608                     (match_operand:DF 3 "mult_operator" ""))
15609                  (const_string "ssemul")
15610                (and (eq_attr "alternative" "2")
15611                     (match_operand:DF 3 "div_operator" ""))
15612                  (const_string "ssediv")
15613                (eq_attr "alternative" "2")
15614                  (const_string "sseadd")
15615                (match_operand:DF 3 "mult_operator" "")
15616                  (const_string "fmul")
15617                (match_operand:DF 3 "div_operator" "")
15618                  (const_string "fdiv")
15619               ]
15620               (const_string "fop")))
15621    (set_attr "mode" "DF")])
15622
15623 (define_insn "*fop_df_1_sse"
15624   [(set (match_operand:DF 0 "register_operand" "=x")
15625         (match_operator:DF 3 "binary_fp_operator"
15626           [(match_operand:DF 1 "register_operand" "0")
15627            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15628   "TARGET_SSE2 && TARGET_SSE_MATH
15629    && !COMMUTATIVE_ARITH_P (operands[3])"
15630   "* return output_387_binary_op (insn, operands);"
15631   [(set_attr "mode" "DF")
15632    (set (attr "type")
15633         (cond [(match_operand:DF 3 "mult_operator" "")
15634                  (const_string "ssemul")
15635                (match_operand:DF 3 "div_operator" "")
15636                  (const_string "ssediv")
15637               ]
15638               (const_string "sseadd")))])
15639
15640 ;; This pattern is not fully shadowed by the pattern above.
15641 (define_insn "*fop_df_1_i387"
15642   [(set (match_operand:DF 0 "register_operand" "=f,f")
15643         (match_operator:DF 3 "binary_fp_operator"
15644                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15645                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15646   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15647    && !COMMUTATIVE_ARITH_P (operands[3])
15648    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15649   "* return output_387_binary_op (insn, operands);"
15650   [(set (attr "type")
15651         (cond [(match_operand:DF 3 "mult_operator" "")
15652                  (const_string "fmul")
15653                (match_operand:DF 3 "div_operator" "")
15654                  (const_string "fdiv")
15655               ]
15656               (const_string "fop")))
15657    (set_attr "mode" "DF")])
15658
15659 ;; ??? Add SSE splitters for these!
15660 (define_insn "*fop_df_2<mode>_i387"
15661   [(set (match_operand:DF 0 "register_operand" "=f,f")
15662         (match_operator:DF 3 "binary_fp_operator"
15663            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15664             (match_operand:DF 2 "register_operand" "0,0")]))]
15665   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15666    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15667   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15668   [(set (attr "type")
15669         (cond [(match_operand:DF 3 "mult_operator" "")
15670                  (const_string "fmul")
15671                (match_operand:DF 3 "div_operator" "")
15672                  (const_string "fdiv")
15673               ]
15674               (const_string "fop")))
15675    (set_attr "fp_int_src" "true")
15676    (set_attr "mode" "<MODE>")])
15677
15678 (define_insn "*fop_df_3<mode>_i387"
15679   [(set (match_operand:DF 0 "register_operand" "=f,f")
15680         (match_operator:DF 3 "binary_fp_operator"
15681            [(match_operand:DF 1 "register_operand" "0,0")
15682             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15683   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15684    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15685   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15686   [(set (attr "type")
15687         (cond [(match_operand:DF 3 "mult_operator" "")
15688                  (const_string "fmul")
15689                (match_operand:DF 3 "div_operator" "")
15690                  (const_string "fdiv")
15691               ]
15692               (const_string "fop")))
15693    (set_attr "fp_int_src" "true")
15694    (set_attr "mode" "<MODE>")])
15695
15696 (define_insn "*fop_df_4_i387"
15697   [(set (match_operand:DF 0 "register_operand" "=f,f")
15698         (match_operator:DF 3 "binary_fp_operator"
15699            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15700             (match_operand:DF 2 "register_operand" "0,f")]))]
15701   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15702    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15703   "* return output_387_binary_op (insn, operands);"
15704   [(set (attr "type")
15705         (cond [(match_operand:DF 3 "mult_operator" "")
15706                  (const_string "fmul")
15707                (match_operand:DF 3 "div_operator" "")
15708                  (const_string "fdiv")
15709               ]
15710               (const_string "fop")))
15711    (set_attr "mode" "SF")])
15712
15713 (define_insn "*fop_df_5_i387"
15714   [(set (match_operand:DF 0 "register_operand" "=f,f")
15715         (match_operator:DF 3 "binary_fp_operator"
15716           [(match_operand:DF 1 "register_operand" "0,f")
15717            (float_extend:DF
15718             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15719   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15720   "* return output_387_binary_op (insn, operands);"
15721   [(set (attr "type")
15722         (cond [(match_operand:DF 3 "mult_operator" "")
15723                  (const_string "fmul")
15724                (match_operand:DF 3 "div_operator" "")
15725                  (const_string "fdiv")
15726               ]
15727               (const_string "fop")))
15728    (set_attr "mode" "SF")])
15729
15730 (define_insn "*fop_df_6_i387"
15731   [(set (match_operand:DF 0 "register_operand" "=f,f")
15732         (match_operator:DF 3 "binary_fp_operator"
15733           [(float_extend:DF
15734             (match_operand:SF 1 "register_operand" "0,f"))
15735            (float_extend:DF
15736             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15737   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15738   "* return output_387_binary_op (insn, operands);"
15739   [(set (attr "type")
15740         (cond [(match_operand:DF 3 "mult_operator" "")
15741                  (const_string "fmul")
15742                (match_operand:DF 3 "div_operator" "")
15743                  (const_string "fdiv")
15744               ]
15745               (const_string "fop")))
15746    (set_attr "mode" "SF")])
15747
15748 (define_insn "*fop_xf_comm_i387"
15749   [(set (match_operand:XF 0 "register_operand" "=f")
15750         (match_operator:XF 3 "binary_fp_operator"
15751                         [(match_operand:XF 1 "register_operand" "%0")
15752                          (match_operand:XF 2 "register_operand" "f")]))]
15753   "TARGET_80387
15754    && COMMUTATIVE_ARITH_P (operands[3])"
15755   "* return output_387_binary_op (insn, operands);"
15756   [(set (attr "type")
15757         (if_then_else (match_operand:XF 3 "mult_operator" "")
15758            (const_string "fmul")
15759            (const_string "fop")))
15760    (set_attr "mode" "XF")])
15761
15762 (define_insn "*fop_xf_1_i387"
15763   [(set (match_operand:XF 0 "register_operand" "=f,f")
15764         (match_operator:XF 3 "binary_fp_operator"
15765                         [(match_operand:XF 1 "register_operand" "0,f")
15766                          (match_operand:XF 2 "register_operand" "f,0")]))]
15767   "TARGET_80387
15768    && !COMMUTATIVE_ARITH_P (operands[3])"
15769   "* return output_387_binary_op (insn, operands);"
15770   [(set (attr "type")
15771         (cond [(match_operand:XF 3 "mult_operator" "")
15772                  (const_string "fmul")
15773                (match_operand:XF 3 "div_operator" "")
15774                  (const_string "fdiv")
15775               ]
15776               (const_string "fop")))
15777    (set_attr "mode" "XF")])
15778
15779 (define_insn "*fop_xf_2<mode>_i387"
15780   [(set (match_operand:XF 0 "register_operand" "=f,f")
15781         (match_operator:XF 3 "binary_fp_operator"
15782            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15783             (match_operand:XF 2 "register_operand" "0,0")]))]
15784   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15785   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15786   [(set (attr "type")
15787         (cond [(match_operand:XF 3 "mult_operator" "")
15788                  (const_string "fmul")
15789                (match_operand:XF 3 "div_operator" "")
15790                  (const_string "fdiv")
15791               ]
15792               (const_string "fop")))
15793    (set_attr "fp_int_src" "true")
15794    (set_attr "mode" "<MODE>")])
15795
15796 (define_insn "*fop_xf_3<mode>_i387"
15797   [(set (match_operand:XF 0 "register_operand" "=f,f")
15798         (match_operator:XF 3 "binary_fp_operator"
15799           [(match_operand:XF 1 "register_operand" "0,0")
15800            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15801   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15802   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15803   [(set (attr "type")
15804         (cond [(match_operand:XF 3 "mult_operator" "")
15805                  (const_string "fmul")
15806                (match_operand:XF 3 "div_operator" "")
15807                  (const_string "fdiv")
15808               ]
15809               (const_string "fop")))
15810    (set_attr "fp_int_src" "true")
15811    (set_attr "mode" "<MODE>")])
15812
15813 (define_insn "*fop_xf_4_i387"
15814   [(set (match_operand:XF 0 "register_operand" "=f,f")
15815         (match_operator:XF 3 "binary_fp_operator"
15816            [(float_extend:XF
15817               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15818             (match_operand:XF 2 "register_operand" "0,f")]))]
15819   "TARGET_80387"
15820   "* return output_387_binary_op (insn, operands);"
15821   [(set (attr "type")
15822         (cond [(match_operand:XF 3 "mult_operator" "")
15823                  (const_string "fmul")
15824                (match_operand:XF 3 "div_operator" "")
15825                  (const_string "fdiv")
15826               ]
15827               (const_string "fop")))
15828    (set_attr "mode" "SF")])
15829
15830 (define_insn "*fop_xf_5_i387"
15831   [(set (match_operand:XF 0 "register_operand" "=f,f")
15832         (match_operator:XF 3 "binary_fp_operator"
15833           [(match_operand:XF 1 "register_operand" "0,f")
15834            (float_extend:XF
15835              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15836   "TARGET_80387"
15837   "* return output_387_binary_op (insn, operands);"
15838   [(set (attr "type")
15839         (cond [(match_operand:XF 3 "mult_operator" "")
15840                  (const_string "fmul")
15841                (match_operand:XF 3 "div_operator" "")
15842                  (const_string "fdiv")
15843               ]
15844               (const_string "fop")))
15845    (set_attr "mode" "SF")])
15846
15847 (define_insn "*fop_xf_6_i387"
15848   [(set (match_operand:XF 0 "register_operand" "=f,f")
15849         (match_operator:XF 3 "binary_fp_operator"
15850           [(float_extend:XF
15851              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15852            (float_extend:XF
15853              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15854   "TARGET_80387"
15855   "* return output_387_binary_op (insn, operands);"
15856   [(set (attr "type")
15857         (cond [(match_operand:XF 3 "mult_operator" "")
15858                  (const_string "fmul")
15859                (match_operand:XF 3 "div_operator" "")
15860                  (const_string "fdiv")
15861               ]
15862               (const_string "fop")))
15863    (set_attr "mode" "SF")])
15864
15865 (define_split
15866   [(set (match_operand 0 "register_operand" "")
15867         (match_operator 3 "binary_fp_operator"
15868            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15869             (match_operand 2 "register_operand" "")]))]
15870   "reload_completed
15871    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
15872   [(const_int 0)]
15873 {
15874   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15875   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15876   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15877                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15878                                           GET_MODE (operands[3]),
15879                                           operands[4],
15880                                           operands[2])));
15881   ix86_free_from_memory (GET_MODE (operands[1]));
15882   DONE;
15883 })
15884
15885 (define_split
15886   [(set (match_operand 0 "register_operand" "")
15887         (match_operator 3 "binary_fp_operator"
15888            [(match_operand 1 "register_operand" "")
15889             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15890   "reload_completed
15891    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
15892   [(const_int 0)]
15893 {
15894   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15895   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15896   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15897                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15898                                           GET_MODE (operands[3]),
15899                                           operands[1],
15900                                           operands[4])));
15901   ix86_free_from_memory (GET_MODE (operands[2]));
15902   DONE;
15903 })
15904 \f
15905 ;; FPU special functions.
15906
15907 ;; This pattern implements a no-op XFmode truncation for
15908 ;; all fancy i386 XFmode math functions.
15909
15910 (define_insn "truncxf<mode>2_i387_noop_unspec"
15911   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15912         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15913         UNSPEC_TRUNC_NOOP))]
15914   "TARGET_USE_FANCY_MATH_387"
15915   "* return output_387_reg_move (insn, operands);"
15916   [(set_attr "type" "fmov")
15917    (set_attr "mode" "<MODE>")])
15918
15919 (define_insn "sqrtxf2"
15920   [(set (match_operand:XF 0 "register_operand" "=f")
15921         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15922   "TARGET_USE_FANCY_MATH_387"
15923   "fsqrt"
15924   [(set_attr "type" "fpspc")
15925    (set_attr "mode" "XF")
15926    (set_attr "athlon_decode" "direct")
15927    (set_attr "amdfam10_decode" "direct")])
15928
15929 (define_insn "sqrt_extend<mode>xf2_i387"
15930   [(set (match_operand:XF 0 "register_operand" "=f")
15931         (sqrt:XF
15932           (float_extend:XF
15933             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15934   "TARGET_USE_FANCY_MATH_387"
15935   "fsqrt"
15936   [(set_attr "type" "fpspc")
15937    (set_attr "mode" "XF")
15938    (set_attr "athlon_decode" "direct")   
15939    (set_attr "amdfam10_decode" "direct")])
15940
15941 (define_insn "*sqrt<mode>2_sse"
15942   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15943         (sqrt:SSEMODEF
15944           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15945   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15946   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15947   [(set_attr "type" "sse")
15948    (set_attr "mode" "<MODE>")
15949    (set_attr "athlon_decode" "*")
15950    (set_attr "amdfam10_decode" "*")])
15951
15952 (define_expand "sqrt<mode>2"
15953   [(set (match_operand:X87MODEF12 0 "register_operand" "")
15954         (sqrt:X87MODEF12
15955           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15956   "TARGET_USE_FANCY_MATH_387
15957    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15958 {
15959   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15960     {
15961       rtx op0 = gen_reg_rtx (XFmode);
15962       rtx op1 = force_reg (<MODE>mode, operands[1]);
15963
15964       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15965       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15966       DONE;
15967    }
15968 })
15969
15970 (define_insn "fpremxf4_i387"
15971   [(set (match_operand:XF 0 "register_operand" "=f")
15972         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15973                     (match_operand:XF 3 "register_operand" "1")]
15974                    UNSPEC_FPREM_F))
15975    (set (match_operand:XF 1 "register_operand" "=u")
15976         (unspec:XF [(match_dup 2) (match_dup 3)]
15977                    UNSPEC_FPREM_U))
15978    (set (reg:CCFP FPSR_REG)
15979         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15980                      UNSPEC_C2_FLAG))]
15981   "TARGET_USE_FANCY_MATH_387"
15982   "fprem"
15983   [(set_attr "type" "fpspc")
15984    (set_attr "mode" "XF")])
15985
15986 (define_expand "fmodxf3"
15987   [(use (match_operand:XF 0 "register_operand" ""))
15988    (use (match_operand:XF 1 "register_operand" ""))
15989    (use (match_operand:XF 2 "register_operand" ""))]
15990   "TARGET_USE_FANCY_MATH_387"
15991 {
15992   rtx label = gen_label_rtx ();
15993
15994   emit_label (label);
15995
15996   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15997                                 operands[1], operands[2]));
15998   ix86_emit_fp_unordered_jump (label);
15999   LABEL_NUSES (label) = 1;
16000
16001   emit_move_insn (operands[0], operands[1]);
16002   DONE;
16003 })
16004
16005 (define_expand "fmod<mode>3"
16006   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16007    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16008    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16009   "TARGET_USE_FANCY_MATH_387"
16010 {
16011   rtx label = gen_label_rtx ();
16012
16013   rtx op1 = gen_reg_rtx (XFmode);
16014   rtx op2 = gen_reg_rtx (XFmode);
16015
16016   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16017   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16018
16019   emit_label (label);
16020   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16021   ix86_emit_fp_unordered_jump (label);
16022   LABEL_NUSES (label) = 1;
16023
16024   /* Truncate the result properly for strict SSE math.  */
16025   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16026       && !TARGET_MIX_SSE_I387)
16027     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16028   else
16029     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16030
16031   DONE;
16032 })
16033
16034 (define_insn "fprem1xf4_i387"
16035   [(set (match_operand:XF 0 "register_operand" "=f")
16036         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16037                     (match_operand:XF 3 "register_operand" "1")]
16038                    UNSPEC_FPREM1_F))
16039    (set (match_operand:XF 1 "register_operand" "=u")
16040         (unspec:XF [(match_dup 2) (match_dup 3)]
16041                    UNSPEC_FPREM1_U))
16042    (set (reg:CCFP FPSR_REG)
16043         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16044                      UNSPEC_C2_FLAG))]
16045   "TARGET_USE_FANCY_MATH_387"
16046   "fprem1"
16047   [(set_attr "type" "fpspc")
16048    (set_attr "mode" "XF")])
16049
16050 (define_expand "remainderxf3"
16051   [(use (match_operand:XF 0 "register_operand" ""))
16052    (use (match_operand:XF 1 "register_operand" ""))
16053    (use (match_operand:XF 2 "register_operand" ""))]
16054   "TARGET_USE_FANCY_MATH_387"
16055 {
16056   rtx label = gen_label_rtx ();
16057
16058   emit_label (label);
16059
16060   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16061                                  operands[1], operands[2]));
16062   ix86_emit_fp_unordered_jump (label);
16063   LABEL_NUSES (label) = 1;
16064
16065   emit_move_insn (operands[0], operands[1]);
16066   DONE;
16067 })
16068
16069 (define_expand "remainder<mode>3"
16070   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16071    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16072    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16073   "TARGET_USE_FANCY_MATH_387"
16074 {
16075   rtx label = gen_label_rtx ();
16076
16077   rtx op1 = gen_reg_rtx (XFmode);
16078   rtx op2 = gen_reg_rtx (XFmode);
16079
16080   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16081   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16082
16083   emit_label (label);
16084
16085   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16086   ix86_emit_fp_unordered_jump (label);
16087   LABEL_NUSES (label) = 1;
16088
16089   /* Truncate the result properly for strict SSE math.  */
16090   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16091       && !TARGET_MIX_SSE_I387)
16092     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16093   else
16094     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16095
16096   DONE;
16097 })
16098
16099 (define_insn "*sinxf2_i387"
16100   [(set (match_operand:XF 0 "register_operand" "=f")
16101         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16102   "TARGET_USE_FANCY_MATH_387
16103    && flag_unsafe_math_optimizations"
16104   "fsin"
16105   [(set_attr "type" "fpspc")
16106    (set_attr "mode" "XF")])
16107
16108 (define_insn "*sin_extend<mode>xf2_i387"
16109   [(set (match_operand:XF 0 "register_operand" "=f")
16110         (unspec:XF [(float_extend:XF
16111                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16112                    UNSPEC_SIN))]
16113   "TARGET_USE_FANCY_MATH_387
16114    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16115        || TARGET_MIX_SSE_I387)
16116    && flag_unsafe_math_optimizations"
16117   "fsin"
16118   [(set_attr "type" "fpspc")
16119    (set_attr "mode" "XF")])
16120
16121 (define_insn "*cosxf2_i387"
16122   [(set (match_operand:XF 0 "register_operand" "=f")
16123         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16124   "TARGET_USE_FANCY_MATH_387
16125    && flag_unsafe_math_optimizations"
16126   "fcos"
16127   [(set_attr "type" "fpspc")
16128    (set_attr "mode" "XF")])
16129
16130 (define_insn "*cos_extend<mode>xf2_i387"
16131   [(set (match_operand:XF 0 "register_operand" "=f")
16132         (unspec:XF [(float_extend:XF
16133                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16134                    UNSPEC_COS))]
16135   "TARGET_USE_FANCY_MATH_387
16136    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16137        || TARGET_MIX_SSE_I387)
16138    && flag_unsafe_math_optimizations"
16139   "fcos"
16140   [(set_attr "type" "fpspc")
16141    (set_attr "mode" "XF")])
16142
16143 ;; When sincos pattern is defined, sin and cos builtin functions will be
16144 ;; expanded to sincos pattern with one of its outputs left unused.
16145 ;; CSE pass will figure out if two sincos patterns can be combined,
16146 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16147 ;; depending on the unused output.
16148
16149 (define_insn "sincosxf3"
16150   [(set (match_operand:XF 0 "register_operand" "=f")
16151         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16152                    UNSPEC_SINCOS_COS))
16153    (set (match_operand:XF 1 "register_operand" "=u")
16154         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16155   "TARGET_USE_FANCY_MATH_387
16156    && flag_unsafe_math_optimizations"
16157   "fsincos"
16158   [(set_attr "type" "fpspc")
16159    (set_attr "mode" "XF")])
16160
16161 (define_split
16162   [(set (match_operand:XF 0 "register_operand" "")
16163         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16164                    UNSPEC_SINCOS_COS))
16165    (set (match_operand:XF 1 "register_operand" "")
16166         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16167   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16168    && !reload_completed && !reload_in_progress"
16169   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16170   "")
16171
16172 (define_split
16173   [(set (match_operand:XF 0 "register_operand" "")
16174         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16175                    UNSPEC_SINCOS_COS))
16176    (set (match_operand:XF 1 "register_operand" "")
16177         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16178   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16179    && !reload_completed && !reload_in_progress"
16180   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16181   "")
16182
16183 (define_insn "sincos_extend<mode>xf3_i387"
16184   [(set (match_operand:XF 0 "register_operand" "=f")
16185         (unspec:XF [(float_extend:XF
16186                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16187                    UNSPEC_SINCOS_COS))
16188    (set (match_operand:XF 1 "register_operand" "=u")
16189         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16190   "TARGET_USE_FANCY_MATH_387
16191    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16192        || TARGET_MIX_SSE_I387)
16193    && flag_unsafe_math_optimizations"
16194   "fsincos"
16195   [(set_attr "type" "fpspc")
16196    (set_attr "mode" "XF")])
16197
16198 (define_split
16199   [(set (match_operand:XF 0 "register_operand" "")
16200         (unspec:XF [(float_extend:XF
16201                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16202                    UNSPEC_SINCOS_COS))
16203    (set (match_operand:XF 1 "register_operand" "")
16204         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16205   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16206    && !reload_completed && !reload_in_progress"
16207   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16208   "")
16209
16210 (define_split
16211   [(set (match_operand:XF 0 "register_operand" "")
16212         (unspec:XF [(float_extend:XF
16213                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16214                    UNSPEC_SINCOS_COS))
16215    (set (match_operand:XF 1 "register_operand" "")
16216         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16217   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16218    && !reload_completed && !reload_in_progress"
16219   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16220   "")
16221
16222 (define_expand "sincos<mode>3"
16223   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16224    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16225    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16226   "TARGET_USE_FANCY_MATH_387
16227    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16228        || TARGET_MIX_SSE_I387)
16229    && flag_unsafe_math_optimizations"
16230 {
16231   rtx op0 = gen_reg_rtx (XFmode);
16232   rtx op1 = gen_reg_rtx (XFmode);
16233
16234   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16235   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16236   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16237   DONE;
16238 })
16239
16240 (define_insn "fptanxf4_i387"
16241   [(set (match_operand:XF 0 "register_operand" "=f")
16242         (match_operand:XF 3 "const_double_operand" "F"))
16243    (set (match_operand:XF 1 "register_operand" "=u")
16244         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16245                    UNSPEC_TAN))]
16246   "TARGET_USE_FANCY_MATH_387
16247    && flag_unsafe_math_optimizations
16248    && standard_80387_constant_p (operands[3]) == 2"
16249   "fptan"
16250   [(set_attr "type" "fpspc")
16251    (set_attr "mode" "XF")])
16252
16253 (define_insn "fptan_extend<mode>xf4_i387"
16254   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16255         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16256    (set (match_operand:XF 1 "register_operand" "=u")
16257         (unspec:XF [(float_extend:XF
16258                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16259                    UNSPEC_TAN))]
16260   "TARGET_USE_FANCY_MATH_387
16261    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16262        || TARGET_MIX_SSE_I387)
16263    && flag_unsafe_math_optimizations
16264    && standard_80387_constant_p (operands[3]) == 2"
16265   "fptan"
16266   [(set_attr "type" "fpspc")
16267    (set_attr "mode" "XF")])
16268
16269 (define_expand "tanxf2"
16270   [(use (match_operand:XF 0 "register_operand" ""))
16271    (use (match_operand:XF 1 "register_operand" ""))]
16272   "TARGET_USE_FANCY_MATH_387
16273    && flag_unsafe_math_optimizations"
16274 {
16275   rtx one = gen_reg_rtx (XFmode);
16276   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16277
16278   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16279   DONE;
16280 })
16281
16282 (define_expand "tan<mode>2"
16283   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16284    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16285   "TARGET_USE_FANCY_MATH_387
16286    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16287        || TARGET_MIX_SSE_I387)
16288    && flag_unsafe_math_optimizations"
16289 {
16290   rtx op0 = gen_reg_rtx (XFmode);
16291
16292   rtx one = gen_reg_rtx (<MODE>mode);
16293   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16294
16295   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16296                                              operands[1], op2));
16297   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16298   DONE;
16299 })
16300
16301 (define_insn "*fpatanxf3_i387"
16302   [(set (match_operand:XF 0 "register_operand" "=f")
16303         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16304                     (match_operand:XF 2 "register_operand" "u")]
16305                    UNSPEC_FPATAN))
16306    (clobber (match_scratch:XF 3 "=2"))]
16307   "TARGET_USE_FANCY_MATH_387
16308    && flag_unsafe_math_optimizations"
16309   "fpatan"
16310   [(set_attr "type" "fpspc")
16311    (set_attr "mode" "XF")])
16312
16313 (define_insn "fpatan_extend<mode>xf3_i387"
16314   [(set (match_operand:XF 0 "register_operand" "=f")
16315         (unspec:XF [(float_extend:XF
16316                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16317                     (float_extend:XF
16318                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
16319                    UNSPEC_FPATAN))
16320    (clobber (match_scratch:XF 3 "=2"))]
16321   "TARGET_USE_FANCY_MATH_387
16322    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16323        || TARGET_MIX_SSE_I387)
16324    && flag_unsafe_math_optimizations"
16325   "fpatan"
16326   [(set_attr "type" "fpspc")
16327    (set_attr "mode" "XF")])
16328
16329 (define_expand "atan2xf3"
16330   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16331                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16332                                (match_operand:XF 1 "register_operand" "")]
16333                               UNSPEC_FPATAN))
16334               (clobber (match_scratch:XF 3 ""))])]
16335   "TARGET_USE_FANCY_MATH_387
16336    && flag_unsafe_math_optimizations"
16337   "")
16338
16339 (define_expand "atan2<mode>3"
16340   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16341    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16342    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16343   "TARGET_USE_FANCY_MATH_387
16344    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16345        || TARGET_MIX_SSE_I387)
16346    && flag_unsafe_math_optimizations"
16347 {
16348   rtx op0 = gen_reg_rtx (XFmode);
16349
16350   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16351   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16352   DONE;
16353 })
16354
16355 (define_expand "atanxf2"
16356   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16357                    (unspec:XF [(match_dup 2)
16358                                (match_operand:XF 1 "register_operand" "")]
16359                               UNSPEC_FPATAN))
16360               (clobber (match_scratch:XF 3 ""))])]
16361   "TARGET_USE_FANCY_MATH_387
16362    && flag_unsafe_math_optimizations"
16363 {
16364   operands[2] = gen_reg_rtx (XFmode);
16365   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16366 })
16367
16368 (define_expand "atan<mode>2"
16369   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16370    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16371   "TARGET_USE_FANCY_MATH_387
16372    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16373        || TARGET_MIX_SSE_I387)
16374    && flag_unsafe_math_optimizations"
16375 {
16376   rtx op0 = gen_reg_rtx (XFmode);
16377
16378   rtx op2 = gen_reg_rtx (<MODE>mode);
16379   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16380
16381   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16382   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16383   DONE;
16384 })
16385
16386 (define_expand "asinxf2"
16387   [(set (match_dup 2)
16388         (mult:XF (match_operand:XF 1 "register_operand" "")
16389                  (match_dup 1)))
16390    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16391    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16392    (parallel [(set (match_operand:XF 0 "register_operand" "")
16393                    (unspec:XF [(match_dup 5) (match_dup 1)]
16394                               UNSPEC_FPATAN))
16395               (clobber (match_scratch:XF 6 ""))])]
16396   "TARGET_USE_FANCY_MATH_387
16397    && flag_unsafe_math_optimizations && !optimize_size"
16398 {
16399   int i;
16400
16401   for (i = 2; i < 6; i++)
16402     operands[i] = gen_reg_rtx (XFmode);
16403
16404   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16405 })
16406
16407 (define_expand "asin<mode>2"
16408   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16409    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16410  "TARGET_USE_FANCY_MATH_387
16411    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16412        || TARGET_MIX_SSE_I387)
16413    && flag_unsafe_math_optimizations && !optimize_size"
16414 {
16415   rtx op0 = gen_reg_rtx (XFmode);
16416   rtx op1 = gen_reg_rtx (XFmode);
16417
16418   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16419   emit_insn (gen_asinxf2 (op0, op1));
16420   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16421   DONE;
16422 })
16423
16424 (define_expand "acosxf2"
16425   [(set (match_dup 2)
16426         (mult:XF (match_operand:XF 1 "register_operand" "")
16427                  (match_dup 1)))
16428    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16429    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16430    (parallel [(set (match_operand:XF 0 "register_operand" "")
16431                    (unspec:XF [(match_dup 1) (match_dup 5)]
16432                               UNSPEC_FPATAN))
16433               (clobber (match_scratch:XF 6 ""))])]
16434   "TARGET_USE_FANCY_MATH_387
16435    && flag_unsafe_math_optimizations && !optimize_size"
16436 {
16437   int i;
16438
16439   for (i = 2; i < 6; i++)
16440     operands[i] = gen_reg_rtx (XFmode);
16441
16442   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16443 })
16444
16445 (define_expand "acos<mode>2"
16446   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16447    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16448  "TARGET_USE_FANCY_MATH_387
16449    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16450        || TARGET_MIX_SSE_I387)
16451    && flag_unsafe_math_optimizations && !optimize_size"
16452 {
16453   rtx op0 = gen_reg_rtx (XFmode);
16454   rtx op1 = gen_reg_rtx (XFmode);
16455
16456   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16457   emit_insn (gen_acosxf2 (op0, op1));
16458   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16459   DONE;
16460 })
16461
16462 (define_insn "fyl2xxf3_i387"
16463   [(set (match_operand:XF 0 "register_operand" "=f")
16464         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16465                     (match_operand:XF 2 "register_operand" "u")]
16466                    UNSPEC_FYL2X))
16467    (clobber (match_scratch:XF 3 "=2"))]
16468   "TARGET_USE_FANCY_MATH_387
16469    && flag_unsafe_math_optimizations"
16470   "fyl2x"
16471   [(set_attr "type" "fpspc")
16472    (set_attr "mode" "XF")])
16473
16474 (define_insn "fyl2x_extend<mode>xf3_i387"
16475   [(set (match_operand:XF 0 "register_operand" "=f")
16476         (unspec:XF [(float_extend:XF
16477                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16478                     (match_operand:XF 2 "register_operand" "u")]
16479                    UNSPEC_FYL2X))
16480    (clobber (match_scratch:XF 3 "=2"))]
16481   "TARGET_USE_FANCY_MATH_387
16482    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16483        || TARGET_MIX_SSE_I387)
16484    && flag_unsafe_math_optimizations"
16485   "fyl2x"
16486   [(set_attr "type" "fpspc")
16487    (set_attr "mode" "XF")])
16488
16489 (define_expand "logxf2"
16490   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16491                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16492                                (match_dup 2)] UNSPEC_FYL2X))
16493               (clobber (match_scratch:XF 3 ""))])]
16494   "TARGET_USE_FANCY_MATH_387
16495    && flag_unsafe_math_optimizations"
16496 {
16497   operands[2] = gen_reg_rtx (XFmode);
16498   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16499 })
16500
16501 (define_expand "log<mode>2"
16502   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16503    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16504   "TARGET_USE_FANCY_MATH_387
16505    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16506        || TARGET_MIX_SSE_I387)
16507    && flag_unsafe_math_optimizations"
16508 {
16509   rtx op0 = gen_reg_rtx (XFmode);
16510
16511   rtx op2 = gen_reg_rtx (XFmode);
16512   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16513
16514   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16515   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16516   DONE;
16517 })
16518
16519 (define_expand "log10xf2"
16520   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16521                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16522                                (match_dup 2)] UNSPEC_FYL2X))
16523               (clobber (match_scratch:XF 3 ""))])]
16524   "TARGET_USE_FANCY_MATH_387
16525    && flag_unsafe_math_optimizations"
16526 {
16527   operands[2] = gen_reg_rtx (XFmode);
16528   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16529 })
16530
16531 (define_expand "log10<mode>2"
16532   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16533    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16534   "TARGET_USE_FANCY_MATH_387
16535    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16536        || TARGET_MIX_SSE_I387)
16537    && flag_unsafe_math_optimizations"
16538 {
16539   rtx op0 = gen_reg_rtx (XFmode);
16540
16541   rtx op2 = gen_reg_rtx (XFmode);
16542   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16543
16544   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16545   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16546   DONE;
16547 })
16548
16549 (define_expand "log2xf2"
16550   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16551                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16552                                (match_dup 2)] UNSPEC_FYL2X))
16553               (clobber (match_scratch:XF 3 ""))])]
16554   "TARGET_USE_FANCY_MATH_387
16555    && flag_unsafe_math_optimizations"
16556 {
16557   operands[2] = gen_reg_rtx (XFmode);
16558   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16559 })
16560
16561 (define_expand "log2<mode>2"
16562   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16563    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16564   "TARGET_USE_FANCY_MATH_387
16565    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16566        || TARGET_MIX_SSE_I387)
16567    && flag_unsafe_math_optimizations"
16568 {
16569   rtx op0 = gen_reg_rtx (XFmode);
16570
16571   rtx op2 = gen_reg_rtx (XFmode);
16572   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16573
16574   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16575   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16576   DONE;
16577 })
16578
16579 (define_insn "fyl2xp1xf3_i387"
16580   [(set (match_operand:XF 0 "register_operand" "=f")
16581         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16582                     (match_operand:XF 2 "register_operand" "u")]
16583                    UNSPEC_FYL2XP1))
16584    (clobber (match_scratch:XF 3 "=2"))]
16585   "TARGET_USE_FANCY_MATH_387
16586    && flag_unsafe_math_optimizations"
16587   "fyl2xp1"
16588   [(set_attr "type" "fpspc")
16589    (set_attr "mode" "XF")])
16590
16591 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16592   [(set (match_operand:XF 0 "register_operand" "=f")
16593         (unspec:XF [(float_extend:XF
16594                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16595                     (match_operand:XF 2 "register_operand" "u")]
16596                    UNSPEC_FYL2XP1))
16597    (clobber (match_scratch:XF 3 "=2"))]
16598   "TARGET_USE_FANCY_MATH_387
16599    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16600        || TARGET_MIX_SSE_I387)
16601    && flag_unsafe_math_optimizations"
16602   "fyl2xp1"
16603   [(set_attr "type" "fpspc")
16604    (set_attr "mode" "XF")])
16605
16606 (define_expand "log1pxf2"
16607   [(use (match_operand:XF 0 "register_operand" ""))
16608    (use (match_operand:XF 1 "register_operand" ""))]
16609   "TARGET_USE_FANCY_MATH_387
16610    && flag_unsafe_math_optimizations && !optimize_size"
16611 {
16612   ix86_emit_i387_log1p (operands[0], operands[1]);
16613   DONE;
16614 })
16615
16616 (define_expand "log1p<mode>2"
16617   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16618    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16619   "TARGET_USE_FANCY_MATH_387
16620    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16621        || TARGET_MIX_SSE_I387)
16622    && flag_unsafe_math_optimizations && !optimize_size"
16623 {
16624   rtx op0 = gen_reg_rtx (XFmode);
16625
16626   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16627
16628   ix86_emit_i387_log1p (op0, operands[1]);
16629   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16630   DONE;
16631 })
16632
16633 (define_insn "fxtractxf3_i387"
16634   [(set (match_operand:XF 0 "register_operand" "=f")
16635         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16636                    UNSPEC_XTRACT_FRACT))
16637    (set (match_operand:XF 1 "register_operand" "=u")
16638         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16639   "TARGET_USE_FANCY_MATH_387
16640    && flag_unsafe_math_optimizations"
16641   "fxtract"
16642   [(set_attr "type" "fpspc")
16643    (set_attr "mode" "XF")])
16644
16645 (define_insn "fxtract_extend<mode>xf3_i387"
16646   [(set (match_operand:XF 0 "register_operand" "=f")
16647         (unspec:XF [(float_extend:XF
16648                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16649                    UNSPEC_XTRACT_FRACT))
16650    (set (match_operand:XF 1 "register_operand" "=u")
16651         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16652   "TARGET_USE_FANCY_MATH_387
16653    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16654        || TARGET_MIX_SSE_I387)
16655    && flag_unsafe_math_optimizations"
16656   "fxtract"
16657   [(set_attr "type" "fpspc")
16658    (set_attr "mode" "XF")])
16659
16660 (define_expand "logbxf2"
16661   [(parallel [(set (match_dup 2)
16662                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16663                               UNSPEC_XTRACT_FRACT))
16664               (set (match_operand:XF 0 "register_operand" "")
16665                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16666   "TARGET_USE_FANCY_MATH_387
16667    && flag_unsafe_math_optimizations"
16668 {
16669   operands[2] = gen_reg_rtx (XFmode);
16670 })
16671
16672 (define_expand "logb<mode>2"
16673   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16674    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16675   "TARGET_USE_FANCY_MATH_387
16676    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16677        || TARGET_MIX_SSE_I387)
16678    && flag_unsafe_math_optimizations"
16679 {
16680   rtx op0 = gen_reg_rtx (XFmode);
16681   rtx op1 = gen_reg_rtx (XFmode);
16682
16683   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16684   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16685   DONE;
16686 })
16687
16688 (define_expand "ilogbxf2"
16689   [(use (match_operand:SI 0 "register_operand" ""))
16690    (use (match_operand:XF 1 "register_operand" ""))]
16691   "TARGET_USE_FANCY_MATH_387
16692    && flag_unsafe_math_optimizations && !optimize_size"
16693 {
16694   rtx op0 = gen_reg_rtx (XFmode);
16695   rtx op1 = gen_reg_rtx (XFmode);
16696
16697   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16698   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16699   DONE;
16700 })
16701
16702 (define_expand "ilogb<mode>2"
16703   [(use (match_operand:SI 0 "register_operand" ""))
16704    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
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 && !optimize_size"
16709 {
16710   rtx op0 = gen_reg_rtx (XFmode);
16711   rtx op1 = gen_reg_rtx (XFmode);
16712
16713   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16714   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16715   DONE;
16716 })
16717
16718 (define_insn "*f2xm1xf2_i387"
16719   [(set (match_operand:XF 0 "register_operand" "=f")
16720         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16721                    UNSPEC_F2XM1))]
16722   "TARGET_USE_FANCY_MATH_387
16723    && flag_unsafe_math_optimizations"
16724   "f2xm1"
16725   [(set_attr "type" "fpspc")
16726    (set_attr "mode" "XF")])
16727
16728 (define_insn "*fscalexf4_i387"
16729   [(set (match_operand:XF 0 "register_operand" "=f")
16730         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16731                     (match_operand:XF 3 "register_operand" "1")]
16732                    UNSPEC_FSCALE_FRACT))
16733    (set (match_operand:XF 1 "register_operand" "=u")
16734         (unspec:XF [(match_dup 2) (match_dup 3)]
16735                    UNSPEC_FSCALE_EXP))]
16736   "TARGET_USE_FANCY_MATH_387
16737    && flag_unsafe_math_optimizations"
16738   "fscale"
16739   [(set_attr "type" "fpspc")
16740    (set_attr "mode" "XF")])
16741
16742 (define_expand "expNcorexf3"
16743   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16744                                (match_operand:XF 2 "register_operand" "")))
16745    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16746    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16747    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16748    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16749    (parallel [(set (match_operand:XF 0 "register_operand" "")
16750                    (unspec:XF [(match_dup 8) (match_dup 4)]
16751                               UNSPEC_FSCALE_FRACT))
16752               (set (match_dup 9)
16753                    (unspec:XF [(match_dup 8) (match_dup 4)]
16754                               UNSPEC_FSCALE_EXP))])]
16755   "TARGET_USE_FANCY_MATH_387
16756    && flag_unsafe_math_optimizations && !optimize_size"
16757 {
16758   int i;
16759
16760   for (i = 3; i < 10; i++)
16761     operands[i] = gen_reg_rtx (XFmode);
16762
16763   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16764 })
16765
16766 (define_expand "expxf2"
16767   [(use (match_operand:XF 0 "register_operand" ""))
16768    (use (match_operand:XF 1 "register_operand" ""))]
16769   "TARGET_USE_FANCY_MATH_387
16770    && flag_unsafe_math_optimizations && !optimize_size"
16771 {
16772   rtx op2 = gen_reg_rtx (XFmode);
16773   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16774
16775   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16776   DONE;
16777 })
16778
16779 (define_expand "exp<mode>2"
16780   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16781    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16782  "TARGET_USE_FANCY_MATH_387
16783    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16784        || TARGET_MIX_SSE_I387)
16785    && flag_unsafe_math_optimizations && !optimize_size"
16786 {
16787   rtx op0 = gen_reg_rtx (XFmode);
16788   rtx op1 = gen_reg_rtx (XFmode);
16789
16790   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16791   emit_insn (gen_expxf2 (op0, op1));
16792   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16793   DONE;
16794 })
16795
16796 (define_expand "exp10xf2"
16797   [(use (match_operand:XF 0 "register_operand" ""))
16798    (use (match_operand:XF 1 "register_operand" ""))]
16799   "TARGET_USE_FANCY_MATH_387
16800    && flag_unsafe_math_optimizations && !optimize_size"
16801 {
16802   rtx op2 = gen_reg_rtx (XFmode);
16803   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16804
16805   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16806   DONE;
16807 })
16808
16809 (define_expand "exp10<mode>2"
16810   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16811    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16812  "TARGET_USE_FANCY_MATH_387
16813    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16814        || TARGET_MIX_SSE_I387)
16815    && flag_unsafe_math_optimizations && !optimize_size"
16816 {
16817   rtx op0 = gen_reg_rtx (XFmode);
16818   rtx op1 = gen_reg_rtx (XFmode);
16819
16820   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16821   emit_insn (gen_exp10xf2 (op0, op1));
16822   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16823   DONE;
16824 })
16825
16826 (define_expand "exp2xf2"
16827   [(use (match_operand:XF 0 "register_operand" ""))
16828    (use (match_operand:XF 1 "register_operand" ""))]
16829   "TARGET_USE_FANCY_MATH_387
16830    && flag_unsafe_math_optimizations && !optimize_size"
16831 {
16832   rtx op2 = gen_reg_rtx (XFmode);
16833   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16834
16835   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16836   DONE;
16837 })
16838
16839 (define_expand "exp2<mode>2"
16840   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16841    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16842  "TARGET_USE_FANCY_MATH_387
16843    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16844        || TARGET_MIX_SSE_I387)
16845    && flag_unsafe_math_optimizations && !optimize_size"
16846 {
16847   rtx op0 = gen_reg_rtx (XFmode);
16848   rtx op1 = gen_reg_rtx (XFmode);
16849
16850   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16851   emit_insn (gen_exp2xf2 (op0, op1));
16852   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16853   DONE;
16854 })
16855
16856 (define_expand "expm1xf2"
16857   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16858                                (match_dup 2)))
16859    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16860    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16861    (set (match_dup 9) (float_extend:XF (match_dup 13)))
16862    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16863    (parallel [(set (match_dup 7)
16864                    (unspec:XF [(match_dup 6) (match_dup 4)]
16865                               UNSPEC_FSCALE_FRACT))
16866               (set (match_dup 8)
16867                    (unspec:XF [(match_dup 6) (match_dup 4)]
16868                               UNSPEC_FSCALE_EXP))])
16869    (parallel [(set (match_dup 10)
16870                    (unspec:XF [(match_dup 9) (match_dup 8)]
16871                               UNSPEC_FSCALE_FRACT))
16872               (set (match_dup 11)
16873                    (unspec:XF [(match_dup 9) (match_dup 8)]
16874                               UNSPEC_FSCALE_EXP))])
16875    (set (match_dup 12) (minus:XF (match_dup 10)
16876                                  (float_extend:XF (match_dup 13))))
16877    (set (match_operand:XF 0 "register_operand" "")
16878         (plus:XF (match_dup 12) (match_dup 7)))]
16879   "TARGET_USE_FANCY_MATH_387
16880    && flag_unsafe_math_optimizations && !optimize_size"
16881 {
16882   int i;
16883
16884   for (i = 2; i < 13; i++)
16885     operands[i] = gen_reg_rtx (XFmode);
16886
16887   operands[13]
16888     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16889
16890   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16891 })
16892
16893 (define_expand "expm1<mode>2"
16894   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16895    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16896  "TARGET_USE_FANCY_MATH_387
16897    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16898        || TARGET_MIX_SSE_I387)
16899    && flag_unsafe_math_optimizations && !optimize_size"
16900 {
16901   rtx op0 = gen_reg_rtx (XFmode);
16902   rtx op1 = gen_reg_rtx (XFmode);
16903
16904   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16905   emit_insn (gen_expm1xf2 (op0, op1));
16906   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16907   DONE;
16908 })
16909
16910 (define_expand "ldexpxf3"
16911   [(set (match_dup 3)
16912         (float:XF (match_operand:SI 2 "register_operand" "")))
16913    (parallel [(set (match_operand:XF 0 " register_operand" "")
16914                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16915                                (match_dup 3)]
16916                               UNSPEC_FSCALE_FRACT))
16917               (set (match_dup 4)
16918                    (unspec:XF [(match_dup 1) (match_dup 3)]
16919                               UNSPEC_FSCALE_EXP))])]
16920   "TARGET_USE_FANCY_MATH_387
16921    && flag_unsafe_math_optimizations && !optimize_size"
16922 {
16923   operands[3] = gen_reg_rtx (XFmode);
16924   operands[4] = gen_reg_rtx (XFmode);
16925 })
16926
16927 (define_expand "ldexp<mode>3"
16928   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16929    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16930    (use (match_operand:SI 2 "register_operand" ""))]
16931  "TARGET_USE_FANCY_MATH_387
16932    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16933        || TARGET_MIX_SSE_I387)
16934    && flag_unsafe_math_optimizations && !optimize_size"
16935 {
16936   rtx op0 = gen_reg_rtx (XFmode);
16937   rtx op1 = gen_reg_rtx (XFmode);
16938
16939   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16940   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16941   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16942   DONE;
16943 })
16944
16945 (define_expand "scalbxf3"
16946   [(parallel [(set (match_operand:XF 0 " register_operand" "")
16947                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16948                                (match_operand:XF 2 "register_operand" "")]
16949                               UNSPEC_FSCALE_FRACT))
16950               (set (match_dup 3)
16951                    (unspec:XF [(match_dup 1) (match_dup 2)]
16952                               UNSPEC_FSCALE_EXP))])]
16953   "TARGET_USE_FANCY_MATH_387
16954    && flag_unsafe_math_optimizations && !optimize_size"
16955 {
16956   operands[3] = gen_reg_rtx (XFmode);
16957 })
16958
16959 (define_expand "scalb<mode>3"
16960   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16961    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16962    (use (match_operand:X87MODEF12 2 "register_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   rtx op2 = gen_reg_rtx (XFmode);
16971
16972   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16973   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16974   emit_insn (gen_scalbxf3 (op0, op1, op2));
16975   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16976   DONE;
16977 })
16978 \f
16979
16980 (define_insn "sse4_1_round<mode>2"
16981   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16982         (unspec:SSEMODEF [(match_operand:SSEMODEF 1 "register_operand" "x")
16983                           (match_operand:SI 2 "const_0_to_15_operand" "n")]
16984                          UNSPEC_ROUND))]
16985   "TARGET_SSE4_1"
16986   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16987   [(set_attr "type" "ssecvt")
16988    (set_attr "prefix_extra" "1")
16989    (set_attr "mode" "<MODE>")])
16990
16991 (define_insn "rintxf2"
16992   [(set (match_operand:XF 0 "register_operand" "=f")
16993         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16994                    UNSPEC_FRNDINT))]
16995   "TARGET_USE_FANCY_MATH_387
16996    && flag_unsafe_math_optimizations"
16997   "frndint"
16998   [(set_attr "type" "fpspc")
16999    (set_attr "mode" "XF")])
17000
17001 (define_expand "rint<mode>2"
17002   [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17003    (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17004   "(TARGET_USE_FANCY_MATH_387
17005     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17006         || TARGET_MIX_SSE_I387)
17007     && flag_unsafe_math_optimizations)
17008    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17009        && !flag_trapping_math
17010        && (TARGET_SSE4_1 || !optimize_size))"
17011 {
17012   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17013       && !flag_trapping_math
17014       && (TARGET_SSE4_1 || !optimize_size))
17015     {
17016       if (TARGET_SSE4_1)
17017         emit_insn (gen_sse4_1_round<mode>2
17018                    (operands[0], operands[1], GEN_INT (0x04)));
17019       else
17020         ix86_expand_rint (operand0, operand1);
17021     }
17022   else
17023     {
17024       rtx op0 = gen_reg_rtx (XFmode);
17025       rtx op1 = gen_reg_rtx (XFmode);
17026
17027       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17028       emit_insn (gen_rintxf2 (op0, op1));
17029
17030       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17031     }
17032   DONE;
17033 })
17034
17035 (define_expand "round<mode>2"
17036   [(match_operand:SSEMODEF 0 "register_operand" "")
17037    (match_operand:SSEMODEF 1 "nonimmediate_operand" "")]
17038   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17039    && !flag_trapping_math && !flag_rounding_math
17040    && !optimize_size"
17041 {
17042   if (TARGET_64BIT || (<MODE>mode != DFmode))
17043     ix86_expand_round (operand0, operand1);
17044   else
17045     ix86_expand_rounddf_32 (operand0, operand1);
17046   DONE;
17047 })
17048
17049 (define_insn_and_split "*fistdi2_1"
17050   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17051         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17052                    UNSPEC_FIST))]
17053   "TARGET_USE_FANCY_MATH_387
17054    && !(reload_completed || reload_in_progress)"
17055   "#"
17056   "&& 1"
17057   [(const_int 0)]
17058 {
17059   if (memory_operand (operands[0], VOIDmode))
17060     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17061   else
17062     {
17063       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17064       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17065                                          operands[2]));
17066     }
17067   DONE;
17068 }
17069   [(set_attr "type" "fpspc")
17070    (set_attr "mode" "DI")])
17071
17072 (define_insn "fistdi2"
17073   [(set (match_operand:DI 0 "memory_operand" "=m")
17074         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17075                    UNSPEC_FIST))
17076    (clobber (match_scratch:XF 2 "=&1f"))]
17077   "TARGET_USE_FANCY_MATH_387"
17078   "* return output_fix_trunc (insn, operands, 0);"
17079   [(set_attr "type" "fpspc")
17080    (set_attr "mode" "DI")])
17081
17082 (define_insn "fistdi2_with_temp"
17083   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17084         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17085                    UNSPEC_FIST))
17086    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17087    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17088   "TARGET_USE_FANCY_MATH_387"
17089   "#"
17090   [(set_attr "type" "fpspc")
17091    (set_attr "mode" "DI")])
17092
17093 (define_split
17094   [(set (match_operand:DI 0 "register_operand" "")
17095         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17096                    UNSPEC_FIST))
17097    (clobber (match_operand:DI 2 "memory_operand" ""))
17098    (clobber (match_scratch 3 ""))]
17099   "reload_completed"
17100   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17101               (clobber (match_dup 3))])
17102    (set (match_dup 0) (match_dup 2))]
17103   "")
17104
17105 (define_split
17106   [(set (match_operand:DI 0 "memory_operand" "")
17107         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17108                    UNSPEC_FIST))
17109    (clobber (match_operand:DI 2 "memory_operand" ""))
17110    (clobber (match_scratch 3 ""))]
17111   "reload_completed"
17112   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17113               (clobber (match_dup 3))])]
17114   "")
17115
17116 (define_insn_and_split "*fist<mode>2_1"
17117   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17118         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17119                            UNSPEC_FIST))]
17120   "TARGET_USE_FANCY_MATH_387
17121    && !(reload_completed || reload_in_progress)"
17122   "#"
17123   "&& 1"
17124   [(const_int 0)]
17125 {
17126   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17127   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17128                                         operands[2]));
17129   DONE;
17130 }
17131   [(set_attr "type" "fpspc")
17132    (set_attr "mode" "<MODE>")])
17133
17134 (define_insn "fist<mode>2"
17135   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17136         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17137                            UNSPEC_FIST))]
17138   "TARGET_USE_FANCY_MATH_387"
17139   "* return output_fix_trunc (insn, operands, 0);"
17140   [(set_attr "type" "fpspc")
17141    (set_attr "mode" "<MODE>")])
17142
17143 (define_insn "fist<mode>2_with_temp"
17144   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17145         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17146                            UNSPEC_FIST))
17147    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17148   "TARGET_USE_FANCY_MATH_387"
17149   "#"
17150   [(set_attr "type" "fpspc")
17151    (set_attr "mode" "<MODE>")])
17152
17153 (define_split
17154   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17155         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17156                            UNSPEC_FIST))
17157    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17158   "reload_completed"
17159   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17160    (set (match_dup 0) (match_dup 2))]
17161   "")
17162
17163 (define_split
17164   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17165         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17166                            UNSPEC_FIST))
17167    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17168   "reload_completed"
17169   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17170   "")
17171
17172 (define_expand "lrintxf<mode>2"
17173   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17174      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17175                       UNSPEC_FIST))]
17176   "TARGET_USE_FANCY_MATH_387"
17177   "")
17178
17179 (define_expand "lrint<SSEMODEF:mode><SSEMODEI24:mode>2"
17180   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17181      (unspec:SSEMODEI24 [(match_operand:SSEMODEF 1 "register_operand" "")]
17182                         UNSPEC_FIX_NOTRUNC))]
17183   "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17184    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17185   "")
17186
17187 (define_expand "lround<SSEMODEF:mode><SSEMODEI24:mode>2"
17188   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17189    (match_operand:SSEMODEF 1 "register_operand" "")]
17190   "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17191    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17192    && !flag_trapping_math && !flag_rounding_math
17193    && !optimize_size"
17194 {
17195   ix86_expand_lround (operand0, operand1);
17196   DONE;
17197 })
17198
17199 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17200 (define_insn_and_split "frndintxf2_floor"
17201   [(set (match_operand:XF 0 "register_operand" "=f")
17202         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17203          UNSPEC_FRNDINT_FLOOR))
17204    (clobber (reg:CC FLAGS_REG))]
17205   "TARGET_USE_FANCY_MATH_387
17206    && flag_unsafe_math_optimizations
17207    && !(reload_completed || reload_in_progress)"
17208   "#"
17209   "&& 1"
17210   [(const_int 0)]
17211 {
17212   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17213
17214   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17215   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17216
17217   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17218                                         operands[2], operands[3]));
17219   DONE;
17220 }
17221   [(set_attr "type" "frndint")
17222    (set_attr "i387_cw" "floor")
17223    (set_attr "mode" "XF")])
17224
17225 (define_insn "frndintxf2_floor_i387"
17226   [(set (match_operand:XF 0 "register_operand" "=f")
17227         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17228          UNSPEC_FRNDINT_FLOOR))
17229    (use (match_operand:HI 2 "memory_operand" "m"))
17230    (use (match_operand:HI 3 "memory_operand" "m"))]
17231   "TARGET_USE_FANCY_MATH_387
17232    && flag_unsafe_math_optimizations"
17233   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17234   [(set_attr "type" "frndint")
17235    (set_attr "i387_cw" "floor")
17236    (set_attr "mode" "XF")])
17237
17238 (define_expand "floorxf2"
17239   [(use (match_operand:XF 0 "register_operand" ""))
17240    (use (match_operand:XF 1 "register_operand" ""))]
17241   "TARGET_USE_FANCY_MATH_387
17242    && flag_unsafe_math_optimizations && !optimize_size"
17243 {
17244   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17245   DONE;
17246 })
17247
17248 (define_expand "floor<mode>2"
17249   [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17250    (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17251   "(TARGET_USE_FANCY_MATH_387
17252     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17253         || TARGET_MIX_SSE_I387)
17254     && flag_unsafe_math_optimizations && !optimize_size)
17255    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17256        && !flag_trapping_math
17257        && (TARGET_SSE4_1 || !optimize_size))"
17258 {
17259   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17260       && !flag_trapping_math
17261       && (TARGET_SSE4_1 || !optimize_size))
17262     {
17263       if (TARGET_SSE4_1)
17264         emit_insn (gen_sse4_1_round<mode>2
17265                    (operands[0], operands[1], GEN_INT (0x01)));
17266       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17267         ix86_expand_floorceil (operand0, operand1, true);
17268       else
17269         ix86_expand_floorceildf_32 (operand0, operand1, true);
17270     }
17271   else
17272     {
17273       rtx op0 = gen_reg_rtx (XFmode);
17274       rtx op1 = gen_reg_rtx (XFmode);
17275
17276       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17277       emit_insn (gen_frndintxf2_floor (op0, op1));
17278
17279       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17280     }
17281   DONE;
17282 })
17283
17284 (define_insn_and_split "*fist<mode>2_floor_1"
17285   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17286         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17287          UNSPEC_FIST_FLOOR))
17288    (clobber (reg:CC FLAGS_REG))]
17289   "TARGET_USE_FANCY_MATH_387
17290    && flag_unsafe_math_optimizations
17291    && !(reload_completed || reload_in_progress)"
17292   "#"
17293   "&& 1"
17294   [(const_int 0)]
17295 {
17296   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17297
17298   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17299   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17300   if (memory_operand (operands[0], VOIDmode))
17301     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17302                                       operands[2], operands[3]));
17303   else
17304     {
17305       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17306       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17307                                                   operands[2], operands[3],
17308                                                   operands[4]));
17309     }
17310   DONE;
17311 }
17312   [(set_attr "type" "fistp")
17313    (set_attr "i387_cw" "floor")
17314    (set_attr "mode" "<MODE>")])
17315
17316 (define_insn "fistdi2_floor"
17317   [(set (match_operand:DI 0 "memory_operand" "=m")
17318         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17319          UNSPEC_FIST_FLOOR))
17320    (use (match_operand:HI 2 "memory_operand" "m"))
17321    (use (match_operand:HI 3 "memory_operand" "m"))
17322    (clobber (match_scratch:XF 4 "=&1f"))]
17323   "TARGET_USE_FANCY_MATH_387
17324    && flag_unsafe_math_optimizations"
17325   "* return output_fix_trunc (insn, operands, 0);"
17326   [(set_attr "type" "fistp")
17327    (set_attr "i387_cw" "floor")
17328    (set_attr "mode" "DI")])
17329
17330 (define_insn "fistdi2_floor_with_temp"
17331   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17332         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17333          UNSPEC_FIST_FLOOR))
17334    (use (match_operand:HI 2 "memory_operand" "m,m"))
17335    (use (match_operand:HI 3 "memory_operand" "m,m"))
17336    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17337    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17338   "TARGET_USE_FANCY_MATH_387
17339    && flag_unsafe_math_optimizations"
17340   "#"
17341   [(set_attr "type" "fistp")
17342    (set_attr "i387_cw" "floor")
17343    (set_attr "mode" "DI")])
17344
17345 (define_split
17346   [(set (match_operand:DI 0 "register_operand" "")
17347         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17348          UNSPEC_FIST_FLOOR))
17349    (use (match_operand:HI 2 "memory_operand" ""))
17350    (use (match_operand:HI 3 "memory_operand" ""))
17351    (clobber (match_operand:DI 4 "memory_operand" ""))
17352    (clobber (match_scratch 5 ""))]
17353   "reload_completed"
17354   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17355               (use (match_dup 2))
17356               (use (match_dup 3))
17357               (clobber (match_dup 5))])
17358    (set (match_dup 0) (match_dup 4))]
17359   "")
17360
17361 (define_split
17362   [(set (match_operand:DI 0 "memory_operand" "")
17363         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17364          UNSPEC_FIST_FLOOR))
17365    (use (match_operand:HI 2 "memory_operand" ""))
17366    (use (match_operand:HI 3 "memory_operand" ""))
17367    (clobber (match_operand:DI 4 "memory_operand" ""))
17368    (clobber (match_scratch 5 ""))]
17369   "reload_completed"
17370   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17371               (use (match_dup 2))
17372               (use (match_dup 3))
17373               (clobber (match_dup 5))])]
17374   "")
17375
17376 (define_insn "fist<mode>2_floor"
17377   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17378         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17379          UNSPEC_FIST_FLOOR))
17380    (use (match_operand:HI 2 "memory_operand" "m"))
17381    (use (match_operand:HI 3 "memory_operand" "m"))]
17382   "TARGET_USE_FANCY_MATH_387
17383    && flag_unsafe_math_optimizations"
17384   "* return output_fix_trunc (insn, operands, 0);"
17385   [(set_attr "type" "fistp")
17386    (set_attr "i387_cw" "floor")
17387    (set_attr "mode" "<MODE>")])
17388
17389 (define_insn "fist<mode>2_floor_with_temp"
17390   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17391         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17392          UNSPEC_FIST_FLOOR))
17393    (use (match_operand:HI 2 "memory_operand" "m,m"))
17394    (use (match_operand:HI 3 "memory_operand" "m,m"))
17395    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17396   "TARGET_USE_FANCY_MATH_387
17397    && flag_unsafe_math_optimizations"
17398   "#"
17399   [(set_attr "type" "fistp")
17400    (set_attr "i387_cw" "floor")
17401    (set_attr "mode" "<MODE>")])
17402
17403 (define_split
17404   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17405         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17406          UNSPEC_FIST_FLOOR))
17407    (use (match_operand:HI 2 "memory_operand" ""))
17408    (use (match_operand:HI 3 "memory_operand" ""))
17409    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17410   "reload_completed"
17411   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17412                                   UNSPEC_FIST_FLOOR))
17413               (use (match_dup 2))
17414               (use (match_dup 3))])
17415    (set (match_dup 0) (match_dup 4))]
17416   "")
17417
17418 (define_split
17419   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17420         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17421          UNSPEC_FIST_FLOOR))
17422    (use (match_operand:HI 2 "memory_operand" ""))
17423    (use (match_operand:HI 3 "memory_operand" ""))
17424    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17425   "reload_completed"
17426   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17427                                   UNSPEC_FIST_FLOOR))
17428               (use (match_dup 2))
17429               (use (match_dup 3))])]
17430   "")
17431
17432 (define_expand "lfloorxf<mode>2"
17433   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17434                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17435                     UNSPEC_FIST_FLOOR))
17436               (clobber (reg:CC FLAGS_REG))])]
17437   "TARGET_USE_FANCY_MATH_387
17438    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17439    && flag_unsafe_math_optimizations"
17440   "")
17441
17442 (define_expand "lfloor<mode>di2"
17443   [(match_operand:DI 0 "nonimmediate_operand" "")
17444    (match_operand:SSEMODEF 1 "register_operand" "")]
17445   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17446    && !flag_trapping_math
17447    && !optimize_size"
17448 {
17449   ix86_expand_lfloorceil (operand0, operand1, true);
17450   DONE;
17451 })
17452
17453 (define_expand "lfloor<mode>si2"
17454   [(match_operand:SI 0 "nonimmediate_operand" "")
17455    (match_operand:SSEMODEF 1 "register_operand" "")]
17456   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17457    && !flag_trapping_math
17458    && (!optimize_size || !TARGET_64BIT)"
17459 {
17460   ix86_expand_lfloorceil (operand0, operand1, true);
17461   DONE;
17462 })
17463
17464 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17465 (define_insn_and_split "frndintxf2_ceil"
17466   [(set (match_operand:XF 0 "register_operand" "=f")
17467         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17468          UNSPEC_FRNDINT_CEIL))
17469    (clobber (reg:CC FLAGS_REG))]
17470   "TARGET_USE_FANCY_MATH_387
17471    && flag_unsafe_math_optimizations
17472    && !(reload_completed || reload_in_progress)"
17473   "#"
17474   "&& 1"
17475   [(const_int 0)]
17476 {
17477   ix86_optimize_mode_switching[I387_CEIL] = 1;
17478
17479   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17480   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17481
17482   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17483                                        operands[2], operands[3]));
17484   DONE;
17485 }
17486   [(set_attr "type" "frndint")
17487    (set_attr "i387_cw" "ceil")
17488    (set_attr "mode" "XF")])
17489
17490 (define_insn "frndintxf2_ceil_i387"
17491   [(set (match_operand:XF 0 "register_operand" "=f")
17492         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17493          UNSPEC_FRNDINT_CEIL))
17494    (use (match_operand:HI 2 "memory_operand" "m"))
17495    (use (match_operand:HI 3 "memory_operand" "m"))]
17496   "TARGET_USE_FANCY_MATH_387
17497    && flag_unsafe_math_optimizations"
17498   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17499   [(set_attr "type" "frndint")
17500    (set_attr "i387_cw" "ceil")
17501    (set_attr "mode" "XF")])
17502
17503 (define_expand "ceilxf2"
17504   [(use (match_operand:XF 0 "register_operand" ""))
17505    (use (match_operand:XF 1 "register_operand" ""))]
17506   "TARGET_USE_FANCY_MATH_387
17507    && flag_unsafe_math_optimizations && !optimize_size"
17508 {
17509   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17510   DONE;
17511 })
17512
17513 (define_expand "ceil<mode>2"
17514   [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17515    (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17516   "(TARGET_USE_FANCY_MATH_387
17517     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17518         || TARGET_MIX_SSE_I387)
17519     && flag_unsafe_math_optimizations && !optimize_size)
17520    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17521        && !flag_trapping_math
17522        && (TARGET_SSE4_1 || !optimize_size))"
17523 {
17524   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17525       && !flag_trapping_math
17526       && (TARGET_SSE4_1 || !optimize_size))
17527     {
17528       if (TARGET_SSE4_1)
17529         emit_insn (gen_sse4_1_round<mode>2
17530                    (operands[0], operands[1], GEN_INT (0x02)));
17531       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17532         ix86_expand_floorceil (operand0, operand1, false);
17533       else
17534         ix86_expand_floorceildf_32 (operand0, operand1, false);
17535     }
17536   else
17537     {
17538       rtx op0 = gen_reg_rtx (XFmode);
17539       rtx op1 = gen_reg_rtx (XFmode);
17540
17541       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17542       emit_insn (gen_frndintxf2_ceil (op0, op1));
17543
17544       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17545     }
17546   DONE;
17547 })
17548
17549 (define_insn_and_split "*fist<mode>2_ceil_1"
17550   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17551         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17552          UNSPEC_FIST_CEIL))
17553    (clobber (reg:CC FLAGS_REG))]
17554   "TARGET_USE_FANCY_MATH_387
17555    && flag_unsafe_math_optimizations
17556    && !(reload_completed || reload_in_progress)"
17557   "#"
17558   "&& 1"
17559   [(const_int 0)]
17560 {
17561   ix86_optimize_mode_switching[I387_CEIL] = 1;
17562
17563   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17564   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17565   if (memory_operand (operands[0], VOIDmode))
17566     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17567                                      operands[2], operands[3]));
17568   else
17569     {
17570       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17571       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17572                                                  operands[2], operands[3],
17573                                                  operands[4]));
17574     }
17575   DONE;
17576 }
17577   [(set_attr "type" "fistp")
17578    (set_attr "i387_cw" "ceil")
17579    (set_attr "mode" "<MODE>")])
17580
17581 (define_insn "fistdi2_ceil"
17582   [(set (match_operand:DI 0 "memory_operand" "=m")
17583         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17584          UNSPEC_FIST_CEIL))
17585    (use (match_operand:HI 2 "memory_operand" "m"))
17586    (use (match_operand:HI 3 "memory_operand" "m"))
17587    (clobber (match_scratch:XF 4 "=&1f"))]
17588   "TARGET_USE_FANCY_MATH_387
17589    && flag_unsafe_math_optimizations"
17590   "* return output_fix_trunc (insn, operands, 0);"
17591   [(set_attr "type" "fistp")
17592    (set_attr "i387_cw" "ceil")
17593    (set_attr "mode" "DI")])
17594
17595 (define_insn "fistdi2_ceil_with_temp"
17596   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17597         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17598          UNSPEC_FIST_CEIL))
17599    (use (match_operand:HI 2 "memory_operand" "m,m"))
17600    (use (match_operand:HI 3 "memory_operand" "m,m"))
17601    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17602    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17603   "TARGET_USE_FANCY_MATH_387
17604    && flag_unsafe_math_optimizations"
17605   "#"
17606   [(set_attr "type" "fistp")
17607    (set_attr "i387_cw" "ceil")
17608    (set_attr "mode" "DI")])
17609
17610 (define_split
17611   [(set (match_operand:DI 0 "register_operand" "")
17612         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17613          UNSPEC_FIST_CEIL))
17614    (use (match_operand:HI 2 "memory_operand" ""))
17615    (use (match_operand:HI 3 "memory_operand" ""))
17616    (clobber (match_operand:DI 4 "memory_operand" ""))
17617    (clobber (match_scratch 5 ""))]
17618   "reload_completed"
17619   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17620               (use (match_dup 2))
17621               (use (match_dup 3))
17622               (clobber (match_dup 5))])
17623    (set (match_dup 0) (match_dup 4))]
17624   "")
17625
17626 (define_split
17627   [(set (match_operand:DI 0 "memory_operand" "")
17628         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17629          UNSPEC_FIST_CEIL))
17630    (use (match_operand:HI 2 "memory_operand" ""))
17631    (use (match_operand:HI 3 "memory_operand" ""))
17632    (clobber (match_operand:DI 4 "memory_operand" ""))
17633    (clobber (match_scratch 5 ""))]
17634   "reload_completed"
17635   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17636               (use (match_dup 2))
17637               (use (match_dup 3))
17638               (clobber (match_dup 5))])]
17639   "")
17640
17641 (define_insn "fist<mode>2_ceil"
17642   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17643         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17644          UNSPEC_FIST_CEIL))
17645    (use (match_operand:HI 2 "memory_operand" "m"))
17646    (use (match_operand:HI 3 "memory_operand" "m"))]
17647   "TARGET_USE_FANCY_MATH_387
17648    && flag_unsafe_math_optimizations"
17649   "* return output_fix_trunc (insn, operands, 0);"
17650   [(set_attr "type" "fistp")
17651    (set_attr "i387_cw" "ceil")
17652    (set_attr "mode" "<MODE>")])
17653
17654 (define_insn "fist<mode>2_ceil_with_temp"
17655   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17656         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17657          UNSPEC_FIST_CEIL))
17658    (use (match_operand:HI 2 "memory_operand" "m,m"))
17659    (use (match_operand:HI 3 "memory_operand" "m,m"))
17660    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17661   "TARGET_USE_FANCY_MATH_387
17662    && flag_unsafe_math_optimizations"
17663   "#"
17664   [(set_attr "type" "fistp")
17665    (set_attr "i387_cw" "ceil")
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_CEIL))
17672    (use (match_operand:HI 2 "memory_operand" ""))
17673    (use (match_operand:HI 3 "memory_operand" ""))
17674    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17675   "reload_completed"
17676   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17677                                   UNSPEC_FIST_CEIL))
17678               (use (match_dup 2))
17679               (use (match_dup 3))])
17680    (set (match_dup 0) (match_dup 4))]
17681   "")
17682
17683 (define_split
17684   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17685         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17686          UNSPEC_FIST_CEIL))
17687    (use (match_operand:HI 2 "memory_operand" ""))
17688    (use (match_operand:HI 3 "memory_operand" ""))
17689    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17690   "reload_completed"
17691   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17692                                   UNSPEC_FIST_CEIL))
17693               (use (match_dup 2))
17694               (use (match_dup 3))])]
17695   "")
17696
17697 (define_expand "lceilxf<mode>2"
17698   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17699                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17700                     UNSPEC_FIST_CEIL))
17701               (clobber (reg:CC FLAGS_REG))])]
17702   "TARGET_USE_FANCY_MATH_387
17703    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17704    && flag_unsafe_math_optimizations"
17705   "")
17706
17707 (define_expand "lceil<mode>di2"
17708   [(match_operand:DI 0 "nonimmediate_operand" "")
17709    (match_operand:SSEMODEF 1 "register_operand" "")]
17710   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17711    && !flag_trapping_math"
17712 {
17713   ix86_expand_lfloorceil (operand0, operand1, false);
17714   DONE;
17715 })
17716
17717 (define_expand "lceil<mode>si2"
17718   [(match_operand:SI 0 "nonimmediate_operand" "")
17719    (match_operand:SSEMODEF 1 "register_operand" "")]
17720   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17721    && !flag_trapping_math"
17722 {
17723   ix86_expand_lfloorceil (operand0, operand1, false);
17724   DONE;
17725 })
17726
17727 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17728 (define_insn_and_split "frndintxf2_trunc"
17729   [(set (match_operand:XF 0 "register_operand" "=f")
17730         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17731          UNSPEC_FRNDINT_TRUNC))
17732    (clobber (reg:CC FLAGS_REG))]
17733   "TARGET_USE_FANCY_MATH_387
17734    && flag_unsafe_math_optimizations
17735    && !(reload_completed || reload_in_progress)"
17736   "#"
17737   "&& 1"
17738   [(const_int 0)]
17739 {
17740   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17741
17742   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17743   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17744
17745   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17746                                         operands[2], operands[3]));
17747   DONE;
17748 }
17749   [(set_attr "type" "frndint")
17750    (set_attr "i387_cw" "trunc")
17751    (set_attr "mode" "XF")])
17752
17753 (define_insn "frndintxf2_trunc_i387"
17754   [(set (match_operand:XF 0 "register_operand" "=f")
17755         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17756          UNSPEC_FRNDINT_TRUNC))
17757    (use (match_operand:HI 2 "memory_operand" "m"))
17758    (use (match_operand:HI 3 "memory_operand" "m"))]
17759   "TARGET_USE_FANCY_MATH_387
17760    && flag_unsafe_math_optimizations"
17761   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17762   [(set_attr "type" "frndint")
17763    (set_attr "i387_cw" "trunc")
17764    (set_attr "mode" "XF")])
17765
17766 (define_expand "btruncxf2"
17767   [(use (match_operand:XF 0 "register_operand" ""))
17768    (use (match_operand:XF 1 "register_operand" ""))]
17769   "TARGET_USE_FANCY_MATH_387
17770    && flag_unsafe_math_optimizations && !optimize_size"
17771 {
17772   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17773   DONE;
17774 })
17775
17776 (define_expand "btrunc<mode>2"
17777   [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17778    (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17779   "(TARGET_USE_FANCY_MATH_387
17780     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17781         || TARGET_MIX_SSE_I387)
17782     && flag_unsafe_math_optimizations && !optimize_size)
17783    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17784        && !flag_trapping_math
17785        && (TARGET_SSE4_1 || !optimize_size))"
17786 {
17787   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17788       && !flag_trapping_math
17789       && (TARGET_SSE4_1 || !optimize_size))
17790     {
17791       if (TARGET_SSE4_1)
17792         emit_insn (gen_sse4_1_round<mode>2
17793                    (operands[0], operands[1], GEN_INT (0x03)));
17794       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17795         ix86_expand_trunc (operand0, operand1);
17796       else
17797         ix86_expand_truncdf_32 (operand0, operand1);
17798     }
17799   else
17800     {
17801       rtx op0 = gen_reg_rtx (XFmode);
17802       rtx op1 = gen_reg_rtx (XFmode);
17803
17804       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17805       emit_insn (gen_frndintxf2_trunc (op0, op1));
17806
17807       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17808     }
17809   DONE;
17810 })
17811
17812 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17813 (define_insn_and_split "frndintxf2_mask_pm"
17814   [(set (match_operand:XF 0 "register_operand" "=f")
17815         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17816          UNSPEC_FRNDINT_MASK_PM))
17817    (clobber (reg:CC FLAGS_REG))]
17818   "TARGET_USE_FANCY_MATH_387
17819    && flag_unsafe_math_optimizations
17820    && !(reload_completed || reload_in_progress)"
17821   "#"
17822   "&& 1"
17823   [(const_int 0)]
17824 {
17825   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17826
17827   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17828   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17829
17830   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17831                                           operands[2], operands[3]));
17832   DONE;
17833 }
17834   [(set_attr "type" "frndint")
17835    (set_attr "i387_cw" "mask_pm")
17836    (set_attr "mode" "XF")])
17837
17838 (define_insn "frndintxf2_mask_pm_i387"
17839   [(set (match_operand:XF 0 "register_operand" "=f")
17840         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17841          UNSPEC_FRNDINT_MASK_PM))
17842    (use (match_operand:HI 2 "memory_operand" "m"))
17843    (use (match_operand:HI 3 "memory_operand" "m"))]
17844   "TARGET_USE_FANCY_MATH_387
17845    && flag_unsafe_math_optimizations"
17846   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17847   [(set_attr "type" "frndint")
17848    (set_attr "i387_cw" "mask_pm")
17849    (set_attr "mode" "XF")])
17850
17851 (define_expand "nearbyintxf2"
17852   [(use (match_operand:XF 0 "register_operand" ""))
17853    (use (match_operand:XF 1 "register_operand" ""))]
17854   "TARGET_USE_FANCY_MATH_387
17855    && flag_unsafe_math_optimizations"
17856 {
17857   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17858
17859   DONE;
17860 })
17861
17862 (define_expand "nearbyintdf2"
17863   [(use (match_operand:DF 0 "register_operand" ""))
17864    (use (match_operand:DF 1 "register_operand" ""))]
17865   "TARGET_USE_FANCY_MATH_387
17866    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17867    && flag_unsafe_math_optimizations"
17868 {
17869   rtx op0 = gen_reg_rtx (XFmode);
17870   rtx op1 = gen_reg_rtx (XFmode);
17871
17872   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17873   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17874
17875   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17876   DONE;
17877 })
17878
17879 (define_expand "nearbyintsf2"
17880   [(use (match_operand:SF 0 "register_operand" ""))
17881    (use (match_operand:SF 1 "register_operand" ""))]
17882   "TARGET_USE_FANCY_MATH_387
17883    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17884    && flag_unsafe_math_optimizations"
17885 {
17886   rtx op0 = gen_reg_rtx (XFmode);
17887   rtx op1 = gen_reg_rtx (XFmode);
17888
17889   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17890   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17891
17892   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17893   DONE;
17894 })
17895
17896 (define_insn "fxam<mode>2_i387"
17897   [(set (match_operand:HI 0 "register_operand" "=a")
17898         (unspec:HI
17899           [(match_operand:X87MODEF 1 "register_operand" "f")]
17900           UNSPEC_FXAM))]
17901   "TARGET_USE_FANCY_MATH_387"
17902   "fxam\n\tfnstsw\t%0"
17903   [(set_attr "type" "multi")
17904    (set_attr "unit" "i387")
17905    (set_attr "mode" "<MODE>")])
17906
17907 (define_expand "isinf<mode>2"
17908   [(use (match_operand:SI 0 "register_operand" ""))
17909    (use (match_operand:X87MODEF 1 "register_operand" ""))]
17910   "TARGET_USE_FANCY_MATH_387
17911    && TARGET_C99_FUNCTIONS
17912    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17913        || TARGET_MIX_SSE_I387)"
17914 {
17915   rtx mask = GEN_INT (0x45);
17916   rtx val = GEN_INT (0x05);
17917
17918   rtx cond;
17919
17920   rtx scratch = gen_reg_rtx (HImode);
17921   rtx res = gen_reg_rtx (QImode);
17922
17923   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17924   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17925   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17926   cond = gen_rtx_fmt_ee (EQ, QImode,
17927                          gen_rtx_REG (CCmode, FLAGS_REG),
17928                          const0_rtx);
17929   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17930   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17931   DONE;
17932 })
17933
17934 \f
17935 ;; Block operation instructions
17936
17937 (define_expand "movmemsi"
17938   [(use (match_operand:BLK 0 "memory_operand" ""))
17939    (use (match_operand:BLK 1 "memory_operand" ""))
17940    (use (match_operand:SI 2 "nonmemory_operand" ""))
17941    (use (match_operand:SI 3 "const_int_operand" ""))
17942    (use (match_operand:SI 4 "const_int_operand" ""))
17943    (use (match_operand:SI 5 "const_int_operand" ""))]
17944   ""
17945 {
17946  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17947                          operands[4], operands[5]))
17948    DONE;
17949  else
17950    FAIL;
17951 })
17952
17953 (define_expand "movmemdi"
17954   [(use (match_operand:BLK 0 "memory_operand" ""))
17955    (use (match_operand:BLK 1 "memory_operand" ""))
17956    (use (match_operand:DI 2 "nonmemory_operand" ""))
17957    (use (match_operand:DI 3 "const_int_operand" ""))
17958    (use (match_operand:SI 4 "const_int_operand" ""))
17959    (use (match_operand:SI 5 "const_int_operand" ""))]
17960   "TARGET_64BIT"
17961 {
17962  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17963                          operands[4], operands[5]))
17964    DONE;
17965  else
17966    FAIL;
17967 })
17968
17969 ;; Most CPUs don't like single string operations
17970 ;; Handle this case here to simplify previous expander.
17971
17972 (define_expand "strmov"
17973   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17974    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17975    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17976               (clobber (reg:CC FLAGS_REG))])
17977    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17978               (clobber (reg:CC FLAGS_REG))])]
17979   ""
17980 {
17981   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17982
17983   /* If .md ever supports :P for Pmode, these can be directly
17984      in the pattern above.  */
17985   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17986   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17987
17988   if (TARGET_SINGLE_STRINGOP || optimize_size)
17989     {
17990       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17991                                       operands[2], operands[3],
17992                                       operands[5], operands[6]));
17993       DONE;
17994     }
17995
17996   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17997 })
17998
17999 (define_expand "strmov_singleop"
18000   [(parallel [(set (match_operand 1 "memory_operand" "")
18001                    (match_operand 3 "memory_operand" ""))
18002               (set (match_operand 0 "register_operand" "")
18003                    (match_operand 4 "" ""))
18004               (set (match_operand 2 "register_operand" "")
18005                    (match_operand 5 "" ""))])]
18006   "TARGET_SINGLE_STRINGOP || optimize_size"
18007   "")
18008
18009 (define_insn "*strmovdi_rex_1"
18010   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18011         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18012    (set (match_operand:DI 0 "register_operand" "=D")
18013         (plus:DI (match_dup 2)
18014                  (const_int 8)))
18015    (set (match_operand:DI 1 "register_operand" "=S")
18016         (plus:DI (match_dup 3)
18017                  (const_int 8)))]
18018   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18019   "movsq"
18020   [(set_attr "type" "str")
18021    (set_attr "mode" "DI")
18022    (set_attr "memory" "both")])
18023
18024 (define_insn "*strmovsi_1"
18025   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18026         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18027    (set (match_operand:SI 0 "register_operand" "=D")
18028         (plus:SI (match_dup 2)
18029                  (const_int 4)))
18030    (set (match_operand:SI 1 "register_operand" "=S")
18031         (plus:SI (match_dup 3)
18032                  (const_int 4)))]
18033   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18034   "{movsl|movsd}"
18035   [(set_attr "type" "str")
18036    (set_attr "mode" "SI")
18037    (set_attr "memory" "both")])
18038
18039 (define_insn "*strmovsi_rex_1"
18040   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18041         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18042    (set (match_operand:DI 0 "register_operand" "=D")
18043         (plus:DI (match_dup 2)
18044                  (const_int 4)))
18045    (set (match_operand:DI 1 "register_operand" "=S")
18046         (plus:DI (match_dup 3)
18047                  (const_int 4)))]
18048   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18049   "{movsl|movsd}"
18050   [(set_attr "type" "str")
18051    (set_attr "mode" "SI")
18052    (set_attr "memory" "both")])
18053
18054 (define_insn "*strmovhi_1"
18055   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18056         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18057    (set (match_operand:SI 0 "register_operand" "=D")
18058         (plus:SI (match_dup 2)
18059                  (const_int 2)))
18060    (set (match_operand:SI 1 "register_operand" "=S")
18061         (plus:SI (match_dup 3)
18062                  (const_int 2)))]
18063   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18064   "movsw"
18065   [(set_attr "type" "str")
18066    (set_attr "memory" "both")
18067    (set_attr "mode" "HI")])
18068
18069 (define_insn "*strmovhi_rex_1"
18070   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18071         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18072    (set (match_operand:DI 0 "register_operand" "=D")
18073         (plus:DI (match_dup 2)
18074                  (const_int 2)))
18075    (set (match_operand:DI 1 "register_operand" "=S")
18076         (plus:DI (match_dup 3)
18077                  (const_int 2)))]
18078   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18079   "movsw"
18080   [(set_attr "type" "str")
18081    (set_attr "memory" "both")
18082    (set_attr "mode" "HI")])
18083
18084 (define_insn "*strmovqi_1"
18085   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18086         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18087    (set (match_operand:SI 0 "register_operand" "=D")
18088         (plus:SI (match_dup 2)
18089                  (const_int 1)))
18090    (set (match_operand:SI 1 "register_operand" "=S")
18091         (plus:SI (match_dup 3)
18092                  (const_int 1)))]
18093   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18094   "movsb"
18095   [(set_attr "type" "str")
18096    (set_attr "memory" "both")
18097    (set_attr "mode" "QI")])
18098
18099 (define_insn "*strmovqi_rex_1"
18100   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18101         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18102    (set (match_operand:DI 0 "register_operand" "=D")
18103         (plus:DI (match_dup 2)
18104                  (const_int 1)))
18105    (set (match_operand:DI 1 "register_operand" "=S")
18106         (plus:DI (match_dup 3)
18107                  (const_int 1)))]
18108   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18109   "movsb"
18110   [(set_attr "type" "str")
18111    (set_attr "memory" "both")
18112    (set_attr "mode" "QI")])
18113
18114 (define_expand "rep_mov"
18115   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18116               (set (match_operand 0 "register_operand" "")
18117                    (match_operand 5 "" ""))
18118               (set (match_operand 2 "register_operand" "")
18119                    (match_operand 6 "" ""))
18120               (set (match_operand 1 "memory_operand" "")
18121                    (match_operand 3 "memory_operand" ""))
18122               (use (match_dup 4))])]
18123   ""
18124   "")
18125
18126 (define_insn "*rep_movdi_rex64"
18127   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18128    (set (match_operand:DI 0 "register_operand" "=D")
18129         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18130                             (const_int 3))
18131                  (match_operand:DI 3 "register_operand" "0")))
18132    (set (match_operand:DI 1 "register_operand" "=S")
18133         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18134                  (match_operand:DI 4 "register_operand" "1")))
18135    (set (mem:BLK (match_dup 3))
18136         (mem:BLK (match_dup 4)))
18137    (use (match_dup 5))]
18138   "TARGET_64BIT"
18139   "{rep\;movsq|rep movsq}"
18140   [(set_attr "type" "str")
18141    (set_attr "prefix_rep" "1")
18142    (set_attr "memory" "both")
18143    (set_attr "mode" "DI")])
18144
18145 (define_insn "*rep_movsi"
18146   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18147    (set (match_operand:SI 0 "register_operand" "=D")
18148         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18149                             (const_int 2))
18150                  (match_operand:SI 3 "register_operand" "0")))
18151    (set (match_operand:SI 1 "register_operand" "=S")
18152         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18153                  (match_operand:SI 4 "register_operand" "1")))
18154    (set (mem:BLK (match_dup 3))
18155         (mem:BLK (match_dup 4)))
18156    (use (match_dup 5))]
18157   "!TARGET_64BIT"
18158   "{rep\;movsl|rep movsd}"
18159   [(set_attr "type" "str")
18160    (set_attr "prefix_rep" "1")
18161    (set_attr "memory" "both")
18162    (set_attr "mode" "SI")])
18163
18164 (define_insn "*rep_movsi_rex64"
18165   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18166    (set (match_operand:DI 0 "register_operand" "=D")
18167         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18168                             (const_int 2))
18169                  (match_operand:DI 3 "register_operand" "0")))
18170    (set (match_operand:DI 1 "register_operand" "=S")
18171         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18172                  (match_operand:DI 4 "register_operand" "1")))
18173    (set (mem:BLK (match_dup 3))
18174         (mem:BLK (match_dup 4)))
18175    (use (match_dup 5))]
18176   "TARGET_64BIT"
18177   "{rep\;movsl|rep movsd}"
18178   [(set_attr "type" "str")
18179    (set_attr "prefix_rep" "1")
18180    (set_attr "memory" "both")
18181    (set_attr "mode" "SI")])
18182
18183 (define_insn "*rep_movqi"
18184   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18185    (set (match_operand:SI 0 "register_operand" "=D")
18186         (plus:SI (match_operand:SI 3 "register_operand" "0")
18187                  (match_operand:SI 5 "register_operand" "2")))
18188    (set (match_operand:SI 1 "register_operand" "=S")
18189         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18190    (set (mem:BLK (match_dup 3))
18191         (mem:BLK (match_dup 4)))
18192    (use (match_dup 5))]
18193   "!TARGET_64BIT"
18194   "{rep\;movsb|rep movsb}"
18195   [(set_attr "type" "str")
18196    (set_attr "prefix_rep" "1")
18197    (set_attr "memory" "both")
18198    (set_attr "mode" "SI")])
18199
18200 (define_insn "*rep_movqi_rex64"
18201   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18202    (set (match_operand:DI 0 "register_operand" "=D")
18203         (plus:DI (match_operand:DI 3 "register_operand" "0")
18204                  (match_operand:DI 5 "register_operand" "2")))
18205    (set (match_operand:DI 1 "register_operand" "=S")
18206         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18207    (set (mem:BLK (match_dup 3))
18208         (mem:BLK (match_dup 4)))
18209    (use (match_dup 5))]
18210   "TARGET_64BIT"
18211   "{rep\;movsb|rep movsb}"
18212   [(set_attr "type" "str")
18213    (set_attr "prefix_rep" "1")
18214    (set_attr "memory" "both")
18215    (set_attr "mode" "SI")])
18216
18217 (define_expand "setmemsi"
18218    [(use (match_operand:BLK 0 "memory_operand" ""))
18219     (use (match_operand:SI 1 "nonmemory_operand" ""))
18220     (use (match_operand 2 "const_int_operand" ""))
18221     (use (match_operand 3 "const_int_operand" ""))
18222     (use (match_operand:SI 4 "const_int_operand" ""))
18223     (use (match_operand:SI 5 "const_int_operand" ""))]
18224   ""
18225 {
18226  if (ix86_expand_setmem (operands[0], operands[1],
18227                          operands[2], operands[3],
18228                          operands[4], operands[5]))
18229    DONE;
18230  else
18231    FAIL;
18232 })
18233
18234 (define_expand "setmemdi"
18235    [(use (match_operand:BLK 0 "memory_operand" ""))
18236     (use (match_operand:DI 1 "nonmemory_operand" ""))
18237     (use (match_operand 2 "const_int_operand" ""))
18238     (use (match_operand 3 "const_int_operand" ""))
18239     (use (match_operand 4 "const_int_operand" ""))
18240     (use (match_operand 5 "const_int_operand" ""))]
18241   "TARGET_64BIT"
18242 {
18243  if (ix86_expand_setmem (operands[0], operands[1],
18244                          operands[2], operands[3],
18245                          operands[4], operands[5]))
18246    DONE;
18247  else
18248    FAIL;
18249 })
18250
18251 ;; Most CPUs don't like single string operations
18252 ;; Handle this case here to simplify previous expander.
18253
18254 (define_expand "strset"
18255   [(set (match_operand 1 "memory_operand" "")
18256         (match_operand 2 "register_operand" ""))
18257    (parallel [(set (match_operand 0 "register_operand" "")
18258                    (match_dup 3))
18259               (clobber (reg:CC FLAGS_REG))])]
18260   ""
18261 {
18262   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18263     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18264
18265   /* If .md ever supports :P for Pmode, this can be directly
18266      in the pattern above.  */
18267   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18268                               GEN_INT (GET_MODE_SIZE (GET_MODE
18269                                                       (operands[2]))));
18270   if (TARGET_SINGLE_STRINGOP || optimize_size)
18271     {
18272       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18273                                       operands[3]));
18274       DONE;
18275     }
18276 })
18277
18278 (define_expand "strset_singleop"
18279   [(parallel [(set (match_operand 1 "memory_operand" "")
18280                    (match_operand 2 "register_operand" ""))
18281               (set (match_operand 0 "register_operand" "")
18282                    (match_operand 3 "" ""))])]
18283   "TARGET_SINGLE_STRINGOP || optimize_size"
18284   "")
18285
18286 (define_insn "*strsetdi_rex_1"
18287   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18288         (match_operand:DI 2 "register_operand" "a"))
18289    (set (match_operand:DI 0 "register_operand" "=D")
18290         (plus:DI (match_dup 1)
18291                  (const_int 8)))]
18292   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18293   "stosq"
18294   [(set_attr "type" "str")
18295    (set_attr "memory" "store")
18296    (set_attr "mode" "DI")])
18297
18298 (define_insn "*strsetsi_1"
18299   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18300         (match_operand:SI 2 "register_operand" "a"))
18301    (set (match_operand:SI 0 "register_operand" "=D")
18302         (plus:SI (match_dup 1)
18303                  (const_int 4)))]
18304   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18305   "{stosl|stosd}"
18306   [(set_attr "type" "str")
18307    (set_attr "memory" "store")
18308    (set_attr "mode" "SI")])
18309
18310 (define_insn "*strsetsi_rex_1"
18311   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18312         (match_operand:SI 2 "register_operand" "a"))
18313    (set (match_operand:DI 0 "register_operand" "=D")
18314         (plus:DI (match_dup 1)
18315                  (const_int 4)))]
18316   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18317   "{stosl|stosd}"
18318   [(set_attr "type" "str")
18319    (set_attr "memory" "store")
18320    (set_attr "mode" "SI")])
18321
18322 (define_insn "*strsethi_1"
18323   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18324         (match_operand:HI 2 "register_operand" "a"))
18325    (set (match_operand:SI 0 "register_operand" "=D")
18326         (plus:SI (match_dup 1)
18327                  (const_int 2)))]
18328   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18329   "stosw"
18330   [(set_attr "type" "str")
18331    (set_attr "memory" "store")
18332    (set_attr "mode" "HI")])
18333
18334 (define_insn "*strsethi_rex_1"
18335   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18336         (match_operand:HI 2 "register_operand" "a"))
18337    (set (match_operand:DI 0 "register_operand" "=D")
18338         (plus:DI (match_dup 1)
18339                  (const_int 2)))]
18340   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18341   "stosw"
18342   [(set_attr "type" "str")
18343    (set_attr "memory" "store")
18344    (set_attr "mode" "HI")])
18345
18346 (define_insn "*strsetqi_1"
18347   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18348         (match_operand:QI 2 "register_operand" "a"))
18349    (set (match_operand:SI 0 "register_operand" "=D")
18350         (plus:SI (match_dup 1)
18351                  (const_int 1)))]
18352   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18353   "stosb"
18354   [(set_attr "type" "str")
18355    (set_attr "memory" "store")
18356    (set_attr "mode" "QI")])
18357
18358 (define_insn "*strsetqi_rex_1"
18359   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18360         (match_operand:QI 2 "register_operand" "a"))
18361    (set (match_operand:DI 0 "register_operand" "=D")
18362         (plus:DI (match_dup 1)
18363                  (const_int 1)))]
18364   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18365   "stosb"
18366   [(set_attr "type" "str")
18367    (set_attr "memory" "store")
18368    (set_attr "mode" "QI")])
18369
18370 (define_expand "rep_stos"
18371   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18372               (set (match_operand 0 "register_operand" "")
18373                    (match_operand 4 "" ""))
18374               (set (match_operand 2 "memory_operand" "") (const_int 0))
18375               (use (match_operand 3 "register_operand" ""))
18376               (use (match_dup 1))])]
18377   ""
18378   "")
18379
18380 (define_insn "*rep_stosdi_rex64"
18381   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18382    (set (match_operand:DI 0 "register_operand" "=D")
18383         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18384                             (const_int 3))
18385                  (match_operand:DI 3 "register_operand" "0")))
18386    (set (mem:BLK (match_dup 3))
18387         (const_int 0))
18388    (use (match_operand:DI 2 "register_operand" "a"))
18389    (use (match_dup 4))]
18390   "TARGET_64BIT"
18391   "{rep\;stosq|rep stosq}"
18392   [(set_attr "type" "str")
18393    (set_attr "prefix_rep" "1")
18394    (set_attr "memory" "store")
18395    (set_attr "mode" "DI")])
18396
18397 (define_insn "*rep_stossi"
18398   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18399    (set (match_operand:SI 0 "register_operand" "=D")
18400         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18401                             (const_int 2))
18402                  (match_operand:SI 3 "register_operand" "0")))
18403    (set (mem:BLK (match_dup 3))
18404         (const_int 0))
18405    (use (match_operand:SI 2 "register_operand" "a"))
18406    (use (match_dup 4))]
18407   "!TARGET_64BIT"
18408   "{rep\;stosl|rep stosd}"
18409   [(set_attr "type" "str")
18410    (set_attr "prefix_rep" "1")
18411    (set_attr "memory" "store")
18412    (set_attr "mode" "SI")])
18413
18414 (define_insn "*rep_stossi_rex64"
18415   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18416    (set (match_operand:DI 0 "register_operand" "=D")
18417         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18418                             (const_int 2))
18419                  (match_operand:DI 3 "register_operand" "0")))
18420    (set (mem:BLK (match_dup 3))
18421         (const_int 0))
18422    (use (match_operand:SI 2 "register_operand" "a"))
18423    (use (match_dup 4))]
18424   "TARGET_64BIT"
18425   "{rep\;stosl|rep stosd}"
18426   [(set_attr "type" "str")
18427    (set_attr "prefix_rep" "1")
18428    (set_attr "memory" "store")
18429    (set_attr "mode" "SI")])
18430
18431 (define_insn "*rep_stosqi"
18432   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18433    (set (match_operand:SI 0 "register_operand" "=D")
18434         (plus:SI (match_operand:SI 3 "register_operand" "0")
18435                  (match_operand:SI 4 "register_operand" "1")))
18436    (set (mem:BLK (match_dup 3))
18437         (const_int 0))
18438    (use (match_operand:QI 2 "register_operand" "a"))
18439    (use (match_dup 4))]
18440   "!TARGET_64BIT"
18441   "{rep\;stosb|rep stosb}"
18442   [(set_attr "type" "str")
18443    (set_attr "prefix_rep" "1")
18444    (set_attr "memory" "store")
18445    (set_attr "mode" "QI")])
18446
18447 (define_insn "*rep_stosqi_rex64"
18448   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18449    (set (match_operand:DI 0 "register_operand" "=D")
18450         (plus:DI (match_operand:DI 3 "register_operand" "0")
18451                  (match_operand:DI 4 "register_operand" "1")))
18452    (set (mem:BLK (match_dup 3))
18453         (const_int 0))
18454    (use (match_operand:QI 2 "register_operand" "a"))
18455    (use (match_dup 4))]
18456   "TARGET_64BIT"
18457   "{rep\;stosb|rep stosb}"
18458   [(set_attr "type" "str")
18459    (set_attr "prefix_rep" "1")
18460    (set_attr "memory" "store")
18461    (set_attr "mode" "QI")])
18462
18463 (define_expand "cmpstrnsi"
18464   [(set (match_operand:SI 0 "register_operand" "")
18465         (compare:SI (match_operand:BLK 1 "general_operand" "")
18466                     (match_operand:BLK 2 "general_operand" "")))
18467    (use (match_operand 3 "general_operand" ""))
18468    (use (match_operand 4 "immediate_operand" ""))]
18469   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18470 {
18471   rtx addr1, addr2, out, outlow, count, countreg, align;
18472
18473   /* Can't use this if the user has appropriated esi or edi.  */
18474   if (global_regs[4] || global_regs[5])
18475     FAIL;
18476
18477   out = operands[0];
18478   if (!REG_P (out))
18479     out = gen_reg_rtx (SImode);
18480
18481   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18482   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18483   if (addr1 != XEXP (operands[1], 0))
18484     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18485   if (addr2 != XEXP (operands[2], 0))
18486     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18487
18488   count = operands[3];
18489   countreg = ix86_zero_extend_to_Pmode (count);
18490
18491   /* %%% Iff we are testing strict equality, we can use known alignment
18492      to good advantage.  This may be possible with combine, particularly
18493      once cc0 is dead.  */
18494   align = operands[4];
18495
18496   if (CONST_INT_P (count))
18497     {
18498       if (INTVAL (count) == 0)
18499         {
18500           emit_move_insn (operands[0], const0_rtx);
18501           DONE;
18502         }
18503       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18504                                      operands[1], operands[2]));
18505     }
18506   else
18507     {
18508       if (TARGET_64BIT)
18509         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18510       else
18511         emit_insn (gen_cmpsi_1 (countreg, countreg));
18512       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18513                                   operands[1], operands[2]));
18514     }
18515
18516   outlow = gen_lowpart (QImode, out);
18517   emit_insn (gen_cmpintqi (outlow));
18518   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18519
18520   if (operands[0] != out)
18521     emit_move_insn (operands[0], out);
18522
18523   DONE;
18524 })
18525
18526 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18527
18528 (define_expand "cmpintqi"
18529   [(set (match_dup 1)
18530         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18531    (set (match_dup 2)
18532         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18533    (parallel [(set (match_operand:QI 0 "register_operand" "")
18534                    (minus:QI (match_dup 1)
18535                              (match_dup 2)))
18536               (clobber (reg:CC FLAGS_REG))])]
18537   ""
18538   "operands[1] = gen_reg_rtx (QImode);
18539    operands[2] = gen_reg_rtx (QImode);")
18540
18541 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18542 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18543
18544 (define_expand "cmpstrnqi_nz_1"
18545   [(parallel [(set (reg:CC FLAGS_REG)
18546                    (compare:CC (match_operand 4 "memory_operand" "")
18547                                (match_operand 5 "memory_operand" "")))
18548               (use (match_operand 2 "register_operand" ""))
18549               (use (match_operand:SI 3 "immediate_operand" ""))
18550               (clobber (match_operand 0 "register_operand" ""))
18551               (clobber (match_operand 1 "register_operand" ""))
18552               (clobber (match_dup 2))])]
18553   ""
18554   "")
18555
18556 (define_insn "*cmpstrnqi_nz_1"
18557   [(set (reg:CC FLAGS_REG)
18558         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18559                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18560    (use (match_operand:SI 6 "register_operand" "2"))
18561    (use (match_operand:SI 3 "immediate_operand" "i"))
18562    (clobber (match_operand:SI 0 "register_operand" "=S"))
18563    (clobber (match_operand:SI 1 "register_operand" "=D"))
18564    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18565   "!TARGET_64BIT"
18566   "repz{\;| }cmpsb"
18567   [(set_attr "type" "str")
18568    (set_attr "mode" "QI")
18569    (set_attr "prefix_rep" "1")])
18570
18571 (define_insn "*cmpstrnqi_nz_rex_1"
18572   [(set (reg:CC FLAGS_REG)
18573         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18574                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18575    (use (match_operand:DI 6 "register_operand" "2"))
18576    (use (match_operand:SI 3 "immediate_operand" "i"))
18577    (clobber (match_operand:DI 0 "register_operand" "=S"))
18578    (clobber (match_operand:DI 1 "register_operand" "=D"))
18579    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18580   "TARGET_64BIT"
18581   "repz{\;| }cmpsb"
18582   [(set_attr "type" "str")
18583    (set_attr "mode" "QI")
18584    (set_attr "prefix_rep" "1")])
18585
18586 ;; The same, but the count is not known to not be zero.
18587
18588 (define_expand "cmpstrnqi_1"
18589   [(parallel [(set (reg:CC FLAGS_REG)
18590                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18591                                      (const_int 0))
18592                   (compare:CC (match_operand 4 "memory_operand" "")
18593                               (match_operand 5 "memory_operand" ""))
18594                   (const_int 0)))
18595               (use (match_operand:SI 3 "immediate_operand" ""))
18596               (use (reg:CC FLAGS_REG))
18597               (clobber (match_operand 0 "register_operand" ""))
18598               (clobber (match_operand 1 "register_operand" ""))
18599               (clobber (match_dup 2))])]
18600   ""
18601   "")
18602
18603 (define_insn "*cmpstrnqi_1"
18604   [(set (reg:CC FLAGS_REG)
18605         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18606                              (const_int 0))
18607           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18608                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18609           (const_int 0)))
18610    (use (match_operand:SI 3 "immediate_operand" "i"))
18611    (use (reg:CC FLAGS_REG))
18612    (clobber (match_operand:SI 0 "register_operand" "=S"))
18613    (clobber (match_operand:SI 1 "register_operand" "=D"))
18614    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18615   "!TARGET_64BIT"
18616   "repz{\;| }cmpsb"
18617   [(set_attr "type" "str")
18618    (set_attr "mode" "QI")
18619    (set_attr "prefix_rep" "1")])
18620
18621 (define_insn "*cmpstrnqi_rex_1"
18622   [(set (reg:CC FLAGS_REG)
18623         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18624                              (const_int 0))
18625           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18626                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18627           (const_int 0)))
18628    (use (match_operand:SI 3 "immediate_operand" "i"))
18629    (use (reg:CC FLAGS_REG))
18630    (clobber (match_operand:DI 0 "register_operand" "=S"))
18631    (clobber (match_operand:DI 1 "register_operand" "=D"))
18632    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18633   "TARGET_64BIT"
18634   "repz{\;| }cmpsb"
18635   [(set_attr "type" "str")
18636    (set_attr "mode" "QI")
18637    (set_attr "prefix_rep" "1")])
18638
18639 (define_expand "strlensi"
18640   [(set (match_operand:SI 0 "register_operand" "")
18641         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18642                     (match_operand:QI 2 "immediate_operand" "")
18643                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18644   ""
18645 {
18646  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18647    DONE;
18648  else
18649    FAIL;
18650 })
18651
18652 (define_expand "strlendi"
18653   [(set (match_operand:DI 0 "register_operand" "")
18654         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18655                     (match_operand:QI 2 "immediate_operand" "")
18656                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18657   ""
18658 {
18659  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18660    DONE;
18661  else
18662    FAIL;
18663 })
18664
18665 (define_expand "strlenqi_1"
18666   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18667               (clobber (match_operand 1 "register_operand" ""))
18668               (clobber (reg:CC FLAGS_REG))])]
18669   ""
18670   "")
18671
18672 (define_insn "*strlenqi_1"
18673   [(set (match_operand:SI 0 "register_operand" "=&c")
18674         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18675                     (match_operand:QI 2 "register_operand" "a")
18676                     (match_operand:SI 3 "immediate_operand" "i")
18677                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18678    (clobber (match_operand:SI 1 "register_operand" "=D"))
18679    (clobber (reg:CC FLAGS_REG))]
18680   "!TARGET_64BIT"
18681   "repnz{\;| }scasb"
18682   [(set_attr "type" "str")
18683    (set_attr "mode" "QI")
18684    (set_attr "prefix_rep" "1")])
18685
18686 (define_insn "*strlenqi_rex_1"
18687   [(set (match_operand:DI 0 "register_operand" "=&c")
18688         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18689                     (match_operand:QI 2 "register_operand" "a")
18690                     (match_operand:DI 3 "immediate_operand" "i")
18691                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18692    (clobber (match_operand:DI 1 "register_operand" "=D"))
18693    (clobber (reg:CC FLAGS_REG))]
18694   "TARGET_64BIT"
18695   "repnz{\;| }scasb"
18696   [(set_attr "type" "str")
18697    (set_attr "mode" "QI")
18698    (set_attr "prefix_rep" "1")])
18699
18700 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18701 ;; handled in combine, but it is not currently up to the task.
18702 ;; When used for their truth value, the cmpstrn* expanders generate
18703 ;; code like this:
18704 ;;
18705 ;;   repz cmpsb
18706 ;;   seta       %al
18707 ;;   setb       %dl
18708 ;;   cmpb       %al, %dl
18709 ;;   jcc        label
18710 ;;
18711 ;; The intermediate three instructions are unnecessary.
18712
18713 ;; This one handles cmpstrn*_nz_1...
18714 (define_peephole2
18715   [(parallel[
18716      (set (reg:CC FLAGS_REG)
18717           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18718                       (mem:BLK (match_operand 5 "register_operand" ""))))
18719      (use (match_operand 6 "register_operand" ""))
18720      (use (match_operand:SI 3 "immediate_operand" ""))
18721      (clobber (match_operand 0 "register_operand" ""))
18722      (clobber (match_operand 1 "register_operand" ""))
18723      (clobber (match_operand 2 "register_operand" ""))])
18724    (set (match_operand:QI 7 "register_operand" "")
18725         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18726    (set (match_operand:QI 8 "register_operand" "")
18727         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18728    (set (reg FLAGS_REG)
18729         (compare (match_dup 7) (match_dup 8)))
18730   ]
18731   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18732   [(parallel[
18733      (set (reg:CC FLAGS_REG)
18734           (compare:CC (mem:BLK (match_dup 4))
18735                       (mem:BLK (match_dup 5))))
18736      (use (match_dup 6))
18737      (use (match_dup 3))
18738      (clobber (match_dup 0))
18739      (clobber (match_dup 1))
18740      (clobber (match_dup 2))])]
18741   "")
18742
18743 ;; ...and this one handles cmpstrn*_1.
18744 (define_peephole2
18745   [(parallel[
18746      (set (reg:CC FLAGS_REG)
18747           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18748                                (const_int 0))
18749             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18750                         (mem:BLK (match_operand 5 "register_operand" "")))
18751             (const_int 0)))
18752      (use (match_operand:SI 3 "immediate_operand" ""))
18753      (use (reg:CC FLAGS_REG))
18754      (clobber (match_operand 0 "register_operand" ""))
18755      (clobber (match_operand 1 "register_operand" ""))
18756      (clobber (match_operand 2 "register_operand" ""))])
18757    (set (match_operand:QI 7 "register_operand" "")
18758         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18759    (set (match_operand:QI 8 "register_operand" "")
18760         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18761    (set (reg FLAGS_REG)
18762         (compare (match_dup 7) (match_dup 8)))
18763   ]
18764   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18765   [(parallel[
18766      (set (reg:CC FLAGS_REG)
18767           (if_then_else:CC (ne (match_dup 6)
18768                                (const_int 0))
18769             (compare:CC (mem:BLK (match_dup 4))
18770                         (mem:BLK (match_dup 5)))
18771             (const_int 0)))
18772      (use (match_dup 3))
18773      (use (reg:CC FLAGS_REG))
18774      (clobber (match_dup 0))
18775      (clobber (match_dup 1))
18776      (clobber (match_dup 2))])]
18777   "")
18778
18779
18780 \f
18781 ;; Conditional move instructions.
18782
18783 (define_expand "movdicc"
18784   [(set (match_operand:DI 0 "register_operand" "")
18785         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18786                          (match_operand:DI 2 "general_operand" "")
18787                          (match_operand:DI 3 "general_operand" "")))]
18788   "TARGET_64BIT"
18789   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18790
18791 (define_insn "x86_movdicc_0_m1_rex64"
18792   [(set (match_operand:DI 0 "register_operand" "=r")
18793         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18794           (const_int -1)
18795           (const_int 0)))
18796    (clobber (reg:CC FLAGS_REG))]
18797   "TARGET_64BIT"
18798   "sbb{q}\t%0, %0"
18799   ; Since we don't have the proper number of operands for an alu insn,
18800   ; fill in all the blanks.
18801   [(set_attr "type" "alu")
18802    (set_attr "pent_pair" "pu")
18803    (set_attr "memory" "none")
18804    (set_attr "imm_disp" "false")
18805    (set_attr "mode" "DI")
18806    (set_attr "length_immediate" "0")])
18807
18808 (define_insn "*movdicc_c_rex64"
18809   [(set (match_operand:DI 0 "register_operand" "=r,r")
18810         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18811                                 [(reg FLAGS_REG) (const_int 0)])
18812                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18813                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18814   "TARGET_64BIT && TARGET_CMOVE
18815    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18816   "@
18817    cmov%O2%C1\t{%2, %0|%0, %2}
18818    cmov%O2%c1\t{%3, %0|%0, %3}"
18819   [(set_attr "type" "icmov")
18820    (set_attr "mode" "DI")])
18821
18822 (define_expand "movsicc"
18823   [(set (match_operand:SI 0 "register_operand" "")
18824         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18825                          (match_operand:SI 2 "general_operand" "")
18826                          (match_operand:SI 3 "general_operand" "")))]
18827   ""
18828   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18829
18830 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18831 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18832 ;; So just document what we're doing explicitly.
18833
18834 (define_insn "x86_movsicc_0_m1"
18835   [(set (match_operand:SI 0 "register_operand" "=r")
18836         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18837           (const_int -1)
18838           (const_int 0)))
18839    (clobber (reg:CC FLAGS_REG))]
18840   ""
18841   "sbb{l}\t%0, %0"
18842   ; Since we don't have the proper number of operands for an alu insn,
18843   ; fill in all the blanks.
18844   [(set_attr "type" "alu")
18845    (set_attr "pent_pair" "pu")
18846    (set_attr "memory" "none")
18847    (set_attr "imm_disp" "false")
18848    (set_attr "mode" "SI")
18849    (set_attr "length_immediate" "0")])
18850
18851 (define_insn "*movsicc_noc"
18852   [(set (match_operand:SI 0 "register_operand" "=r,r")
18853         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18854                                 [(reg FLAGS_REG) (const_int 0)])
18855                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18856                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18857   "TARGET_CMOVE
18858    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18859   "@
18860    cmov%O2%C1\t{%2, %0|%0, %2}
18861    cmov%O2%c1\t{%3, %0|%0, %3}"
18862   [(set_attr "type" "icmov")
18863    (set_attr "mode" "SI")])
18864
18865 (define_expand "movhicc"
18866   [(set (match_operand:HI 0 "register_operand" "")
18867         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18868                          (match_operand:HI 2 "general_operand" "")
18869                          (match_operand:HI 3 "general_operand" "")))]
18870   "TARGET_HIMODE_MATH"
18871   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18872
18873 (define_insn "*movhicc_noc"
18874   [(set (match_operand:HI 0 "register_operand" "=r,r")
18875         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18876                                 [(reg FLAGS_REG) (const_int 0)])
18877                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18878                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18879   "TARGET_CMOVE
18880    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18881   "@
18882    cmov%O2%C1\t{%2, %0|%0, %2}
18883    cmov%O2%c1\t{%3, %0|%0, %3}"
18884   [(set_attr "type" "icmov")
18885    (set_attr "mode" "HI")])
18886
18887 (define_expand "movqicc"
18888   [(set (match_operand:QI 0 "register_operand" "")
18889         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18890                          (match_operand:QI 2 "general_operand" "")
18891                          (match_operand:QI 3 "general_operand" "")))]
18892   "TARGET_QIMODE_MATH"
18893   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18894
18895 (define_insn_and_split "*movqicc_noc"
18896   [(set (match_operand:QI 0 "register_operand" "=r,r")
18897         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18898                                 [(match_operand 4 "flags_reg_operand" "")
18899                                  (const_int 0)])
18900                       (match_operand:QI 2 "register_operand" "r,0")
18901                       (match_operand:QI 3 "register_operand" "0,r")))]
18902   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18903   "#"
18904   "&& reload_completed"
18905   [(set (match_dup 0)
18906         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18907                       (match_dup 2)
18908                       (match_dup 3)))]
18909   "operands[0] = gen_lowpart (SImode, operands[0]);
18910    operands[2] = gen_lowpart (SImode, operands[2]);
18911    operands[3] = gen_lowpart (SImode, operands[3]);"
18912   [(set_attr "type" "icmov")
18913    (set_attr "mode" "SI")])
18914
18915 (define_expand "movsfcc"
18916   [(set (match_operand:SF 0 "register_operand" "")
18917         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18918                          (match_operand:SF 2 "register_operand" "")
18919                          (match_operand:SF 3 "register_operand" "")))]
18920   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18921   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18922
18923 (define_insn "*movsfcc_1_387"
18924   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18925         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18926                                 [(reg FLAGS_REG) (const_int 0)])
18927                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18928                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18929   "TARGET_80387 && TARGET_CMOVE
18930    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18931   "@
18932    fcmov%F1\t{%2, %0|%0, %2}
18933    fcmov%f1\t{%3, %0|%0, %3}
18934    cmov%O2%C1\t{%2, %0|%0, %2}
18935    cmov%O2%c1\t{%3, %0|%0, %3}"
18936   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18937    (set_attr "mode" "SF,SF,SI,SI")])
18938
18939 (define_expand "movdfcc"
18940   [(set (match_operand:DF 0 "register_operand" "")
18941         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18942                          (match_operand:DF 2 "register_operand" "")
18943                          (match_operand:DF 3 "register_operand" "")))]
18944   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18945   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18946
18947 (define_insn "*movdfcc_1"
18948   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18949         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18950                                 [(reg FLAGS_REG) (const_int 0)])
18951                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18952                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18953   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18954    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18955   "@
18956    fcmov%F1\t{%2, %0|%0, %2}
18957    fcmov%f1\t{%3, %0|%0, %3}
18958    #
18959    #"
18960   [(set_attr "type" "fcmov,fcmov,multi,multi")
18961    (set_attr "mode" "DF")])
18962
18963 (define_insn "*movdfcc_1_rex64"
18964   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18965         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18966                                 [(reg FLAGS_REG) (const_int 0)])
18967                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18968                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18969   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18970    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18971   "@
18972    fcmov%F1\t{%2, %0|%0, %2}
18973    fcmov%f1\t{%3, %0|%0, %3}
18974    cmov%O2%C1\t{%2, %0|%0, %2}
18975    cmov%O2%c1\t{%3, %0|%0, %3}"
18976   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18977    (set_attr "mode" "DF")])
18978
18979 (define_split
18980   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18981         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18982                                 [(match_operand 4 "flags_reg_operand" "")
18983                                  (const_int 0)])
18984                       (match_operand:DF 2 "nonimmediate_operand" "")
18985                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18986   "!TARGET_64BIT && reload_completed"
18987   [(set (match_dup 2)
18988         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18989                       (match_dup 5)
18990                       (match_dup 7)))
18991    (set (match_dup 3)
18992         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18993                       (match_dup 6)
18994                       (match_dup 8)))]
18995   "split_di (operands+2, 1, operands+5, operands+6);
18996    split_di (operands+3, 1, operands+7, operands+8);
18997    split_di (operands, 1, operands+2, operands+3);")
18998
18999 (define_expand "movxfcc"
19000   [(set (match_operand:XF 0 "register_operand" "")
19001         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19002                          (match_operand:XF 2 "register_operand" "")
19003                          (match_operand:XF 3 "register_operand" "")))]
19004   "TARGET_80387 && TARGET_CMOVE"
19005   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19006
19007 (define_insn "*movxfcc_1"
19008   [(set (match_operand:XF 0 "register_operand" "=f,f")
19009         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19010                                 [(reg FLAGS_REG) (const_int 0)])
19011                       (match_operand:XF 2 "register_operand" "f,0")
19012                       (match_operand:XF 3 "register_operand" "0,f")))]
19013   "TARGET_80387 && TARGET_CMOVE"
19014   "@
19015    fcmov%F1\t{%2, %0|%0, %2}
19016    fcmov%f1\t{%3, %0|%0, %3}"
19017   [(set_attr "type" "fcmov")
19018    (set_attr "mode" "XF")])
19019
19020 ;; These versions of the min/max patterns are intentionally ignorant of
19021 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19022 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19023 ;; are undefined in this condition, we're certain this is correct.
19024
19025 (define_insn "sminsf3"
19026   [(set (match_operand:SF 0 "register_operand" "=x")
19027         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19028                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19029   "TARGET_SSE_MATH"
19030   "minss\t{%2, %0|%0, %2}"
19031   [(set_attr "type" "sseadd")
19032    (set_attr "mode" "SF")])
19033
19034 (define_insn "smaxsf3"
19035   [(set (match_operand:SF 0 "register_operand" "=x")
19036         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19037                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19038   "TARGET_SSE_MATH"
19039   "maxss\t{%2, %0|%0, %2}"
19040   [(set_attr "type" "sseadd")
19041    (set_attr "mode" "SF")])
19042
19043 (define_insn "smindf3"
19044   [(set (match_operand:DF 0 "register_operand" "=x")
19045         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19046                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19047   "TARGET_SSE2 && TARGET_SSE_MATH"
19048   "minsd\t{%2, %0|%0, %2}"
19049   [(set_attr "type" "sseadd")
19050    (set_attr "mode" "DF")])
19051
19052 (define_insn "smaxdf3"
19053   [(set (match_operand:DF 0 "register_operand" "=x")
19054         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19055                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19056   "TARGET_SSE2 && TARGET_SSE_MATH"
19057   "maxsd\t{%2, %0|%0, %2}"
19058   [(set_attr "type" "sseadd")
19059    (set_attr "mode" "DF")])
19060
19061 ;; These versions of the min/max patterns implement exactly the operations
19062 ;;   min = (op1 < op2 ? op1 : op2)
19063 ;;   max = (!(op1 < op2) ? op1 : op2)
19064 ;; Their operands are not commutative, and thus they may be used in the
19065 ;; presence of -0.0 and NaN.
19066
19067 (define_insn "*ieee_sminsf3"
19068   [(set (match_operand:SF 0 "register_operand" "=x")
19069         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19070                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19071                    UNSPEC_IEEE_MIN))]
19072   "TARGET_SSE_MATH"
19073   "minss\t{%2, %0|%0, %2}"
19074   [(set_attr "type" "sseadd")
19075    (set_attr "mode" "SF")])
19076
19077 (define_insn "*ieee_smaxsf3"
19078   [(set (match_operand:SF 0 "register_operand" "=x")
19079         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19080                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19081                    UNSPEC_IEEE_MAX))]
19082   "TARGET_SSE_MATH"
19083   "maxss\t{%2, %0|%0, %2}"
19084   [(set_attr "type" "sseadd")
19085    (set_attr "mode" "SF")])
19086
19087 (define_insn "*ieee_smindf3"
19088   [(set (match_operand:DF 0 "register_operand" "=x")
19089         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19090                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19091                    UNSPEC_IEEE_MIN))]
19092   "TARGET_SSE2 && TARGET_SSE_MATH"
19093   "minsd\t{%2, %0|%0, %2}"
19094   [(set_attr "type" "sseadd")
19095    (set_attr "mode" "DF")])
19096
19097 (define_insn "*ieee_smaxdf3"
19098   [(set (match_operand:DF 0 "register_operand" "=x")
19099         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19100                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19101                    UNSPEC_IEEE_MAX))]
19102   "TARGET_SSE2 && TARGET_SSE_MATH"
19103   "maxsd\t{%2, %0|%0, %2}"
19104   [(set_attr "type" "sseadd")
19105    (set_attr "mode" "DF")])
19106
19107 ;; Make two stack loads independent:
19108 ;;   fld aa              fld aa
19109 ;;   fld %st(0)     ->   fld bb
19110 ;;   fmul bb             fmul %st(1), %st
19111 ;;
19112 ;; Actually we only match the last two instructions for simplicity.
19113 (define_peephole2
19114   [(set (match_operand 0 "fp_register_operand" "")
19115         (match_operand 1 "fp_register_operand" ""))
19116    (set (match_dup 0)
19117         (match_operator 2 "binary_fp_operator"
19118            [(match_dup 0)
19119             (match_operand 3 "memory_operand" "")]))]
19120   "REGNO (operands[0]) != REGNO (operands[1])"
19121   [(set (match_dup 0) (match_dup 3))
19122    (set (match_dup 0) (match_dup 4))]
19123
19124   ;; The % modifier is not operational anymore in peephole2's, so we have to
19125   ;; swap the operands manually in the case of addition and multiplication.
19126   "if (COMMUTATIVE_ARITH_P (operands[2]))
19127      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19128                                  operands[0], operands[1]);
19129    else
19130      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19131                                  operands[1], operands[0]);")
19132
19133 ;; Conditional addition patterns
19134 (define_expand "addqicc"
19135   [(match_operand:QI 0 "register_operand" "")
19136    (match_operand 1 "comparison_operator" "")
19137    (match_operand:QI 2 "register_operand" "")
19138    (match_operand:QI 3 "const_int_operand" "")]
19139   ""
19140   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19141
19142 (define_expand "addhicc"
19143   [(match_operand:HI 0 "register_operand" "")
19144    (match_operand 1 "comparison_operator" "")
19145    (match_operand:HI 2 "register_operand" "")
19146    (match_operand:HI 3 "const_int_operand" "")]
19147   ""
19148   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19149
19150 (define_expand "addsicc"
19151   [(match_operand:SI 0 "register_operand" "")
19152    (match_operand 1 "comparison_operator" "")
19153    (match_operand:SI 2 "register_operand" "")
19154    (match_operand:SI 3 "const_int_operand" "")]
19155   ""
19156   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19157
19158 (define_expand "adddicc"
19159   [(match_operand:DI 0 "register_operand" "")
19160    (match_operand 1 "comparison_operator" "")
19161    (match_operand:DI 2 "register_operand" "")
19162    (match_operand:DI 3 "const_int_operand" "")]
19163   "TARGET_64BIT"
19164   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19165
19166 \f
19167 ;; Misc patterns (?)
19168
19169 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19170 ;; Otherwise there will be nothing to keep
19171 ;;
19172 ;; [(set (reg ebp) (reg esp))]
19173 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19174 ;;  (clobber (eflags)]
19175 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19176 ;;
19177 ;; in proper program order.
19178 (define_insn "pro_epilogue_adjust_stack_1"
19179   [(set (match_operand:SI 0 "register_operand" "=r,r")
19180         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19181                  (match_operand:SI 2 "immediate_operand" "i,i")))
19182    (clobber (reg:CC FLAGS_REG))
19183    (clobber (mem:BLK (scratch)))]
19184   "!TARGET_64BIT"
19185 {
19186   switch (get_attr_type (insn))
19187     {
19188     case TYPE_IMOV:
19189       return "mov{l}\t{%1, %0|%0, %1}";
19190
19191     case TYPE_ALU:
19192       if (CONST_INT_P (operands[2])
19193           && (INTVAL (operands[2]) == 128
19194               || (INTVAL (operands[2]) < 0
19195                   && INTVAL (operands[2]) != -128)))
19196         {
19197           operands[2] = GEN_INT (-INTVAL (operands[2]));
19198           return "sub{l}\t{%2, %0|%0, %2}";
19199         }
19200       return "add{l}\t{%2, %0|%0, %2}";
19201
19202     case TYPE_LEA:
19203       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19204       return "lea{l}\t{%a2, %0|%0, %a2}";
19205
19206     default:
19207       gcc_unreachable ();
19208     }
19209 }
19210   [(set (attr "type")
19211         (cond [(eq_attr "alternative" "0")
19212                  (const_string "alu")
19213                (match_operand:SI 2 "const0_operand" "")
19214                  (const_string "imov")
19215               ]
19216               (const_string "lea")))
19217    (set_attr "mode" "SI")])
19218
19219 (define_insn "pro_epilogue_adjust_stack_rex64"
19220   [(set (match_operand:DI 0 "register_operand" "=r,r")
19221         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19222                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19223    (clobber (reg:CC FLAGS_REG))
19224    (clobber (mem:BLK (scratch)))]
19225   "TARGET_64BIT"
19226 {
19227   switch (get_attr_type (insn))
19228     {
19229     case TYPE_IMOV:
19230       return "mov{q}\t{%1, %0|%0, %1}";
19231
19232     case TYPE_ALU:
19233       if (CONST_INT_P (operands[2])
19234           /* Avoid overflows.  */
19235           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19236           && (INTVAL (operands[2]) == 128
19237               || (INTVAL (operands[2]) < 0
19238                   && INTVAL (operands[2]) != -128)))
19239         {
19240           operands[2] = GEN_INT (-INTVAL (operands[2]));
19241           return "sub{q}\t{%2, %0|%0, %2}";
19242         }
19243       return "add{q}\t{%2, %0|%0, %2}";
19244
19245     case TYPE_LEA:
19246       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19247       return "lea{q}\t{%a2, %0|%0, %a2}";
19248
19249     default:
19250       gcc_unreachable ();
19251     }
19252 }
19253   [(set (attr "type")
19254         (cond [(eq_attr "alternative" "0")
19255                  (const_string "alu")
19256                (match_operand:DI 2 "const0_operand" "")
19257                  (const_string "imov")
19258               ]
19259               (const_string "lea")))
19260    (set_attr "mode" "DI")])
19261
19262 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19263   [(set (match_operand:DI 0 "register_operand" "=r,r")
19264         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19265                  (match_operand:DI 3 "immediate_operand" "i,i")))
19266    (use (match_operand:DI 2 "register_operand" "r,r"))
19267    (clobber (reg:CC FLAGS_REG))
19268    (clobber (mem:BLK (scratch)))]
19269   "TARGET_64BIT"
19270 {
19271   switch (get_attr_type (insn))
19272     {
19273     case TYPE_ALU:
19274       return "add{q}\t{%2, %0|%0, %2}";
19275
19276     case TYPE_LEA:
19277       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19278       return "lea{q}\t{%a2, %0|%0, %a2}";
19279
19280     default:
19281       gcc_unreachable ();
19282     }
19283 }
19284   [(set_attr "type" "alu,lea")
19285    (set_attr "mode" "DI")])
19286
19287 (define_insn "allocate_stack_worker_32"
19288   [(set (match_operand:SI 0 "register_operand" "+a")
19289         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19290    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19291    (clobber (reg:CC FLAGS_REG))]
19292   "!TARGET_64BIT && TARGET_STACK_PROBE"
19293   "call\t__alloca"
19294   [(set_attr "type" "multi")
19295    (set_attr "length" "5")])
19296
19297 (define_insn "allocate_stack_worker_64"
19298   [(set (match_operand:DI 0 "register_operand" "=a")
19299         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19300    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19301    (clobber (reg:DI R10_REG))
19302    (clobber (reg:DI R11_REG))
19303    (clobber (reg:CC FLAGS_REG))]
19304   "TARGET_64BIT && TARGET_STACK_PROBE"
19305   "call\t___chkstk"
19306   [(set_attr "type" "multi")
19307    (set_attr "length" "5")])
19308
19309 (define_expand "allocate_stack"
19310   [(match_operand 0 "register_operand" "")
19311    (match_operand 1 "general_operand" "")]
19312   "TARGET_STACK_PROBE"
19313 {
19314   rtx x;
19315
19316 #ifndef CHECK_STACK_LIMIT
19317 #define CHECK_STACK_LIMIT 0
19318 #endif
19319
19320   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19321       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19322     {
19323       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19324                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19325       if (x != stack_pointer_rtx)
19326         emit_move_insn (stack_pointer_rtx, x);
19327     }
19328   else
19329     {
19330       x = copy_to_mode_reg (Pmode, operands[1]);
19331       if (TARGET_64BIT)
19332         x = gen_allocate_stack_worker_64 (x);
19333       else
19334         x = gen_allocate_stack_worker_32 (x);
19335       emit_insn (x);
19336     }
19337
19338   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19339   DONE;
19340 })
19341
19342 (define_expand "builtin_setjmp_receiver"
19343   [(label_ref (match_operand 0 "" ""))]
19344   "!TARGET_64BIT && flag_pic"
19345 {
19346   if (TARGET_MACHO)
19347     {
19348       rtx xops[3];
19349       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19350       rtx label_rtx = gen_label_rtx ();
19351       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19352       xops[0] = xops[1] = picreg;
19353       xops[2] = gen_rtx_CONST (SImode,
19354                   gen_rtx_MINUS (SImode,
19355                     gen_rtx_LABEL_REF (SImode, label_rtx),
19356                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19357       ix86_expand_binary_operator (MINUS, SImode, xops);
19358     }
19359   else
19360     emit_insn (gen_set_got (pic_offset_table_rtx));
19361   DONE;
19362 })
19363 \f
19364 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19365
19366 (define_split
19367   [(set (match_operand 0 "register_operand" "")
19368         (match_operator 3 "promotable_binary_operator"
19369            [(match_operand 1 "register_operand" "")
19370             (match_operand 2 "aligned_operand" "")]))
19371    (clobber (reg:CC FLAGS_REG))]
19372   "! TARGET_PARTIAL_REG_STALL && reload_completed
19373    && ((GET_MODE (operands[0]) == HImode
19374         && ((!optimize_size && !TARGET_FAST_PREFIX)
19375             /* ??? next two lines just !satisfies_constraint_K (...) */
19376             || !CONST_INT_P (operands[2])
19377             || satisfies_constraint_K (operands[2])))
19378        || (GET_MODE (operands[0]) == QImode
19379            && (TARGET_PROMOTE_QImode || optimize_size)))"
19380   [(parallel [(set (match_dup 0)
19381                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19382               (clobber (reg:CC FLAGS_REG))])]
19383   "operands[0] = gen_lowpart (SImode, operands[0]);
19384    operands[1] = gen_lowpart (SImode, operands[1]);
19385    if (GET_CODE (operands[3]) != ASHIFT)
19386      operands[2] = gen_lowpart (SImode, operands[2]);
19387    PUT_MODE (operands[3], SImode);")
19388
19389 ; Promote the QImode tests, as i386 has encoding of the AND
19390 ; instruction with 32-bit sign-extended immediate and thus the
19391 ; instruction size is unchanged, except in the %eax case for
19392 ; which it is increased by one byte, hence the ! optimize_size.
19393 (define_split
19394   [(set (match_operand 0 "flags_reg_operand" "")
19395         (match_operator 2 "compare_operator"
19396           [(and (match_operand 3 "aligned_operand" "")
19397                 (match_operand 4 "const_int_operand" ""))
19398            (const_int 0)]))
19399    (set (match_operand 1 "register_operand" "")
19400         (and (match_dup 3) (match_dup 4)))]
19401   "! TARGET_PARTIAL_REG_STALL && reload_completed
19402    /* Ensure that the operand will remain sign-extended immediate.  */
19403    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19404    && ! optimize_size
19405    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19406        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19407   [(parallel [(set (match_dup 0)
19408                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19409                                     (const_int 0)]))
19410               (set (match_dup 1)
19411                    (and:SI (match_dup 3) (match_dup 4)))])]
19412 {
19413   operands[4]
19414     = gen_int_mode (INTVAL (operands[4])
19415                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19416   operands[1] = gen_lowpart (SImode, operands[1]);
19417   operands[3] = gen_lowpart (SImode, operands[3]);
19418 })
19419
19420 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19421 ; the TEST instruction with 32-bit sign-extended immediate and thus
19422 ; the instruction size would at least double, which is not what we
19423 ; want even with ! optimize_size.
19424 (define_split
19425   [(set (match_operand 0 "flags_reg_operand" "")
19426         (match_operator 1 "compare_operator"
19427           [(and (match_operand:HI 2 "aligned_operand" "")
19428                 (match_operand:HI 3 "const_int_operand" ""))
19429            (const_int 0)]))]
19430   "! TARGET_PARTIAL_REG_STALL && reload_completed
19431    /* Ensure that the operand will remain sign-extended immediate.  */
19432    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19433    && ! TARGET_FAST_PREFIX
19434    && ! optimize_size"
19435   [(set (match_dup 0)
19436         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19437                          (const_int 0)]))]
19438 {
19439   operands[3]
19440     = gen_int_mode (INTVAL (operands[3])
19441                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19442   operands[2] = gen_lowpart (SImode, operands[2]);
19443 })
19444
19445 (define_split
19446   [(set (match_operand 0 "register_operand" "")
19447         (neg (match_operand 1 "register_operand" "")))
19448    (clobber (reg:CC FLAGS_REG))]
19449   "! TARGET_PARTIAL_REG_STALL && reload_completed
19450    && (GET_MODE (operands[0]) == HImode
19451        || (GET_MODE (operands[0]) == QImode
19452            && (TARGET_PROMOTE_QImode || optimize_size)))"
19453   [(parallel [(set (match_dup 0)
19454                    (neg:SI (match_dup 1)))
19455               (clobber (reg:CC FLAGS_REG))])]
19456   "operands[0] = gen_lowpart (SImode, operands[0]);
19457    operands[1] = gen_lowpart (SImode, operands[1]);")
19458
19459 (define_split
19460   [(set (match_operand 0 "register_operand" "")
19461         (not (match_operand 1 "register_operand" "")))]
19462   "! TARGET_PARTIAL_REG_STALL && reload_completed
19463    && (GET_MODE (operands[0]) == HImode
19464        || (GET_MODE (operands[0]) == QImode
19465            && (TARGET_PROMOTE_QImode || optimize_size)))"
19466   [(set (match_dup 0)
19467         (not:SI (match_dup 1)))]
19468   "operands[0] = gen_lowpart (SImode, operands[0]);
19469    operands[1] = gen_lowpart (SImode, operands[1]);")
19470
19471 (define_split
19472   [(set (match_operand 0 "register_operand" "")
19473         (if_then_else (match_operator 1 "comparison_operator"
19474                                 [(reg FLAGS_REG) (const_int 0)])
19475                       (match_operand 2 "register_operand" "")
19476                       (match_operand 3 "register_operand" "")))]
19477   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19478    && (GET_MODE (operands[0]) == HImode
19479        || (GET_MODE (operands[0]) == QImode
19480            && (TARGET_PROMOTE_QImode || optimize_size)))"
19481   [(set (match_dup 0)
19482         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19483   "operands[0] = gen_lowpart (SImode, operands[0]);
19484    operands[2] = gen_lowpart (SImode, operands[2]);
19485    operands[3] = gen_lowpart (SImode, operands[3]);")
19486
19487 \f
19488 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19489 ;; transform a complex memory operation into two memory to register operations.
19490
19491 ;; Don't push memory operands
19492 (define_peephole2
19493   [(set (match_operand:SI 0 "push_operand" "")
19494         (match_operand:SI 1 "memory_operand" ""))
19495    (match_scratch:SI 2 "r")]
19496   "!optimize_size && !TARGET_PUSH_MEMORY
19497    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19498   [(set (match_dup 2) (match_dup 1))
19499    (set (match_dup 0) (match_dup 2))]
19500   "")
19501
19502 (define_peephole2
19503   [(set (match_operand:DI 0 "push_operand" "")
19504         (match_operand:DI 1 "memory_operand" ""))
19505    (match_scratch:DI 2 "r")]
19506   "!optimize_size && !TARGET_PUSH_MEMORY
19507    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19508   [(set (match_dup 2) (match_dup 1))
19509    (set (match_dup 0) (match_dup 2))]
19510   "")
19511
19512 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19513 ;; SImode pushes.
19514 (define_peephole2
19515   [(set (match_operand:SF 0 "push_operand" "")
19516         (match_operand:SF 1 "memory_operand" ""))
19517    (match_scratch:SF 2 "r")]
19518   "!optimize_size && !TARGET_PUSH_MEMORY
19519    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19520   [(set (match_dup 2) (match_dup 1))
19521    (set (match_dup 0) (match_dup 2))]
19522   "")
19523
19524 (define_peephole2
19525   [(set (match_operand:HI 0 "push_operand" "")
19526         (match_operand:HI 1 "memory_operand" ""))
19527    (match_scratch:HI 2 "r")]
19528   "!optimize_size && !TARGET_PUSH_MEMORY
19529    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19530   [(set (match_dup 2) (match_dup 1))
19531    (set (match_dup 0) (match_dup 2))]
19532   "")
19533
19534 (define_peephole2
19535   [(set (match_operand:QI 0 "push_operand" "")
19536         (match_operand:QI 1 "memory_operand" ""))
19537    (match_scratch:QI 2 "q")]
19538   "!optimize_size && !TARGET_PUSH_MEMORY
19539    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19540   [(set (match_dup 2) (match_dup 1))
19541    (set (match_dup 0) (match_dup 2))]
19542   "")
19543
19544 ;; Don't move an immediate directly to memory when the instruction
19545 ;; gets too big.
19546 (define_peephole2
19547   [(match_scratch:SI 1 "r")
19548    (set (match_operand:SI 0 "memory_operand" "")
19549         (const_int 0))]
19550   "! optimize_size
19551    && ! TARGET_USE_MOV0
19552    && TARGET_SPLIT_LONG_MOVES
19553    && get_attr_length (insn) >= ix86_cost->large_insn
19554    && peep2_regno_dead_p (0, FLAGS_REG)"
19555   [(parallel [(set (match_dup 1) (const_int 0))
19556               (clobber (reg:CC FLAGS_REG))])
19557    (set (match_dup 0) (match_dup 1))]
19558   "")
19559
19560 (define_peephole2
19561   [(match_scratch:HI 1 "r")
19562    (set (match_operand:HI 0 "memory_operand" "")
19563         (const_int 0))]
19564   "! optimize_size
19565    && ! TARGET_USE_MOV0
19566    && TARGET_SPLIT_LONG_MOVES
19567    && get_attr_length (insn) >= ix86_cost->large_insn
19568    && peep2_regno_dead_p (0, FLAGS_REG)"
19569   [(parallel [(set (match_dup 2) (const_int 0))
19570               (clobber (reg:CC FLAGS_REG))])
19571    (set (match_dup 0) (match_dup 1))]
19572   "operands[2] = gen_lowpart (SImode, operands[1]);")
19573
19574 (define_peephole2
19575   [(match_scratch:QI 1 "q")
19576    (set (match_operand:QI 0 "memory_operand" "")
19577         (const_int 0))]
19578   "! optimize_size
19579    && ! TARGET_USE_MOV0
19580    && TARGET_SPLIT_LONG_MOVES
19581    && get_attr_length (insn) >= ix86_cost->large_insn
19582    && peep2_regno_dead_p (0, FLAGS_REG)"
19583   [(parallel [(set (match_dup 2) (const_int 0))
19584               (clobber (reg:CC FLAGS_REG))])
19585    (set (match_dup 0) (match_dup 1))]
19586   "operands[2] = gen_lowpart (SImode, operands[1]);")
19587
19588 (define_peephole2
19589   [(match_scratch:SI 2 "r")
19590    (set (match_operand:SI 0 "memory_operand" "")
19591         (match_operand:SI 1 "immediate_operand" ""))]
19592   "! optimize_size
19593    && get_attr_length (insn) >= ix86_cost->large_insn
19594    && TARGET_SPLIT_LONG_MOVES"
19595   [(set (match_dup 2) (match_dup 1))
19596    (set (match_dup 0) (match_dup 2))]
19597   "")
19598
19599 (define_peephole2
19600   [(match_scratch:HI 2 "r")
19601    (set (match_operand:HI 0 "memory_operand" "")
19602         (match_operand:HI 1 "immediate_operand" ""))]
19603   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19604   && TARGET_SPLIT_LONG_MOVES"
19605   [(set (match_dup 2) (match_dup 1))
19606    (set (match_dup 0) (match_dup 2))]
19607   "")
19608
19609 (define_peephole2
19610   [(match_scratch:QI 2 "q")
19611    (set (match_operand:QI 0 "memory_operand" "")
19612         (match_operand:QI 1 "immediate_operand" ""))]
19613   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19614   && TARGET_SPLIT_LONG_MOVES"
19615   [(set (match_dup 2) (match_dup 1))
19616    (set (match_dup 0) (match_dup 2))]
19617   "")
19618
19619 ;; Don't compare memory with zero, load and use a test instead.
19620 (define_peephole2
19621   [(set (match_operand 0 "flags_reg_operand" "")
19622         (match_operator 1 "compare_operator"
19623           [(match_operand:SI 2 "memory_operand" "")
19624            (const_int 0)]))
19625    (match_scratch:SI 3 "r")]
19626   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19627   [(set (match_dup 3) (match_dup 2))
19628    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19629   "")
19630
19631 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19632 ;; Don't split NOTs with a displacement operand, because resulting XOR
19633 ;; will not be pairable anyway.
19634 ;;
19635 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19636 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19637 ;; so this split helps here as well.
19638 ;;
19639 ;; Note: Can't do this as a regular split because we can't get proper
19640 ;; lifetime information then.
19641
19642 (define_peephole2
19643   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19644         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19645   "!optimize_size
19646    && peep2_regno_dead_p (0, FLAGS_REG)
19647    && ((TARGET_NOT_UNPAIRABLE
19648         && (!MEM_P (operands[0])
19649             || !memory_displacement_operand (operands[0], SImode)))
19650        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))"
19651   [(parallel [(set (match_dup 0)
19652                    (xor:SI (match_dup 1) (const_int -1)))
19653               (clobber (reg:CC FLAGS_REG))])]
19654   "")
19655
19656 (define_peephole2
19657   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19658         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19659   "!optimize_size
19660    && peep2_regno_dead_p (0, FLAGS_REG)
19661    && ((TARGET_NOT_UNPAIRABLE
19662         && (!MEM_P (operands[0])
19663             || !memory_displacement_operand (operands[0], HImode)))
19664        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))"
19665   [(parallel [(set (match_dup 0)
19666                    (xor:HI (match_dup 1) (const_int -1)))
19667               (clobber (reg:CC FLAGS_REG))])]
19668   "")
19669
19670 (define_peephole2
19671   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19672         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19673   "!optimize_size
19674    && peep2_regno_dead_p (0, FLAGS_REG)
19675    && ((TARGET_NOT_UNPAIRABLE
19676         && (!MEM_P (operands[0])
19677             || !memory_displacement_operand (operands[0], QImode)))
19678        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))"
19679   [(parallel [(set (match_dup 0)
19680                    (xor:QI (match_dup 1) (const_int -1)))
19681               (clobber (reg:CC FLAGS_REG))])]
19682   "")
19683
19684 ;; Non pairable "test imm, reg" instructions can be translated to
19685 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19686 ;; byte opcode instead of two, have a short form for byte operands),
19687 ;; so do it for other CPUs as well.  Given that the value was dead,
19688 ;; this should not create any new dependencies.  Pass on the sub-word
19689 ;; versions if we're concerned about partial register stalls.
19690
19691 (define_peephole2
19692   [(set (match_operand 0 "flags_reg_operand" "")
19693         (match_operator 1 "compare_operator"
19694           [(and:SI (match_operand:SI 2 "register_operand" "")
19695                    (match_operand:SI 3 "immediate_operand" ""))
19696            (const_int 0)]))]
19697   "ix86_match_ccmode (insn, CCNOmode)
19698    && (true_regnum (operands[2]) != 0
19699        || satisfies_constraint_K (operands[3]))
19700    && peep2_reg_dead_p (1, operands[2])"
19701   [(parallel
19702      [(set (match_dup 0)
19703            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19704                             (const_int 0)]))
19705       (set (match_dup 2)
19706            (and:SI (match_dup 2) (match_dup 3)))])]
19707   "")
19708
19709 ;; We don't need to handle HImode case, because it will be promoted to SImode
19710 ;; on ! TARGET_PARTIAL_REG_STALL
19711
19712 (define_peephole2
19713   [(set (match_operand 0 "flags_reg_operand" "")
19714         (match_operator 1 "compare_operator"
19715           [(and:QI (match_operand:QI 2 "register_operand" "")
19716                    (match_operand:QI 3 "immediate_operand" ""))
19717            (const_int 0)]))]
19718   "! TARGET_PARTIAL_REG_STALL
19719    && ix86_match_ccmode (insn, CCNOmode)
19720    && true_regnum (operands[2]) != 0
19721    && peep2_reg_dead_p (1, operands[2])"
19722   [(parallel
19723      [(set (match_dup 0)
19724            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19725                             (const_int 0)]))
19726       (set (match_dup 2)
19727            (and:QI (match_dup 2) (match_dup 3)))])]
19728   "")
19729
19730 (define_peephole2
19731   [(set (match_operand 0 "flags_reg_operand" "")
19732         (match_operator 1 "compare_operator"
19733           [(and:SI
19734              (zero_extract:SI
19735                (match_operand 2 "ext_register_operand" "")
19736                (const_int 8)
19737                (const_int 8))
19738              (match_operand 3 "const_int_operand" ""))
19739            (const_int 0)]))]
19740   "! TARGET_PARTIAL_REG_STALL
19741    && ix86_match_ccmode (insn, CCNOmode)
19742    && true_regnum (operands[2]) != 0
19743    && peep2_reg_dead_p (1, operands[2])"
19744   [(parallel [(set (match_dup 0)
19745                    (match_op_dup 1
19746                      [(and:SI
19747                         (zero_extract:SI
19748                           (match_dup 2)
19749                           (const_int 8)
19750                           (const_int 8))
19751                         (match_dup 3))
19752                       (const_int 0)]))
19753               (set (zero_extract:SI (match_dup 2)
19754                                     (const_int 8)
19755                                     (const_int 8))
19756                    (and:SI
19757                      (zero_extract:SI
19758                        (match_dup 2)
19759                        (const_int 8)
19760                        (const_int 8))
19761                      (match_dup 3)))])]
19762   "")
19763
19764 ;; Don't do logical operations with memory inputs.
19765 (define_peephole2
19766   [(match_scratch:SI 2 "r")
19767    (parallel [(set (match_operand:SI 0 "register_operand" "")
19768                    (match_operator:SI 3 "arith_or_logical_operator"
19769                      [(match_dup 0)
19770                       (match_operand:SI 1 "memory_operand" "")]))
19771               (clobber (reg:CC FLAGS_REG))])]
19772   "! optimize_size && ! TARGET_READ_MODIFY"
19773   [(set (match_dup 2) (match_dup 1))
19774    (parallel [(set (match_dup 0)
19775                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19776               (clobber (reg:CC FLAGS_REG))])]
19777   "")
19778
19779 (define_peephole2
19780   [(match_scratch:SI 2 "r")
19781    (parallel [(set (match_operand:SI 0 "register_operand" "")
19782                    (match_operator:SI 3 "arith_or_logical_operator"
19783                      [(match_operand:SI 1 "memory_operand" "")
19784                       (match_dup 0)]))
19785               (clobber (reg:CC FLAGS_REG))])]
19786   "! optimize_size && ! TARGET_READ_MODIFY"
19787   [(set (match_dup 2) (match_dup 1))
19788    (parallel [(set (match_dup 0)
19789                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19790               (clobber (reg:CC FLAGS_REG))])]
19791   "")
19792
19793 ; Don't do logical operations with memory outputs
19794 ;
19795 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19796 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19797 ; the same decoder scheduling characteristics as the original.
19798
19799 (define_peephole2
19800   [(match_scratch:SI 2 "r")
19801    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19802                    (match_operator:SI 3 "arith_or_logical_operator"
19803                      [(match_dup 0)
19804                       (match_operand:SI 1 "nonmemory_operand" "")]))
19805               (clobber (reg:CC FLAGS_REG))])]
19806   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19807   [(set (match_dup 2) (match_dup 0))
19808    (parallel [(set (match_dup 2)
19809                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19810               (clobber (reg:CC FLAGS_REG))])
19811    (set (match_dup 0) (match_dup 2))]
19812   "")
19813
19814 (define_peephole2
19815   [(match_scratch:SI 2 "r")
19816    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19817                    (match_operator:SI 3 "arith_or_logical_operator"
19818                      [(match_operand:SI 1 "nonmemory_operand" "")
19819                       (match_dup 0)]))
19820               (clobber (reg:CC FLAGS_REG))])]
19821   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19822   [(set (match_dup 2) (match_dup 0))
19823    (parallel [(set (match_dup 2)
19824                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19825               (clobber (reg:CC FLAGS_REG))])
19826    (set (match_dup 0) (match_dup 2))]
19827   "")
19828
19829 ;; Attempt to always use XOR for zeroing registers.
19830 (define_peephole2
19831   [(set (match_operand 0 "register_operand" "")
19832         (match_operand 1 "const0_operand" ""))]
19833   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19834    && (! TARGET_USE_MOV0 || optimize_size)
19835    && GENERAL_REG_P (operands[0])
19836    && peep2_regno_dead_p (0, FLAGS_REG)"
19837   [(parallel [(set (match_dup 0) (const_int 0))
19838               (clobber (reg:CC FLAGS_REG))])]
19839 {
19840   operands[0] = gen_lowpart (word_mode, operands[0]);
19841 })
19842
19843 (define_peephole2
19844   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19845         (const_int 0))]
19846   "(GET_MODE (operands[0]) == QImode
19847     || GET_MODE (operands[0]) == HImode)
19848    && (! TARGET_USE_MOV0 || optimize_size)
19849    && peep2_regno_dead_p (0, FLAGS_REG)"
19850   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19851               (clobber (reg:CC FLAGS_REG))])])
19852
19853 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19854 (define_peephole2
19855   [(set (match_operand 0 "register_operand" "")
19856         (const_int -1))]
19857   "(GET_MODE (operands[0]) == HImode
19858     || GET_MODE (operands[0]) == SImode
19859     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19860    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
19861    && peep2_regno_dead_p (0, FLAGS_REG)"
19862   [(parallel [(set (match_dup 0) (const_int -1))
19863               (clobber (reg:CC FLAGS_REG))])]
19864   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19865                               operands[0]);")
19866
19867 ;; Attempt to convert simple leas to adds. These can be created by
19868 ;; move expanders.
19869 (define_peephole2
19870   [(set (match_operand:SI 0 "register_operand" "")
19871         (plus:SI (match_dup 0)
19872                  (match_operand:SI 1 "nonmemory_operand" "")))]
19873   "peep2_regno_dead_p (0, FLAGS_REG)"
19874   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19875               (clobber (reg:CC FLAGS_REG))])]
19876   "")
19877
19878 (define_peephole2
19879   [(set (match_operand:SI 0 "register_operand" "")
19880         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19881                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19882   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19883   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19884               (clobber (reg:CC FLAGS_REG))])]
19885   "operands[2] = gen_lowpart (SImode, operands[2]);")
19886
19887 (define_peephole2
19888   [(set (match_operand:DI 0 "register_operand" "")
19889         (plus:DI (match_dup 0)
19890                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19891   "peep2_regno_dead_p (0, FLAGS_REG)"
19892   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19893               (clobber (reg:CC FLAGS_REG))])]
19894   "")
19895
19896 (define_peephole2
19897   [(set (match_operand:SI 0 "register_operand" "")
19898         (mult:SI (match_dup 0)
19899                  (match_operand:SI 1 "const_int_operand" "")))]
19900   "exact_log2 (INTVAL (operands[1])) >= 0
19901    && peep2_regno_dead_p (0, FLAGS_REG)"
19902   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19903               (clobber (reg:CC FLAGS_REG))])]
19904   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19905
19906 (define_peephole2
19907   [(set (match_operand:DI 0 "register_operand" "")
19908         (mult:DI (match_dup 0)
19909                  (match_operand:DI 1 "const_int_operand" "")))]
19910   "exact_log2 (INTVAL (operands[1])) >= 0
19911    && peep2_regno_dead_p (0, FLAGS_REG)"
19912   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19913               (clobber (reg:CC FLAGS_REG))])]
19914   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19915
19916 (define_peephole2
19917   [(set (match_operand:SI 0 "register_operand" "")
19918         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19919                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19920   "exact_log2 (INTVAL (operands[2])) >= 0
19921    && REGNO (operands[0]) == REGNO (operands[1])
19922    && peep2_regno_dead_p (0, FLAGS_REG)"
19923   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19924               (clobber (reg:CC FLAGS_REG))])]
19925   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19926
19927 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19928 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19929 ;; many CPUs it is also faster, since special hardware to avoid esp
19930 ;; dependencies is present.
19931
19932 ;; While some of these conversions may be done using splitters, we use peepholes
19933 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19934
19935 ;; Convert prologue esp subtractions to push.
19936 ;; We need register to push.  In order to keep verify_flow_info happy we have
19937 ;; two choices
19938 ;; - use scratch and clobber it in order to avoid dependencies
19939 ;; - use already live register
19940 ;; We can't use the second way right now, since there is no reliable way how to
19941 ;; verify that given register is live.  First choice will also most likely in
19942 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19943 ;; call clobbered registers are dead.  We may want to use base pointer as an
19944 ;; alternative when no register is available later.
19945
19946 (define_peephole2
19947   [(match_scratch:SI 0 "r")
19948    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19949               (clobber (reg:CC FLAGS_REG))
19950               (clobber (mem:BLK (scratch)))])]
19951   "optimize_size || !TARGET_SUB_ESP_4"
19952   [(clobber (match_dup 0))
19953    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19954               (clobber (mem:BLK (scratch)))])])
19955
19956 (define_peephole2
19957   [(match_scratch:SI 0 "r")
19958    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19959               (clobber (reg:CC FLAGS_REG))
19960               (clobber (mem:BLK (scratch)))])]
19961   "optimize_size || !TARGET_SUB_ESP_8"
19962   [(clobber (match_dup 0))
19963    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19964    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19965               (clobber (mem:BLK (scratch)))])])
19966
19967 ;; Convert esp subtractions to push.
19968 (define_peephole2
19969   [(match_scratch:SI 0 "r")
19970    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19971               (clobber (reg:CC FLAGS_REG))])]
19972   "optimize_size || !TARGET_SUB_ESP_4"
19973   [(clobber (match_dup 0))
19974    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19975
19976 (define_peephole2
19977   [(match_scratch:SI 0 "r")
19978    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19979               (clobber (reg:CC FLAGS_REG))])]
19980   "optimize_size || !TARGET_SUB_ESP_8"
19981   [(clobber (match_dup 0))
19982    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19983    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19984
19985 ;; Convert epilogue deallocator to pop.
19986 (define_peephole2
19987   [(match_scratch:SI 0 "r")
19988    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19989               (clobber (reg:CC FLAGS_REG))
19990               (clobber (mem:BLK (scratch)))])]
19991   "optimize_size || !TARGET_ADD_ESP_4"
19992   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19993               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19994               (clobber (mem:BLK (scratch)))])]
19995   "")
19996
19997 ;; Two pops case is tricky, since pop causes dependency on destination register.
19998 ;; We use two registers if available.
19999 (define_peephole2
20000   [(match_scratch:SI 0 "r")
20001    (match_scratch:SI 1 "r")
20002    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20003               (clobber (reg:CC FLAGS_REG))
20004               (clobber (mem:BLK (scratch)))])]
20005   "optimize_size || !TARGET_ADD_ESP_8"
20006   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20007               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20008               (clobber (mem:BLK (scratch)))])
20009    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20010               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20011   "")
20012
20013 (define_peephole2
20014   [(match_scratch:SI 0 "r")
20015    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20016               (clobber (reg:CC FLAGS_REG))
20017               (clobber (mem:BLK (scratch)))])]
20018   "optimize_size"
20019   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20020               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20021               (clobber (mem:BLK (scratch)))])
20022    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20023               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20024   "")
20025
20026 ;; Convert esp additions to pop.
20027 (define_peephole2
20028   [(match_scratch:SI 0 "r")
20029    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20030               (clobber (reg:CC FLAGS_REG))])]
20031   ""
20032   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20033               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20034   "")
20035
20036 ;; Two pops case is tricky, since pop causes dependency on destination register.
20037 ;; We use two registers if available.
20038 (define_peephole2
20039   [(match_scratch:SI 0 "r")
20040    (match_scratch:SI 1 "r")
20041    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20042               (clobber (reg:CC FLAGS_REG))])]
20043   ""
20044   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20045               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20046    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20047               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20048   "")
20049
20050 (define_peephole2
20051   [(match_scratch:SI 0 "r")
20052    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20053               (clobber (reg:CC FLAGS_REG))])]
20054   "optimize_size"
20055   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20056               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20057    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20058               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20059   "")
20060 \f
20061 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20062 ;; required and register dies.  Similarly for 128 to plus -128.
20063 (define_peephole2
20064   [(set (match_operand 0 "flags_reg_operand" "")
20065         (match_operator 1 "compare_operator"
20066           [(match_operand 2 "register_operand" "")
20067            (match_operand 3 "const_int_operand" "")]))]
20068   "(INTVAL (operands[3]) == -1
20069     || INTVAL (operands[3]) == 1
20070     || INTVAL (operands[3]) == 128)
20071    && ix86_match_ccmode (insn, CCGCmode)
20072    && peep2_reg_dead_p (1, operands[2])"
20073   [(parallel [(set (match_dup 0)
20074                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20075               (clobber (match_dup 2))])]
20076   "")
20077 \f
20078 (define_peephole2
20079   [(match_scratch:DI 0 "r")
20080    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20081               (clobber (reg:CC FLAGS_REG))
20082               (clobber (mem:BLK (scratch)))])]
20083   "optimize_size || !TARGET_SUB_ESP_4"
20084   [(clobber (match_dup 0))
20085    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20086               (clobber (mem:BLK (scratch)))])])
20087
20088 (define_peephole2
20089   [(match_scratch:DI 0 "r")
20090    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20091               (clobber (reg:CC FLAGS_REG))
20092               (clobber (mem:BLK (scratch)))])]
20093   "optimize_size || !TARGET_SUB_ESP_8"
20094   [(clobber (match_dup 0))
20095    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20096    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20097               (clobber (mem:BLK (scratch)))])])
20098
20099 ;; Convert esp subtractions to push.
20100 (define_peephole2
20101   [(match_scratch:DI 0 "r")
20102    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20103               (clobber (reg:CC FLAGS_REG))])]
20104   "optimize_size || !TARGET_SUB_ESP_4"
20105   [(clobber (match_dup 0))
20106    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20107
20108 (define_peephole2
20109   [(match_scratch:DI 0 "r")
20110    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20111               (clobber (reg:CC FLAGS_REG))])]
20112   "optimize_size || !TARGET_SUB_ESP_8"
20113   [(clobber (match_dup 0))
20114    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20115    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20116
20117 ;; Convert epilogue deallocator to pop.
20118 (define_peephole2
20119   [(match_scratch:DI 0 "r")
20120    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20121               (clobber (reg:CC FLAGS_REG))
20122               (clobber (mem:BLK (scratch)))])]
20123   "optimize_size || !TARGET_ADD_ESP_4"
20124   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20125               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20126               (clobber (mem:BLK (scratch)))])]
20127   "")
20128
20129 ;; Two pops case is tricky, since pop causes dependency on destination register.
20130 ;; We use two registers if available.
20131 (define_peephole2
20132   [(match_scratch:DI 0 "r")
20133    (match_scratch:DI 1 "r")
20134    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20135               (clobber (reg:CC FLAGS_REG))
20136               (clobber (mem:BLK (scratch)))])]
20137   "optimize_size || !TARGET_ADD_ESP_8"
20138   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20139               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20140               (clobber (mem:BLK (scratch)))])
20141    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20142               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20143   "")
20144
20145 (define_peephole2
20146   [(match_scratch:DI 0 "r")
20147    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20148               (clobber (reg:CC FLAGS_REG))
20149               (clobber (mem:BLK (scratch)))])]
20150   "optimize_size"
20151   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20152               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20153               (clobber (mem:BLK (scratch)))])
20154    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20155               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20156   "")
20157
20158 ;; Convert esp additions to pop.
20159 (define_peephole2
20160   [(match_scratch:DI 0 "r")
20161    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20162               (clobber (reg:CC FLAGS_REG))])]
20163   ""
20164   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20165               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20166   "")
20167
20168 ;; Two pops case is tricky, since pop causes dependency on destination register.
20169 ;; We use two registers if available.
20170 (define_peephole2
20171   [(match_scratch:DI 0 "r")
20172    (match_scratch:DI 1 "r")
20173    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20174               (clobber (reg:CC FLAGS_REG))])]
20175   ""
20176   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20177               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20178    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20179               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20180   "")
20181
20182 (define_peephole2
20183   [(match_scratch:DI 0 "r")
20184    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20185               (clobber (reg:CC FLAGS_REG))])]
20186   "optimize_size"
20187   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20188               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20189    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20190               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20191   "")
20192 \f
20193 ;; Convert imul by three, five and nine into lea
20194 (define_peephole2
20195   [(parallel
20196     [(set (match_operand:SI 0 "register_operand" "")
20197           (mult:SI (match_operand:SI 1 "register_operand" "")
20198                    (match_operand:SI 2 "const_int_operand" "")))
20199      (clobber (reg:CC FLAGS_REG))])]
20200   "INTVAL (operands[2]) == 3
20201    || INTVAL (operands[2]) == 5
20202    || INTVAL (operands[2]) == 9"
20203   [(set (match_dup 0)
20204         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20205                  (match_dup 1)))]
20206   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20207
20208 (define_peephole2
20209   [(parallel
20210     [(set (match_operand:SI 0 "register_operand" "")
20211           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20212                    (match_operand:SI 2 "const_int_operand" "")))
20213      (clobber (reg:CC FLAGS_REG))])]
20214   "!optimize_size
20215    && (INTVAL (operands[2]) == 3
20216        || INTVAL (operands[2]) == 5
20217        || INTVAL (operands[2]) == 9)"
20218   [(set (match_dup 0) (match_dup 1))
20219    (set (match_dup 0)
20220         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20221                  (match_dup 0)))]
20222   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20223
20224 (define_peephole2
20225   [(parallel
20226     [(set (match_operand:DI 0 "register_operand" "")
20227           (mult:DI (match_operand:DI 1 "register_operand" "")
20228                    (match_operand:DI 2 "const_int_operand" "")))
20229      (clobber (reg:CC FLAGS_REG))])]
20230   "TARGET_64BIT
20231    && (INTVAL (operands[2]) == 3
20232        || INTVAL (operands[2]) == 5
20233        || INTVAL (operands[2]) == 9)"
20234   [(set (match_dup 0)
20235         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20236                  (match_dup 1)))]
20237   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20238
20239 (define_peephole2
20240   [(parallel
20241     [(set (match_operand:DI 0 "register_operand" "")
20242           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20243                    (match_operand:DI 2 "const_int_operand" "")))
20244      (clobber (reg:CC FLAGS_REG))])]
20245   "TARGET_64BIT
20246    && !optimize_size
20247    && (INTVAL (operands[2]) == 3
20248        || INTVAL (operands[2]) == 5
20249        || INTVAL (operands[2]) == 9)"
20250   [(set (match_dup 0) (match_dup 1))
20251    (set (match_dup 0)
20252         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20253                  (match_dup 0)))]
20254   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20255
20256 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20257 ;; imul $32bit_imm, reg, reg is direct decoded.
20258 (define_peephole2
20259   [(match_scratch:DI 3 "r")
20260    (parallel [(set (match_operand:DI 0 "register_operand" "")
20261                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20262                             (match_operand:DI 2 "immediate_operand" "")))
20263               (clobber (reg:CC FLAGS_REG))])]
20264   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20265    && !satisfies_constraint_K (operands[2])"
20266   [(set (match_dup 3) (match_dup 1))
20267    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20268               (clobber (reg:CC FLAGS_REG))])]
20269 "")
20270
20271 (define_peephole2
20272   [(match_scratch:SI 3 "r")
20273    (parallel [(set (match_operand:SI 0 "register_operand" "")
20274                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20275                             (match_operand:SI 2 "immediate_operand" "")))
20276               (clobber (reg:CC FLAGS_REG))])]
20277   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20278    && !satisfies_constraint_K (operands[2])"
20279   [(set (match_dup 3) (match_dup 1))
20280    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20281               (clobber (reg:CC FLAGS_REG))])]
20282 "")
20283
20284 (define_peephole2
20285   [(match_scratch:SI 3 "r")
20286    (parallel [(set (match_operand:DI 0 "register_operand" "")
20287                    (zero_extend:DI
20288                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20289                               (match_operand:SI 2 "immediate_operand" ""))))
20290               (clobber (reg:CC FLAGS_REG))])]
20291   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20292    && !satisfies_constraint_K (operands[2])"
20293   [(set (match_dup 3) (match_dup 1))
20294    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20295               (clobber (reg:CC FLAGS_REG))])]
20296 "")
20297
20298 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20299 ;; Convert it into imul reg, reg
20300 ;; It would be better to force assembler to encode instruction using long
20301 ;; immediate, but there is apparently no way to do so.
20302 (define_peephole2
20303   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20304                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20305                             (match_operand:DI 2 "const_int_operand" "")))
20306               (clobber (reg:CC FLAGS_REG))])
20307    (match_scratch:DI 3 "r")]
20308   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20309    && satisfies_constraint_K (operands[2])"
20310   [(set (match_dup 3) (match_dup 2))
20311    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20312               (clobber (reg:CC FLAGS_REG))])]
20313 {
20314   if (!rtx_equal_p (operands[0], operands[1]))
20315     emit_move_insn (operands[0], operands[1]);
20316 })
20317
20318 (define_peephole2
20319   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20320                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20321                             (match_operand:SI 2 "const_int_operand" "")))
20322               (clobber (reg:CC FLAGS_REG))])
20323    (match_scratch:SI 3 "r")]
20324   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20325    && satisfies_constraint_K (operands[2])"
20326   [(set (match_dup 3) (match_dup 2))
20327    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20328               (clobber (reg:CC FLAGS_REG))])]
20329 {
20330   if (!rtx_equal_p (operands[0], operands[1]))
20331     emit_move_insn (operands[0], operands[1]);
20332 })
20333
20334 (define_peephole2
20335   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20336                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20337                             (match_operand:HI 2 "immediate_operand" "")))
20338               (clobber (reg:CC FLAGS_REG))])
20339    (match_scratch:HI 3 "r")]
20340   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20341   [(set (match_dup 3) (match_dup 2))
20342    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20343               (clobber (reg:CC FLAGS_REG))])]
20344 {
20345   if (!rtx_equal_p (operands[0], operands[1]))
20346     emit_move_insn (operands[0], operands[1]);
20347 })
20348
20349 ;; After splitting up read-modify operations, array accesses with memory
20350 ;; operands might end up in form:
20351 ;;  sall    $2, %eax
20352 ;;  movl    4(%esp), %edx
20353 ;;  addl    %edx, %eax
20354 ;; instead of pre-splitting:
20355 ;;  sall    $2, %eax
20356 ;;  addl    4(%esp), %eax
20357 ;; Turn it into:
20358 ;;  movl    4(%esp), %edx
20359 ;;  leal    (%edx,%eax,4), %eax
20360
20361 (define_peephole2
20362   [(parallel [(set (match_operand 0 "register_operand" "")
20363                    (ashift (match_operand 1 "register_operand" "")
20364                            (match_operand 2 "const_int_operand" "")))
20365                (clobber (reg:CC FLAGS_REG))])
20366    (set (match_operand 3 "register_operand")
20367         (match_operand 4 "x86_64_general_operand" ""))
20368    (parallel [(set (match_operand 5 "register_operand" "")
20369                    (plus (match_operand 6 "register_operand" "")
20370                          (match_operand 7 "register_operand" "")))
20371                    (clobber (reg:CC FLAGS_REG))])]
20372   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20373    /* Validate MODE for lea.  */
20374    && ((!TARGET_PARTIAL_REG_STALL
20375         && (GET_MODE (operands[0]) == QImode
20376             || GET_MODE (operands[0]) == HImode))
20377        || GET_MODE (operands[0]) == SImode
20378        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20379    /* We reorder load and the shift.  */
20380    && !rtx_equal_p (operands[1], operands[3])
20381    && !reg_overlap_mentioned_p (operands[0], operands[4])
20382    /* Last PLUS must consist of operand 0 and 3.  */
20383    && !rtx_equal_p (operands[0], operands[3])
20384    && (rtx_equal_p (operands[3], operands[6])
20385        || rtx_equal_p (operands[3], operands[7]))
20386    && (rtx_equal_p (operands[0], operands[6])
20387        || rtx_equal_p (operands[0], operands[7]))
20388    /* The intermediate operand 0 must die or be same as output.  */
20389    && (rtx_equal_p (operands[0], operands[5])
20390        || peep2_reg_dead_p (3, operands[0]))"
20391   [(set (match_dup 3) (match_dup 4))
20392    (set (match_dup 0) (match_dup 1))]
20393 {
20394   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20395   int scale = 1 << INTVAL (operands[2]);
20396   rtx index = gen_lowpart (Pmode, operands[1]);
20397   rtx base = gen_lowpart (Pmode, operands[3]);
20398   rtx dest = gen_lowpart (mode, operands[5]);
20399
20400   operands[1] = gen_rtx_PLUS (Pmode, base,
20401                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20402   if (mode != Pmode)
20403     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20404   operands[0] = dest;
20405 })
20406 \f
20407 ;; Call-value patterns last so that the wildcard operand does not
20408 ;; disrupt insn-recog's switch tables.
20409
20410 (define_insn "*call_value_pop_0"
20411   [(set (match_operand 0 "" "")
20412         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20413               (match_operand:SI 2 "" "")))
20414    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20415                             (match_operand:SI 3 "immediate_operand" "")))]
20416   "!TARGET_64BIT"
20417 {
20418   if (SIBLING_CALL_P (insn))
20419     return "jmp\t%P1";
20420   else
20421     return "call\t%P1";
20422 }
20423   [(set_attr "type" "callv")])
20424
20425 (define_insn "*call_value_pop_1"
20426   [(set (match_operand 0 "" "")
20427         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20428               (match_operand:SI 2 "" "")))
20429    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20430                             (match_operand:SI 3 "immediate_operand" "i")))]
20431   "!TARGET_64BIT"
20432 {
20433   if (constant_call_address_operand (operands[1], Pmode))
20434     {
20435       if (SIBLING_CALL_P (insn))
20436         return "jmp\t%P1";
20437       else
20438         return "call\t%P1";
20439     }
20440   if (SIBLING_CALL_P (insn))
20441     return "jmp\t%A1";
20442   else
20443     return "call\t%A1";
20444 }
20445   [(set_attr "type" "callv")])
20446
20447 (define_insn "*call_value_0"
20448   [(set (match_operand 0 "" "")
20449         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20450               (match_operand:SI 2 "" "")))]
20451   "!TARGET_64BIT"
20452 {
20453   if (SIBLING_CALL_P (insn))
20454     return "jmp\t%P1";
20455   else
20456     return "call\t%P1";
20457 }
20458   [(set_attr "type" "callv")])
20459
20460 (define_insn "*call_value_0_rex64"
20461   [(set (match_operand 0 "" "")
20462         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20463               (match_operand:DI 2 "const_int_operand" "")))]
20464   "TARGET_64BIT"
20465 {
20466   if (SIBLING_CALL_P (insn))
20467     return "jmp\t%P1";
20468   else
20469     return "call\t%P1";
20470 }
20471   [(set_attr "type" "callv")])
20472
20473 (define_insn "*call_value_1"
20474   [(set (match_operand 0 "" "")
20475         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20476               (match_operand:SI 2 "" "")))]
20477   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20478 {
20479   if (constant_call_address_operand (operands[1], Pmode))
20480     return "call\t%P1";
20481   return "call\t%A1";
20482 }
20483   [(set_attr "type" "callv")])
20484
20485 (define_insn "*sibcall_value_1"
20486   [(set (match_operand 0 "" "")
20487         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20488               (match_operand:SI 2 "" "")))]
20489   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20490 {
20491   if (constant_call_address_operand (operands[1], Pmode))
20492     return "jmp\t%P1";
20493   return "jmp\t%A1";
20494 }
20495   [(set_attr "type" "callv")])
20496
20497 (define_insn "*call_value_1_rex64"
20498   [(set (match_operand 0 "" "")
20499         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20500               (match_operand:DI 2 "" "")))]
20501   "!SIBLING_CALL_P (insn) && TARGET_64BIT
20502    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20503 {
20504   if (constant_call_address_operand (operands[1], Pmode))
20505     return "call\t%P1";
20506   return "call\t%A1";
20507 }
20508   [(set_attr "type" "callv")])
20509
20510 (define_insn "*call_value_1_rex64_large"
20511   [(set (match_operand 0 "" "")
20512         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20513               (match_operand:DI 2 "" "")))]
20514   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20515   "call\t%A1"
20516   [(set_attr "type" "callv")])
20517
20518 (define_insn "*sibcall_value_1_rex64"
20519   [(set (match_operand 0 "" "")
20520         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20521               (match_operand:DI 2 "" "")))]
20522   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20523   "jmp\t%P1"
20524   [(set_attr "type" "callv")])
20525
20526 (define_insn "*sibcall_value_1_rex64_v"
20527   [(set (match_operand 0 "" "")
20528         (call (mem:QI (reg:DI R11_REG))
20529               (match_operand:DI 1 "" "")))]
20530   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20531   "jmp\t*%%r11"
20532   [(set_attr "type" "callv")])
20533 \f
20534 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20535 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20536 ;; caught for use by garbage collectors and the like.  Using an insn that
20537 ;; maps to SIGILL makes it more likely the program will rightfully die.
20538 ;; Keeping with tradition, "6" is in honor of #UD.
20539 (define_insn "trap"
20540   [(trap_if (const_int 1) (const_int 6))]
20541   ""
20542   { return ASM_SHORT "0x0b0f"; }
20543   [(set_attr "length" "2")])
20544
20545 (define_expand "sse_prologue_save"
20546   [(parallel [(set (match_operand:BLK 0 "" "")
20547                    (unspec:BLK [(reg:DI 21)
20548                                 (reg:DI 22)
20549                                 (reg:DI 23)
20550                                 (reg:DI 24)
20551                                 (reg:DI 25)
20552                                 (reg:DI 26)
20553                                 (reg:DI 27)
20554                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20555               (use (match_operand:DI 1 "register_operand" ""))
20556               (use (match_operand:DI 2 "immediate_operand" ""))
20557               (use (label_ref:DI (match_operand 3 "" "")))])]
20558   "TARGET_64BIT"
20559   "")
20560
20561 (define_insn "*sse_prologue_save_insn"
20562   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20563                           (match_operand:DI 4 "const_int_operand" "n")))
20564         (unspec:BLK [(reg:DI 21)
20565                      (reg:DI 22)
20566                      (reg:DI 23)
20567                      (reg:DI 24)
20568                      (reg:DI 25)
20569                      (reg:DI 26)
20570                      (reg:DI 27)
20571                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20572    (use (match_operand:DI 1 "register_operand" "r"))
20573    (use (match_operand:DI 2 "const_int_operand" "i"))
20574    (use (label_ref:DI (match_operand 3 "" "X")))]
20575   "TARGET_64BIT
20576    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20577    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20578   "*
20579 {
20580   int i;
20581   operands[0] = gen_rtx_MEM (Pmode,
20582                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20583   output_asm_insn (\"jmp\\t%A1\", operands);
20584   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20585     {
20586       operands[4] = adjust_address (operands[0], DImode, i*16);
20587       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20588       PUT_MODE (operands[4], TImode);
20589       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20590         output_asm_insn (\"rex\", operands);
20591       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20592     }
20593   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20594                              CODE_LABEL_NUMBER (operands[3]));
20595   return \"\";
20596 }
20597   "
20598   [(set_attr "type" "other")
20599    (set_attr "length_immediate" "0")
20600    (set_attr "length_address" "0")
20601    (set_attr "length" "135")
20602    (set_attr "memory" "store")
20603    (set_attr "modrm" "0")
20604    (set_attr "mode" "DI")])
20605
20606 (define_expand "prefetch"
20607   [(prefetch (match_operand 0 "address_operand" "")
20608              (match_operand:SI 1 "const_int_operand" "")
20609              (match_operand:SI 2 "const_int_operand" ""))]
20610   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20611 {
20612   int rw = INTVAL (operands[1]);
20613   int locality = INTVAL (operands[2]);
20614
20615   gcc_assert (rw == 0 || rw == 1);
20616   gcc_assert (locality >= 0 && locality <= 3);
20617   gcc_assert (GET_MODE (operands[0]) == Pmode
20618               || GET_MODE (operands[0]) == VOIDmode);
20619
20620   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20621      supported by SSE counterpart or the SSE prefetch is not available
20622      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20623      of locality.  */
20624   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20625     operands[2] = GEN_INT (3);
20626   else
20627     operands[1] = const0_rtx;
20628 })
20629
20630 (define_insn "*prefetch_sse"
20631   [(prefetch (match_operand:SI 0 "address_operand" "p")
20632              (const_int 0)
20633              (match_operand:SI 1 "const_int_operand" ""))]
20634   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20635 {
20636   static const char * const patterns[4] = {
20637    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20638   };
20639
20640   int locality = INTVAL (operands[1]);
20641   gcc_assert (locality >= 0 && locality <= 3);
20642
20643   return patterns[locality];
20644 }
20645   [(set_attr "type" "sse")
20646    (set_attr "memory" "none")])
20647
20648 (define_insn "*prefetch_sse_rex"
20649   [(prefetch (match_operand:DI 0 "address_operand" "p")
20650              (const_int 0)
20651              (match_operand:SI 1 "const_int_operand" ""))]
20652   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20653 {
20654   static const char * const patterns[4] = {
20655    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20656   };
20657
20658   int locality = INTVAL (operands[1]);
20659   gcc_assert (locality >= 0 && locality <= 3);
20660
20661   return patterns[locality];
20662 }
20663   [(set_attr "type" "sse")
20664    (set_attr "memory" "none")])
20665
20666 (define_insn "*prefetch_3dnow"
20667   [(prefetch (match_operand:SI 0 "address_operand" "p")
20668              (match_operand:SI 1 "const_int_operand" "n")
20669              (const_int 3))]
20670   "TARGET_3DNOW && !TARGET_64BIT"
20671 {
20672   if (INTVAL (operands[1]) == 0)
20673     return "prefetch\t%a0";
20674   else
20675     return "prefetchw\t%a0";
20676 }
20677   [(set_attr "type" "mmx")
20678    (set_attr "memory" "none")])
20679
20680 (define_insn "*prefetch_3dnow_rex"
20681   [(prefetch (match_operand:DI 0 "address_operand" "p")
20682              (match_operand:SI 1 "const_int_operand" "n")
20683              (const_int 3))]
20684   "TARGET_3DNOW && TARGET_64BIT"
20685 {
20686   if (INTVAL (operands[1]) == 0)
20687     return "prefetch\t%a0";
20688   else
20689     return "prefetchw\t%a0";
20690 }
20691   [(set_attr "type" "mmx")
20692    (set_attr "memory" "none")])
20693
20694 (define_expand "stack_protect_set"
20695   [(match_operand 0 "memory_operand" "")
20696    (match_operand 1 "memory_operand" "")]
20697   ""
20698 {
20699 #ifdef TARGET_THREAD_SSP_OFFSET
20700   if (TARGET_64BIT)
20701     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20702                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20703   else
20704     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20705                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20706 #else
20707   if (TARGET_64BIT)
20708     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20709   else
20710     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20711 #endif
20712   DONE;
20713 })
20714
20715 (define_insn "stack_protect_set_si"
20716   [(set (match_operand:SI 0 "memory_operand" "=m")
20717         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20718    (set (match_scratch:SI 2 "=&r") (const_int 0))
20719    (clobber (reg:CC FLAGS_REG))]
20720   ""
20721   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20722   [(set_attr "type" "multi")])
20723
20724 (define_insn "stack_protect_set_di"
20725   [(set (match_operand:DI 0 "memory_operand" "=m")
20726         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20727    (set (match_scratch:DI 2 "=&r") (const_int 0))
20728    (clobber (reg:CC FLAGS_REG))]
20729   "TARGET_64BIT"
20730   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20731   [(set_attr "type" "multi")])
20732
20733 (define_insn "stack_tls_protect_set_si"
20734   [(set (match_operand:SI 0 "memory_operand" "=m")
20735         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20736    (set (match_scratch:SI 2 "=&r") (const_int 0))
20737    (clobber (reg:CC FLAGS_REG))]
20738   ""
20739   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20740   [(set_attr "type" "multi")])
20741
20742 (define_insn "stack_tls_protect_set_di"
20743   [(set (match_operand:DI 0 "memory_operand" "=m")
20744         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20745    (set (match_scratch:DI 2 "=&r") (const_int 0))
20746    (clobber (reg:CC FLAGS_REG))]
20747   "TARGET_64BIT"
20748   {
20749      /* The kernel uses a different segment register for performance reasons; a
20750         system call would not have to trash the userspace segment register,
20751         which would be expensive */
20752      if (ix86_cmodel != CM_KERNEL)
20753         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20754      else
20755         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20756   }
20757   [(set_attr "type" "multi")])
20758
20759 (define_expand "stack_protect_test"
20760   [(match_operand 0 "memory_operand" "")
20761    (match_operand 1 "memory_operand" "")
20762    (match_operand 2 "" "")]
20763   ""
20764 {
20765   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20766   ix86_compare_op0 = operands[0];
20767   ix86_compare_op1 = operands[1];
20768   ix86_compare_emitted = flags;
20769
20770 #ifdef TARGET_THREAD_SSP_OFFSET
20771   if (TARGET_64BIT)
20772     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20773                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20774   else
20775     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20776                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20777 #else
20778   if (TARGET_64BIT)
20779     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20780   else
20781     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20782 #endif
20783   emit_jump_insn (gen_beq (operands[2]));
20784   DONE;
20785 })
20786
20787 (define_insn "stack_protect_test_si"
20788   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20789         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20790                      (match_operand:SI 2 "memory_operand" "m")]
20791                     UNSPEC_SP_TEST))
20792    (clobber (match_scratch:SI 3 "=&r"))]
20793   ""
20794   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20795   [(set_attr "type" "multi")])
20796
20797 (define_insn "stack_protect_test_di"
20798   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20799         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20800                      (match_operand:DI 2 "memory_operand" "m")]
20801                     UNSPEC_SP_TEST))
20802    (clobber (match_scratch:DI 3 "=&r"))]
20803   "TARGET_64BIT"
20804   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20805   [(set_attr "type" "multi")])
20806
20807 (define_insn "stack_tls_protect_test_si"
20808   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20809         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20810                      (match_operand:SI 2 "const_int_operand" "i")]
20811                     UNSPEC_SP_TLS_TEST))
20812    (clobber (match_scratch:SI 3 "=r"))]
20813   ""
20814   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20815   [(set_attr "type" "multi")])
20816
20817 (define_insn "stack_tls_protect_test_di"
20818   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20819         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20820                      (match_operand:DI 2 "const_int_operand" "i")]
20821                     UNSPEC_SP_TLS_TEST))
20822    (clobber (match_scratch:DI 3 "=r"))]
20823   "TARGET_64BIT"
20824   {
20825      /* The kernel uses a different segment register for performance reasons; a
20826         system call would not have to trash the userspace segment register,
20827         which would be expensive */
20828      if (ix86_cmodel != CM_KERNEL)
20829         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20830      else
20831         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20832   }
20833   [(set_attr "type" "multi")])
20834
20835 (define_mode_macro CRC32MODE [QI HI SI])
20836 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
20837 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
20838
20839 (define_insn "sse4_2_crc32<mode>"
20840   [(set (match_operand:SI 0 "register_operand" "=r")
20841         (unspec:SI
20842           [(match_operand:SI 1 "register_operand" "0")
20843            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
20844           UNSPEC_CRC32))]
20845   "TARGET_SSE4_2"
20846   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
20847   [(set_attr "type" "sselog1")
20848    (set_attr "prefix_rep" "1")
20849    (set_attr "prefix_extra" "1")
20850    (set_attr "mode" "SI")])
20851
20852 (define_insn "sse4_2_crc32di"
20853   [(set (match_operand:DI 0 "register_operand" "=r")
20854         (unspec:DI
20855           [(match_operand:DI 1 "register_operand" "0")
20856            (match_operand:DI 2 "nonimmediate_operand" "rm")]
20857           UNSPEC_CRC32))]
20858   "TARGET_SSE4_2 && TARGET_64BIT"
20859   "crc32q\t{%2, %0|%0, %2}"
20860   [(set_attr "type" "sselog1")
20861    (set_attr "prefix_rep" "1")
20862    (set_attr "prefix_extra" "1")
20863    (set_attr "mode" "DI")])
20864
20865 (include "mmx.md")
20866 (include "sse.md")
20867 (include "sync.md")